OSDN Git Service

V303, newcomer: FastForth I2C TERMINAL
[fast-forth/master.git] / forthMSP430FR_TERM_I2C.asm
1 ; -*- coding: utf-8 -*-
2
3 ; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices with I2C TERMINAL
4 ; Copyright (C) <2019>  <J.M. THOORENS>
5 ;
6 ; This program is free software: you can redistribute it and/or modify
7 ; it under the terms of the GNU General Public License as published by
8 ; the Free Software Foundation, either version 3 of the License, or
9 ; (at your option) any later version.
10 ;
11 ; This program is distributed in the hope that it will be useful,
12 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ; GNU General Public License for more details.
15 ;
16 ; You should have received a copy of the GNU General Public License
17 ; along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19 ; for I2C_Slave init, see in /inc/TARGET.asm file
20
21 ; ----------------------------------;
22 ; ACCEPT part I prepare TERMINAL_INT;   a START can be match here, with START ifg flag 
23 ; ----------------------------------;
24             MOV TOS,W               ;1 -- addr len  W=len
25             MOV @PSP,TOS            ;2 -- org ptr                                               )
26             ADD TOS,W               ;1 -- org ptr   W=buf_end                                   )
27             MOV #0Ah,T              ;2              T = 'LF' to speed up char loop in part II   > prepare stack and registers for TERMINAL_INT use
28             MOV #20h,S              ;2              S = 'BL' to speed up char loop in part II   ) 
29             PUSHM #4,IP             ;6          PUSH IP,S,T,W  r-- IP, 'BL', 'LF', buf_end )
30 ACCEPT1     BIC #IE_TERM,&TERM_IFG  ;           clear UCSTTIFG before use during SLEEP
31 ; ----------------------------------;
32 ;; -test-v-test-v-test-v-test-v-test-;
33 ;            BIC.B #LED1,&LED1_DIR   ;           Red led OFF, end of Slave TX
34 ;            BIC.B #LED1,&LED1_OUT   ;           Red led OFF, end of Slave TX
35 ;; -test-^-test-^-test-^-test-^-test-;
36 ; ----------------------------------;
37             BIT #10h,&TERM_CTLW0    ;4          test UCTR
38             JZ SLEEP                ;2          UCTR=0, IC2_Slave RX mode or I2C_Slave unplugged, 16~
39 ACCEPT2     BIT #TX_TERM,&TERM_IFG  ;3          UCTR=1, IC2_Slave TX mode
40             JZ ACCEPT2              ;2          wait complete send of char
41             MOV.B #0,&TERM_TXBUF    ;           send ctrl_char $00
42 ; ----------------------------------;
43             JMP SLEEP               ;2          which calls RXON before shut down to LPMx mode
44 ; ----------------------------------;
45
46 ; **********************************;
47 TERMINAL_INT                        ; <--- START interrupt vector, bus stalled, waiting ACK first char by I2C_Slave RX
48 ; **********************************;
49 ; (ACCEPT) part II under interrupt  ; Org Ptr --
50 ; ----------------------------------;
51             ADD #4,RSP              ;1      remove SR and PC from stack, SR flags are lost (unused by FORTH interpreter)
52             BIT #10h,&TERM_CTLW0    ;4      test UCTR
53             JNZ ACCEPT1             ;       if I2C_Master RX, send $00 then return to SLEEP
54             POPM #4,IP               ;6      POPM  IP=ret_IP,W=src_end,T=0Ah,S=20h
55 ;; -test-v-test-v-test-v-test-v-test-;
56 ;            BIS.B #LED2,&LED2_OUT   ;       green led ON, start of Slave RX
57 ;            BIS.B #LED2,&LED2_DIR   ;       green led ON, start of Slave RX
58 ;; -test-^-test-^-test-^-test-^-test-;
59 QNEWCHAR    BIT #RX_TERM,&TERM_IFG  ;3      test RX BUF IFG
60             JZ QNEWCHAR             ;2      wait RX BUF full
61 AREADCHAR   MOV.B &TERM_RXBUF,Y     ;3      read char into Y, RX_IFG is cleared, bus unstalled by I2C_Slave
62             CMP.B S,Y               ;1      printable char ?
63             JC ASTORETEST           ;2      char U>= BL --> yes
64             CMP.B T,Y               ;1      char = LF ?
65             JZ ENDACCEPT            ;2      yes
66 ; ----------------------------------;
67             CMP.B #8,Y              ;       char = BS ?
68             JNZ QNEWCHAR            ;       case of other control chars
69 ; ----------------------------------;
70 ; start of backspace                ;       made only by an human
71 ; ----------------------------------;
72             CMP @PSP,TOS            ;       Ptr = Org ?
73             JZ QNEWCHAR             ;       yes: do nothing else
74             SUB #1,TOS              ;       no : dec Ptr
75             JMP QNEWCHAR
76 ; ----------------------------------;
77 ASTORETEST  CMP W,TOS               ; 1     end of buffer is reached ?
78             JZ QNEWCHAR             ; 2 yes: loopback
79             MOV.B Y,0(TOS)          ; 3 no: store char @ dst_Ptr
80             ADD #1,TOS              ; 1     increment dst_Ptr
81             JMP QNEWCHAR
82 ; ----------------------------------;
83 ENDACCEPT                           ;       here, after char 'LF' TXed, I2C_Master reSTARTs in RX mode
84 ;; -test-v-test-v-test-v-test-v-test-;
85 ;            BIC.B #LED2,&LED2_DIR   ;       green led OFF, end of Slave RX
86 ;            BIC.B #LED2,&LED2_OUT   ;       green led OFF, end of Slave RX
87 ;            BIS.B #LED1,&LED1_DIR   ;       Red led ON, start of Slave TX
88 ;            BIS.B #LED1,&LED1_OUT   ;       Red led ON, start of Slave TX
89 ;; -test-^-test-^-test-^-test-^-test-;
90 ; ----------------------------------; -- Org Ptr
91             CMP #0,&LINE            ;  
92             JZ ACCEPTEND            ;           if LINE <> 0 increment LINE
93             ADD #1,&LINE            ;
94 ACCEPTEND   SUB @PSP+,TOS           ;   -- len'
95 AWAITTX     BIT #40h,&TERM_STATW    ;           wait SCL held low, i.e. I2C_Master RX waits a char from I2C_Slave
96             JZ AWAITTX              ;      
97 ; ----------------------------------;
98 ;        MOV #CPUOFF+GIE,&LPM_MODE   ;   reset LPM_MODE to default mode LPM0 for next line of input stream
99         MOV #LPM4+GIE,&LPM_MODE     ;   reset LPM_MODE to default mode LPM4 for next line of input stream
100 ; ----------------------------------;
101             MOV @IP+,PC             ;   ...until next falling down to LPMx mode of (ACCEPT) part1,
102 ; **********************************;    i.e. when the FORTH interpreter has no more to do.
103
104 ; ----------------------------------;
105 RXOFF                               ;
106 ; ----------------------------------;
107 RXON        MOV @RSP+,PC            ; <======= SLEEP
108 ; ----------------------------------;
109
110 ; ----------------------------------;
111 COLD                                ;
112 ; ----------------------------------;
113             MOV #5A4Dh,&WDTCTL      ;           start Watchdog Reset : XDTPW, WDTSSEL=VLOCLK, WDTCNTCL=1, WDTIS=2^13 (1s)
114 ; ----------------------------------;           WDT_RST time = 1s because the ABORT loop time on I2C_Master side.
115 ; send $02 (ABORT request)          ;
116 ; ----------------------------------;
117             BIT #10h,&TERM_CTLW0    ;4          test UCTR
118             JZ COLDI2CEND2          ;2          UCTR=0, IC2_Slave RX mode or I2C_Slave unplugged, 16~
119 COLDI2C     BIT #TX_TERM,&TERM_IFG  ;3          UCTR=1, IC2_Slave TX mode
120             JZ COLDI2C              ;2          wait complete send of previous char
121             MOV.B #2,&TERM_TXBUF    ;           send ctrl_char $02 to I2C_Master which will execute QABORT_TERM
122 ; ----------------------------------;
123 ; wait STOP from Master             ;
124 ; ----------------------------------;
125 COLDI2CEND  BIC #8,&TERM_IFG        ;           clear STOP ifg before test
126 COLDI2CEND1 BIT #8,&TERM_IFG        ;           test STOP occurring
127             JZ COLDI2CEND1          ; 
128 ; ----------------------------------;
129 COLDI2CEND2 MOV #0A504h,&PMMCTL0    ;           performs BOR
130 ; ----------------------------------;
131
132 ; ------------------------------------------------------------------------------
133 ; TERMINAL I/O, input part
134 ; ------------------------------------------------------------------------------
135
136             FORTHWORD "KEY"
137 ; https://forth-standard.org/standard/core/KEY
138 ; KEY      -- c      wait character from input device ; primary DEFERred word
139 KEY         MOV @PC+,PC             ; Code Field Address (CFA) of KEY
140 PFAKEY      .word BODYKEY           ; Param Field Address (PFA) of KEY, with its default value
141 BODYKEY     SUB #2,PSP              ;           push old TOS..
142             MOV TOS,0(PSP)          ;           ..onto stack
143             MOV #0,TOS              ; -- 0      aborted KEY value
144 ; ----------------------------------;
145             BIT #10h,&TERM_CTLW0    ;           test UCTR
146             JZ BKEYEND              ;           when UCTR=0, IC2_Slave is in (RX|SWRST) mode, KEY can't work.
147 ; ----------------------------------;
148 KEYQEMIT    BIT #TX_TERM,&TERM_IFG  ;           TX buffer empty ?
149             JZ KEYQEMIT             ;           wait TX buffer empty
150             MOV.B #1,&TERM_TXBUF    ;           send $01 to I2C_Master RX as KEY request
151 BKEYLOOP    BIT #RX_TERM,&TERM_IFG  ;           received char ?
152             JZ BKEYLOOP             ;           wait char received
153             MOV &TERM_RXBUF,TOS     ; -- char
154 ; ----------------------------------;
155 BKEYEND     MOV @IP+,PC             ; -- char|0 Z=aborted KEY
156
157 ; ------------------------------------------------------------------------------
158 ; TERMINAL I/O, output part
159 ; ------------------------------------------------------------------------------
160
161             FORTHWORD "EMIT"
162 ; https://forth-standard.org/standard/core/EMIT
163 ; EMIT     c --    output character to an output device ; primary DEFERred word
164 EMIT        MOV @PC+,PC             ;3 Code Field Address (CFA) of EMIT
165 PFAEMIT     .word BODYEMIT          ;  Parameter Field Address (PFA) of EMIT, with its default value
166 BODYEMIT    MOV TOS,Y               ;1 sends character to the default output TERMINAL
167             MOV @PSP+,TOS           ;2
168 ; ----------------------------------;
169 YEMIT2      BIT #10h,&TERM_CTLW0    ;4 test UCTR
170             JZ YEMITEND             ;2 UCTR=0, IC2_Slave RX mode or I2C_Slave unplugged, 16~
171 ; ----------------------------------;
172 YEMIT1      BIT #TX_TERM,&TERM_IFG  ;3 UCTR=1, IC2_Slave TX mode
173             JZ YEMIT1               ;2 wait complete send of previous char
174 YEMIT       .word   4882h           ; 4882h = MOV Y,&<next_adr>
175             .word   TERM_TXBUF      ; 3
176 ; ----------------------------------;
177 YEMITEND    MOV @IP+,PC             ;4 14 words
178
179             FORTHWORD "ECHO"
180 ;Z ECHO     --      connect EMIT to TERMINAL (default)
181 ECHO        MOV #4882h,&YEMIT       ; 4882h = MOV Y,&<next_adr>
182             MOV #0,&LINE            ;
183             MOV #5,Y                ;
184             JMP YEMIT2              ; send ctrl_char $05 to I2C_Master
185
186             FORTHWORD "NOECHO"
187 ;Z NOECHO   --      disconnect EMIT to TERMINAL
188 NOECHO      MOV #1,&LINE            ;
189             MOV #4,Y                ;
190             mDOCOL
191             .word YEMIT2            ; send ctrl_char $04 to I2C_Master
192             .word $+2
193             MOV #NEXT,&YEMIT        ;  NEXT = 4030h = MOV @IP+,PC
194             MOV @RSP+,IP
195             MOV @IP+,PC
196