1 \ -*- coding: utf-8 -*-
3 ; -----------------------------------
5 ; -----------------------------------
7 \ to see kernel options, download FastForthSpecs.f
8 \ FastForth kernel options: MSP430ASSEMBLER, CONDCOMP, FREQUENCY = 8/16/24 MHz
11 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
15 \ R4 to R7 must be saved before use and restored after
16 \ scratch registers Y to S are free for use
17 \ under interrupt, IP is free for use
18 \ interrupts reset SR register !
20 \ PUSHM order : PSP,TOS, IP, S, T, W, X, Y, rEXIT,rDOVAR,rDOCON, rDODOES, R3, SR,RSP, PC
21 \ PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
23 \ example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
25 \ POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
26 \ POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
28 \ example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
30 \ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
31 \ ASSEMBLER conditionnal usage before ?JMP ?GOTO : S< S>= U< U>= 0= 0<> 0<
33 \ FORTH conditionnal : 0= 0< = < > U<
35 \ display on a LCD 2x20 CHAR the code sent by an IR remote under philips RC5 protocol
36 \ target : any TI MSP-EXP430FRxxxx launchpad (FRAM)
37 \ LPM_MODE = LPM0 because use SMCLK for LCDVo
39 \ DEMO : driver for IR remote compatible with the PHILIPS RC5 protocol
40 \ plus : driver for 5V LCD 2x20 characters display with 4 bits data interface
41 \ without usage of an auxiliary 5V to feed the LCD_Vo
42 \ and without potentiometer to adjust the LCD contrast :
43 \ to adjust LCD contrast, just press S1 (-) or S2 (+)
44 \ LCDVo current consumption ~ 500 uA.
46 \ ===================================================================================
47 \ notice : adjust WDT_TIM_EX0,LCD_TIM_CTL,LCD_TIM_EX0 and 20_us to the target frequency if <> 8MHz !
48 \ ===================================================================================
51 \ layout : I/O are defined in the launchpad.pat file (don't work with ChipStick_FR2433)
53 \ GND <-------o---0V0----------> 1 LCD_Vss
54 \ VCC >-------|---3V6-----o----> 2 LCD_Vdd
61 \ TB0.2 >---||--o--^/\/\/v--o----> 3 LCD_Vo (= 0V6 without modulation)
62 \ -------------------------> 4 LCD_RW
63 \ -------------------------> 5 LCD_RW
64 \ -------------------------> 6 LCD_EN
65 \ <------------------------> 11 LCD_DB4
66 \ <------------------------> 12 LCD_DB5
67 \ <------------------------> 13 LCD_DB5
68 \ <------------------------> 14 LCD_DB7
70 \ <----- LCD contrast + <--- Sw1 <--- (finger) :-)
71 \ <----- LCD contrast - <--- Sw2 <--- (finger) :-)
73 \ rc5 <--- OUT IR_Receiver (1 TSOP32236)
76 [DEFINED] {RC5TOLCD} [IF] {RC5TOLCD} [THEN] \ remove application
78 [UNDEFINED] MARKER [IF]
79 \ https://forth-standard.org/standard/core/MARKER
81 \ ( "<spaces>name" -- )
82 \ Skip leading space delimiters. Parse name delimited by a space. Create a definition for name
83 \ with the execution semantics defined below.
85 \ name Execution: ( -- )
86 \ Restore all dictionary allocation and search order pointers to the state they had just prior to the
87 \ definition of name. Remove the definition of name and all subsequent definitions. Restoration
88 \ of any structures still existing that could refer to deleted definitions or deallocated data space is
89 \ not necessarily provided. No other contextual information such as numeric base is affected
94 MOV &LASTVOC,0(W) \ [BODY] = LASTVOC
96 MOV Y,2(W) \ 3 [BODY+2] = LFA = DP to be restored
97 ADD #4,&DP \ 3 add 2 cells
101 MOV @RSP+,IP \ -- PFA
102 MOV @TOS+,&INIVOC \ set VOC_LINK value for RST_STATE
103 MOV @TOS,&INIDP \ set DP value for RST_STATE
105 MOV #RST_STATE,PC \ execute RST_STATE, PWR_STATE then STATE_DOES
112 \ https://forth-standard.org/standard/core/Fetch
113 \ @ c-addr -- char fetch char from memory
120 [UNDEFINED] CONSTANT [IF]
121 \ https://forth-standard.org/standard/core/CONSTANT
122 \ CONSTANT <name> n -- define a Forth CONSTANT
126 MOV TOS,-2(W) \ PFA = n
133 [UNDEFINED] STATE [IF]
134 \ https://forth-standard.org/standard/core/STATE
135 \ STATE -- a-addr holds compiler state
136 STATEADR CONSTANT STATE
140 \ https://forth-standard.org/standard/core/Equal
141 \ = x1 x2 -- flag test x1=x2
148 XOR #-1,TOS \ 1 flag Z = 1
154 \ https://forth-standard.org/standard/core/IF
155 \ IF -- IFadr initialize conditional forward branch
159 MOV &DP,TOS \ -- HERE
160 ADD #4,&DP \ compile one word, reserve one word
161 MOV #QFBRAN,0(TOS) \ -- HERE compile QFBRAN
162 ADD #2,TOS \ -- HERE+2=IFadr
167 [UNDEFINED] THEN [IF]
168 \ https://forth-standard.org/standard/core/THEN
169 \ THEN IFadr -- resolve forward branch
170 CODE THEN \ immediate
171 MOV &DP,0(TOS) \ -- IFadr
177 [UNDEFINED] ELSE [IF]
178 \ https://forth-standard.org/standard/core/ELSE
179 \ ELSE IFadr -- ELSEadr resolve forward IF branch, leave ELSEadr on stack
180 CODE ELSE \ immediate
181 ADD #4,&DP \ make room to compile two words
184 MOV W,0(TOS) \ HERE+4 ==> [IFadr]
186 MOV W,TOS \ -- ELSEadr
191 [UNDEFINED] DEFER [IF]
192 \ https://forth-standard.org/standard/core/DEFER
193 \ DEFER "<spaces>name" --
194 \ Skip leading space delimiters. Parse name delimited by a space.
195 \ Create a definition for name with the execution semantics defined below.
198 \ Execute the xt that name is set to execute, i.e. NEXT (nothing),
199 \ until the phrase ' word IS name is executed, causing a new value of xt to be assigned to name.
203 MOV #$4030,-4(W) \ CFA = MOV @PC+,PC = BR MOV @IP+,PC
204 MOV #NEXT_ADR,-2(W) \ PFA = address of MOV @IP+,PC to do nothing.
210 [UNDEFINED] DEFER! [IF]
211 \ https://forth-standard.org/standard/core/DEFERStore
212 \ Set the word xt1 to execute xt2. An ambiguous condition exists if xt1 is not for a word defined by DEFER.
213 CODE DEFER! \ xt2 xt1 --
214 MOV @PSP+,2(TOS) \ -- xt1=CFA_DEFER xt2 --> [CFA_DEFER+2]
221 \ https://forth-standard.org/standard/core/IS
224 \ DEFER DISPLAY create a "do nothing" definition (2 CELLS)
225 \ inline command : ' U. IS DISPLAY U. becomes the runtime of the word DISPLAY
226 \ or in a definition : ... ['] U. IS DISPLAY ...
227 \ KEY, EMIT, CR, ACCEPT and WARM are examples of DEFERred words
229 \ as IS replaces the PFA value of any word, it's a TO alias for VARIABLE and CONSTANT words...
232 IF POSTPONE ['] POSTPONE DEFER!
238 [UNDEFINED] >BODY [IF]
239 \ https://forth-standard.org/standard/core/toBODY
240 \ >BODY -- addr leave BODY of a CREATEd word\ also leave default ACTION-OF primary DEFERred word
247 \ CODE 20uS \ n -- 8MHz version
248 \ BEGIN \ 4 + 16 ~ loop
249 \ MOV #39,rDOCON \ 39
256 \ MOV #XDOCON,rDOCON \ 2
261 CODE 20_US \ n -- n * 20 us
262 BEGIN \ here we presume that LCD_TIM_IFG = 1...
264 BIT #1,&LCD_TIM_CTL \ 3
265 0<> UNTIL \ 2 loop until LCD_TIM_IFG set
266 BIC #1,&LCD_TIM_CTL \ 3 clear LCD_TIM_IFG
268 U< UNTIL \ 2 ...so add a dummy loop with U< instead of 0=
273 CODE TOP_LCD \ LCD Sample
274 \ \ if write : %xxxx_WWWW --
275 \ \ if read : -- %0000_RRRR
276 BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
277 BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
278 0= IF \ write LCD bits pattern
280 MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
281 BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
284 THEN \ read LCD bits pattern
287 BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
288 MOV.B &LCD_DB_IN,TOS \ get LCD_Data
293 CODE LCD_WRC \ char -- Write Char
294 BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
296 MOV TOS,0(PSP) \ -- %xxxx_LLLL %HHHH_LLLL
297 RRUM #4,TOS \ -- %xxxx_LLLL %xxxx_HHHH
298 BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
299 BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
300 COLON \ high level word starts here
301 TOP_LCD 2 20_US \ write high nibble first
305 CODE LCD_WRF \ func -- Write Fonction
306 BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
310 : LCD_CLEAR $01 LCD_WRF 100 20_us ; \ $01 LCD_WrF 80 20_us ==> bad init !
311 : LCD_HOME $02 LCD_WRF 100 20_us ;
313 \ [UNDEFINED] OR [IF]
315 \ \ https://forth-standard.org/standard/core/OR
316 \ \ C OR x1 x2 -- x3 logical OR
324 \ : LCD_ENTRY_SET $04 OR LCD_WrF ;
325 \ : LCD_DSP_CTRL $08 OR LCD_WrF ;
326 \ : LCD_DSP_SHIFT $10 OR LCD_WrF ;
327 \ : LCD_FN_SET $20 OR LCD_WrF ;
328 \ : LCD_CGRAM_SET $40 OR LCD_WrF ;
329 \ : LCD_GOTO $80 OR LCD_WrF ;
332 \ CODE LCD_RDS \ -- status Read Status
333 \ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
334 \ BW1 BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
335 \ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
336 \ COLON \ starts a FORTH word
337 \ TOP_LCD 2 20_us \ -- %0000_HHHH
338 \ TOP_LCD 2 20_us \ -- %0000_HHHH %0000_LLLL
339 \ HI2LO \ switch from FORTH to assembler
340 \ RLAM #4,0(PSP) \ -- %HHHH_0000 %0000_LLLL
341 \ ADD.B @PSP+,TOS \ -- %HHHH_LLLL
342 \ MOV @RSP+,IP \ restore IP saved by COLON
346 \ CODE LCD_RDC \ -- char Read Char
347 \ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
352 \ ******************************\
353 ASM WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
354 \ ******************************\
355 ADD #2,RSP \ 1 smart and fast RETI with GIE=0
356 \ XOR.B #LED1,&LED1_OUT \ to visualise WDT
357 BIT.B #SW2,&SW2_IN \ test switch S2
358 0= IF \ case of switch S2 pressed
359 CMP #19,&LCD_TIM_CCRn \ maxi Ton = 19/20 & VDD=3V6 ==> LCD_Vo = -1V4
361 ADD #1,&LCD_TIM_CCRn \ action for switch S2 (P2.5) : 150 mV / increment
364 BIT.B #SW1,&SW1_IN \ test switch S1 input
365 0= IF \ case of Switch S1 pressed
366 CMP #3,&LCD_TIM_CCRn \ mini Ton = 3/20 & VDD=3V6 ==> LCD_Vo = 0V
368 SUB #1,&LCD_TIM_CCRn \ action for switch S1 (P2.6) : -150 mV / decrement
372 BW1 \ from quit on truncated RC5 message, repeated RC5 command
376 \ ******************************\
377 ASM RC5_INT \ wake up on Px.RC5 change interrupt
378 \ ******************************\
379 \ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
380 \ ******************************\
381 \ \ in : SR(9)=old Toggle bit memory (ADD on)
382 \ \ SMclock = 8|16|24 MHz
383 \ \ use : T,W,X,Y, RC5_TIM_ timer, RC5_TIM_R register
384 \ \ out : X = 0 C6 C5 C4 C3 C2 C1 C0
385 \ \ SR(9)=new Toggle bit memory (ADD on)
386 \ ******************************\
387 \ RC5_FirstStartBitHalfCycle: \
388 \ ******************************\ division in RC5_TIM_CTL (SMCLK/1|SMCLK/1|SMCLK/2|SMCLK/4|SMCLK/8)
389 ADD #2,RSP \ 1 smart and fast RETI with GIE=0
390 \ FREQ_KHZ @ 8000 = [IF] \ 8 MHz ?
391 \ MOV #0,&RC5_TIM_EX0 \ predivide by 1 in RC5_TIM_EX0 register, reset value
393 FREQ_KHZ @ 16000 = [IF] \ 16 MHz ?
394 MOV #1,&RC5_TIM_EX0 \ predivide by 2 in RC5_TIM_EX0 register
396 FREQ_KHZ @ 24000 = [IF] \ 24 MHz ?
397 MOV #2,&RC5_TIM_EX0 \ predivide by 3 in RC5_TIM_EX0 register
399 MOV #1778,X \ RC5_Period * 1us
400 MOV #14,W \ count of loop
402 \ ******************************\
403 \ RC5_HalfCycle \ <--- loop back ---+ with readjusted RC5_Period
404 \ ******************************\ |
405 MOV #%1011100100,&RC5_TIM_CTL \ (re)start timer_A | SMCLK/8 time interval,free running,clear RC5_TIM__IFG and RC5_TIM_R
406 \ RC5_Compute_3/4_Period: \ |
407 RRUM #1,X \ X=1/2 cycle |
410 ADD X,Y \ Y=3/4 cycle
411 BEGIN CMP Y,&RC5_TIM_R \ 3 wait 1/2 + 3/4 cycle = n+1/4 cycles
413 \ ******************************\
414 \ RC5_SampleOnFirstQuarter \ at n+1/4 cycles, we sample RC5_input, ST2/C6 bit first
415 \ ******************************\
416 BIT.B #RC5,&IR_IN \ C_flag = IR bit
417 ADDC T,T \ C_flag <-- T(15):T(0) <-- C_flag
418 MOV.B &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
419 BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
420 SUB #1,W \ decrement count loop
421 \ \ count = 13 ==> T = x x x x x x x x |x x x x x x x /C6
422 \ \ count = 0 ==> T = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
423 0<> WHILE \ ----> out of loop ----+
424 ADD X,Y \ | Y = n+3/4 cycles = time out because n+1/2 cycles edge is always present
426 MOV &RC5_TIM_R,X \ 3 | X grows from n+1/4 up to n+3/4 cycles
427 CMP Y,X \ 1 | cycle time out of bound ?
429 BIC #$30,&RC5_TIM_CTL \ | | stop timer
430 GOTO BW1 \ | | quit on truncated RC5 message
432 BIT.B #RC5,&IR_IFG \ 3 | | n+1/2 cycles edge is always present
434 REPEAT \ ----> loop back --+ | with X = new RC5_period value
435 \ ******************************\ |
436 \ RC5_SampleEndOf: \ <---------------------+
437 \ ******************************\
438 BIC #$30,&RC5_TIM_CTL \ stop timer
439 \ ******************************\
440 \ RC5_ComputeNewRC5word \
441 \ ******************************\
442 RLAM #1,T \ T = x /C6 Tg A4 A3 A2 A1 A0|C5 C4 C3 C2 C1 C0 1 0
443 MOV.B T,X \ X = C5 C4 C3 C2 C1 C0 1 0
444 RRUM #2,X \ X = 0 0 C5 C4 C3 C2 C1 C0
445 \ ******************************\
447 \ ******************************\
448 BIT #BIT14,T \ test /C6 bit in T
449 0= IF BIS #BIT6,X \ set C6 bit in X
450 THEN \ X = 0 C6 C5 C4 C3 C2 C1 C0
451 \ ******************************\
452 \ RC5_CommandByteIsDone \ -- BASE RC5_code
453 \ ******************************\
454 \ Only New_RC5_Command ADD_ON \ use SR(9) bit as toggle bit
455 \ ******************************\
456 RRUM #3,T \ new toggle bit = T(13) ==> T(10)
457 XOR @RSP,T \ (new XOR old) Toggle bits
458 BIT #UF10,T \ repeated RC5_command ?
459 0= ?GOTO BW1 \ yes, RETI without UF10 change and without action !
460 XOR #UF10,0(RSP) \ 5 toggle bit memory
461 \ ******************************\
462 \ Display IR_RC5 code \
463 \ ******************************\
464 SUB #8,PSP \ TOS -- x x x x TOS
465 MOV TOS,6(PSP) \ -- Save_TOS x x x TOS
466 MOV &BASEADR,4(PSP) \ -- Save_TOS Save_Base x x TOS
467 MOV #$10,&BASEADR \ set hexadecimal base
468 MOV X,0(PSP) \ -- Save_TOS Save_Base x RC5_code TOS convert number to ascii low word = RC5 byte
469 MOV #0,TOS \ -- Save_TOS Save_Base x RC5_code 0 convert number to ascii high word = 0
470 LO2HI \ switch from assembler to FORTH
471 LCD_CLEAR \ set LCD cursor at home
472 <# # #S #36 HOLD #> \ 32 bits conversion as "$xx"
473 ['] LCD_WRC IS EMIT \ redirect EMIT to LCD
474 TYPE \ -- Save_TOS Save_Base x adr cnt display "$xx" on LCD
475 ['] EMIT >BODY IS EMIT \ -- Save_TOS Save_Base TOS restore EMIT
476 HI2LO \ -- switch from FORTH to assembler
477 MOV @PSP+,&BASEADR \ -- Save_TOS TOS restore current BASE
478 MOV @PSP+,TOS \ -- TOS
482 \ ******************************\
484 \ ******************************\
486 \ ... \ insert here your background task
489 CALL &RXON \ comment this line to disable TERMINAL_INPUT
491 \ ******************************\
492 \ here start all interrupts \
493 \ ******************************\
494 \ here return all interrupts \
495 \ ******************************\
498 \ ******************************\
500 \ ------------------------------\
501 ASM SYS_OUT \ system OUT init, replaces WARM at the request of STOP.
502 \ ------------------------------\
503 \ ... \ init specific I/O sys as you want
504 \ ... \ before executing default WARM
505 MOV #WARM,X \ ['] WARM
507 MOV X,PC \ EXECUTE (which activates IO and TERMINAL)
509 \ ------------------------------\
511 \ ------------------------------\
512 CODE STOP \ stops multitasking, must to be used before downloading app
513 \ ------------------------------\
514 BW1 MOV #SLEEP,X \ the ASM word SLEEP is only visible in mode assembler.
515 ADD #4,X \ X = BODY of SLEEP, X-2 = PFA of SLEEP
516 MOV X,-2(X) \ restore the default background: SLEEP
518 MOV #SYS_OUT,2(X) \ default WARM is replaced by JMJ_BOX SYS_OUT (ended by default WARM)
519 BIC.B #RC5,&IR_IE \ clear RC5_Int
520 BIC.B #RC5,&IR_IFG \ clear RC5_Int flag
521 MOV #0,&LCD_TIM_CTL \ stop LCD_TIMER
522 MOV #0,&WDT_TIM_CTL \ stop WDT_TIMER
523 MOV #0,&WDT_TIM_CCTL0 \ clear CCIFG0 disable CCIE0
524 CALL #INIT_VECT \ reset all vectors other than TERMINAL_int
525 COLON \ restore default action of primary DEFERred word WARM (FORTH version)
527 ." RC5toLCD is removed,"
528 ." type START to restart"
529 WARM \ performs reset to reset all interrupt vectors.
531 \ ------------------------------\
533 \ ------------------------------\
534 CODE SYS_INIT \ this routine completes the init of system, i.e. FORTH + this app.
535 \ ------------------------------\
536 \ LCD_TIM_CTL = %0000 0010 1001 0100\$3C0
537 \ - - \CNTL Counter lentgh \ 00 = 16 bits
538 \ -- \TBSSEL TimerB clock select \ 10 = SMCLK
539 \ -- \ID input divider \ 10 = /4
540 \ -- \MC Mode Control \ 01 = up to LCD_TIM_CCR0
541 \ - \TBCLR TimerB Clear
544 \ -------------------------------\
545 \ LCD_TIM_CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
546 \ -- \CM Capture Mode
551 \ --- \OUTMOD \ 011 = set/reset
557 \ -------------------------------\
559 \ -------------------------------\
561 \ ------------------------------\
562 \ set LCD_TIM_ to make 50kHz PWM \ for LCD_Vo; works without interrupt
563 \ ------------------------------\
564 MOV #%10_1101_0100,&LCD_TIM_CTL \ SMCLK/8, up mode, clear timer, no int
565 \ MOV #0,&LCD_TIM_EX0 \ predivide by 1 in LCD_TIM_EX0 register (8 MHZ)
566 FREQ_KHZ @ 16000 = [IF] \ if 16 MHz
567 MOV #1,&LCD_TIM_EX0 \ predivide by 2 in LCD_TIM_EX0 register (16 MHZ)
569 FREQ_KHZ @ 24000 = [IF] \ if 24 MHz
570 MOV #2,&LCD_TIM_EX0 \ predivide by 3 in LCD_TIM_EX0 register (24 MHZ)
572 MOV #19,&LCD_TIM_CCR0 \ 19+1=20*1us=20us
573 \ ------------------------------\
574 \ set LCD_TIM_.2 to generate PWM for LCD_Vo
575 \ ------------------------------\
576 MOV #%0110_0000,&LCD_TIM_CCTLn \ output mode = set/reset \ clear CCIFG
577 MOV #10,&LCD_TIM_CCRn \ contrast adjust : 10/20 ==> LCD_Vo = -0V6|+3V6 (Vcc=3V6)
578 \ MOV #12,&LCD_TIM_CCRn \ contrast adjust : 12/20 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
579 \ ------------------------------\
580 BIS.B #LCDVo,&LCDVo_DIR \
581 BIS.B #LCDVo,&LCDVo_SEL \ SEL.2
582 \ ------------------------------\
583 BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
584 BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
585 \ ------------------------------\
586 BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
587 BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
588 \ ******************************\
590 \ ******************************\
591 BIS.B #RC5,&IR_IE \ enable RC5_Int
592 BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
593 MOV #RC5_INT,&IR_Vec \ init interrupt vector
594 \ ******************************\
595 \ init WatchDog WDT_TIM_ \ eUSCI_A0 (FORTH terminal) has higher priority than WDT_TIM_
596 \ ******************************\
597 \ %01 0001 0100 \ TAxCTL
598 \ -- \ TASSEL CLK = ACLK = LFXT = 32768 Hz
599 \ -- \ ID divided by 1
600 \ -- \ MC MODE = up to TAxCCRn
601 \ - \ TACLR clear timer count
604 \ ------------------------------\
605 MOV #%01_0001_0100,&WDT_TIM_CTL \ start WDT_TIM_, ACLK, up mode, disable int,
606 \ ------------------------------\
608 \ --- \ TAIDEX pre divisor
609 \ ------------------------------\
610 \ %0000 0000 0000 0101 \ TAxCCR0
611 MOV ##3276,&WDT_TIM_CCR0 \ else init WDT_TIM_ for LFXT: 32768/20=1638 ==> 100ms
612 \ ------------------------------\
613 \ %0000 0000 0001 0000 \ TAxCCTL0
614 \ - \ CAP capture/compare mode = compare
617 MOV #%10000,&WDT_TIM_CCTL0 \ enable compare interrupt, clear CCIFG0
618 \ ------------------------------\
619 MOV #WDT_INT,&WDT_TIM_0_Vec \ for only CCIFG0 int, this interrupt clears automatically CCIFG0
620 \ ------------------------------\
621 \ define LPM mode for ACCEPT \
622 \ ------------------------------\
623 \ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
624 \ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
625 \ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
626 \ ------------------------------\
628 \ ------------------------------\
629 BIC #1,&PM5CTL0 \ activate all previous I/O settings; if not activated, nothing works after reset !
630 BIS.B #TERM_BUS,&TERM_SEL \ Configure pins TXD & RXD for TERM_UART use, otherwise no TERMINAL !
631 \ ------------------------------\
632 \ RESET events handling \ search "SYSRSTIV" in your MSP430FRxxxx datasheet
633 \ ------------------------------\
634 MOV &SAVE_SYSRSTIV,Y \ Y = SYSRSTIV register memory
635 \ CMP #2,Y \ Power_ON event
636 \ 0= ?GOTO BW1 \ uncomment if you want to loose application in this case...
638 0= ?GOTO BW1 \ hardware RESET performs STOP. Should be mandatory...
640 \ 0= ?GOTO BW1 \ COLD event performs STOP... uncomment if it's that you want.
642 \ 0= ?GOTO BW1 \ fault event (violation memory protected areas) performs STOP
644 \ U>= ?GOTO BW1 \ all other fault events + Deep Reset perform STOP
645 \ ------------------------------\
647 \ ------------------------------\
649 \ ------------------------------\
650 #1000 20_US \ 1- wait 20 ms
651 %011 TOP_LCD \ 2- send DB5=DB4=1
652 #205 20_US \ 3- wait 4,1 ms
653 %011 TOP_LCD \ 4- send again DB5=DB4=1
654 #5 20_US \ 5- wait 0,1 ms
655 %011 TOP_LCD \ 6- send again again DB5=DB4=1
656 #2 20_US \ wait 40 us = LCD cycle
657 %010 TOP_LCD \ 7- send DB5=1 DB4=0
658 #2 20_US \ wait 40 us = LCD cycle
659 %00101000 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
660 %1000 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
661 LCD_CLEAR \ 10- "LCD_Clear"
662 %0110 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
663 %1100 LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
664 LCD_CLEAR \ 10- "LCD_Clear"
665 ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
666 ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
667 CR ." I love you" \ display message on LCD
668 ['] CR >BODY IS CR \ CR executes its default value
669 ['] EMIT >BODY IS EMIT \ EMIT executes its defaulte value
670 ." RC5toLCD is running. Type STOP to quit" \ display message on FastForth Terminal
671 PWR_STATE ABORT \ init DP and continues with ABORT
673 \ ------------------------------\
675 \ ------------------------------\
676 CODE START \ this routine replaces WARM and SLEEP default values by these of this application.
677 \ ------------------------------\
678 MOV #SLEEP,X \ replace default background process SLEEP
679 MOV #BACKGROUND,2(X) \ by RC5toLCD BACKGROUND
680 MOV #WARM,X \ replace default WARM
681 MOV #SYS_INIT,2(X) \ by RC5toLCD SYS_INIT
682 MOV X,PC \ then execute new WARM
684 \ ------------------------------\
687 ; downloading RC5toLCD.4th is done
688 RST_HERE ; this app is protected against <reset>