; ***************************************************************
; LogiAsm 20211028  =  =
; ***************************************************************
    LIST        P=PIC16F18326    ;  使用するPICを指定
    INCLUDE     "P16F18326.INC"  ;  読み込む設定ファイルを指定

 __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF &  _CSWEN_OFF & _FCMEN_OFF
 __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _WDTE_OFF & _LPBOREN_OFF & _BOREN_OFF & _BORV_LOW & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
 __CONFIG _CONFIG3, _WRT_OFF & _LVP_ON
 __CONFIG _CONFIG4, _CP_OFF & _CPD_OFF

; *********************** Bank RAMエリア **************************
      CBLOCK   0x20   ; Bank 0x10  Linear 2500
        bRxbuf0    ; コマンド受信バッファ
        bRxbuf1
        bRxbuf2
        bRxbuf3
        bRxbuf4
        bRxbuf5
        bRxbuf6
        iFSR0L    ; 割込み処理で使用のFSR0 退避用
        iFSR0H    ; 割込み処理で使用のFSR0 退避用
        bErr_Cmd  ; 受信文字列のエラー確認
      ENDC
; *********************** 共通RAMエリア **************************
   CBLOCK   0x70
       RxComd        ; コマンド受信フラグ
       RxDATA        ; 受信データ一時保管
       DATA_INDEX    ; メッセージ送信ポインタ
       Temp_1        ; 共用変数メモリ
       Temp_2        ; 共用変数メモリ
       Temp_3        ; 共用変数メモリ
       FreRun        ; フリーラン モード
       BfrAqH        ; トリガ前収集数
       BfrAqL        ; トリガ前収集数
       AftAqH        ; トリガ後収集数
       AftAqL        ; トリガ後収集数
   ENDC

; ***************************************************************
        ORG    0
        GOTO   START

        ORG    4
; 割り込み処理 UART 受信 ==========================
;   一般RAM Bank 16  FSR 2500 -
;    bRxbuf0-7 受信データバッファ
;    iFSR0    割り込みに使用 FSR0 の退避
;   共通RAM
;    RxComd RxDATA
;=====================================================
        MOVLB 0x10          ; Bank 16
        MOVF  iFSR0L, W     ; 割り込みに使用している
        MOVWF FSR0L         ; FSR0 の値をロード
        MOVF  iFSR0H, W
        MOVWF FSR0H

        MOVLB 0x0           ; Bank 0
        BTFSS PIR1, RCIF    ; uart 受信からの割り込みか
        GOTO RTNINT         ; 受信で無いなら復帰
                            ; 受信なら
        MOVLB 0x3           ; Bank 3
        BTFSS RC1STA, OERR  ; OERR 受信エラーか
        GOTO RX_OK          ;   受信エラー無しなら
        BCF RC1STA, CREN    ;   エラーなら CREN OFF/ONで
        BSF RC1STA, CREN    ;              エラークリア
        GOTO RTNINT         ;   復帰

;       正常受信なら
RX_OK
        MOVLB 0x3          ; Bank 3
        MOVF RC1REG, W     ; RxData = RC1REG;
        MOVWF RxDATA       ; 受信データをRxDataに保管;
        XORLW 0x21         ;   '!' STOP か
        BTFSC STATUS, Z    ;   '!' なら
        GOTO CASRST        ;   case re-startへ

        MOVF RxDATA, W
        XORLW 0x0A         ;   'CR' か
        BTFSC STATUS, Z    ;   'CR' か
        GOTO C_CRLF        ;   case C_CRLFへ

        MOVF RxDATA, W
        XORLW 0x0D         ;   'LF' か
        BTFSC STATUS, Z    ;   'LF' なら
        GOTO C_CRLF        ;   case C_CRLFへ
        GOTO C_OTHR

CASRST  RESET               ; デバイスのリセット
        GOTO RTNINT
C_CRLF
        MOVF FSR0L, W       ; 受信ポインタを W に
        XORLW 0x07          ; 受信データ数を
        BTFSC STATUS, Z     ; 確認
        BSF   RxComd, 0     ;   7 ならフラグセット
        CLRF  FSR0L         ; 受信ポインタをリセット
        GOTO RTNINT
