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
10 \ TARGET SELECTION ( = the name of \INC\target.pat file without the extension)
11 \ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989
15 \ from scite editor : copy your target selection in (shift+F8) parameter 1:
19 \ drag and drop this file onto SendSourceFileToTarget.bat
20 \ then select your TARGET when asked.
23 \ ================================================================================
24 \ REGISTERS USAGE for embedded MSP430 ASSEMBLER
25 \ ================================================================================
26 \ don't use R2, R3, R4
27 \ R5, R6, R7 must be PUSHed/POPed before/after use, OR restored after: MOV #{XDOCOL|XDOCON|R>},{rDODOES|rDOCON|rDOVAR}
28 \ scratch registers Y to S are free,
29 \ under interrupt, IP is free,
30 \ use FORTH rules for reg. TOS, PSP, RSP.
32 \ PUSHM order : PSP,TOS, IP, S , T , W , X , Y ,rDOVAR,rDOCON,rDODOES,rDOCOL, R3, SR,RSP, PC
33 \ PUSHM order : R15,R14,R13,R12,R11,R10, R9, R8, R7 , R6 , R5 , R4 , R3, R2, R1, R0
35 \ example : PUSHM #6,IP pushes IP,S,T,W,X,Y registers to return stack
37 \ POPM order : PC,RSP, SR, R3, rDODOES,rDOCON,rDOVAR,rEXIT, Y, X, W, T, S, IP,TOS,PSP
38 \ POPM order : R0, R1, R2, R3, R4 , R5 , R6 , R7 , R8, R9,R10,R11,R12,R13,R14,R15
40 \ example : POPM #6,IP pop Y,X,W,T,S,IP registers from return stack
42 \ ASSEMBLER conditionnal usage after IF UNTIL WHILE : S< S>= U< U>= 0= 0<> 0>=
43 \ ASSEMBLER conditionnal usage before ?GOTO : S< S>= U< U>= 0= 0<> 0<
46 \ display on a LCD 2x20 CHAR the code sent by an IR remote under philips RC5 protocol
47 \ target : any TI MSP-EXP430FRxxxx launchpad (FRAM)
48 \ LPM_MODE = LPM0 because use SMCLK for LCDVo
50 \ DEMO : driver for IR remote compatible with the PHILIPS RC5 protocol
51 \ plus : driver for 5V LCD 2x20 characters display with 4 bits data interface
52 \ without usage of an auxiliary 5V to feed the LCD_Vo
53 \ and without potentiometer to adjust the LCD contrast :
54 \ to adjust LCD contrast, just press S1 (-) or S2 (+)
55 \ LCDVo current consumption ~ 500 uA.
57 \ ===================================================================================
58 \ notice : adjust WDT_TIM_EX0,LCD_TIM_CTL,LCD_TIM_EX0 and 20_us to the target frequency if <> 8MHz !
59 \ ===================================================================================
62 \ layout : I/O are defined in the launchpad.pat file (don't work with ChipStick_FR2433)
64 \ GND <-------o---0V0----------> 1 LCD_Vss
65 \ VCC >-------|---3V6-----o----> 2 LCD_Vdd
72 \ TB0.2 >---||--o--^/\/\/v--o----> 3 LCD_Vo (= 0V6 without modulation)
73 \ -------------------------> 4 LCD_RW
74 \ -------------------------> 5 LCD_RW
75 \ -------------------------> 6 LCD_EN
76 \ <------------------------> 11 LCD_DB4
77 \ <------------------------> 12 LCD_DB5
78 \ <------------------------> 13 LCD_DB5
79 \ <------------------------> 14 LCD_DB7
81 \ <----- LCD contrast + <--- Sw1 <--- (finger) :-)
82 \ <----- LCD contrast - <--- Sw2 <--- (finger) :-)
84 \ rc5 <--- OUT IR_Receiver (1 TSOP32236)
87 \ first, we do some tests allowing the download
92 SUB #400,TOS \ FastForth V4.0
94 'CR' EMIT \ return to column 1 without 'LF'
95 ABORT" FastForth V4.0 please!"
96 RST_RET \ remove ABORT_UARTI2CS definition before resuming
101 MARKER {RC5TOLCD} \ restore the state before MARKER definition
102 \ \ {UARTI2CS}-2 = RET_ADR: by default MARKER_DOES does CALL #RET_ADR
103 8 ALLOT \ {UARTI2CS} make room to save previous HARD_APP address
104 \ {RC5TOLCD}+2 make room to save previous WDT_TIM_0_VEC
105 \ {RC5TOLCD}+4 make room to save previous IR_VEC
106 \ {RC5TOLCD}+6 make room for 20 us count loop.
108 ; ------------------------------------------------------------------
109 ; first we download the set of definitions we need (from CORE_ANS.f)
110 ; ------------------------------------------------------------------
112 \ https://forth-standard.org/standard/core/Equal
113 \ = x1 x2 -- flag test x1=x2
122 XOR #-1,TOS \ 1 flag Z = 1
128 [IF] \ define IF and THEN
129 \ https://forth-standard.org/standard/core/IF
130 \ IF -- IFadr initialize conditional forward branch
134 MOV &DP,TOS \ -- HERE
135 ADD #4,&DP \ compile one word, reserve one word
136 MOV #QFBRAN,0(TOS) \ -- HERE compile QFBRAN
137 ADD #2,TOS \ -- HERE+2=IFadr
141 \ https://forth-standard.org/standard/core/THEN
142 \ THEN IFadr -- resolve forward branch
143 CODE THEN \ immediate
144 MOV &DP,0(TOS) \ -- IFadr
150 \ https://forth-standard.org/standard/core/ELSE
151 \ ELSE IFadr -- ELSEadr resolve forward IF branch, leave ELSEadr on stack
154 CODE ELSE \ immediate
155 ADD #4,&DP \ make room to compile two words
158 MOV W,0(TOS) \ HERE+4 ==> [IFadr]
160 MOV W,TOS \ -- ELSEadr
165 \ \ https://forth-standard.org/standard/core/DEFERStore
166 \ \ Set the word xt1 to execute xt2. An ambiguous condition exists if xt1 is not for a word defined by DEFER.
168 \ [IF] \ define DEFER! and IS
169 \ CODE DEFER! \ xt2 xt1 --
170 \ MOV @PSP+,2(TOS) \ -- xt1=CFA_DEFER xt2 --> [CFA_DEFER+2]
175 \ \ https://forth-standard.org/standard/core/IS
178 \ \ DEFER DISPLAY create a "do nothing" definition (2 CELLS)
179 \ \ inline command : ' U. IS DISPLAY U. becomes the runtime of the word DISPLAY
180 \ \ or in a definition : ... ['] U. IS DISPLAY ...
181 \ \ KEY, EMIT, CR, ACCEPT and WARM are examples of DEFERred words
183 \ \ as IS replaces the PFA value of any word, it's a TO alias for VARIABLE and CONSTANT words...
187 \ IF POSTPONE ['] POSTPONE DEFER!
193 \ https://forth-standard.org/standard/core/CR
194 \ CR -- send CR+LF to the output device
197 \ create a primary defered word, i.e. with its default runtime beginning at the >BODY of the definition
198 CODE CR \ part I : DEFERed definition of CR
199 MOV #NEXT_ADR,PC \ [PFA] = NEXT_ADR
207 \ https://forth-standard.org/standard/core/toBODY
208 \ >BODY -- addr leave BODY of a CREATEd word\ also leave default ACTION-OF primary DEFERred word
217 ; --------------------------
218 ; end of definitions we need
219 ; --------------------------
222 BEGIN \ J_loop 8000 16000 24000 kHz
223 MOV &{RC5TOLCD}+6,X \ 3 X = {40 80 120}
224 SUB #2,X \ +1 X = {38 78 118} I_loops + 2 J_loops = {40 80 120} * 4 cycles
236 \ \ if write : %xxxx_WWWW --
237 \ \ if read : -- %0000_RRRR
238 CODE TOP_LCD \ LCD Sample
239 BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
240 BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
241 0= IF \ write LCD bits pattern
243 MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
244 BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
247 THEN \ read LCD bits pattern
250 BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
251 MOV.B &LCD_DB_IN,TOS \ get LCD_Data
256 CODE LCD_WRC \ char -- Write Char
257 BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
259 MOV TOS,0(PSP) \ -- %HHHH_LLLL %HHHH_LLLL
260 RRUM #4,TOS \ -- %xxxx_LLLL %xxxx_HHHH
261 BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
262 BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
263 COLON \ high level word starts here
264 TOP_LCD 2 20_US \ write high nibble first
268 CODE LCD_WRF \ func -- Write Fonction
269 BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
273 : LCD_CLEAR $01 LCD_WRF 100 20_us ; \ $01 LCD_WrF 80 20_us ==> bad init !
274 : LCD_HOME $02 LCD_WRF 100 20_us ;
307 \ CODE LCD_RDS \ -- status Read Status
308 \ BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
309 \ BW1 BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
310 \ BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
311 \ COLON \ starts a FORTH word
312 \ TOP_LCD 2 20_us \ -- %0000_HHHH
313 \ TOP_LCD 2 20_us \ -- %0000_HHHH %0000_LLLL
314 \ HI2LO \ switch from FORTH to assembler
315 \ RLAM #4,0(PSP) \ -- %HHHH_0000 %0000_LLLL
316 \ ADD.B @PSP+,TOS \ -- %HHHH_LLLL
317 \ MOV @RSP+,IP \ restore IP saved by COLON
321 \ CODE LCD_RDC \ -- char Read Char
322 \ BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
327 \ ********************************\
328 HDNCODE WDT_INT \ Watchdog interrupt routine, warning : not FORTH executable !
329 \ ********************************\
330 \ XOR.B #LED1,&LED1_OUT \ to visualise WDT
331 BIT.B #SW2,&SW2_IN \ test switch S2
332 0= IF \ case of switch S2 pressed
333 CMP #19,&LCD_TIM_CCRn \ maxi Ton = 19/20 & VDD=3V6 ==> LCD_Vo = -1V4
335 ADD #1,&LCD_TIM_CCRn \ action for switch S2 (P2.5) : 150 mV / increment
338 BIT.B #SW1,&SW1_IN \ test switch S1 input
339 0= IF \ case of Switch S1 pressed
340 CMP #3,&LCD_TIM_CCRn \ mini Ton = 3/20 & VDD=3V6 ==> LCD_Vo = 0V
342 SUB #1,&LCD_TIM_CCRn \ action for switch S1 (P2.6) : -150 mV / decrement
348 \ ********************************\
350 \ ********************************\
351 HDNCODE RC5_INT \ wake up on Px.RC5 change interrupt
352 \ ********************************\
353 \ IR_RC5 driver \ IP,S,T,W,X,Y registers are free for use
354 \ ********************************\
355 \ \ in : SR(9)=old Toggle bit memory (ADD on)
356 \ \ SMclock = 8|16|24 MHz
357 \ \ use : T,W,X,Y, RC5_TIM_ timer, RC5_TIM_R register
358 \ \ out : X = 0 C6 C5 C4 C3 C2 C1 C0
359 \ \ SR(9)=new Toggle bit memory (ADD on)
360 \ ********************************\
361 \ RC5_FirstStartBitHalfCycle: \
362 \ ********************************\
363 MOV #1778,X \ RC5_Period in us
364 MOV #14,W \ count of loop
366 \ ****************************\
367 \ RC5_HalfCycle \ <--- loop back ---+ with readjusted RC5_Period
368 \ ****************************\ |
369 MOV #%1011100100,&RC5_TIM_CTL \ (re)start timer_A | SMCLK/8 time interval,free running,clear RC5_TIM__IFG and RC5_TIM_R
370 \ RC5_Compute_3/4_Period: \ |
371 RRUM #1,X \ X=1/2 cycle |
374 ADD X,Y \ Y=3/4 cycle
376 CMP Y,&RC5_TIM_R \ 3 wait 1/2 + 3/4 cycle = n+1/4 cycles
378 \ ****************************\
379 \ RC5_SampleOnFirstQuarter \ at n+1/4 cycles, we sample RC5_input, ST2/C6 bit first
380 \ ****************************\
381 BIT.B #RC5,&IR_IN \ C_flag = IR bit
382 ADDC T,T \ C_flag <-- T(15):T(0) <-- C_flag
383 MOV.B &IR_IN,&IR_IES \ preset Px_IES.y state for next IFG
384 BIC.B #RC5,&IR_IFG \ clear Px_IFG.y after 4/4 cycle pin change
385 SUB #1,W \ decrement count loop
386 \ \ count = 13 ==> T = x x x x x x x x |x x x x x x x /C6
387 \ \ count = 0 ==> T = x x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0 1
388 0<> WHILE \ ----> out of loop ----+
389 ADD X,Y \ | Y = n+3/4 cycles = time out because n+1/2 cycles edge is always present
391 MOV &RC5_TIM_R,X \ 3 | X grows from n+1/4 up to n+3/4 cycles
392 CMP Y,X \ 1 ^ | cycle time out of bound ?
393 U>= ?GOTO FW1 \ | | quit on truncated RC5 message
394 BIT.B #RC5,&IR_IFG \ 3 | | n+1/2 cycles edge is always present
396 REPEAT \ ----> loop back --+ | with X = new RC5_period value
397 \ ********************************\ |
398 \ RC5_SampleEndOf: \ <---------------------+
399 \ ********************************\
400 BIC #$30,&RC5_TIM_CTL \ stop timer
401 \ ********************************\
402 \ RC5_ComputeNewRC5word \
403 \ ********************************\
404 RLAM #1,T \ T = x /C6 Tg A4 A3 A2 A1 A0|C5 C4 C3 C2 C1 C0 1 0
405 MOV.B T,X \ X = C5 C4 C3 C2 C1 C0 1 0
406 RRUM #2,X \ X = 0 0 C5 C4 C3 C2 C1 C0
407 \ ********************************\
409 \ ********************************\
410 BIT #BIT14,T \ test /C6 bit in T
411 0= IF BIS #BIT6,X \ set C6 bit in X
412 THEN \ X = 0 C6 C5 C4 C3 C2 C1 C0
413 \ ********************************\
414 \ RC5_CommandByteIsDone \
415 \ ********************************\
416 \ Only New_RC5_Command ADD_ON \ use SR(10) bit as toggle bit
417 \ ********************************\
418 RRUM #3,T \ new toggle bit = T(13) ==> T(10)
419 XOR @RSP,T \ (new XOR old) Toggle bits
420 BIT #UF10,T \ repeated RC5_command ?
421 0= ?GOTO FW2 \ yes, RETI without UF10 change and without action !
422 XOR #UF10,0(RSP) \ 5 toggle bit memory
423 \ ********************************\
424 \ Display IR_RC5 code \
425 \ ********************************\
426 SUB #6,PSP \ -- x x x TOS
427 MOV TOS,4(PSP) \ -- TOS x x TOS
428 MOV &BASEADR,2(PSP) \ -- TOS Base x TOS
429 MOV #$10,&BASEADR \ set hexadecimal base
430 MOV X,0(PSP) \ -- TOS Base RC5_code TOS convert number to ascii low word = RC5 byte
431 MOV #0,TOS \ -- TOS Base RC5_code 0 convert double number to ascii
432 LO2HI \ switch from assembler to FORTH
433 LCD_CLEAR \ set LCD cursor at home
434 <# # #S #36 HOLD #> \ -- TOS Base adr cnt 32 bits conversion as "$xx"
435 ['] LCD_WRC IS EMIT \ redirect EMIT to LCD
436 TYPE \ -- TOS Base display "$xx" on LCD
437 ['] EMIT >BODY IS EMIT \ restore EMIT
438 HI2LO \ switch from FORTH to assembler
439 MOV @PSP+,&BASEADR \ -- TOS restore current BASE
441 FW1 BIC #$30,&RC5_TIM_CTL \ stop timer (case of truncated RC5 message)
442 FW2 BIC #%1111_1000,0(RSP) \ force CPU Active Mode and disable GIE in saved SR
445 \ ********************************\
447 \ define our STOP_APP
448 \ ----------------------------------\
449 HDNCODE STOP_R2L \ called by STOP|INIT_R2L|{RC5TOLCD}
450 \ ----------------------------------\
451 CMP #WDT_INT,&WDT_TIM_0_VEC \ value set by START
452 0= IF \ only if START is done
453 BIC.B #RC5,&IR_IE \ clear I/O RC5_Int
454 BIC.B #RC5,&IR_IFG \ clear I/O RC5_Int flag
455 MOV #0,&LCD_TIM_CTL \ stop LCD_TIMER, clear LCD_TIMER IFG
456 MOV #0,&WDT_TIM_CTL \ stop WDT_TIMER
457 MOV #0,&WDT_TIM_CCTL0 \ clear CCIFG0 disable CCIE0
459 MOV #RET_ADR,-2(W) \ clear MARKER_DOES call
460 MOV @W+,&HARD_APP \ restore previous ini_APP
461 MOV @W+,&WDT_TIM_0_VEC \ restore Vector previous value
462 MOV @W+,&IR_VEC \ restore Vector previous value
464 MOV @RSP+,PC \ RET to STOP|WARM+4|{RC5TOLCD}
466 \ ----------------------------------\
468 \ ----------------------------------\
469 CODE STOP \ also called by INIT_R2L for some events
470 \ ----------------------------------\
474 ." type START to start RC5toLCD"
476 \ ----------------------------------\
478 \ this routine completes the INIT_HARD of FORTH, with INIT_HARD for this app.
479 \ ----------------------------------\
480 HDNCODE INIT_R2L \ called by START|SYS
481 \ ----------------------------------\
482 \ LCD_TIM_CTL = %0000 0010 1001 0100\$3C0
483 \ - - \CNTL Counter lentgh \ 00 = 16 bits
484 \ -- \TBSSEL TimerB clock select \ 10 = SMCLK
485 \ -- \ID input divider \ 10 = /4
486 \ -- \MC Mode Control \ 01 = up to LCD_TIM_CCR0
487 \ - \TBCLR TimerB Clear
490 \ ----------------------------------\
491 \ LCD_TIM_CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
492 \ -- \CM Capture Mode
497 \ --- \OUTMOD \ 011 = set/reset
503 \ ----------------------------------\
505 \ ----------------------------------\
507 \ ----------------------------------\
508 \ set LCD_TIM_ to make 50kHz PWM \ for LCD_Vo; works without interrupt
509 \ ----------------------------------\
510 MOV #%10_1101_0100,&LCD_TIM_CTL \ SMCLK/8, up mode, clear timer, no int, set IFG
511 \ MOV #0,&RC5_TIM_EX0 \ predivide by 1 in RC5_TIM_EX0 register, reset value
512 \ MOV #0,&LCD_TIM_EX0 \ predivide by 1 in LCD_TIM_EX0 register (8 MHZ)
515 MOV #1,&RC5_TIM_EX0 \ predivide by 2 in RC5_TIM_EX0 register
516 MOV #1,&LCD_TIM_EX0 \ predivide by 2 in LCD_TIM_EX0 register (16 MHZ)
520 MOV #2,&RC5_TIM_EX0 \ predivide by 3 in RC5_TIM_EX0 register
521 MOV #2,&LCD_TIM_EX0 \ predivide by 3 in LCD_TIM_EX0 register (24 MHZ)
523 MOV #19,&LCD_TIM_CCR0 \ 19+1=20*1us=20us
524 \ ----------------------------------\
525 \ set LCD_TIM_.2 to generate PWM for LCD_Vo
526 \ ----------------------------------\
527 MOV #%0110_0000,&LCD_TIM_CCTLn \ output mode = set/reset \ clear CCIFG
528 MOV #10,&LCD_TIM_CCRn \ contrast adjust : 10/20 ==> LCD_Vo = -0V6|+3V6 (Vcc=3V6)
529 \ MOV #12,&LCD_TIM_CCRn \ contrast adjust : 12/20 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
530 \ ----------------------------------\
531 BIS.B #LCDVo,&LCDVo_DIR \
532 BIS.B #LCDVo,&LCDVo_SEL \ SEL.2
533 \ ----------------------------------\
534 BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
535 BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
536 \ ----------------------------------\
537 BIS.B #LCD_DB,&LCD_DB_DIR \ as output, wired to DB(4-7) LCD_Data
538 BIC.B #LCD_DB,&LCD_DB_REN \ LCD_Data pullup/down disable
539 \ ----------------------------------\
541 \ ----------------------------------\
542 BIS.B #RC5,&IR_IE \ enable RC5_Int
543 BIC.B #RC5,&IR_IFG \ reset RC5_Int flag
544 \ ----------------------------------\
545 \ init WatchDog WDT_TIM_ \ eUSCI_A0 (FORTH terminal) has higher priority than WDT_TIM_
546 \ ----------------------------------\
547 \ %01 0001 0100 \ TAxCTL
548 \ -- \ TASSEL CLK = ACLK = LFXT = 32768 Hz
549 \ -- \ ID divided by 1
550 \ -- \ MC MODE = up to TAxCCRn
551 \ - \ TACLR clear timer count
554 \ ----------------------------------\
555 MOV #%01_0001_0100,&WDT_TIM_CTL \ start WDT_TIM_, ACLK, up mode, disable int,
556 \ ----------------------------------\
558 \ --- \ TAIDEX pre divisor
559 \ ----------------------------------\
560 \ %0000 0000 0000 0101 \ TAxCCR0
561 MOV ##3276,&WDT_TIM_CCR0 \ else init WDT_TIM_ for LFXT: 32768/20=1638 ==> 100ms
562 \ ----------------------------------\
563 \ %0000 0000 0001 0000 \ TAxCCTL0
564 \ - \ CAP capture/compare mode = compare
567 MOV #%10000,&WDT_TIM_CCTL0 \ enable compare interrupt, clear CCIFG0
568 \ ----------------------------------\
570 \ ----------------------------------\
571 CALL &{RC5TOLCD} \ run previous INIT_HARD_APP
572 \ ----------------------------------\
573 \ RESET events handling \ search "SYSRSTIV" in your MSP430FRxxxx datasheet to get listing
574 \ ----------------------------------\
575 CMP #$0E,TOS \ SYSRSTIV = SVSHIFG SVSH event ?
577 CMP #$0A,TOS \ SYSRSTIV >= violation memory protected areas | USERSYS <0 = DEEP_RESET request ?
578 U>= ?GOTO BW1 \ if yes execute STOP_R2L then RET to BODY of WARM
580 \ CMP #2,TOS \ Power_ON event
581 \ 0= ?GOTO BW1 \ uncomment if you want to loose application in this case...
582 CMP #4,TOS \ SYSRSTIV|USERSYS RST ?
583 0= ?GOTO BW1 \ if yes run STOP.
584 \ CMP #$0E,TOS \ SYSRSTIV = SVSHIFG SVSH event ?
585 \ 0= ?GOTO BW1 \ SVSHIFG SVSH event performs STOP
586 \ ----------------------------------\
588 \ ----------------------------------\
590 \ ----------------------------------\
591 #1000 20_US \ 1- wait 20 ms
592 %011 TOP_LCD \ 2- send DB5=DB4=1
593 #205 20_US \ 3- wait 4,1 ms
594 %011 TOP_LCD \ 4- send again DB5=DB4=1
595 #5 20_US \ 5- wait 0,1 ms
596 %011 TOP_LCD \ 6- send again again DB5=DB4=1
597 #2 20_US \ wait 40 us = LCD cycle
598 %010 TOP_LCD \ 7- send DB5=1 DB4=0
599 #2 20_US \ wait 40 us = LCD cycle
600 %00101000 LCD_WRF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
601 %1000 LCD_WRF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
602 LCD_CLEAR \ 10- "LCD_Clear"
603 %0110 LCD_WRF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
604 %1100 LCD_WRF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
605 LCD_CLEAR \ 10- "LCD_Clear"
607 MOV @RSP+,PC \ RET to WARM|START
609 \ ----------------------------------\
611 \ ----------------------------------\
612 CODE START \ this routine replaces INT_HARD_APP default values by these of this application.
613 \ ----------------------------------\
614 CMP #WDT_INT,&WDT_TIM_0_VEC \ value set by START
616 MOV @IP+,PC \ does nothing if already initialised
618 MOV #STOP_R2L,&{RC5TOLCD}-2 \ execution of {RC5TOLCD} will perform STOP_R2L.
619 MOV &HARD_APP,&{RC5TOLCD} \ save previous HARD_APP subroutine
620 MOV #INIT_R2L,&HARD_APP \ replace it by RC5toLCD INIT_R2L
621 MOV &WDT_TIM_0_VEC,&{RC5TOLCD}+2 \ save Vector previous value
622 MOV #WDT_INT,&WDT_TIM_0_VEC \ for only CCIFG0 int, this interrupt clears automatically CCIFG0
623 MOV &IR_VEC,&{RC5TOLCD}+4 \ save Vector previous value
624 MOV #RC5_INT,&IR_VEC \ init interrupt vector
625 \ ----------------------------------\
626 \ init 20 us count loop \ see 20_US
627 \ ----------------------------------\ -- TOS
628 SUB #6,PSP \ -- x x x TOS
629 MOV TOS,4(PSP) \ -- TOS x x TOS
630 MOV &FREQ_KHZ,2(PSP) \ -- TOS DVDlo x TOS
631 MOV #0,0(PSP) \ -- TOS DVDlo DVDhi TOS
632 MOV #200,TOS \ -- TOS DVDlo DVDhi DIVlo
633 CALL #MUSMOD \ -- TOS REMlo QUOTlo QUOThi
634 MOV @PSP,&{RC5TOLCD}+6 \ set count+2 for 20_US
635 ADD #4,PSP \ -- TOS QUOThi
636 MOV @PSP+,TOS \ -- TOS
637 \ ----------------------------------\
638 CALL #INIT_R2L \ run new INIT_HARD_APP
640 \ ['] LCD_HOME IS CR \ ' CR redirected to LCD_HOME
641 \ ['] LCD_WRC IS EMIT \ ' EMIT redirected to LCD_WrC
642 \ CR ." I love you" \ display message on LCD
643 \ ['] CR >BODY IS CR \ CR executes its default value
644 \ ['] EMIT >BODY IS EMIT \ EMIT executes its defaulte value
645 ." RC5toLCD is running," \
646 ." Type STOP to quit." \ display message on FastForth Terminal
648 MOV #ABORT,PC \ goto FORTH interpreter without WARM message.
650 \ ----------------------------------\