OSDN Git Service

v 162, added Conditionnal Compilation and bootloader
[fast-forth/master.git] / MSP430_COND / RC5toLCD.f
1 ; -----------------------------------
2 ; RC5toLCD.4th
3 ; -----------------------------------
4     \
5 \ Copyright (C) <2016>  <J.M. THOORENS>
6 \
7 \ This program is free software: you can redistribute it and/or modify
8 \ it under the terms of the GNU General Public License as published by
9 \ the Free Software Foundation, either version 3 of the License, or
10 \ (at your option) any later version.
11 \
12 \ This program is distributed in the hope that it will be useful,
13 \ but WITHOUT ANY WARRANTY\ without even the implied warranty of
14 \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 \ GNU General Public License for more details.
16 \
17 \ You should have received a copy of the GNU General Public License
18 \ along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20
21 \ ===========================================================================
22 \ remember: for good downloading to target, all lines must be ended with CR+LF !
23 \ ===========================================================================
24
25
26 \ REGISTERS USAGE
27 \ R4 to R7 must be saved before use and restored after
28 \ scratch registers Y to S are free for use
29 \ under interrupt, IP is free for use
30 \ interrupts reset SR register !
31
32 \ PUSHM order : PSP,TOS, IP,  S,  T,  W,  X,  Y, R7, R6, R5, R4
33 \ example : PUSHM IP,Y
34 \
35 \ POPM  order :  R4, R5, R6, R7,  Y,  X,  W,  T,  S, IP,TOS,PSP
36 \ example : POPM Y,IP
37
38 \ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
39 \ ASSEMBLER conditionnal usage before ?JMP ?GOTO    : S< S>= U< U>= 0= 0<> 0< 
40
41 \ FORTH conditionnal    : 0= 0< = < > U<
42
43 \ display on a LCD 2x20 CHAR the code sent by an IR remote under philips RC5 protocol
44 \ target : any TI MSP-EXP430FRxxxx launchpad (FRAM)
45 \ LPM_MODE = LPM0 because use SMCLK for LCDVo
46
47 \ DEMO : driver for IR remote compatible with the PHILIPS RC5 protocol
48 \ plus : driver for 5V LCD 2x20 characters display with 4 bits data interface
49 \        without usage of an auxiliary 5V to feed the LCD_Vo
50 \        and without potentiometer to adjust the LCD contrast :
51 \        to adjust LCD contrast, just press S1 (-) or S2 (+)
52 \        LCDVo current consumption ~ 500 uA.
53
54 \ ===================================================================================
55 \ notice : adjust TA0EX0,TB0CTL,TB0EX0 and 20_us to the target frequency if <> 8MHz !
56 \ ===================================================================================
57
58
59 \ layout : I/O are defined in the launchpad.pat file (don't work with ChipStick_FR2433)
60
61 \  GND  <-------+---0V0---------->  1 LCD_Vss
62 \  VCC  >------ | --3V6-----+---->  2 LCD_Vdd
63 \               |           |
64 \              ___    470n ---
65 \               ^          ---
66 \              / \ 1N4148   |
67 \              ---          |
68 \          100n |    2k2    |
69 \ TB0.2 >---||--+--^/\/\/v--+---->  3 LCD_Vo (= 0V6 without modulation)
70 \       ------------------------->  4 LCD_RW
71 \       ------------------------->  5 LCD_RW
72 \       ------------------------->  6 LCD_EN
73 \       <------------------------> 11 LCD_DB4
74 \       <------------------------> 12 LCD_DB5
75 \       <------------------------> 13 LCD_DB5
76 \       <------------------------> 14 LCD_DB7
77
78 \       <----- LCD contrast + <---    Sw1   <--- (finger) :-)
79 \       <----- LCD contrast - <---    Sw2   <--- (finger) :-)
80
81 \ rc5   <--- OUT IR_Receiver (1 TSOP32236)
82
83
84
85 [UNDEFINED] {RC5TOLCD} [IF]
86     \
87 MARKER {RC5TOLCD}
88     \
89 [UNDEFINED] MAX [IF]    \ MAX and MIN are defined in {ANS_COMP}
90     \
91 CODE MAX    \    n1 n2 -- n3       signed maximum
92     CMP @PSP,TOS    \ n2-n1
93     S<  ?GOTO FW1   \ n2<n1
94 BW1 ADD #2,PSP
95     MOV @IP+,PC
96 ENDCODE
97     \
98
99 CODE MIN    \    n1 n2 -- n3       signed minimum
100     CMP @PSP,TOS     \ n2-n1
101     S<  ?GOTO BW1    \ n2<n1
102 FW1 MOV @PSP+,TOS
103     MOV @IP+,PC
104 ENDCODE
105
106 [THEN]
107     \
108
109 [UNDEFINED] U.R [IF]        \ defined in {UTILITY}
110 : U.R                       \ u n --           display u unsigned in n width (n >= 2)
111   >R  <# 0 # #S #>  
112   R> OVER - 0 MAX SPACES TYPE
113 ;
114 [THEN]
115     \
116
117 \ CODE 20_US                      \ n --      n * 20 us
118 \ BEGIN                           \ 3 cycles loop + 6~  
119 \ \    MOV     #5,W                \ 3 MCLK = 1 MHz
120 \ \    MOV     #23,W               \ 3 MCLK = 4 MHz
121 \ \    MOV     #51,W               \ 3 MCLK = 8 MHz
122 \     MOV     #104,W              \ 3 MCLK = 16 MHz
123 \ \    MOV     #158,W              \ 3 MCLK = 24 MHz
124 \     BEGIN                       \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
125 \         SUB #1,W                \ 1
126 \     0= UNTIL                    \ 2
127 \     SUB     #1,TOS              \ 1
128 \ 0= UNTIL                        \ 2
129 \     MOV     @PSP+,TOS           \ 2
130 \     MOV     @IP+,PC             \ 4
131 \ ENDCODE
132 \     \
133
134 CODE 20_US                  \ n --      n * 20 us
135 BEGIN                       \ here we presume that TB0IFG = 1...
136     BEGIN
137         BIT #1,&TB0CTL      \ 3
138     0<> UNTIL               \ 2         loop until TB0IFG set
139     BIC #1,&TB0CTL          \ 3         clear TB0IFG
140     SUB #1,TOS              \ 1
141 U< UNTIL                    \ 2 ...so add a dummy loop with U< instead of 0=
142 MOV @PSP+,TOS               \ 2
143 MOV @IP+,PC                 \ 4
144 ENDCODE
145     \
146
147 CODE TOP_LCD                    \ LCD Sample
148 \                               \ if write : %xxxxWWWW --
149 \                               \ if read  : -- %0000RRRR
150     BIS.B #LCD_EN,&LCD_CMD_OUT  \ lcd_en 0-->1
151     BIT.B #LCD_RW,&LCD_CMD_IN   \ lcd_rw test
152 0= IF                           \ write LCD bits pattern
153     AND.B #LCD_DB,TOS           \ 
154     MOV.B TOS,&LCD_DB_OUT       \ send LCD_Data
155     BIC.B #LCD_EN,&LCD_CMD_OUT  \ lcd_en 1-->0 ==> strobe data
156     MOV @PSP+,TOS               \
157     MOV @IP+,PC
158 THEN                            \ read LCD bits pattern
159     SUB #2,PSP
160     MOV TOS,0(PSP)
161     BIC.B #LCD_EN,&LCD_CMD_OUT  \ lcd_en 1-->0 ==> strobe data
162     MOV.B &LCD_DB_IN,TOS        \ get LCD_Data
163     AND.B #LCD_DB,TOS           \
164     MOV @IP+,PC
165 ENDCODE
166     \
167
168 CODE LCD_W                      \ byte --       write byte to LCD 
169     SUB #2,PSP                  \
170     MOV TOS,0(PSP)              \ -- %xxxxLLLL %HHHHLLLL
171     RRUM #4,TOS                 \ -- %xxxxLLLL %xxxxHHHH
172     BIC.B #LCD_RW,&LCD_CMD_OUT  \ lcd_rw=0
173     BIS.B #LCD_DB,&LCD_DB_DIR   \ LCD_Data as output
174 COLON                           \ high level word starts here 
175     TOP_LCD 2 20_US             \ write high nibble first
176     TOP_LCD 2 20_US 
177 ;
178     \
179
180 CODE LCD_WrC                    \ char --         Write Char
181     BIS.B #LCD_RS,&LCD_CMD_OUT  \ lcd_rs=1
182     JMP LCD_W 
183 ENDCODE
184     \
185
186 CODE LCD_WrF                    \ func --         Write Fonction
187     BIC.B #LCD_RS,&LCD_CMD_OUT  \ lcd_rs=0
188     JMP LCD_W 
189 ENDCODE
190     \
191
192 : LCD_Clear 
193     $01 LCD_WrF 100 20_us      \  $01 LCD_WrF 80 20_us ==> bad init !
194 ;
195     \
196
197 : LCD_Home 
198     $02 LCD_WrF 100 20_us 
199 ;
200     \
201
202 : LCD_Entry_set     $04 OR LCD_WrF ;
203     \
204 : LCD_DSP_Ctrl      $08 OR LCD_WrF ;
205     \
206 : LCD_DSP_Shift     $10 OR LCD_WrF ;
207     \
208 : LCD_Fn_Set        $20 OR LCD_WrF ;
209     \
210 : LCD_CGRAM_Set     $40 OR LCD_WrF ;
211     \
212 : LCD_Goto          $80 OR LCD_WrF ;
213     \
214 CODE LCD_R                      \ -- byte       read byte from LCD
215     BIC.B #LCD_DB,&LCD_DB_DIR   \ LCD_Data as intput
216     BIS.B #LCD_RW,&LCD_CMD_OUT  \ lcd_rw=1
217 COLON                           \ starts a FORTH word
218     TOP_LCD 2 20_us             \ -- %0000HHHH
219     TOP_LCD 2 20_us             \ -- %0000HHHH %0000LLLL
220 HI2LO                           \ switch from FORTH to assembler
221     RLAM #4,0(PSP)              \ -- %HHHH0000 %0000LLLL
222     ADD.B @PSP+,TOS             \ -- %HHHHLLLL
223     MOV @RSP+,IP                \ restore IP saved by COLON
224     MOV @IP+,PC                 \
225 ENDCODE
226     \
227
228 CODE LCD_RdS                    \ -- status       Read Status
229     BIC.B #LCD_RS,&LCD_CMD_OUT  \ lcd_rs=0
230     JMP LCD_R
231 ENDCODE
232     \
233
234 CODE LCD_RdC                    \ -- char         Read Char
235     BIS.B #LCD_RS,&LCD_CMD_OUT  \ lcd_rs=1
236     JMP LCD_R
237 ENDCODE
238     \
239
240
241 \ ******************************\
242 ASM WDT_INT                     \ Watchdog interrupt routine, warning : not FORTH executable !
243 \ ******************************\
244 \ XOR.B #LED1,&LED1_OUT           \ to visualise WDT
245 BIT.B #SW2,&SW2_IN              \ test switch S2
246 0= IF                           \ case of switch S2 pressed
247     CMP #19,&TB0CCR2             \ maxi Ton = 19/20 & VDD=3V6 ==> LCD_Vo = -1V4
248     U< IF
249         ADD #1,&TB0CCR2         \ action for switch S2 (P2.5) : 150 mV / increment
250     THEN
251 ELSE
252     BIT.B #SW1,&SW1_IN          \ test switch S1 input
253     0= IF                       \ case of Switch S1 pressed
254         CMP #3,&TB0CCR2         \ mini Ton = 3/20 & VDD=3V6 ==> LCD_Vo = 0V
255         U>= IF                  \
256             SUB #1,&TB0CCR2     \ action for switch S1 (P2.6) : -150 mV / decrement
257         THEN                    \
258     THEN                        \
259 THEN                            \
260 BW1                             \ from quit on truncated RC5 message
261 BW2                             \ from repeated RC5 command
262 BW3                             \ from end of RC5_INT
263 BIC #$78,0(RSP)                 \4  SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPM0_LOOP despite pending interrupt
264 RETI                            \5
265 ENDASM
266     \
267
268 \ ******************************\
269 ASM RC5_INT                     \   wake up on Px.RC5 change interrupt
270 \ ******************************\
271 \ IR_RC5 driver                 \ IP,S,T,W,X,Y registers are free for use
272 \ ******************************\
273 \                               \ in :  SR(9)=old Toggle bit memory (ADD on)
274 \                               \       SMclock = 8|16|24 MHz
275 \                               \ use : T,W,X,Y, TA1 timer, TA1R register
276 \                               \ out : X = 0 C6 C5 C4 C3 C2 C1 C0
277 \                               \       SR(9)=new Toggle bit memory (ADD on)
278 \ ******************************\
279 \ RC5_FirstStartBitHalfCycle:   \
280 \ ******************************\                division in TA1CTL (SMCLK/1|SMCLK/1|SMCLK/2|SMCLK/4|SMCLK/8)
281 \ MOV #0,&TA1EX0                \ predivide by 1 in TA1EX0 register ( 125kHz|  1MHz |  2MHZ |  4MHZ |  8MHZ ), reset value
282   MOV #1,&TA1EX0                \ predivide by 2 in TA1EX0 register ( 250kHZ|  2MHz |  4MHZ |  8MHZ | 16MHZ )
283 \ MOV #2,&TA1EX0                \ predivide by 3 in TA1EX0 register ( 375kHz|  3MHz |  6MHZ | 12MHZ | 24MHZ )
284 \ MOV #3,&TA1EX0                \ predivide by 4 in TA1EX0 register ( 500kHZ|  4MHz |  8MHZ | 16MHZ )
285 \ MOV #4,&TA1EX0                \ predivide by 6 in TA1EX0 register ( 625kHz|  5MHz | 10MHZ | 20MHZ )
286 \ MOV #5,&TA1EX0                \ predivide by 6 in TA1EX0 register ( 750kHz|  6MHz | 12MHZ | 24MHZ )
287 \ MOV #6,&TA1EX0                \ predivide by 7 in TA1EX0 register ( 875kHz|  7MHz | 14MHZ | 28MHZ )
288 \ MOV #7,&TA1EX0                \ predivide by 8 in TA1EX0 register (  1MHz |  8MHz | 16MHZ | 32MHZ )
289 MOV #1778,X                     \ RC5_Period * 1us
290 \ MOV #222,X                    \ RC5_Period * 8us (SMCLK/1 and first column above)
291 MOV #14,W                       \ count of loop
292 BEGIN                           \
293 \ ******************************\
294 \ RC5_HalfCycle                 \ <--- loop back ---+ with readjusted RC5_Period
295 \ ******************************\                   |
296 \   MOV #%1000100100,&TA1CTL    \ (re)start timer_A | SMCLK/1 time interval,free running,clear TA1_IFG and TA1R
297 \   MOV #%1002100100,&TA1CTL    \ (re)start timer_A | SMCLK/2 time interval,free running,clear TA1_IFG and TA1R
298 \   MOV #%1010100100,&TA1CTL    \ (re)start timer_A | SMCLK/4 time interval,free running,clear TA1_IFG and TA1R
299     MOV #%1011100100,&TA1CTL    \ (re)start timer_A | SMCLK/8 time interval,free running,clear TA1_IFG and TA1R
300 \ RC5_Compute_3/4_Period:       \                   |
301     RRUM    #1,X                \ X=1/2 cycle       |
302     MOV     X,Y                 \                   ^
303     RRUM    #1,Y                \ Y=1/4
304     ADD     X,Y                 \ Y=3/4 cycle
305     BEGIN   CMP Y,&TA1R         \3 wait 1/2 + 3/4 cycle = n+1/4 cycles 
306     U>= UNTIL                   \2
307 \ ******************************\
308 \ RC5_SampleOnFirstQuarter      \ at n+1/4 cycles, we sample RC5_input, ST2/C6 bit first
309 \ ******************************\
310     BIT.B   #RC5,&IR_IN         \ C_flag = IR bit
311     ADDC    T,T                 \ C_flag <-- T(15):T(0) <-- C_flag
312     MOV.B   &IR_IN,&IR_IES      \ preset Px_IES.y state for next IFG
313     BIC.B   #RC5,&IR_IFG        \ clear Px_IFG.y after 4/4 cycle pin change
314     SUB     #1,W                \ decrement count loop
315 \                               \  count = 13 ==> T = x  x  x  x  x  x  x  x |x  x  x  x  x  x  x /C6
316 \                               \  count = 0  ==> T = x  x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0  1 
317 0<> WHILE                       \ ----> out of loop ----+
318     ADD X,Y                     \                       |   Y = n+3/4 cycles = time out because n+1/2 cycles edge is always present
319     BEGIN                       \                       |
320         MOV &TA1R,X             \3                      |   X grows from n+1/4 up to n+3/4 cycles
321         CMP Y,X                 \1                      |   cycle time out of bound ?
322         U>= IF                  \2                  ^   |   yes:
323             BIC #$30,&TA1CTL    \                   |   |      stop timer
324             GOTO BW1            \                   |   |      quit on truncated RC5 message
325         THEN                    \                   |   |
326         BIT.B #RC5,&IR_IFG      \3                  |   |   n+1/2 cycles edge is always present
327     0<> UNTIL                   \2                  |   |
328 REPEAT                          \ ----> loop back --+   |   with X = new RC5_period value
329 \ ******************************\                       |
330 \ RC5_SampleEndOf:              \ <---------------------+
331 \ ******************************\
332 BIC #$30,&TA1CTL                \   stop timer
333 \ ******************************\
334 \ RC5_ComputeNewRC5word         \
335 \ ******************************\
336 RLAM    #1,T                    \ T =  x /C6 Tg A4 A3 A2 A1 A0|C5 C4 C3 C2 C1 C0  1  0
337 MOV.B   T,X                     \ X = C5 C4 C3 C2 C1 C0  1  0
338 RRUM    #2,X                    \ X =  0  0 C5 C4 C3 C2 C1 C0
339 \ ******************************\
340 \ RC5_ComputeC6bit              \
341 \ ******************************\
342 BIT     #BIT14,T                \ test /C6 bit in T
343 0= IF   BIS #BIT6,X             \ set C6 bit in X
344 THEN                            \ X =  0  C6 C5 C4 C3 C2 C1 C0
345 \ ******************************\
346 \ RC5_CommandByteIsDone         \ -- BASE RC5_code
347 \ ******************************\
348 \ Only New_RC5_Command ADD_ON   \ use SR(9) bit as toggle bit
349 \ ******************************\
350 RRUM    #3,T                    \ new toggle bit = T(13) ==> T(10)
351 XOR     @RSP,T                  \ (new XOR old) Toggle bits
352 BIT     #UF10,T                 \ repeated RC5_command ?
353 0= ?GOTO BW2                    \ yes, RETI without UF10 change and without action !
354 XOR #UF10,0(RSP)                \ 5 toggle bit memory
355 \ ******************************\
356 \ Display IR_RC5 code           \ X = RC5 code
357 \ ******************************\
358 SUB #4,PSP                      \
359 MOV &BASE,2(PSP)                \ save current base
360 MOV #$0A,&BASE                  \ set hex base
361 MOV TOS,0(PSP)                  \ save TOS
362 MOV X,TOS                       \
363 LO2HI                           \ switch from assembler to FORTH
364     ['] LCD_CLEAR IS CR         \ redirects CR
365     ['] LCD_WrC  IS EMIT        \ redirects EMIT
366     CR ." $" 2 U.R              \ print IR_RC5 code
367     ['] (CR) IS CR              \ restore CR
368     ['] (EMIT) IS EMIT          \ restore EMIT
369 HI2LO                           \ switch from FORTH to assembler
370 MOV @PSP+,&BASE                 \ restore current BASE
371 \ ******************************\
372 GOTO BW3
373 \ ******************************\
374 ENDASM
375     \ 
376
377 \ ------------------------------\
378 ASM BACKGROUND                  \ 
379 \ ------------------------------\
380 \ ...                           \ insert here your background task
381 \ ...                           \
382 \ ...                           \
383 MOV #(SLEEP),PC                 \ Must be the last statement of BACKGROUND
384 ENDASM                          \
385 \ ------------------------------\
386     \
387
388 CODE START                      \
389 \ ------------------------------\
390 \ TB0CTL =  %0000 0010 1001 0100\$3C0
391 \               - -             \CNTL Counter lentgh \ 00 = 16 bits
392 \                   --          \TBSSEL TimerB clock select \ 10 = SMCLK
393 \                      --       \ID input divider \ 10 = /4
394 \                        --     \MC Mode Control \ 01 = up to TB0CCR0
395 \                            -  \TBCLR TimerB Clear
396 \                             - \TBIE
397 \                              -\TBIFG
398 \ -------------------------------\
399 \ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
400 \             --                 \CM Capture Mode
401 \               --               \CCIS
402 \                  -             \SCS
403 \                   --           \CLLD
404 \                     -          \CAP
405 \                       ---      \OUTMOD \ 011 = set/reset
406 \                          -     \CCIE
407 \                            -   \CCI
408 \                             -  \OUT
409 \                              - \COV
410 \                               -\CCIFG
411 \ -------------------------------\
412 \ TB0CCRx                        \
413 \ -------------------------------\
414 \ TB0EX0                         \ 
415 \ ------------------------------\
416 \ set TB0 to make 50kHz PWM     \ for LCD_Vo, works without interrupt
417 \ ------------------------------\
418 \    MOV #%1000010100,&TB0CTL   \ SMCLK/1, up mode, clear timer, no int
419 \    MOV #0,&TB0EX0             \ predivide by 1 in TB0EX0 register (1 MHZ)
420 \ ------------------------------\
421 \    MOV #%1001010100,&TB0CTL   \ SMCLK/2, up mode, clear timer, no int
422 \    MOV #1,&TB0EX0             \ predivide by 2 in TB0EX0 register (2 MHZ)
423 \ ------------------------------\
424 \    MOV #%1010010100,&TB0CTL   \ SMCLK/4, up mode, clear timer, no int
425 \    MOV #1,&TB0EX0             \ predivide by 2 in TB0EX0 register (4 MHZ)
426 \ ------------------------------\
427 \    MOV #%1011010100,&TB0CTL    \ SMCLK/8, up mode, clear timer, no int
428 \    MOV #0,&TB0EX0              \ predivide by 1 in TB0EX0 register (8 MHZ)
429 \ ------------------------------\
430     MOV #%1011010100,&TB0CTL   \ SMCLK/8, up mode, clear timer, no int
431     MOV #1,&TB0EX0             \ predivide by 2 in TB0EX0 register (16 MHZ)
432 \ ------------------------------\
433 \    MOV #%1011010100,&TB0CTL   \ SMCLK/8, up mode, clear timer, no int
434 \    MOV #2,&TB0EX0             \ predivide by 3 in TB0EX0 register (24 MHZ)
435 \ ------------------------------\
436     MOV #20,&TB0CCR0            \ 20*1us=20us
437 \ ------------------------------\
438 \ set TB0.2 to generate PWM for LCD_Vo
439 \ ------------------------------\
440     MOV #%1100000,&TB0CCTL2     \ output mode = set/reset \ clear CCIFG
441     MOV #10,&TB0CCR2           \ contrast adjust : 10/20 ==> LCD_Vo = -0V6|+3V6 (Vcc=3V6)
442 \    MOV #12,&TB0CCR2            \ contrast adjust : 12/20 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
443     BIS.B #LCDVo,&LCDVo_DIR     \
444     BIS.B #LCDVo,&LCDVo_SEL     \ SEL.2 TB0.2
445 \ ------------------------------\
446     BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
447     BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
448 \ ------------------------------\
449     BIS.B #LCD_DB,&LCD_DB_DIR   \ as output, wired to DB(4-7) LCD_Data
450     BIC.B #LCD_DB,&LCD_DB_REN   \ LCD_Data pullup/down disable
451 \ ******************************\
452 \ init RC5_Int                  \
453 \ ******************************\
454     BIS.B #RC5,&IR_IE           \ enable RC5_Int
455     BIC.B #RC5,&IR_IFG          \ reset RC5_Int flag
456     MOV #RC5_INT,&IR_Vec        \ init interrupt vector
457 \ ******************************\
458 \ init WatchDog TA0             \ eUSCI_A0 (FORTH terminal) has higher priority than TA0
459 \ ******************************\
460 \              %01 0001 0100    \ TAxCTL
461 \               --              \ TASSEL    CLK = ACLK = LFXT = 32768 Hz
462 \                  --           \ ID        divided by 1
463 \                    --         \ MC        MODE = up to TAxCCRn
464 \                        -      \ TACLR     clear timer count
465 \                         -     \ TAIE
466 \                          -    \ TAIFG
467 \ ------------------------------\
468     MOV #%0100010100,&TA0CTL    \ start TA0, ACLK, up mode, disable int, 
469 \ ------------------------------\
470 \                        000    \ TAxEX0
471 \                        ---    \ TAIDEX    pre divisor
472 \ ------------------------------\
473 \          %0000 0000 0000 0101 \ TAxCCR0
474     MOV ##1638,&TA0CCR0         \ init WDT for LFXT: 32768/20=1638 ==> 50ms
475 \    MOV ##400,&TA0CCR0          \ init WDT for VLO: 8000/20=400 ==> 50ms
476 \ ------------------------------\
477 \          %0000 0000 0001 0000 \ TAxCCTL0
478 \                   -           \ CAP capture/compare mode = compare
479 \                        -      \ CCIEn
480 \                             - \ CCIFGn
481     MOV #%10000,&TA0CCTL0       \ enable compare interrupt, clear CCIFG0
482 \ ------------------------------\
483     MOV #WDT_INT,&TA0_0_Vec     \ for only CCIFG0 int, this interrupt clears automatically CCIFG0
484 \ ------------------------------\
485 \ define LPM mode for ACCEPT    \
486 \ ------------------------------\
487 \    MOV #LPM4,&LPM_MODE         \ with MSP430FR59xx
488 \    MOV #LPM2,&LPM_MODE         \ with MSP430FR57xx, terminal input don't work for LPMx > 2
489 \                               \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
490
491 \ ------------------------------\
492 \ redirects to background task  \
493 \ ------------------------------\
494     MOV #SLEEP,X                \
495     MOV #BACKGROUND,2(X)        \
496 \ ------------------------------\
497
498 LO2HI                           \ no need to push IP because (WARM) resets the Return Stack ! 
499
500 \ ------------------------------\
501 \ Init LCD 2x20                 \
502 \ ------------------------------\
503     $03E8 20_US                 \ 1-  wait 20 ms
504     $03 TOP_LCD                 \ 2- send DB5=DB4=1
505     $CD 20_US                   \ 3- wait 4,1 ms
506     $03 TOP_LCD                 \ 4- send again DB5=DB4=1
507     $5 20_US                    \ 5- wait 0,1 ms
508     $03 TOP_LCD                 \ 6- send again again DB5=DB4=1
509     $2 20_US                    \    wait 40 us = LCD cycle
510     $02 TOP_LCD                 \ 7- send DB5=1 DB4=0
511     $2 20_US                    \    wait 40 us = LCD cycle
512     $28 LCD_WRF                 \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
513     $08 LCD_WRF                 \ 9- %1DCB   "DisplayControl" : Display off, Cursor off, Blink off. 
514     LCD_Clear                   \ 10- "LCD_Clear"
515     $06 LCD_WRF                 \ 11- %01xx   "LCD_EntrySet" : address and cursor shift after writing in RAM
516     $0C LCD_WRF                 \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off. 
517     LCD_Clear                   \ 10- "LCD_Clear"
518     ['] LCD_HOME IS CR          \ ' CR redirected to LCD_HOME
519     ['] LCD_WRC  IS EMIT        \ ' EMIT redirected to LCD_WrC
520     CR ." I love you"   
521     ['] (CR) IS CR              \ ' (CR) is CR
522     ['] (EMIT) IS EMIT          \ ' (EMIT) is EMIT
523 \    NOECHO                      \ uncomment to run this app without terminal connexion
524     CR
525     ."    RC5toLCD is running. Type STOP to quit"
526     LIT RECURSE IS WARM         \ insert this START routine between WARM and (WARM)...
527     (WARM)                      \ ...and continue with (WARM), must be the START last statement.
528 ;
529     \
530
531 CODE STOP                   \ stops multitasking, must to be used before downloading app
532     MOV #SLEEP,X            \
533     MOV #(SLEEP),2(X)       \ restore the default background
534 COLON
535     ['] (WARM) IS WARM      \ remove START app from FORTH init process
536     ECHO COLD               \ reset CPU, interrupt vectors, and start FORTH
537 ;
538     \
539
540 ECHO
541             ; downloading RC5toLCD.4th is done
542 RST_HERE    ; this app is protected against <reset>
543     \
544 [THEN]
545     \
546 START