C_OTHR
        MOVLW   0x07        ; Buff満杯か
        SUBWF   FSR0L, w    ;   ポインタを確認
        MOVF    RxDATA, W   ; 受信データを W に
        BTFSS   STATUS, C   ; 満杯でなければ
        MOVWF   INDF0       ;   Buffに保存
        INCF    FSR0L, F    ; 満杯でもポインタは進める
        GOTO    RTNINT
RTNINT
        MOVLB 0x10         ; Bank 16
        MOVF  FSR0L, W     ; PUSH FSR0 退避する
        MOVWF iFSR0L
        MOVF  FSR0H, W
        MOVWF iFSR0H
        RETFIE

;void main =====================================
START
        MOVLB 0x1        ; Bank 1
        MOVLW 0x3F       ; 0b111111;
        MOVWF TRISA      ; すべて入力
        MOVLW 0x3F       ; 0b111111;
        MOVWF TRISC      ; Port すべて入力
        MOVLB 0x3        ; Bank 3
        CLRF ANSELA      ; すべてデジタル
        CLRF ANSELC      ; すべてデジタル
        MOVLB 0x4        ; Bank 4
        MOVLW 0xF        ; 0b001111;
        MOVWF WPUA       ; RA0-RA3 弱プルアップ ON
        MOVLW 0x20       ; 0b100000;
        MOVWF WPUC       ; RC5 弱プルアップ ON
        MOVLB 0x1C       ; Bank 1C
        MOVLW 0x4        ; RXPPS  = 0x04;
        MOVWF RXPPS      ; RA4->EUSART RX
        MOVLB 0x1D       ; Bank 1D
        MOVLW 0x14       ; RA5PPS = 0x14;
        MOVWF RA5PPS     ; RA5->EUSART TX
;
;//------------ Initialize timer 0 -------------------------------
       MOVLB 0x0          ; Bank 0x0 選択
       MOVLW 0x4D         ; 0b01001101;
       MOVWF T0CON1       ; Fosc/4 Sync PreS 1/8192
       CLRF  T0CON0       ; T0 OFF 8bit Post 1/1
       MOVLW 0xFF         ; TMR0 PR を FF にセット
       MOVWF TMR0H        ; TMR0H = 0xFF
;
;//------------ Initialize UART ----------------------------
        MOVLB 0x3        ; Bank 3
        MOVLW 0x90       ; 0b10010000;
        MOVWF RC1STA     ; 8 bit 連続受信
        MOVLW 0x24       ; 0b00100100;
        MOVWF TX1STA     ; 非同期送受信 High Baud Rate選択
        MOVLW 0x8        ; 0b00001000;
        MOVWF BAUD1CON   ; 115200 baud
        CLRF SP1BRGH     ; SP1BRGH  = 0;
        MOVLW 0x0        ; SP1BRG   = 68;
        MOVWF SP1BRGH
        MOVLW 0x44
        MOVWF SP1BRG

; CLC 設定 ------------------------------------
       MOVLB 0x1C
       MOVLW 0x10
       MOVWF CLCIN0PPS   ; RC0->CLCIN0
       MOVLW 0x11
       MOVWF CLCIN1PPS   ; RC1->CLCIN1
       MOVLW 0x12
       MOVWF CLCIN2PPS   ; RC2->CLCIN2
;// Set the CLC1
       MOVLB 0x1E
       MOVLW 0x2
       MOVWF CLC1POL     ; G2出力は負極性 他出力は正極性
       CLRF  CLC1SEL0     ; LC1D1S (CLCIN0PPS)
       MOVLW 0x1
       MOVWF CLC1SEL1    ; LC1D2S (CLCIN1PPS)
       MOVLW 0x2
       MOVWF CLC1SEL2    ; LC1D3S (CLCIN2PPS)
       MOVLW 0x18
       MOVWF CLC1SEL3    ; LC1D4S T0_overflow
       MOVLW 0x80
       MOVWF CLC1GLS0    ; G1D1-3 Vss G1D4 正接続
       MOVLW 0x2
       MOVWF CLC1GLS1    ; G2D1 負接続 G2D2-4 Vss
       CLRF  CLC1GLS2    ;  全てVss
       CLRF  CLC1GLS3    ;  全てVss
       MOVLW 0x84
       MOVWF CLC1CON     ;  1-input D ff
