; ***************************************************************
; リスト uart interrupt 20211022
; ***************************************************************
    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

; *********************** 共通RAMエリア **************************
       CBLOCK   0x70
       DATA_INDEX
       IR_FLAG
       DLY_1
       DLY_2
       RxDATA
       ENDC

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

        ORG    4
;void __interrupt() Rx_isr ==========================
        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
        MOVF RC1REG, W     ; RxData = RC1REG;
        MOVWF RxDATA       ; 受信データをRxDataに保管;
        XORLW 0x21         ;   '!' か
        BTFSC STATUS, Z    ;   '!' なら
        GOTO CASRST        ;   case re-startへ
        MOVF RxDATA, W
        XORLW '1'          ;   '1' か
        BTFSC STATUS, Z    ;   '1' か
        GOTO CASONE        ;   case LED ONへ
        MOVF RxDATA, W
        XORLW '2'          ;   '2' か
        BTFSC STATUS, Z    ;   '2' なら
        GOTO CASTWO        ;   case LED OFFへ
        GOTO RTNINT
;              case '1'     // 1 なら
CASONE  MOVLB 0x2           ; Bank 2
        BSF LATA, LATA2     ; LED 点灯
        GOTO RTNINT
;              case '2'     //  2 なら
CASTWO  MOVLB 0x2           ; Bank 2
        BCF LATA, LATA2     ; LED 消灯
        GOTO RTNINT

;              case ';'     //  ; なら
CASRST  RESET               ; デバイスのリセット
        GOTO RTNINT

RTNINT
        RETFIE


;void main =====================================
START
        MOVLB 0x1        ; Bank 1
        MOVLW 0x3B       ; 0b111011;
        MOVWF TRISA      ; RA2 出力 他は すべて入力
        MOVLW 0x3F       ; 0b111111;
        MOVWF TRISC      ; Port すべて入力

        MOVLB 0x3        ; Bank 3
        CLRF ANSELA      ; すべてデジタル
        CLRF ANSELC      ; すべてデジタル

        MOVLB 0x4        ; Bank 4
        MOVLW 0xB        ; 0b001011;
        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 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

; LED 点滅 ------------------------------------
        MOVLB 0x2        ; Bank 2
        BSF LATA, LATA2  ; LED = 1;
        CALL DLY200      ; 200ms 遅延
        MOVLB 0x2        ; Bank 2
        BCF LATA, LATA2  ; LED = 0;
        CALL DLY200      ; 200ms 遅延
        MOVLB 0x2        ; Bank 2
        BSF LATA, LATA2  ; LED = 1;
        CALL DLY200      ; 200ms 遅延
        MOVLB 0x2        ; Bank 2
        BCF LATA, LATA2  ; LED = 0;
        CALL DLY200      ; 200ms 遅延
    GOTO EN_INT

; __delay_ms(200); -----------------------
DLY200 MOVLB 0x0        ; Bank 0
        MOVLW 0x9
        MOVWF DLY_1
        MOVLW 0x1E
        MOVWF DLY_2
        MOVLW 0xE4
DLYUOOP DECFSZ WREG, F
        GOTO DLYUOOP
        DECFSZ DLY_2, F
        GOTO DLYUOOP
        DECFSZ DLY_1, F
        GOTO DLYUOOP
        RETURN

;
; UART Rx 割込みを使用許可
EN_INT   MOVLB 0x1        ; Bank 1
         BSF PIE1, RCIE   ; UART Rx 割込みを使用許可
         BSF INTCON, PEIE ; 周辺機能割込みの使用許可
         BSF INTCON, GIE  ; 全割込みの使用許可
;
;;    printf("Start\r\n");       // 準備完了を送信
    CLRW
    CALL PRINT_MSG

;    // ----------- 繰返し --------------------------------------------

LOOP  GOTO LOOP    ;    while(1) ;


;--------------------------------------------------
; 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      "Start\r\n",0x00
       DT      "Hello OK\r\n",0x00
;--------------------------------------------------
;   一文字出力 WREG に送信する文字を持ってCALL
;--------------------------------------------------
PUTCH
       MOVLB   0x0            ; BANK 1 を選択
W_TXIF BTFSS   PIR1, TXIF     ; 送信終了待ち
       GOTO    W_TXIF
       MOVLB   0x3          ; BANK 3 選択
       MOVWF   TX1REG         ; 文字出力
       RETURN

ENDPGM MOVLP   0x0

       END