OSDN Git Service

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