;// Set the CLC2
       MOVLW 0x2
       MOVWF CLC2POL
       CLRF  CLC2SEL0
       MOVLW 0x4
       MOVWF CLC2SEL1    ; LC1_out
       MOVLW 0x2
       MOVWF CLC2SEL2
       MOVLW 0x18
       MOVWF CLC2SEL3
       MOVLW 0x80
       MOVWF CLC2GLS0
       MOVLW 0x5           ; G1D1-2 正接続 G2D3-4 Vss
       MOVWF CLC2GLS1
       CLRF  CLC2GLS2
       CLRF  CLC2GLS3
       MOVLW 0x84
       MOVWF CLC2CON
; 変数初期設定 ------------------------------------
        CLRF   RxComd     ; コマンド受信フラグ
        CLRF   Temp_1

        MOVLB  0x10        ; Bank 16
        CLRF   iFSR0L     ; 受信ポインタ(FSR0退避)をリセット
        MOVLW  0x25
        MOVWF  iFSR0H
; UART Rx 割込みを使用許可
         MOVLB 0x1        ; Bank 1
         BSF PIE1, RCIE   ; UART Rx 割込みを使用許可
         BSF INTCON, PEIE ; 周辺機能割込みの使用許可
         BSF INTCON, GIE  ; 全割込みの使用許可
;   !!\r\n   準備完了を送信
         CLRW
         CALL PRINT_MSG
;    // ----------- メイン 繰返し ---------------------
LOOP
        BTFSS  RxComd, 0   ; コマンドを受信したか
        GOTO   LOOP        ;   否 繰返しに戻る
        BCF    RxComd, 0   ; フラグ クリア
        call CkValidity
        MOVLB  0x10        ; Bank 16 設定
        BTFSS  bErr_Cmd, 0
        goto   Cmd_OK
Cmd_NG  movlw  0x1        ; コマンドエラー検知
        call   PRINT_MSG  ; 1 ![CRLF]を送信
        goto   LOOP       ; コマンド受信待ちへ
Cmd_OK
        MOVLW  0x6             ; コマンド OK
        call   PRINT_MSG       ;  #[CRLF]を送信
        CALL   SetTrigger      ; トリガ条件の設定
        call   SetSampRate     ; サンプルレートの設定
        CALL   SetTrgPosition  ; トリガ位置の設定
        CALL   Aquition        ; データの取得
        CALL   OutAqData       ; データの送信
        GOTO   LOOP            ; LOOP を繰り返す


; ***********************************************
cTstNum   equ   Temp_1       ; テスト文字変換数値
PrePtn    equ   CLC1GLS1     ; CLC1 Gate2 入力
PstPtn    equ   CLC2GLS1     ; CLC2 Gate2 入力
TrgChn    equ   CLC2SEL0     ; CLC2 入力1 選択

; // ----------- 各ChのTrigger条件設定 --------
SetTrigger
       MOVLW 0x25      ; FSR0 にBank RAM番地
       MOVWF FSR0H     ; 設定し受信データ取得
       MOVLW 0x03      ; FSR0 = 2503
       MOVWF FSR0L     ; 3chから処理開始
       MOVLB 0x1E      ; CLC ファイルの Bank
       CLRF  PrePtn    ; CLC1 Gate2 入力 クリア
       CLRF  PstPtn    ; CLC2 Gate2 入力 クリア
       CLRF  TrgChn    ; CLC2 入力1 選択  クリア
