1 \ name : I2C_Slave_to_LCD_2x20.f
3 \ Copyright (C) <2015> <J.M. THOORENS>
5 \ This program is free software: you can redistribute it and/or modify
6 \ it under the terms of the GNU General Public License as published by
7 \ the Free Software Foundation, either version 3 of the License, or
8 \ (at your option) any later version.
10 \ This program is distributed in the hope that it will be useful,
11 \ but WITHOUT ANY WARRANTY\ without even the implied warranty of
12 \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 \ GNU General Public License for more details.
15 \ You should have received a copy of the GNU General Public License
16 \ along with this program. If not, see <http://www.gnu.org/licenses/>.
19 \ --------------------------------------\
20 \ example of App running under interrupt
21 \ --------------------------------------\
23 \ for MSP_EXP430FR5739, MSP_EXP430FR5969, MSP_EXP430FR6989, ... launchpads @ 8MHz
25 \ prerequisites : your launchpad is wired as described in launchpad.pat file : UART0, SDA, SCL, LCD parts
26 \ and FastForth runs @ 8MHz
27 \ usage : create a logical network drive ( a: b: as you want) from your local copy of Gitlab FAST FORTH
28 \ with scite.exe open this file MSP430-FORTH\I2C_Slave_to_LCD_2x20.f,
29 \ select "tools" menu, "preprocess" item 2 (CTRL+1),
30 \ a dialog box asks you for 4 parameters $(1) to $(4),
31 \ in the 2th param. field, type your launchpad to select the launchpad.pat to be used : for example MSP_EXP430FR5969,
32 \ in the 3th param. field, type the COMx port of your USBtoUART device.
33 \ result : a file.4th in which all symbolic addresses are resolved according to the rules described in the selected launchpad.pat
34 \ the word START starts the app that runs under LPMx.
35 \ to recover the console input (i.e. to quit LPMx), type a space. Then you can enter a command, for example STOP.
40 : U.R \ u n -- display u unsigned in n width
42 R> OVER - 0 MAX SPACES TYPE
46 CODE ? \ adr -- display the content of adr
53 \ ------------------------------\
54 CODE 20_us \ n -- n * 20 us
55 \ ------------------------------\
56 BEGIN \ 3 cycles loop + 6~
57 \ MOV #5,W \ 3 MCLK = 1 MHz
58 \ MOV #23,W \ 3 MCLK = 4 MHz
59 MOV #51,W \ 3 MCLK = 8 MHz
60 \ MOV #104,W \ 3 MCLK = 16 MHz
61 \ MOV #158,W \ 3 MCLK = 24 MHz
62 BEGIN \ 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
71 \ ------------------------------\
72 CODE TOP_LCD \ LCD Sample
73 \ ------------------------------\ if write : %xxxxWWWW --
74 \ \ if read : -- %0000RRRR
75 BIS.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 0-->1
76 BIT.B #LCD_RW,&LCD_CMD_IN \ lcd_rw test
77 0= IF \ write LCD bits pattern
79 MOV.B TOS,&LCD_DB_OUT \ send LCD_Data
80 BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
83 THEN \ read LCD bits pattern
86 BIC.B #LCD_EN,&LCD_CMD_OUT \ lcd_en 1-->0 ==> strobe data
87 MOV.B &LCD_DB_IN,TOS \ get LCD_Data
92 \ ------------------------------\
93 CODE LCD_W \ byte -- write byte
94 \ ------------------------------\
96 MOV TOS,0(PSP) \ -- %xxxxLLLL %HHHHLLLL
97 RRUM #4,TOS \ -- %xxxxLLLL %xxxxHHHH
98 BIC.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=0
99 BIS.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as output
101 TOP_LCD 2 20_us \ write high nibble first
104 \ ------------------------------\
105 CODE LCD_R \ -- byte read byte
106 \ ------------------------------\
107 BIC.B #LCD_DB,&LCD_DB_DIR \ LCD_Data as intput
108 BIS.B #LCD_RW,&LCD_CMD_OUT \ lcd_rw=1
110 TOP_LCD 2 20_us \ read high nibble first
112 HI2LO \ -- %0000HHHH %0000LLLL
114 MOV @PSP+,W \ W = high nibble
115 RLAM #4,W \ -- %0000LLLL W = %HHHH0000
120 \ ------------------------------\
121 CODE LCD_WrF \ func -- Write Fonction
122 \ ------------------------------\
123 BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
127 \ ------------------------------\
128 CODE LCD_RdS \ -- status Read Status
129 \ ------------------------------\
130 BIC.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=0
134 \ ------------------------------\
135 CODE LCD_WrC \ char -- Write Char
136 \ ------------------------------\
137 BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
141 \ ------------------------------\
142 CODE LCD_RdC \ -- char Read Char
143 \ ------------------------------\
144 BIS.B #LCD_RS,&LCD_CMD_OUT \ lcd_rs=1
148 \ ------------------------------\
149 \ : LCD_Clear $01 LCD_WrF 80 20_us \ bad init !
150 : LCD_Clear $01 LCD_WrF 100 20_us ;
152 \ ------------------------------\
153 : LCD_Home $02 LCD_WrF 80 20_us ;
155 \ ------------------------------\
156 \ : LCD_Entry_set $04 OR LCD_WrF ;
157 \ : LCD_Display_Ctrl $08 OR LCD_WrF ;
158 \ : LCD_Display_Shift $10 OR LCD_WrF ;
159 \ : LCD_Fn_Set $20 OR LCD_WrF ;
160 \ : LCD_CGRAM_Set $40 OR LCD_WrF ;
161 \ : LCD_Goto $80 OR LCD_WrF ;
163 \ -------------+------+------+------+------++---+---+---+---+---------+
164 \ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
165 \ -------------+------+------+------+------++---+---+---+---+---------+
166 \ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
167 \ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
168 \ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
169 \ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
170 \ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
171 \ -------------+------+------+------+------++---+---+---+---+---------+
173 \ ******************************\
174 ASM WDT_Int \ Watchdog interrupt routine, warning : not FORTH executable !
175 \ ******************************\
176 \ ------------------------------\
177 \ define LPM mode for ACCEPT \ LPM0 is the default mode.
178 \ ------------------------------\
179 \ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
180 \ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
181 \ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0
182 \ ------------------------------\
183 BIT.B #SW2,&SW2_IN \ test switch S2
184 0= IF \ case of switch S2 pressed
185 CMP #34,&TB0CCR2 \ maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
187 ADD #1,&TB0CCR2 \ action for switch S2 (P2.5) : 78 mV / increment
190 BIT.B #SW1,&SW1_IN \ test switch S1 input
191 0= IF \ case of Switch S1 pressed
192 CMP #7,&TB0CCR2 \ mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
194 SUB #1,&TB0CCR2 \ action for switch S1 (P2.6) : -78 mV / decrement
198 BIC #WDTIFG,&SFRIFG1 \ reset WDT_INT flag
199 BIC #$F8,0(RSP) \ set CPU ON and GIE OFF in retiSR
200 RETI \ CPU is ON, GIE is OFF
206 VARIABLE I2CS_OWN \ slave I2C address without RW flag (low byte) + DATA0 input (HIGH byte)
207 \ 2 ALLOT \ next the low byte of I2CS_OWN word, it is the input buffer
208 VARIABLE I2CS_BUF \ buffer output, lentgh (low byte),DATA0 output (HIGH byte)
209 \ 2 ALLOT \ this byte lentgh is shared by input and output buffers
211 \ ******************************\
212 ASM I2CS_TX \ TX part of I2C_Slave
213 \ ******************************\
214 \ \ T = TX buffer_org
215 \ \ use W = TX buffer_ptr
216 \ \ out : low(I2CS_BUF) = RX or TX lentgh
217 \ ------------------------------\
218 MOV T,W \ W = TX_buf_ptr -1
220 ADD #1,W \ first reserve one byte for length then inc
221 MOV.B @W,&UCB0TXBUF \ +[W] --> UCB0TXBUF
222 \ ----------------------------\
224 \ ----------------------------\
226 BIT #$0C,&UCB0IFG \ UCB0IFG(STP,STT) = 1 ?
228 \ --------------------\
229 \ stop or restart received
230 \ --------------------\
232 SUB.B #1,W \ sub #1, because char +[W] is not sent
233 MOV.B W,0(T) \ store length in first byte of buffer output
234 BIC #UCTR,&UCB0CTLW0 \ reset UCTR R/W bit for next START
235 MOV @RSP+,PC \ ===> ret
236 \ --------------------\
238 BIT #2,&UCB0IFG \ UCB0IFG(TX0) = 1 ?
244 \ -------------+------+------+------+------++---+---+---+---+---------+
245 \ SR(low byte) | SCG1 | SCG0 |OSCOFF|CPUOFF||GIE| N | Z | C | current |
246 \ -------------+------+------+------+------++---+---+---+---+---------+
247 \ LPM0 = $18 | 0 | 0 | 0 | 1 || 1 | x | x | x | 180uA | default mode
248 \ LPM1 = $58 | 0 | 1 | 0 | 1 || 1 | x | x | x | | same mode as LPM0
249 \ LPM2 = $98 | 1 | 0 | 0 | 1 || 1 | x | x | x | 60uA |
250 \ LPM3 = $D8 | 1 | 1 | 0 | 1 || 1 | x | x | x | 10uA | 32768Hz XTAL is running
251 \ LPM4 = $F8 | 1 | 1 | 1 | 1 || 1 | x | x | x | 6uA |
252 \ -------------+------+------+------+------++---+---+---+---+---------+
254 \ **************************************\
255 ASM I2C_S \ <== eUSCIB0 interrupt vector : i2c_addres&R/w sent by master is received
256 \ **************************************\
257 BIC #$F8,0(RSP) \ SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPM0_LOOP with pending interrupt
258 \ --------------------------------------\
259 \ define LPM mode for ACCEPT \ LPM0 is the default mode.
260 \ --------------------------------------\
261 \ MOV #LPM4,&LPM_MODE \ MSP430FR59xx family : LPM 0 to 4
262 \ MOV #LPM2,&LPM_MODE \ MSP430FR57xx family : terminal input don't work for LPMx > 2
263 \ \ MSP430FR2xxx family : terminal input don't work for LPMx > 0
264 \ --------------------------------------\
265 MOV #I2CS_BUF,T \ T = buffer output address -1
266 MOV #I2CS_OWN,S \ S = buffer input address -1
267 MOV #0,&UCB0IFG \ write UCB0IFG to clear all int flags (STTIFG,TXIFG,..)
268 CMP.B &UCB0I2COA0,&UCB0ADDRX \ UCB0ADDRX = own address ?
270 BIS #UCTXACK,&UCB0CTLW0 \ send software Ack address
271 BIT #UCTR,&UCB0CTLW0 \ test UCB0CTLW0(UCTR) R/W bit
272 0= IF \ I2C_Master Write
273 \ --------------------------------\
274 \ slave receive datas \ yes
275 \ --------------------------------\
276 MOV S,W \ W = input buffer address - 1
278 \ ----------------------------\
279 \ slave receive one byte \
280 \ ----------------------------\
282 BIT #$8C,&UCB0IFG \ UCB0IFG(STP,STT,CLTO) = 1 ? (STOP, START, SCL low timeout)
284 \ --------------------\
285 \ TX stop or restart \ from master
286 \ --------------------\
287 SUB S,W \ W = Adr_end - Adr_start = length
288 MOV.B W,0(T) \ store length in first byte of buffer output
289 \ --------------------\
290 \ insert here post RX code
291 \ --------------------\
292 \ BIS.B #LED1,&LED1_OUT \ OUT high ==> switch ON LED1 to test
293 \ display IR_RC5 command
296 MOV.B 1(X),TOS \ display RC6 command
297 \ MOV.B 0(W),TOS \ display count
301 BASE @ HEX \ save BASE before change
302 CR ." $" 2 U.R SPACE \ display received byte
303 ." LPM = $" LPM_MODE ? \ display also LPM value
306 BASE ! \ restore BASE
307 HI2LO \ nice code, right ?
309 \ BIC.B #LED1,&LED1_OUT \ OUT low ==> switch OFF LED1 to test
310 \ --------------------\
312 \ --------------------\
313 THEN \ if not (stop, restart, CLTO)
314 BIT #1,&UCB0IFG \ UCB0IFG(RX0) = 1 ?
316 ADD #1,W \ reserve one byte for length first, then preincrement
317 MOV.B &UCB0RXBUF,0(W) \ [UCB0RXBUF] = data --> +[W]
318 AGAIN \ loop for new received data if any
319 THEN \ end of I2C_Master read
320 \ ------------------------------------\
321 \ slave transmit datas variant 1 \ to loop back after bad_own_address code
322 \ ------------------------------------\
325 \ ------------------------------------\
326 \ slave transmit datas variant 2 \
327 \ ------------------------------------\
328 \ MOV T,W \ W = output buffer address -1
330 \ ADD #1,W \ first reserve one byte for length
331 \ MOV.B @W,&UCB0TXBUF \ +[W] --> UCB0TXBUF
332 \ \ ----------------------------\
333 \ \ slave send byte \
334 \ \ ----------------------------\
336 \ BIT.B #$0C,&UCB0IFG \ UCB0IFG(STP,STT) = 1 ?
338 \ \ ------------------------\
339 \ \ RX stop or restart \ from master
340 \ \ ------------------------\
341 \ SUB T,W \ W = Adr_end - Adr_start = length
342 \ SUB.B #1,W \ sub #1, because char +[W] is not sent
343 \ MOV.B W,0(T) \ store length in first byte of buffer output
344 \ BIC.B #UCTR,&UCB0CTLW0 \ reset UCTR R/W bit for next START
347 \ BIT.B #$02,&UCB0IFG \ UCB0IFG(TX0) = 1 ?
350 \ ------------------------------------\
351 \ End of slave transmit datas variants\
352 \ ------------------------------------\
353 THEN \ if bad I2C address
354 \ --------------------------------------\
355 \ BAD I2C ADDRESS CaseOf \
356 \ --------------------------------------\
357 \ insert here post BAD I2C address code \
358 \ ...that can loop back to I2CS_TX... \
359 \ --------------------------------------\
360 BIC #UCTXACK,&UCB0CTLW0 \ send Nack address
368 \ START performs a complementary initialisation of the FAST FORTH system to start your app.
369 \ START is inserted COLD and ABORT via the fragment of code : LIT RECURSE IS WARM.
370 \ --------------------------------------\
371 CODE START \ init I2C_slave
372 \ --------------------------------------\
373 \ %0000 0111 1100 0001 UCB0CTLW0
374 \ - UCMST = 0 : I2C_Slave
375 \ -- UCMODE = %11 = I2C
376 \ _ USYNC =1 (always 1)
377 \ -- UCSSEL =SMCLK (don't care in slave mode)
378 \ - UCTXACK =0 not auto ACK slave address
379 \ - UCTR =0 : RX (for RX address)
381 \ --------------------------------------\
382 \ %0000 0000 1101 0000 UCB0CTLW1
383 \ - UCETXINT =0 : UCTXIFG0 set address match UCxI2COAx and TX mode
384 \ -- UCCLTO =%11 : SCL low time out = 34 ms
385 \ - UCSWACK =1 : UCTXACK must be written to continue
386 \ --------------------------------------\
389 \ UCB0I2COA0 must be written ? enabled ?
392 \ --------------------------------------\
393 \ %0000 0000 0000 0100 UCB0IE
394 \ - UCSTTIE : StartCond Interrupt only
395 \ --------------------------------------\
397 \ UCB0IV : write it to clear all IFG
399 \ ------------------------------\
401 \ ------------------------------\
402 MOV #1,&UCB0CTLW0 \ set eUSCI_B in reset state, clear UCB0IE & UCB0IFG all flags
403 BIS #$07A0,&UCB0CTLW0 \
404 BIS #$10,&UCB0CTLW1 \ set software ack address (UCSWACK=1)
405 MOV #%1010,&UCB0I2COA0 \ set my own address
406 BIS #$0400,&UCB0I2COA0 \ UCOAEN=1 enable UCB0I2COA0 with address slave
407 \ MOV #0,&UCB0ADDMSK \ enable address mask for all addresses i.e. software address
408 BIC #1,&UCB0CTLW0 \ activate eUSCI_B
409 MOV #4,&UCB0IE \ enable StartCond interrupt
410 MOV #%1010,&I2CS_OWN \ my slave address, without RW flag !
411 \ ------------------------------\
412 \ init PORT complement
413 \ ------------------------------\
414 \ notice : UCB0 I2C driver seems to control only DIR register !!!
415 BIC.B #S_BUS,&I2CS_REN \ SDA + SCL pullup/down disable
416 BIC.B #S_BUS,&I2CS_OUT \ OUT0 : preset output low
417 BIS.B #S_BUS,&I2CS_SEL1 \ enable I2C I/O
418 \ ------------------------------\
419 BIS.B #LCDVo,&LCDVo_DIR \
420 BIS.B #LCDVo,&LCDVo_SEL0 \ TB0.2
421 \ ------------------------------\
422 BIS.B #LCD_CMD,&LCD_CMD_DIR \ lcd_cmd as outputs
423 BIC.B #LCD_CMD,&LCD_CMD_REN \ lcd_cmd pullup/down disable
424 \ ------------------------------\
425 BIS.B #LCD_DB,&LCD_DB_DIR \ lcd_db as output, wired to DB(4-7) LCD_Data
426 BIC.B #LCD_DB,&LCD_DB_REN \ lcd_db pullup/down disable
427 \ ------------------------------\
428 \ TB0CTL = %0000 0010 1001 0100\$3C0
429 \ - - \CNTL Counter lentgh \ 00 = 16 bits
430 \ -- \TBSSEL TimerB clock select \ 10 = SMCLK
431 \ -- \ID input divider \ 10 = /4
432 \ -- \MC Mode Control \ 01 = up mode
433 \ - \TBCLR TimerB Clear
436 \ --------------------------------\\
437 \ TB0CCTLx = %0000 0000 0110 0000\$3C{2,4,6,8,A,C,E}
438 \ -- \CM Capture Mode
443 \ --- \OUTMOD \ 011 = set/reset
449 \ TB0CCRx \$3D{2,4,6,8,A,C,E}
451 \ ------------------------------\
452 \ set TimerB to make 50kHz PWM \
453 \ ------------------------------\
454 \ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
455 \ MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
456 \ ------------------------------\
457 \ MOV #%1000010100,&TB0CTL \ SMCLK/1, up mode, clear timer, no int
458 \ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (4 MHZ)
459 \ ------------------------------\
460 MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
461 MOV #0,&TB0EX0 \ predivide by 1 in TB0EX0 register (8 MHZ)
462 \ ------------------------------\
463 \ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
464 \ MOV #1,&TB0EX0 \ predivide by 2 in TB0EX0 register (16 MHZ)
465 \ ------------------------------\
466 \ MOV #%1010010100,&TB0CTL \ SMCLK/4, up mode, clear timer, no int
467 \ MOV #2,&TB0EX0 \ predivide by 3 in TB0EX0 register (24 MHZ)
468 \ ------------------------------\
469 MOV #40,&TB0CCR0 \ 40*0.5us=20us (40us @ 1MHz)
470 \ ------------------------------\
471 \ set TimerB to generate LCD_V0 via TB0.2 and P1.5/P2.2
472 \ ------------------------------\
473 MOV #%1100000,&TB0CCTL2 \ output mode = set/reset \ clear CCIFG
474 \ MOV #20,&TB0CCR2 \ contrast adjust : 20/40 ==> LCD_Vo = -1V1|+3V6 (Vcc=3V6)
475 MOV #25,&TB0CCR2 \ contrast adjust : 25/40 ==> LCD_Vo = -1V4|+3V3 (Vcc=3V3)
476 \ ------------------------------\
477 \ WDT interval init part \
478 \ ------------------------------\
479 \ MOV #$5A5E,&WDTCTL \ init WDT Vloclk source 10kHz /2^9 (50 ms), interval mode
480 MOV #$5A3D,&WDTCTL \ init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
481 \ MOV #$5A5D,&WDTCTL \ init WDT Vloclk source 10kHz /2^13 (800 ms), interval mode
482 BIS #1,&SFRIE1 \ enable WDT interval mode interrupt in SFRIE
483 \ ------------------------------\
484 \ init interrupt vectors
485 \ ------------------------------\
486 MOV #I2C_S,&I2CS_Vec \ eUSCIB0 interrupt vector
487 MOV #WDT_Int,&WDT_Vec \ init WDT interval vector interrupt
488 \ ------------------------------\
489 \ define LPM mode for ACCEPT \ LPM0 is the default mode.
490 \ ------------------------------\
491 \ MOV #LPM4,&LPM_MODE \ with MSP430FR59xx
492 \ MOV #LPM2,&LPM_MODE \ with MSP430FR57xx, terminal input don't work for LPMx > 2
493 \ \ with MSP430FR2xxx, terminal input don't work for LPMx > 0
494 \ ------------------------------\
497 $03E8 20_us \ 1- wait 20 ms
498 $03 TOP_LCD \ 2- send DB5=DB4=1
499 $CD 20_us \ 3- wait 4,1 ms
500 $03 TOP_LCD \ 4- send again DB5=DB4=1
501 5 20_us \ 5- wait 0,1 ms
502 $03 TOP_LCD \ 6- send again again DB5=DB4=1
503 2 20_us \ wait 40 us = LCD cycle
504 $02 TOP_LCD \ 7- send DB5=1 DB4=0
505 2 20_us \ wait 40 us = LCD cycle
506 $28 LCD_WrF \ 8- %001DNFxx "FonctionSet" D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
507 $08 LCD_WrF \ 9- %1DCB "DisplayControl" : Display off, Cursor off, Blink off.
508 LCD_Clear \ 10- "LCD_Clear"
509 $06 LCD_WrF \ 11- %01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
510 $0C LCD_WrF \ 12- %1DCB "DisplayControl" : Display on, Cursor off, Blink off.
512 ['] LCD_HOME IS CR \ CR redirected to LCD_HOME
513 ['] LCD_WrC IS EMIT \ EMIT redirected to LCD_WrC
514 CR ." I love you" \ display it on the LCD
515 ['] (EMIT) IS EMIT \ restore EMIT
516 ['] (CR) IS CR \ restore CR
517 ." I2C_Slave_to_LCD is running. Type STOP to quit" \ display on terminal
518 \ NOECHO \ uncomment to run this app without terminal connexion
519 lit RECURSE IS WARM \ insert this starting routine between COLD and WARM...
520 (WARM) ; \ ...and continue with (WARM)
524 : STOP \ stops multitasking, must to be used before downloading app
525 ['] (WARM) IS WARM \ remove START app from FORTH init process
526 ECHO COLD \ reset CPU, interrupt vectors, and start FORTH
533 \ START runs your App.
534 \ when downloading this file, all lines beyond the START command are ignored. Usefull to comment.
536 \ driver for LCD 2x20 characters display with 4 bits data interface
537 \ without usage of an auxiliary 5V to feed the Vo of LCD
538 \ without potentiometer to adjust the LCD contrast
539 \ LCD contrast software adjustable by 2 switches
540 \ TB0.2 current consumption ~ 500 uA
542 \ layout : see config.pat file for defining I/O
544 \ GND <-------+---0V0----------> 1 LCD_Vss
545 \ VCC >------ | --3V6-----+----> 2 LCD_Vdd
552 \ TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
553 \ -------------------------> 4 LCD_RW
554 \ -------------------------> 5 LCD_RW
555 \ -------------------------> 6 LCD_EN
556 \ <------------------------> 11 LCD_DB4
557 \ <------------------------> 12 LCD_DB5
558 \ <------------------------> 13 LCD_DB5
559 \ <------------------------> 14 LCD_DB7
561 \ Sw1 <--- LCD contrast + (finger :-)
562 \ Sw2 <--- LCD contrast - (finger \-)