OSDN Git Service

2bda341f0882e684fddd0edebebe05cf947671f2
[fast-forth/master.git] / forthMSP430FR_TERM_I2C.asm
1 ; -*- coding: utf-8 -*-
2
3
4 ; ---------------------------------------------------
5 ; TERMINAL driver for I2CFastForth target (I2C Slave)
6 ; ---------------------------------------------------
7
8 ;      hardware                                                         Software                 
9 ;      I2C Slave                                                        I2C Master
10 ;     
11 ; I2CFastForth target SCL     SDA   connected to:   SCL     SDA  of  UART to I2C bridge
12 ; ------------------  ----    ----                  ----    ----     ------------------
13 ; MSP_EXP430FR5739    P1.7    P1.6                  P4.1    P4.0     MSP_EXP430FR5739  
14 ; MSP_EXP430FR5969    P1.7    P1.6                  P1.3    P1.2     MSP_EXP430FR5969  
15 ; MSP_EXP430FR5994    P7.1    P7.0                  P8.1    P8.2     MSP_EXP430FR5994  
16 ; MSP_EXP430FR6989    P1.7    P1.6                  P1.5    P1.3     MSP_EXP430FR6989  
17 ; MSP_EXP430FR4133    P5.3    P5.2                  P8.3    P8.2     MSP_EXP430FR4133  
18 ; CHIPSTICK_FR2433    P1.3    P1.2                  P2.2    P2.0     CHIPSTICK_FR2433  
19 ; MSP_EXP430FR2433    P1.3    P1.2                  P3.1    P3.2     MSP_EXP430FR2433  
20 ; MSP_EXP430FR2355    P1.3    P1.2                  P3.3    P3.2     MSP_EXP430FR2355  
21 ; LP_MSP430FR2476     P4.3    P4.4                  P3.3    P3.2     LP_MSP430FR2476   
22 ;
23 ; don't forget to link 3V3 and GND on each side and to add 3k3 pullup resistors on SDA and SCL.
24
25 ;-------------------------------------------------------------------------------
26 ; I2C TERMINAL: QABORT ABORT_TERM INI_TERM COLD_TERM RXON I2C_CTRL_CH
27 ;-------------------------------------------------------------------------------
28 ; define run-time part of ABORT"
29 ;Z ?ABORT   xi f c-addr u --           abort & print msg.
30 ;            FORTHWORD "?ABORT"
31 QABORT      CMP #0,2(PSP)           ; -- f c-addr u         test flag f
32             JNZ ABORT_TERM          ;
33 THREEDROP   ADD #4,PSP              ; -- u
34             MOV @PSP+,TOS           ; -- 
35             MOV @IP+,PC             ;
36 ; ----------------------------------;
37 ABORT_TERM                          ; exit from downloading then reinit some variables via INI_FORTH
38 ; ----------------------------------;
39             MOV.B #2,Y              ; -- f c-addr u         ABORT request Ctrl_Char = $02
40             CALL #I2C_CTRL_CH       ;                       send it to I2C_Master which will run QABORT_TERM on its side
41 ; ----------------------------------;
42             PUSH TOS                ;
43             CALL #INI_FORTH         ;
44 ; ----------------------------------;
45 ; display line of error if NOECHO   ;
46 ; ----------------------------------;
47             .word   lit,LINE,FETCH  ; -- f c-addr u line    fetch line number before set ECHO !
48             .word   ECHO            ;
49             .word   RFROM           ; -- f c-addr u line u 
50             .word   QFBRAN,ABORT_END;                       display nothing if ABORT" with empty string
51             .word   XSQUOTE         ; -- f c-addr u line 
52             .byte   5,27,"[7m",'@'  ;
53             .word   TYPE            ;                       cmd "reverse video" + displays "@"
54             .word   LIT,I2CSLAVEADR ;
55             .word   FETCH,DOT       ;                       displays <I2C_Slave_Address>
56             .word   QDUP,QFBRAN     ;                       don't display line if line = 0 (ECHO was ON)
57             .word   ABORT_TYPE      ;
58             .word   XSQUOTE         ; -- f c-addr u line c-addr1 u1   displays the line where error occured
59             .byte   15,"LAST.4TH, line " ;
60             .word   TYPE            ; -- f c-addr u line
61             .word   UDOT            ; -- f c-addr u
62 ; ----------------------------------;
63 ; Display ABORT|WARM message        ; <== WARM jumps here
64 ; ----------------------------------;
65 ABORT_TYPE  .word   TYPE            ; -- f              display abort|warm message
66             .word   XSQUOTE         ; -- f c-addr u
67             .byte   4,27,"[0m"      ;
68             .word   TYPE            ; -- f              set normal video
69 ABORT_END   .word   ABORT           ; -- f              no return
70 ; ----------------------------------;
71
72 ; ----------------------------------;
73 INIT_TERM                           ; TOS = RSTIV_MEM
74 ; ----------------------------------;
75 I2C_INIT_TERM
76         CMP #2,TOS                  ;
77         JNC I2C_INIT_TERM_END       ; no INIT_TERM if RSTIV_MEM U< 2 (WARM)
78 ; ----------------------------------;
79         BIS #07C0h,&TERM_CTLW0      ; set I2C_Slave in RX mode to receive I2C_address
80         MOV &I2CSLAVEADR,Y          ; init value found in FRAM INFO
81         RRA Y                       ; I2C Slave address without R/W bit 
82         BIS #400h,Y                 ; enable I2COA0 Slave address
83         MOV Y,&TERM_I2COA0          ;
84         BIS.B #BUS_TERM,&TERM_SEL   ; Configure pins TERM_I2C
85         BIC #1,&TERM_CTLW0          ; release UC_TERM from reset...
86         BIS #WAKE_UP,&TERM_IE       ; then enable interrupt for wake up on terminal input
87         BIC #LOCKLPM5,&PM5CTL0      ; activate all previous I/O settings.
88 I2C_INIT_TERM_END
89 ; ----------------------------------;
90 COLD_TERM                           ; nothing to do
91 ; ----------------------------------;
92         MOV @RSP+,PC                ;
93 ; ----------------------------------;
94
95
96 ; ----------------------------------;
97 RXON                                ; send ctrl_char $00 as ACCEPT request
98 ; ----------------------------------;
99 I2C_RXON    MOV.B #0,Y              ; ACCEPT request Ctrl_Char = $00
100
101 ; ----------------------------------;
102 I2C_CTRL_CH                         ; send it to I2C_Master_RX to restart it in TX mode
103 ; ----------------------------------;
104         BIT #TX_TERM,&TERM_IFG      ;3
105         JZ I2C_CTRL_CH              ;2 wait TX buffer empty
106         MOV.B Y,&TERM_TXBUF         ;3 send Ctrl_Char
107 WAITCHAREND 
108         BIT #4,&TERM_IFG            ; I2C_Master (re)STARTed ?
109         JZ WAITCHAREND              ; no
110         MOV @RSP+,PC                ;
111 ; ----------------------------------;
112 ; I2C_CTRL_CHAR sends a CTRL_Char that asks I2C_Master RX to (re)START in TX mode.
113 ; As TI tells nothing about I2C_Slave UCSTTIFG ON --> OFF,
114 ; it is assumed that the Slave clears itself UCSTTIFG after the first character has been exchanged.
115
116 ;-------------------------------------------------------------------------------
117 ; I2C TERMINAL : WIPE COLD WARM ACCEPT KEY EMIT ECHO NOECHO
118 ;-------------------------------------------------------------------------------
119
120 ;-----------------------------------;
121             FORTHWORD "WIPE"        ; software DEEP_RESET
122 ;-----------------------------------;
123 WIPE        MOV #-1,&RSTIV_MEM      ; negative value forces DEEP_RESET
124             JMP COLD
125
126 ; ----------------------------------;
127             FORTHWORD "COLD"        ; performs a software reset
128 ; ----------------------------------;
129 ; as pin RST is replaced by pin NMI, RESET by pin activation is redirected here via USER NMI vector
130 ; that allows specific actions before executing software BOR.
131 COLD        CALL @PC+               ; COLD first calls STOP_APP, in this instance: CALL #COLD_TERM by default
132 PFACOLD     .word COLD_TERM         ; PFACOLD default value set by WIPE.
133 BODYCOLD    BIT.B #IO_WIPE,&WIPE_IN ; hardware Deep_RESET request (low) ?
134             JNZ COLDEXE             ; no
135             MOV #-1,&RSTIV_MEM      ; yes, set negative value to force DEEP_RESET
136 COLDEXE     MOV #0A504h,&PMMCTL0    ; performs software_BOR --> RST_vector --> RESET in forthMSP430FR.asm
137 ; ----------------------------------;
138
139 ;-----------------------------------;
140             FORTHWORD "WARM"        ;
141 ;-----------------------------------;
142 ;Z WARM     xi --                   ; the end of RESET
143 ;-----------------------------------;
144 WARM                                ;
145 ;-------------------------------------------------------------------------------
146 ; RESET 7: if RSTIV_MEM <> WARM, init TERM and enable I/O
147 ;-------------------------------------------------------------------------------
148             CALL @PC+               ; init TERM, only if TOS U>= 2 (RSTIV_MEM <> WARM)
149     .IFNDEF SD_CARD_LOADER          ;
150 PFAWARM     .word INIT_TERM         ; INI_HARD_APP default value, init TERM UC, unlock I/O's, TOS = RSTIV_MEM
151     .ELSE
152 PFAWARM     .word INI_HARD_SD       ; init SD Card + init TERM, see forthMSP430FR_SD_INIT.asm
153     .ENDIF                          ; TOS = RSTIV_MEM
154 ;-----------------------------------;
155 WARM_DISPLAY                        ; TOS = RSTIV_MEM value
156     MOV.B  #3,Y                     ; WARM request Ctrl_Char = $03
157     CALL #I2C_CTRL_CH               ; send it to I2C_Master to reSTART in RX mode
158     ASMtoFORTH
159     .word   XSQUOTE
160     .byte   7,13,10,27,"[7m@"       ; CR+LF + cmd "reverse video" + @
161     .word   TYPE
162     .word   LIT,I2CSLAVEADR,FETCH,DOT
163     .word   LIT,'#',EMIT
164     .word   DOT                     ; display signed RSTIV_MEM
165     .word   XSQUOTE
166     .byte   25,"FastForth ©J.M.Thoorens "
167     .word   TYPE
168     .word   LIT,FRAM_FULL,HERE,MINUS,UDOT
169     .word   XSQUOTE
170     .byte   10,"bytes free"
171     .word   BRAN,ABORT_TYPE         ; without return!
172
173 ; ----------------------------------;
174             FORTHWORD "ACCEPT"
175 ; ----------------------------------;
176 ;https://forth-standard.org/standard/core/ACCEPT
177 ;C ACCEPT  addr addr len -- addr len'  get line at addr to interpret len' chars
178 ACCEPT      MOV @PC+,PC             ;3 Code Field Address (CFA) of ACCEPT
179 PFAACCEPT   .word   BODYACCEPT      ;  Parameter Field Address (PFA) of ACCEPT
180 BODYACCEPT                          ;  BODY of ACCEPT = default execution of ACCEPT
181 ; ----------------------------------;
182 ; ACCEPT part I prepare TERMINAL_INT;
183 ; ----------------------------------;
184             MOV TOS,W               ;1 -- org len   W=len
185             MOV @PSP,TOS            ;2 -- org ptr                                               )
186             ADD TOS,W               ;1 -- org ptr   W=buf_end                                   )
187             MOV #0Ah,T              ;2              T = 'LF' to speed up char loop in part II   > prepare stack and registers for TERMINAL_INT use
188             MOV #20h,S              ;2              S = 'BL' to speed up char loop in part II   ) 
189             PUSHM #4,IP             ;6              PUSH IP,S,T,W  r-- IP, 'BL', 'LF', buf_end  )
190 ;vvvvvvvvvvvvv OPTION vvvvvvvvvvvvvv;
191 ;            BIC.B #LED1,&LED1_DIR   ;           Red led OFF,
192 ;            BIC.B #LED1,&LED1_OUT   ;           end of Slave TX
193 ;^^^^^^^^^^^^^ OPTION ^^^^^^^^^^^^^^;
194             JMP SLEEP               ;            which calls RXON before goto sleep
195 ; ----------------------------------;
196
197 ; **********************************;
198 TERMINAL_INT                        ; <--- START interrupt vector, bus is stalled, waiting ACK first char by I2C_Slave RX
199 ; **********************************;
200 ; (ACCEPT) part II under interrupt  ; Org Ptr --
201 ; ----------------------------------;
202             ADD #4,RSP              ;1      remove SR and PC from stack, SR flags are lost (unused by FORTH interpreter)
203             BIC #WAKE_UP,&TERM_IFG  ;       clear UCSTTIFG before return to SLEEP (because not cleared by RX_TERM reading)
204             BIT #10h,&TERM_CTLW0    ;4      test UCTR
205             JNZ SLEEP               ;       if I2C_Master RX, loop back to SLEEP
206             POPM #4,IP              ;6      POPM  IP=ret_IP,W=src_end,T=0Ah,S=20h
207 ;vvvvvvvvvvvvv OPTION vvvvvvvvvvvvvv;
208 ;            BIS.B #LED2,&LED2_OUT   ;       green led ON,
209 ;            BIS.B #LED2,&LED2_DIR   ;       start of Slave RX
210 ;^^^^^^^^^^^^^ OPTION ^^^^^^^^^^^^^^;
211 QNEWCHAR    BIT #RX_TERM,&TERM_IFG  ;3      test RX BUF IFG
212             JZ QNEWCHAR             ;2      wait RX BUF full
213 ; ----------------------------------;
214 AKEYREAD    MOV.B &TERM_RXBUF,Y     ;3      read char into Y, RX_IFG is cleared, bus unstalled by I2C_Slave
215 ; ----------------------------------;
216             CMP.B T,Y               ;1      char = LF ?
217             JZ LF_NEXT              ;2      jump if char = LF
218             CMP.B S,Y               ;1      printable char ?
219             JC ASTORETEST           ;2      jump if char U>= BL
220 ; ----------------------------------;
221             CMP.B #8,Y              ;       char = BS ?
222             JNZ QNEWCHAR            ;       case of all other control chars
223 ; ----------------------------------;
224 ; start of backspace                ;       made only by an human
225 ; ----------------------------------;
226             CMP @PSP,TOS            ;       Ptr = Org ?
227             JZ QNEWCHAR             ;       yes: do nothing else
228             SUB #1,TOS              ;       no : dec Ptr
229             JMP QNEWCHAR
230 ; ----------------------------------;
231 ASTORETEST  CMP W,TOS               ; 1     end of buffer is reached ?
232             JZ QNEWCHAR             ; 2     yes: loopback
233             MOV.B Y,0(TOS)          ; 3     no: store char @ dst_Ptr
234             ADD #1,TOS              ; 1     increment dst_Ptr
235             JMP QNEWCHAR
236 ; ----------------------------------;
237 LF_NEXT                             ; -- Org Ptr
238 ; ----------------------------------;
239             SUB @PSP+,TOS           ; -- len'
240 ; ----------------------------------;
241 ;           MOV #LPMx+GIE,&LPM_MODE ;       no need to redefine LPM_MODE because I2C START works down to LPM4 mode
242 ; ----------------------------------;       after the sent of 'LF', I2C_Master automaticaly reSTARTs in RX mode:
243             CALL #WAITCHAREND       ;       wait I2C_Master (re)START RX
244 ;vvvvvvvvvvvvv OPTION vvvvvvvvvvvvvv;
245 ;            BIC.B #LED2,&LED2_DIR   ;       green led OFF,
246 ;            BIC.B #LED2,&LED2_OUT   ;       end of Slave RX
247 ;            BIS.B #LED1,&LED1_DIR   ;       Red led ON,
248 ;            BIS.B #LED1,&LED1_OUT   ;       start of Slave TX
249 ;^^^^^^^^^^^^^ OPTION ^^^^^^^^^^^^^^;
250 ACCEPT_EOL  CMP #0,&LINE            ;            
251             JZ ACCEPT_END           ;
252             ADD #1,&LINE            ;       if LINE <> 0 increment LINE
253 ACCEPT_END                          ;
254 ; ----------------------------------;
255             MOV S,Y                 ;       output a BL on TERMINAL (for the case of error occuring)
256             JMP YEMIT               ;       before line interpreting
257 ; **********************************;
258
259 ; ----------------------------------;
260             FORTHWORD "KEY"
261 ; ----------------------------------;
262 ; https://forth-standard.org/standard/core/KEY
263 ; KEY      -- c      wait character from input device ; primary DEFERred word
264 KEY         MOV @PC+,PC             ; Code Field Address (CFA) of KEY
265 PFAKEY      .word BODYKEY           ; Param Field Address (PFA) of KEY, with its default value
266 BODYKEY     SUB #2,PSP              ;           push old TOS..
267             MOV TOS,0(PSP)          ;           ..onto stack
268             MOV.B #1,Y              ; KEY request Ctrl_Char = $01
269             CALL #I2C_CTRL_CH       ; send it to I2C_Master to restart UART in RX mode
270 BKEYLOOP    BIT #RX_TERM,&TERM_IFG  ;           received char ?
271             JZ BKEYLOOP             ;           wait char received
272             MOV &TERM_RXBUF,TOS     ; -- char
273 BKEYEND     MOV @IP+,PC             ; -- char
274
275 ; ----------------------------------;
276             FORTHWORD "EMIT"
277 ; ----------------------------------;
278 ; https://forth-standard.org/standard/core/EMIT
279 ; EMIT     c --    output character to an output device ; primary DEFERred word
280 EMIT        MOV @PC+,PC             ;3 Code Field Address (CFA) of EMIT
281 PFAEMIT     .word BODYEMIT          ;  Parameter Field Address (PFA) of EMIT, with its default value
282 BODYEMIT    MOV TOS,Y               ;1 sends character to the default output TERMINAL
283             MOV @PSP+,TOS           ;2
284 YEMIT       BIT #TX_TERM,&TERM_IFG  ;3
285             JZ YEMIT                ;2 wait TX buffer empty
286 QYEMIT      .word   48C2h           ;3 48C2h = MOV.B Y,&<next_adr>
287             .word   TERM_TXBUF      ;
288 YEMITEND    MOV @IP+,PC             ;4 11 words
289
290 ; ----------------------------------;
291             FORTHWORD "ECHO"
292 ; ----------------------------------;
293 ;Z ECHO     --      connect EMIT to TERMINAL (default)
294 ECHO        MOV #48C2h,&QYEMIT      ; 48C2h = MOV.B Y,&<next_adr>
295             MOV #0,&LINE            ;
296             MOV #5,Y                ; ECHO request Ctrl_Char = $05
297 ECHOEND     CALL #I2C_CTRL_CH       ; send it to I2C_Master to do it echo char to TERMINAL
298             MOV @IP+,PC
299
300 ; ----------------------------------;
301             FORTHWORD "NOECHO"
302 ; ----------------------------------;
303 ;Z NOECHO   --      disconnect EMIT to TERMINAL
304 NOECHO      MOV #4D30h,&QYEMIT      ;  NEXT = 4D30h = MOV @IP+,PC
305             MOV #1,&LINE            ;
306             MOV #4,Y                ; NOECHO request Ctrl_Char = $04
307             JMP ECHOEND             ; send it to I2C_Master, to not do it echo to TERMINAL
308