TrgDo
       LSLF  PrePtn, F  ; PrePtnを左シフト
       LSLF  PrePtn, F  ; PrePtnを左シフト
       MOVIW FSR0--     ; 設定文字を取得
       ANDLW 0x07       ; 設定文字を数値に変換
       MOVWF cTstNum    ; 設定数値を保存
       ; 立上り の設定
       CALL   PreData   ; PreData取得
       IORWF  PrePtn, F ; PrePtnに結合
       ; PrePtn の設定
       MOVF  cTstNum, W ; 処理する数値を取得
       xorlw 0x3        ; 立上り'3'指定か
       btfss STATUS, Z  ;   立上りはスキップ
       goto  TgCk4      ; 異なれば、次
       movlw 0x05       ; Ch CLC1out 反転入力
       movwf PstPtn     ; CLC2 Gate2 入力 に設定
       movf  FSR0L, W   ; Ch番号 - 1
       movwf TrgChn     ; CLC2 入力1 選択に設定
TgCk4  ; 立下り の設定
       MOVF  cTstNum, W ; 処理する数値を取得
       xorlw 0x4        ; 立下り'4'指定か
       btfss STATUS, Z
       goto  TgCkNx
       movlw 0x06
       movwf PstPtn
       movf  FSR0L, W
       movwf TrgChn
TgCkNx ; Ch処理の終了か
       MOVF  FSR0L, F   ; 次処理Chを取得
       BTFSS STATUS, Z  ;   ch 0 で終了
       GOTO  TrgDo      ; 0 でなければ次のchを処理
       return
PreData
       BRW
       DT    0,1,2,2,1
;
; // ----------- サンプルレート設定 --------------
;       TMR0 の プリスケラーとPR(TMR0H) を設定する
; // -------------------------------------------
SetSampRate
        MOVLB  0x10         ; Bank 16
        MOVF   bRxbuf5, W   ; 受信データSampRateを取得
        ANDLW  0x0F         ; 設定文字を数値に変換
        MOVWF  cTstNum      ; 設定数値を保存
        call   T0_CON1      ; T0CON1設定値に変換
        MOVLB  0x0          ; Bank 0
        MOVWF  T0CON1       ; T0CON1設定を保存
        movf   cTstNum, W   ; 設定数値を取得
        call   TMR0_H       ; TMR0H設定値に変換
        MOVWF  TMR0H        ; TMR0H設定を保存
        RETURN
T0_CON1     ; サンプルレート毎の T0CON1 設定値
       BRW  ; 1us,   2,   5,  10,  20,  50, 100, 200, 500, 1ms
       DT    0x40,0x40,0x40,0x43,0x43,0x43,0x43,0x43,0x45,0x45
TMR0_H      ; サンプルレート毎の TMR0H 設定値
       BRW  ; 1us,   2,   5,  10,  20,  50, 100, 200, 500, 1ms
       DT     0x7, 0xF,0x27, 0x9,0x13,0x31,0x63,0xC7,0x7C,0xF9


; =========================================
; トリガ前後の収集数を設定
;        BfrAqH  BfrAqL      ; トリガ前収集数
;        AftAqH  AftAqL      ; トリガ後収集数
;        フリーラン時は FreRun [1]にする
; =========================================
SetTrgPosition
        clrf   FreRun       ; フリーラン解除
        MOVLB   0x10        ; Bank 16
        movf    bRxbuf6, W
        ANDLW  0x07         ; 設定文字を数値に変換
        MOVWF  cTstNum      ; 設定数値を保存
        call   Bfr_AqH      ; BfrAqH 設定値に変換保存
        MOVWF  BfrAqH       ;
        movf   cTstNum, W   ; 設定数値を取得
        call   Bfr_AqL      ; BfrAqL 設定値に変換保存
        MOVWF  BfrAqL       ;
        movf   cTstNum, W   ; 設定数値を取得
        call   Aft_AqH      ; AftAqH 設定値に変換保存
        MOVWF  AftAqH       ;
        movf   cTstNum, W   ; 設定数値を取得
        call   Aft_AqL      ; AftAqL 設定値に変換保存
        MOVWF  AftAqL       ;
        movf   cTstNum, W   ; 設定数値を取得
        xorlw  0x03
        BTFSC   STATUS, Z   ; フリーラン なら
        bsf     FreRun, 0   ; フリーランフラグ設定
        RETURN

Bfr_AqH     ; トリガ前データ取得 パス 設定値
       BRW  ;  前,   1,   2,Free,中央,  後
       DT    0x01,0x01,0x01,0x04,0x03,0x04
Bfr_AqL     ; トリガ前データ取得 端数 設定値
       BRW  ;  前,   1,   2,Free,中央,  後
       DT    0x64,0x01,0x01,0x00,0x26,0xE8
Aft_AqH     ; トリガ後データ取得 パス 設定値
       BRW  ;  前,   1,   2,Free,中央,  後
       DT    0x04,0x08,0x0C,0x01,0x02,0x01
Aft_AqL     ; トリガ後データ取得 端数 設定値
       BRW  ;  前,   1,   2,Free,中央,  後
       DT    0x9C,0x84,0x6C,0x01,0xDA,0x18


; データ収集 ===============================================

; =========================================================
Aquition
         MOVLB 0x0        ; Bank 0x0 設定
         BSF T0CON0, T0EN ; Timer1スタート
         MOVLW  0x20      ; FSR0 に番地設定
         MOVWF  FSR0H
         MOVLW  0x00
         MOVWF  FSR0L
         MOVLB 0x0              ; Bank 0x0 設定
         BCF PIR0, TMR0IF       ; TMR0IF リセット

; -------------- トリガ前保存 および FreeRun --------------
BfrTrg
         BTFSS  PIR0, TMR0IF  ; 取得タイミングを待つ
         GOTO   BfrTrg
         BCF    PIR0, TMR0IF  ; TMR0IF リセット
         MOVF   PORTC, W      ; PORTC 取得
         MOVWI  FSR0++        ; データを保存
         movlw  0x23          ; リングバッファ
         andwf  FSR0H, f      ; のための処理
         DECFSZ BfrAqL, F     ; 保存数を確認
         GOTO   BfrTrg        ;   端数を確認
         DECFSZ BfrAqH, F     ;   パス数を確認
         GOTO   BfrTrg
         BTFSC FreRun, 0      ; FreRun なら
         RETURN               ; FreeRun時は、収集完了

; ---------------- トリガ条件の確認 ------------------
WatTrg
         MOVLB 0x0               ; Bank 0x0 設定
WaitTm
         BTFSS PIR0, TMR0IF      ; 取得タイミングを
         GOTO  WaitTm            ;   待つ
         BCF PIR0, TMR0IF        ; TMR0IF リセット
         MOVF   PORTC, W         ; PORTC 取得
         MOVWI  FSR0++           ; データを保存
         movlw  0x23             ; リングバッファ
         andwf  FSR0H, f         ; のための処理
         MOVLB 0x1E              ; Bank 0x1E 設定
         BTFSS  CLC2CON, LC2OUT  ;  LC2OUT 確認
         GOTO   WatTrg
         MOVLB  0x0              ; Bank 0x0 設定

; -------------- トリガ後保存 -------------------------
AftTrg
         BTFSS  PIR0, TMR0IF     ; 取得タイミングを
         GOTO   AftTrg           ;    待つ
         BCF    PIR0, TMR0IF     ; TMR0IF リセット
         MOVF   PORTC, W         ; PORTC 取得
         MOVWI  FSR0++           ; データを保存
         movlw  0x23             ; リングバッファ
         andwf  FSR0H, f         ; のための処理
         DECFSZ AftAqL, F        ; 保存数を循環
         GOTO   AftTrg
         DECFSZ AftAqH, F
         GOTO   AftTrg
         RETURN                ; 収集完了

;--------------------------------------------------
; 収集データを送信
;   ESR0 に、送信開始あそれえ雨を持っている
;   Temp_1 Temp_2 に
;--------------------------------------------------
OutAqData
         MOVLW  0x40       ; 行の文字数を
         MOVWF  Temp_1     ;   64文字に設定
         MOVLW  0x10       ; 行数を16行にし
         MOVWF  Temp_2     ;   64 x 16行 = 1024
OutAq1
         moviw  FSR0++     ; データを読み
         ANDLW  0x1F       ; 不要ビットを削除
         IORLW  0x40       ; @ からの文字に変換
         call   PUTCH      ; === 一文字出力 ===
         movlw  0x23       ; FSR0 の
         andwf  FSR0H, f   ;   リングバッファ処理
         DECFSZ Temp_1, F  ; 64文字送信したか
         GOTO   OutAq1     ;   まだなら戻る
         MOVLW  0x40       ; 次の準備で
         MOVWF  Temp_1     ;   Temp_1 初期化
         MOVLW  0x2        ; 行末の
         call   PRINT_MSG  ;   CRLFを送信
         DECFSZ Temp_2, F  ; 16行送信したか
         GOTO   OutAq1     ;   まだなら戻る
         MOVLW  0x5        ; データ送信完了したので
         call   PRINT_MSG  ; ##[CRLF]を送信
         RETURN

;--------------------------------------------------
; コマンドを処理
;
;--------------------------------------------------
CkValidity
        MOVLB  0x10          ; Bank 16
        bsf    bErr_Cmd, 0   ;  エラー『有』に設定
CkCha0  MOVF   bRxbuf0, W    ; 受信データ1を取得
        XORLW  '#'
        BTFSS  STATUS, Z     ; '#' か
        RETURN               ;  否 ならエラーで復帰
CkCha4  MOVF   bRxbuf4, W    ; 受信データ1を取得
        XORLW  '#'
        BTFSS  STATUS, Z     ; '#' か
        RETURN               ;  否 ならエラーで復帰

        clrf   bErr_Cmd      ;  エラー『無』に設定
        movlw  0x5           ; 5 以上はエラー
        movwf  Temp_1
        MOVF   bRxbuf1, W    ; 受信データ1を取得
        call   CkRange
        MOVF   bRxbuf2, W    ; 受信データ2を取得
        call   CkRange
        MOVF   bRxbuf3, W    ; 受信データ3を取得
        call   CkRange
        movlw  0xA           ; A 以上はエラー
        movwf  Temp_1
        MOVF   bRxbuf5, W    ; 受信データ5を取得
        call   CkRange
        movlw  0x6           ; 6 以上はエラー
        movwf  Temp_1
        MOVF   bRxbuf6, W    ; 受信データ6を取得
        call   CkRange
        RETURN                ;  復帰

CkRange  ; 上下限を確認し、超えていればエラービットをセット
         sublw  0x2F         ; L - W 下限確認 0以上でOK
         BTFSC  STATUS, C    ; 引くことができれば C set
         GOTO   Rerror       ; エラー
         addwf  Temp_1, w    ; 上限確認 
         BTFSS  STATUS, C    ; 引くことができれば C set
Rerror   bsf  bErr_Cmd, 0    ; エラービットをセット
         return


;--------------------------------------------------
; Start と送信
;   WREG に送信する文字の先頭番号を持ってCALL
;--------------------------------------------------
PRINT_MSG
       MOVLB   0x0          ; BANK 0 選択
       MOVWF   DATA_INDEX     ; 文字INDEXを 設定
P_NEXT MOVF    DATA_INDEX,W   ; 文字INDEXを W に取得
       CALL    MSG_DT         ; 文字を W に取得
       MOVF    WREG,F         ; 文字終端かテスト
       BTFSC   STATUS,Z       ; 終端文字なら
       RETURN                 ;   リターン
       ; 送信する文字なら
       CALL    PUTCH          ;   一文字出力
       ; 次の文字を準備
       MOVLB   0x0            ;  BANK 0 選択
       INCF    DATA_INDEX,F   ;   文字INDEXを +1
       GOTO    P_NEXT         ;   次の文字へ
MSG_DT BRW
       DT      "!!\r\n",0x00        ; 0 !![CRLF]
       DT      "##\r\n",0x00        ; 5 ##[CRLF]
       DT      "Hello OK\r\n",0x00  ; 10 Hello OK[CRLF]
;--------------------------------------------------
;   一文字出力 WREG に送信する文字を持ってCALL
;--------------------------------------------------
PUTCH
       MOVLB   0x0            ; BANK 1 を選択
W_TXIF BTFSS   PIR1, TXIF     ; 送信終了待ち
       GOTO    W_TXIF
       MOVLB   0x3          ; BANK 3 選択
       MOVWF   TX1REG         ; 文字出力
       RETURN


       END