OSDN Git Service

fixed ASSEMBLER crash
[fast-forth/master.git] / MSP430-FORTH / UARTI2CS.f
index 73c55ce..67ed5ad 100644 (file)
 ; UARTI2CS.f
 ; ----------------------------------------------------------------------
 \
-\ TARGET SELECTION
-\ LP_MSP430FR2476
+\ TARGET SELECTION ( = the name of \INC\target.pat file without the extension)
 \ MSP_EXP430FR5739  MSP_EXP430FR5969    MSP_EXP430FR5994    MSP_EXP430FR6989
 \ MSP_EXP430FR4133 (can't use LED1 because wired on UART TX)
-\ MSP_EXP430FR2433  MSP_EXP430FR2355    CHIPSTICK_FR2433
+\ MSP_EXP430FR2433  CHIPSTICK_FR2433    MSP_EXP430FR2355
+\ LP_MSP430FR2476
+\
+\ from scite editor : copy your target selection in (shift+F8) parameter 1:
+\
+\ OR
+\
+\ drag and drop this file onto SendSourceFileToTarget.bat
+\ then select your TARGET when asked.
 \
-\ software I2C MASTER, you can use any pin for SDA and SCL,
-\ Preferably use a couple of pins in the interval Px0...Px3.
-\ don't forget to wire 3.3k pullup resitors on pin SDA and SCL.
 \
 \ FastForth kernel compilation minimal options:
 \ TERMINAL3WIRES, TERMINAL4WIRES
 \ MSP430ASSEMBLER, CONDCOMP
 \
-\ driver test @ speed maxi: MCLK=24MHz
+\ coupled to a PL2303HXD cable, this driver enables a FastForth target to do an USB to I2C_Slave bridge,
+\ thus, any I2C_FastForth target can communicate with TERATERM.
+\ In addition, UARTI2CS simulates a full duplex TERMINAL while the I2C bus is half duplex.
+\ 
+\ driver test @ speed maxi: MCLK=24MHz, PL2303HXD with shortened cable (20cm), WIFI off, all windows apps closed else Scite and TERATERM.
 \ ------------------------------------
 \
-\     notebook                                  USB to I2C_Slave bridge                                     any I2C_slave
+\     notebook                                  USB to I2C_Slave bridge                                     any I2C_slave target
 \ +---------------+          +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +            +-------------------------------+
-\ |               |          i    CP2102                  master running UARTI2CS @ 24MHz i           +-------------------------------+|
+\ |               |          i   PL2303HXD                target running UARTI2CS @ 24MHz i           +-------------------------------+|
 \ |               |          +---------------+           +--------------------------------+          +-------------------------------+||
-\ |               |          |               |           |                                |RX:1.15MHz|                               |||
+\ |               |          |               |           |                                |RX:1150kHz|                               |||
 \ |   TERATERM   -o--> USB --o--> USB2UART --o--> UART --o--> FAST FORTH ---> UARTI2CS  --o--> I2C --o--> FAST FORTH @ 24MHz with    ||+
-\ |   terminal    |          |               | 2457600Bds|                                |TX:692kHz |   kernel option TERMINAL_I2C  |+
+\ |   terminal    |          |               |   6 MBds  |                                |TX:750kHz |   kernel option TERMINAL_I2C  |+
 \ |               |          +---------------+           +--------------------------------+          +-------------------------------+
-\ |               |          i                                                            i 
+\ |               |          i               |<-L<=20cm->|                                i 
 \ +---------------+          +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
 \
-\ I2C frequency = (TX+RX)/2 = 921 kHz @ MCLK=24 MHz, without any error...
-\ downloading (+ interpret + compile + execute) CORETEST.4TH to I2C Slave in 859ms.
-\ downloading (+ interpret + compile + execute) CORETEST.4TH to I2C Master in 625ms.
+\ I2C frequency = (TX+RX)/2 = 950 kHz @ MCLK=24 MHz, without any error...
+\ downloading (+ interpret + compile + execute) CORETEST.4TH to I2C Slave best time = 844ms.
+\ downloading (+ interpret + compile + execute) CORETEST.4TH to I2C Master best time = 531ms.
+\ nota: the difference (313 ms) is the time of the I2C Half duplex exchange (I2C freq. about 1MHz).
+\ 
+\ also tested with I2C_Master @ 24MHz and I2C_Slave @ 1MHz.
+\
+\ You can use any pin for SDA and SCL, preferably in the interval Px0...Px3.
+\ don't forget to wire 3.3k pullup resitors on pin SDA and SCL.
+\ you will find SCA and SCL pin by searching 'SM_BUS' in your \inc\target.pat file
 \
 \
-\ the LEDs TX and RX work fine, uncomment if you want.
+\ the LEDs TX and RX work fine, comment/uncomment as you want.
 \
 \ Multi Master Mode works but is not tested in the real word.
 \
-\ les arcanes du bus I2C
-\ ----------------------
+\ les limitations du bus I2C
+\ --------------------------
 \
-\ le bus I2C est orienté Maître vers esclave, l'esclave ne décide de rien.
-\ Cet ordre des choses permet en tout cas d'établir la liaison.
-\ On placera donc le maître du côté du TERMINAL de commande et la cible FastForth côté esclave.
-\ Mais une fois que la liaison est établie il faut trouver une astuce pour renverser
-\ les rôles, pour que l'esclave puisse prendre le contrôle de la liaison.
+\ 1- le bus I2C est orienté Maître vers Esclave, l'esclave ne décide de rien.
+\    Cet ordre des choses permet en tout cas d'établir la liaison.
+\    On placera donc le maître du côté du TERMINAL de commande et la cible FastForth côté esclave.
+\    Mais une fois que la liaison est établie il faut trouver une astuce pour renverser
+\    les rôles, afin que l'esclave puisse prendre le contrôle de l'échange de données.
 \
-\ Pour ce faire l'esclave envoie "servilement" des caractères de contrôle au maître,
+\ 2- le bus I2C fonctionne en Half Duplex. 
+\    Une autre astuce consistera donc à simuler une liaison I2C_Slave TERMINAL en mode Full Duplex.
+\
+\ Solutions : l'esclave envoie "servilement" des caractères de contrôle au maître,
 \ et comme celui-ci obéit à un plus grand que lui, le programmeur,
 \ il se fait un devoir "magistral" d'obéir à l'esclave.
 \
-\ Pour prendre le contrôle du maître, l'esclave émet donc 1 parmi 6 CTRL-Char:
-\   CTRL-Char $00 envoyé par ACCEPT (1ère partie, avant SLEEP),
+\ Pour prendre le contrôle du maître, l'esclave lui émet donc 1 parmi 6 CTRL-Char:
+\   CTRL-Char $00 envoyé par ACCEPT (1ère partie, avant de s'endormir avec SLEEP),
 \   CTRL-Char $01 envoyé par KEY: demande d'envoi d'un caractère unique saisi sur TERMINAL,
 \   CTRL-Char $02 envoyé par ABORT: demande d'abandon du fichier en cours de transmission le cas échéant,
-\                                   suivi de la réception du message envoyé par ABORT,
-\   CTRL-Char $03 envoyé par COLD, pour que le maître relance la connexion I2C,
+\                                   suivi d'un START RX pour la réception du message envoyé par ABORT,
+\   CTRL-Char $03 envoyé par COLD, pour que le maître relance la connexion I2C en mode RX,
 \   CTRL-Char $04 envoyé par NOECHO, pour qu'il passe l'UART en mode half duplex,
 \   CTRL-Char $05 envoyé par ECHO, pour qu'il rétablisse l'UART en mode full duplex.
 \
 \ Enfin, si le maître reçoit un caractère $FF, il considère que la liaison est coupée,
-\ il envoie le reste du fichier en cours de téléchargment à la poubelle, quitte le driver
-\ puis exécute COLD.
+\ il effectue ABORT pour forcer le maître à effectuer un START RX en boucle.
 \
 \ Une fois que l'esclave a envoyé le CTRL_Char $00, il s'endort, 
-\ à la reception de ce CTRL_Char, le maître s'endort aussi, dans l'attente d'une nouvelle entrée TERMINAL.
-\ Tant que le TERMINAL n'envoie pas de nouvelle ligne, le maître et l'esclave sont en mode SLEEP,
-\ LPM0 pour le maître, LPM4 pour l'esclave.
+\ à la reception de ce CTRL_Char, le maître s'endort aussi, dans l'attente d'une interruption UART RX.
+\ Tant que le TERMINAL est silencieux, le maître et l'esclave restent en mode SLEEP,
+\ LPM0 pour le maître (l'UART ne fonctionne pas si LPMx < LPM0), LPM4 pour l'esclave.
+\
+\ ---------------
+\ interruptions
+\ ---------------
+\
+\ TxIFG_INT sert à générer une interruption 1/2 seconde qui est prise en compte uniquement quand le maître fait dodo.
+\ Elle effectue un (re)START RX ce qui permet de rétablir la liaison I2C suite à un RESET|COLD effectué sur I2C_Slave.
+\    (Le switch RESET est en effet redirigé sur COLD via l'interruption USER NMI).
+\ Logique d'établissement de la liaison I2C (START RX): 
+\   si X U>= 4 (1ère connexion demandée par le maître) ==> un START RX à chaque 1/2s, 
+\   si X U< 4 (perte de connexion suite à I2C_Slave{COLD|RESET|WARM|ABORT}) ==> START RX répété en boucle.
+\
+\ WDT_INT génère une interruption 8 ms qui est prise en compte quand le maître fait dodo.
+\ elle permet la sortie du programme UARTI2CS quand Teraterm envoie Alt-B ou quand l'utilisateur actionne SW2+RESET.
 \
+\ TERM_INT redirige l'interruption par défaut UART RX_INT
 \
-\ le timer TB0 sert à générer une interruption 1/2 seconde
-\ pour détecter un hard RESET effectué sur I2C_Slave, quand I2C_Master fait dodo, 
-\ ainsi que pour effectuer le couplage dans la boucle I2C_Master RX: 
-\   si X U>= 4 (I2C_WARM state) ==> un START RX à chaque 1/2s, 
-\   si X U< 4 (I2C_Slave COLD|RESET|ABORT) ==> continuous repeated START RX 
+\
+[UNDEFINED] @ [IF]
+\ https://forth-standard.org/standard/core/Fetch
+\ @     c-addr -- char   fetch char from memory
+CODE @
+MOV @TOS,TOS
+MOV @IP+,PC
+ENDCODE
+[THEN]
 
-PWR_STATE
+[UNDEFINED] AND [IF]
+\ https://forth-standard.org/standard/core/AND
+\ C AND    x1 x2 -- x3           logical AND
+CODE AND
+AND @PSP+,TOS
+MOV @IP+,PC
+ENDCODE
+[THEN]
+
+[UNDEFINED] 0= [IF]
+\ https://forth-standard.org/standard/core/ZeroEqual
+\ 0=     n/u -- flag    return true if TOS=0
+CODE 0=
+SUB #1,TOS      \ borrow (clear cy) if TOS was 0
+SUBC TOS,TOS    \ TOS=-1 if borrow was set
+MOV @IP+,PC
+ENDCODE
+[THEN]
+
+: I2CTERM_ABORT
+$0D EMIT   \ return to column 1
+1 ABORT" <-- Ouch! unexpected target with I2C TERMINAL"
+;
+
+KERNEL_ADDON @ $7800 AND 0= [IF] ; unexpected I2C TERMINAL ?
+I2CTERM_ABORT
+[THEN]
 
-[DEFINED] {FF_I2C} [IF]  {FF_I2C} [THEN]
+PWR_STATE \ remove the above words 
 
-MARKER {FF_I2C}
+[DEFINED] {UARTI2CS} [IF] {UARTI2CS} [THEN]
+
+MARKER {UARTI2CS}
+
+[UNDEFINED] < [IF]      \ define < and >
+\ https://forth-standard.org/standard/core/less
+\ <      n1 n2 -- flag        test n1<n2, signed
+CODE <
+        SUB @PSP+,TOS   \ 1 TOS=n2-n1
+        S< ?GOTO FW1    \ 2 signed
+        0<> IF          \ 2
+BW1         MOV #-1,TOS \ 1 flag Z = 0
+        THEN
+        MOV @IP+,PC
+ENDCODE
+
+\ https://forth-standard.org/standard/core/more
+\ >     n1 n2 -- flag         test n1>n2, signed
+CODE >
+        SUB @PSP+,TOS   \ 2 TOS=n2-n1
+        S< ?GOTO BW1    \ 2 --> +5
+FW1     AND #0,TOS      \ 1 flag Z = 1
+        MOV @IP+,PC
+ENDCODE
+[THEN]
 
 [UNDEFINED] @ [IF]
 \ https://forth-standard.org/standard/core/Fetch
@@ -123,11 +209,12 @@ MOV @IP+,PC
 ENDCODE
 [THEN]
 
-$1820 CONSTANT SLAVE_ADR    \ CONSTANT = I2C_Slave address in FRAM
+I2CSLA0 CONSTANT I2CS_ADR       \ CONSTANT = I2C_Slave address in FRAM (I2CSLA0=$FFA2)
 
-ASM QUIT_I2C                    \ as ASM word, QUIT_I2C is hidden.
 \ ------------------------------\
-BW1                             \
+ASM QUIT_I2C                    \ <== MultiMaster, START_RX loop, I2C_WARM
+\ ------------------------------\
+BW1                             \ <== WDT_INT
 \ \ ------------------------------\
 \     BIC.B #LED2,&LED2_DIR       \ RX green led OFF
 \     BIC.B #LED2,&LED2_OUT       \ RX green led OFF
@@ -151,13 +238,15 @@ BW1                             \
     MOV #COLD,PC                \ explicit return with COLD
 ENDASM
 
-ASM WDT_INT                     \ to enable Alt+B when I2C_Master is sleeping
+\ ******************************\
+ASM WDT_INT                     \ enables Alt+B when I2C_Master is sleeping
+\ ******************************\
 BIT #8,&TERM_STATW              \ UART break sent by TERATERM ?
 0<> IF
     ADD #4,RSP                  \ remove RETI
-    GOTO BW1                    \
+    GOTO BW1                    \ goto QUIT_I2C
 THEN
-RETI
+RETI                            \ return to SLEEP
 ENDASM
 
 \ \ vvvvvvvMulti-Master-Modevvvvvv\
@@ -183,8 +272,6 @@ ENDASM
 \ ENDASM
 \ \ ^^^^^^^Multi-Master-Mode^^^^^^\
 
-\ wake up from LPM0 is longer with MSP30FR2xxx devices than with MSP430FR5xxx devices:
-\ @ MCLK = 24MHz baudrate max = 5MBds with FR2xxx, and 6MBds with FR57xx. 
 \ **************************************\
 ASM TERM_INT                            \  interrupt starts on RX first char of line input from TERMINAL
 \ **************************************\
@@ -198,15 +285,15 @@ BEGIN                                   \
     ADD #1,T                            \ 1
     MOV.B Y,-1(T)                       \ 3 ... to buffer (PAD)
     CMP.B Y,S                           \ 1 char = CR ?
-0<> WHILE                               \ 2 28 cycles loop ==> up to 2.96 Mbds @ 8MHz
+0<> WHILE                               \ 2 28 cycles loop ==> up to 2.85 Mbds @ 8MHz
     CMP #0,W                            \ 1
     0= IF                               \ 2 if echo ON requested by I2C_Slave
         BEGIN                           \   )
-            BIT #2,&TERM_IFG            \ 3 > mandatory for low baudrates
+            BIT #2,&TERM_IFG            \ 3 > Test TX_Buf empty mandatory for low baudrates
         0<> UNTIL                       \ 2 )
         MOV.B Y,&TERM_TXBUF             \ 3
     THEN
-    BEGIN                               \
+    BEGIN                               \ 
         BIT #1,&TERM_IFG                \ 3 received char ?
     0<> UNTIL                           \ 2 
 REPEAT                                  \ 2
@@ -217,25 +304,25 @@ BEGIN                                   \
 \ --------------------------------------\
 BW1                                     \   <=== Ctrl_char $01 (KEY input)
 \ --------------------------------------\
-MOV.B &TERM_RXBUF,S                     \ 3 S = last char (LF|KEY) ...
+MOV.B &TERM_RXBUF,S                     \ 3 S = last char (LF|KEY_input) ...
 MOV.B S,0(T)                            \ 4 store it into buffer
 \ ======================================\
-\ ======================================\ S = last char to be transmitted
-\ I2C MASTER TX                         \ T = last char transmitted
-\ ======================================\ W = bits count
-\ ======================================\ X = I2C_Address / I2C_Data           
+\ ======================================\
+\ I2C MASTER TX                         \ now we transmit UART RX buffer (PAD) to I2C_Slave, S = last char to transmit
+\ ======================================\
+\ ======================================\          
 \ \ --------------------------------------\
 \ BIS.B #LED1,&LED1_DIR                   \ red led ON = I2C TX 
 \ BIS.B #LED1,&LED1_OUT                   \ red led ON = I2C TX
 \ \ --------------------------------------\
 \ \     vvvvvvvvvvMulti-Master-Modevvvvvvv\
-BW2 \ I2C_Master TX Start               \ here, SDA and SCL must be in idle state
-\ \     ^^^^^^^^^^Multi-Master-Mode^^^^^^^\
-BIS.B   #SM_SDA,&I2CSM_DIR              \ 3 l   force SDA as output (low)
-MOV.B   &SLAVE_ADR,X                    \ 3 h   X = Slave_Address
-MOV     #PAD_ORG,Y                      \ 2 h   Y = input buffer for I2C_Master TX
-NOP3                                    \ 3 h
-BIS.B   #SM_SCL,&I2CSM_DIR              \ 3 h   force SCL as output (low)
+BW2 \ I2C_Master TX Start               \ here, SDA and SCL must be in idle state
+\ \     ^^^^^^^^^^Multi-Master-Mode^^^^^^^\   _
+BIS.B   #SM_SDA,&I2CSM_DIR              \ 3 l  v_ force SDA as output (low)
+MOV.B   &I2CS_ADR,X                     \ 3 h     X = Slave_Address
+MOV     #PAD_ORG,Y                      \ 2 h     Y = input buffer for I2C_Master TX
+NOP3                                    \ 3 h _
+BIS.B   #SM_SCL,&I2CSM_DIR              \ 3 h  v_ force SCL as output (low)
 \ --------------------------------------\
 BEGIN
 \   ------------------------------------\
@@ -248,23 +335,20 @@ BEGIN
             BIC.B #SM_SDA,&I2CSM_DIR    \ 3 l       yes : SDA as input  ==> SDA high because pull up resistor
         ELSE                            \ 2 l
             BIS.B #SM_SDA,&I2CSM_DIR    \ 3 l       no  : SDA as output ==> SDA low
-            NOP2                        \ 2
+\            NOP2                        \ 2        uncomment for beautiful code
         THEN                            \   l   _
         BIC.B #SM_SCL,&I2CSM_DIR        \ 3 l _^    release SCL (high)
-        BEGIN                           \           9~h/16~l
-            BIT.B #SM_SCL,&I2CSM_IN     \ 3 h       test if SCL is released (Slave RX addr/data)
-        0<> UNTIL                       \ 2 h 
+        BEGIN                           \           we must wait I2C_Slave wake up
+            BIT.B #SM_SCL,&I2CSM_IN     \ 3 h       by testing SCL released
+        0<> UNTIL                       \ 2 h
 \ \       vvvvvvvvMulti-Master-Modevvvvvvv\
-\         BIT.B #SM_SDA,&I2CSM_IN         \ 3 h _     test SDA
-\ \       ^^^^^^^^Multi-Master-Mode^^^^^^^\
+\         BIT.B #SM_SDA,&I2CSM_IN         \ 3 h       test SDA
+\ \       ^^^^^^^^Multi-Master-Mode^^^^^^^\   _
         BIS.B #SM_SCL,&I2CSM_DIR        \ 3 h  v_   SCL as output : force SCL low
 \ \       vvvvvvvvvvvvMulti-Master-Modevvvvvvvvvvv\
-\         0= IF                                   \ 2 l
-\             BIT.B #SM_SDA,&I2CSM_DIR            \ 3 l
-\             0= IF                               \ 2 l
-\ \               --------------------------------\
-\ \               collision detected              \   l collision if SDA(IN)=0 AND SDA(DIR)=0
-\ \               --------------------------------\
+\         0= IF                                   \ 2 l   SDA input low
+\             BIT.B #SM_SDA,&I2CSM_DIR            \ 3 l + SDA command high
+\             0= IF                               \ 2 l = collision detected
 \                 BIS.B #SM_SCL,&I2CSM_DIR        \ 4 l release SCL first
 \                 CALL #DO_IDLE                   \     wait stable idle state 
 \                 GOTO BW2                        \ 2 l goto START TX
@@ -280,41 +364,44 @@ BEGIN
 \   ------------------------------------\       _
     BIC.B #SM_SCL,&I2CSM_DIR            \ 3 l _^    release SCL (high)
 \    BEGIN                               \
-\        BIT.B #SM_SCL,&I2CSM_IN         \ 3 h      useless test if SCL is released (SLAVE ACK Addr/data) 
-\    0<> UNTIL                           \ 2 h
+\        BIT.B #SM_SCL,&I2CSM_IN         \ 3 h      testing SCL released is useless
+\    0<> UNTIL                           \ 2 h      replaced by NOP3
     NOP3                                \ 3 h
     BIT.B #SM_SDA,&I2CSM_IN             \ 3 h _     get SDA state
     BIS.B #SM_SCL,&I2CSM_DIR            \ 3 h  v_   SCL as output : force SCL low
 \   ------------------------------------\
-0= WHILE \ 1 Slave Ack received         \ 2 l       goto THEN; out of loop if Nack
+0= WHILE \ 1- Slave Ack received        \ 2 l       else goto THEN; out of loop if Nack
 \   ------------------------------------\           
 \   I2C_Master_TX_data_loop             \
 \   ------------------------------------\
-    CMP S,T                             \ 1         T = S = last char to transmit ? after address is sent, T = PAD_ORG <> S = any char
-0<> WHILE \ 2                           \ 2         out of loop if yes
+    CMP S,T                             \ 1         T = last char to transmit ? (when address is sent, T = 16bits <> S = 8bits)
+\   ------------------------------------\
+0<> WHILE \ 2- TXed char <> last char   \ 2         else out of loop
+\   ------------------------------------\
     MOV.B @Y+,X                         \ 2 l       get next byte to TX
     MOV X,T                             \ 1         T = last char TX for comparaison above
 REPEAT                                  \           <-- WHILE2  search "Extended control-flow patterns"... 
 THEN                                    \           <-- WHILE1  ...in https://forth-standard.org/standard/rationale
 \   ------------------------------------\
-\ Nack or Ack on last char              \           Nack = I2C_Slave request or I2C_Slave RESET, Ack = last char has been TX
+\ Nack or Ack on last char              \           Nack = I2C_Slave request or I2C_Slave RESET, Ack = last char has been TXed
 \   ------------------------------------\
     NOP3                                \ 3 l   _   delay to reach I2C tLO
-    BIC.B #SM_SCL,&I2CSM_DIR            \ 3 l _^    release SCL to enable reSTART
+    BIC.B #SM_SCL,&I2CSM_DIR            \ 3 l _^    release SCL to enable START RX
 \ \ --------------------------------------\
 \     BIC.B #LED1,&LED1_DIR               \   red led OFF = endof I2C TX 
 \     BIC.B #LED1,&LED1_OUT               \   red led OFF = endof I2C TX
 \ \ --------------------------------------\
-GOTO FW1                                \   X > 4 ==> continuous repeated START RX below
+GOTO FW1                                \   X > 4 ==> START RX every 1/2s 
 \ ======================================\
 \ END OF I2C MASTER TX                  \
 \ ======================================\
 ENDASM
 
-ASM RX_INT
 \ **************************************\
-\ I2C MASTER RX                         \
+ASM TxIFG_INT
 \ **************************************\
+\ I2C MASTER RX                         \
+\ --------------------------------------\
 ADD #4,RSP                              \ 1 remove RET and SR
 \ --------------------------------------\
 FW1                                     \   from TERM_INT above
@@ -323,14 +410,14 @@ BW3                                     \   from I2C_WARM below
 \ --------------------------------------\
 \ I2C_Master START RX                   \
 \ --------------------------------------\
-CMP #0,&KERNEL_ADDON                    \ 3
-0>= IF                                  \ 2 if LF XTAL present
-    MOV #%0001_0101_0110,&TB0CTL        \ 3 (re)starts RX_timer,ACLK=VLO=8kHz,/2=4096Hz,up mode,clear timer,enable TB0 int, clear IFG
-\    MOV #%0001_0101_0110,&TA0CTL        \ 3 (re)starts RX_timer,ACLK=VLO=8kHz,/2=4096Hz,up mode,clear timer,enable TB0 int, clear IFG
-ELSE                                    \ 2
+KERNEL_ADDON @ 0 <                      \ 
+[IF]                                    \ if LF XTAL
     MOV #%0001_1101_0110,&TB0CTL        \ 3 (re)starts RX_timer,ACLK=LFXTAL=32738,/8=4096Hz,up mode,clear timer,enable TB0 int, clear IFG
-\    MOV #%0001_1101_0110,&TA0CTL        \ 3 (re)starts RX_timer,ACLKLFXTAL=32768,/8=4096Hz,up mode,clear timer,enable TB0 int, clear IFG
-THEN
+\    MOV #%0001_1101_0110,&TA0CTL        \ 3 (re)starts RX_timer,ACLK=LFXTAL=32768,/8=4096Hz,up mode,clear timer,enable TA0 int, clear IFG
+[ELSE]                                    \ 2
+    MOV #%0001_0101_0110,&TB0CTL        \ 3 (re)starts RX_timer,ACLK=VLO=8kHz,/2=4096Hz,up mode,clear timer,enable TB0 int, clear IFG
+\    MOV #%0001_0101_0110,&TA0CTL        \ 3 (re)starts RX_timer,ACLK=VLO=8kHz,/2=4096Hz,up mode,clear timer,enable TA0 int, clear IFG
+[THEN]
 \ --------------------------------------\
 \ le driver I2C_Master envoie START RX en boucle continue (X < 4) ou discontinue (X >= 4).
 \ le test d'un break en provenance de l'UART est intégré dans cette boucle.
@@ -345,12 +432,12 @@ BEGIN                                   \   I2C MASTER RX
         THEN
 \       --------------------------------\
 \       I2C_Master_Start_Cond           \   here, SDA and SCL must be in idle state
-\       --------------------------------\
-        BIS.B   #SM_SDA,&I2CSM_DIR      \ 3 l       force SDA as output (low)
-        MOV.B   &SLAVE_ADR,Y            \ 3 h       X = Slave_Address
+\       --------------------------------\     _
+        BIS.B   #SM_SDA,&I2CSM_DIR      \ 3 l  v_   force SDA as output (low)
+        MOV.B   &I2CS_ADR,Y             \ 3 h       X = Slave_Address
         BIS.B   #1,Y                    \ 1 h       Master RX
-        NOP2                            \ 2
-        BIS.B   #SM_SCL,&I2CSM_DIR      \ 3 h       force SCL as output (low)
+        NOP2                            \ 2   _
+        BIS.B   #SM_SCL,&I2CSM_DIR      \ 3 h  v_   force SCL as output (low)
 \       --------------------------------\
 \       I2C_Master_Send_address         \           may be SCL is held low by slave
 \       --------------------------------\
@@ -361,24 +448,21 @@ BEGIN                                   \   I2C MASTER RX
                BIC.B #SM_SDA,&I2CSM_DIR \ 3 l yes : SDA as input  ==> SDA high because pull up resistor
             ELSE                        \ 2 l
                BIS.B #SM_SDA,&I2CSM_DIR \ 3 l no  : SDA as output ==> SDA low
-               NOP2                     \ 2 l
+\            NOP2                        \ 2        uncomment for beautiful code
             THEN                        \       _
             BIC.B #SM_SCL,&I2CSM_DIR    \ 3 l _^    release SCL (high)
 \            BEGIN                       \
-\                BIT.B #SM_SCL,&I2CSM_IN \ 3 h       useless test if SCL is released (SLAVE RX Addr)
-\            0<> UNTIL                   \ 2 h
+\                BIT.B #SM_SCL,&I2CSM_IN \ 3 h      testing SCL released is useless
+\            0<> UNTIL                   \ 2 h      replaced by NOP3
             NOP3                        \ 3
 \ \           vvvvvvMulti-Master-Modevvvvv\
-\             BIT.B #SM_SDA,&I2CSM_IN     \ 3 h     test SDA
-\ \           ^^^^^^Multi-Master-Mode^^^^^\
-            BIS.B #SM_SCL,&I2CSM_DIR     \ 3 h  v_   SCL as output : force SCL low
+\             BIT.B #SM_SDA,&I2CSM_IN     \ 3 h     test SDA
+\ \           ^^^^^^Multi-Master-Mode^^^^^\   _
+            BIS.B #SM_SCL,&I2CSM_DIR    \ 3 h  v_  force SCL as output (low)
 \ \           vvvvvvvvvvvvMulti-Master-Modevvvvvvvvvvv\
-\             0= IF                                   \ 2 l
-\                 BIT.B #SM_SDA,&I2CSM_DIR            \ 3 l
-\                 0= IF                               \ 2 l
-\ \               ------------------------------------\
-\ \               collision detection                 \   l collision if SDA(IN)=0 AND SDA(DIR)=0
-\ \               ------------------------------------\
+\             0= IF                                   \ 2 l   SDA input low
+\                 BIT.B #SM_SDA,&I2CSM_DIR            \ 3 l + SDA command high
+\                 0= IF                               \ 2 l = collision detected
 \                     BIS.B #SM_SCL,&I2CSM_DIR        \ 4 l release SCL first
 \                     CALL #DO_IDLE                   \     wait stable idle state 
 \                     GOTO BW3                        \ 2 l goto START RX
@@ -393,8 +477,8 @@ BEGIN                                   \   I2C MASTER RX
         BIC.B   #SM_SDA,&I2CSM_DIR      \ 3 l   _   after TX address we must release SDA to read Ack/Nack from Slave
         BIC.B   #SM_SCL,&I2CSM_DIR      \ 3 l _^    release SCL (high)
         BEGIN                           \
-            BIT.B #SM_SCL,&I2CSM_IN     \ 3 h       test if SCL is released (SLAVE TX ACK_ON_Addr)
-        0<> UNTIL                       \ 2 h
+            BIT.B #SM_SCL,&I2CSM_IN     \ 3 h       wait I2C_Slave ready 
+        0<> UNTIL                       \ 2 h       I2C_Slave releases SCL
         BIT.B   #SM_SDA,&I2CSM_IN       \ 3 h _     get SDA
         BIS.B   #SM_SCL,&I2CSM_DIR      \ 3 h  v_   SCL as output : force SCL low
 \       --------------------------------\  
@@ -411,8 +495,8 @@ BEGIN                                   \   I2C MASTER RX
         NOP3                            \ 3 h   _
         BIC.B #SM_SDA,&I2CSM_DIR        \ 3 h _^    SDA as input  ==> SDA high with pull up resistor
         CMP.B #4,X                      \           last CTRL_char <> ABORT ?
-        U>= IF                          \
-            MOV #SLEEP,PC               \ 4          if yes goto dodo
+        U>= IF                          \           if X >= 4 goto dodo for 1/2 s..
+            MOV #SLEEP,PC               \ 4           ..wake up by TxIFG_INT to reSTART RX or by WDT_INT (to QUIT UARTI2CS)
         THEN
     REPEAT                              \ 2
 \ \   ------------------------------------\
@@ -432,8 +516,8 @@ BEGIN                                   \   I2C MASTER RX
 \              -------------------------\       _
                BIC.B #SM_SCL,&I2CSM_DIR \ 3 l _^    release SCL (high)
 \               BEGIN                   \           9/16~l
-\               BIT.B #SM_SCL,&I2CSM_IN \ 3 h       useless test if SCL is released (SLAVE TX Data)
-\               0<> UNTIL               \ 2 h
+\               BIT.B #SM_SCL,&I2CSM_IN \ 3 h       testing SCL released is useless
+\               0<> UNTIL               \ 2 h       replaced by NOP3
                NOP3
                BIT.B #SM_SDA,&I2CSM_IN  \ 3 h _     get SDA
                BIS.B #SM_SCL,&I2CSM_DIR \ 3 h  v_   SCL as output : force SCL low   13~
@@ -454,11 +538,13 @@ BEGIN                                   \   I2C MASTER RX
             0<> UNTIL                   \ 2 l       loop if no
 \           ----------------------------\   
             BIS.B #SM_SDA,&I2CSM_DIR    \ 3 l       prepare Ack
+\           ----------------------------\
+\           I2C_Master Send Ack         \
 \           ----------------------------\       _   
             BIC.B #SM_SCL,&I2CSM_DIR    \ 3 l _^    release SCL (high)
             BEGIN                       \
-                BIT.B #SM_SCL,&I2CSM_IN \ 3 h       test if SCL is released (SLAVE RX Ack)
-            0<> UNTIL                   \ 2 h
+                BIT.B #SM_SCL,&I2CSM_IN \ 3 h       wait I2C_Slave ready 
+            0<> UNTIL                   \ 2 h       I2C_Slave releases SCL
             MOV.B X,&TERM_TXBUF         \ 3 h _     send RX char to UART TERMINAL
             BIS.B #SM_SCL,&I2CSM_DIR    \ 3 h  v_   SCL as output : force SCL low
         REPEAT                          \ 2 l       loop back to I2C_Master_RX_data
@@ -474,11 +560,13 @@ BEGIN                                   \   I2C MASTER RX
             THEN
             BIS.B #SM_SDA,&I2CSM_DIR    \ 3 l       prepare Ack
         THEN
+\       --------------------------------\
+\       I2C_Master send Ack/Nack        \
 \       --------------------------------\       _   
         BIC.B #SM_SCL,&I2CSM_DIR        \ 3 l _^    release SCL (high)
         BEGIN                           \
-            BIT.B #SM_SCL,&I2CSM_IN     \ 3 h       test if SCL is released (SLAVE RX Ack)
-        0<> UNTIL                       \ 2 h
+            BIT.B #SM_SCL,&I2CSM_IN     \ 3 h       wait I2C_Slave ready 
+        0<> UNTIL                       \ 2 h       I2C_Slave releases SCL
         BIT.B #SM_SDA,&I2CSM_IN         \ 3 h _     get SDA
         BIS.B #SM_SCL,&I2CSM_DIR        \ 3 h  v_   SCL as output : force SCL low
 \       --------------------------------\       
@@ -541,12 +629,12 @@ CMP.B #1,X                              \ 1 l
 \ il attend un caractère en provenance de TERMINAL UART
 \ et une fois ce caractère reçu reSTART TX pour l'envoyer à I2C_Slave
 0= IF                                   \ 2 l
-    CALL &RXON                          \ 4 l  to enable UART RX; use no registers
-    BEGIN                               \   wait for a char or for a break
-        BIT #UCRXIFG,&TERM_IFG          \ 3 received char ?
+    CALL &RXON                          \ 4 l   enables TERMINAL to TX; use no registers
+    BEGIN                               \       wait for a char or for a break
+        BIT #UCRXIFG,&TERM_IFG          \ 3     received char ?
     0<> UNTIL                           \ 2 
-    CALL &RXOFF                         \ stops UART RX
-    GOTO BW1                            \ goto end of TERMINAL line input to RX KEY char to 0(T) with T = 
+    CALL &RXOFF                         \       stops UART RX then
+    GOTO BW1                            \       goto end of UART RX line input, for receiving last char
 THEN                                    \                             
 \ --------------------------------------\
 \ I2C_Slave ACCEPT ctrl_char $00        \ I2C_Slave requests I2C_Master to stop RX and start TX
@@ -557,11 +645,11 @@ THEN                                    \
 \ --------------------------------------\
 \ et si I2C_Slave est sorti de son sommeil par un START RX, idem.
 \ --------------------------------------\
-MOV #SLEEP,PC                           \ execute RXON then goto dodo
+MOV #SLEEP,PC                           \ execute RXON (that enables TERMINAL to TX) then goto dodo
 \ --------------------------------------\
 \ I2C_Master se réveillera au premier caractère saisi sur le TERMINAL ==> TERM_INT,
-\ ou en fin du temps TxyCCR0 ==> RX_INT,
-\ ou par un break opérateur ==> WDT_INT. 
+\ ou en fin du temps TxIFG ==> TxIFG_INT\
+\ ou par un break opérateur ==> WDT_INT \ 
 ENDASM                                  \ 
 \ --------------------------------------\
 
@@ -586,20 +674,20 @@ MOV #0,&SAVE_SYSRSTIV                   \           clear SAVE_SYSRSTIV after us
 \ --------------------------------------\
 MOV #%0101_1010_0101_1111,&WDTCTL       \           start Watchdog Timer : XDTPW, WDTSSEL=VLOCLK, WDTCNTCL=1, WDTIS=2^6 (8ms)
 BIS #1,&SFRIE1                          \           enable WDT
-MOV #WDT_INT,&WDT_VEC                   \           replace WDT_VEC default value (COLD) by WDT_INT
+MOV #WDT_INT,&WDT_VEC                   \           replace WDT_VEC default COLD value by WDT_INT
 \ --------------------------------------\
-\ init RX_INT                           \           used to scan I2C_Slave hard RESET during SLEEP and to slow START RX loop
+\ init TxIFG_INT                        \           used to scan I2C_Slave hard RESET during SLEEP and to slow START RX loop
 \ --------------------------------------\
 MOV #$800,&TB0CCR0                      \           be careful:  RX_Int time = (2047+1)/4096 = 0.5s must be >> COLD time !
-MOV #RX_INT,&TB0_x_VEC                  \
+MOV #TxIFG_INT,&TB0_x_VEC               \           replace TB0_x_VEC default COLD value by TxIFG_INT
 \ MOV #$800,&TA0CCR0                      \           be careful:  RX_Int time = (2047+1)/4096 = 0.5s must be >> COLD time !
-\ MOV #RX_INT,&TA0_x_VEC                  \
+\ MOV #TxIFG_INT,&TA0_x_VEC               \           replace TA0_x_VEC default COLD value by TxIFG_INT
 \ --------------------------------------\
 \ init UART_INT                         \
 \ --------------------------------------\
 MOV #TERM_INT,&TERM_VEC                 \           replace TERM_VEC default value (TERMINAL_INT) by TERM_INT
 \ --------------------------------------\
-\ init I2C_MASTER I/O                   \           reset state: I2CSM_DIR(SM_BUS) = 0
+\ init I2C_MASTER I/O                   \           see \inc\your_target.pat
 \ --------------------------------------\
 BIC.B #SM_BUS,&I2CSM_REN                \           remove internal pullup resistors because of external 3.3k pullup resistor
 BIC.B #SM_BUS,&I2CSM_OUT                \           preset SDA + SCL output LOW
@@ -607,13 +695,13 @@ BIC.B #SM_BUS,&I2CSM_OUT                \           preset SDA + SCL output LOW
 \ activate I/O                          \           SYSRSTIV = $02 | $0E = POWER ON | SVSH threshold
 \ --------------------------------------\
 BIC #1,&PM5CTL0                         \           activate all previous I/O settings; if not activated, nothing works after reset !
-\ --------------------------------------\
-MOV.B #4,X                              \           to enable RX_INT sleep
+\ --------------------------------------\           else CLOCK
+MOV.B #4,X                              \           to enable sleep during START RX loop
 GOTO BW3                                \           goto I2C_Master START RX loop
 ENDASM
 
 \ ================================================================================
-\ Driver UART to I2CM: this FastForth launchpad becomes an USB to I2C_Slave bridge
+\ Driver UART to I2CM : any FastForth launchpad becomes an USB to I2C_Slave bridge
 \ ================================================================================
 \ type on TERMINAL "$10 UARTI2CS" to link TERMINAL with FastForth I2C_Slave at address hex $10
 \
@@ -621,7 +709,7 @@ ENDASM
 CR                      \ to compensate the lack of one INTERPRET
 HI2LO
 MOV @RSP+,IP
-MOV TOS,&SLAVE_ADR      \ save in FRAM
+MOV TOS,&I2CS_ADR       \ save in FRAM
 MOV @PSP+,TOS
 MOV #WARM,X
 MOV #I2C_WARM,2(X)      \ replace WARM by I2C_WARM, so POR falls down to I2C_WARM
@@ -629,6 +717,7 @@ MOV X,PC                \ execute I2C_WARM
 ENDCODE
 
 RST_HERE ECHO
+
 #16 UARTI2CS    ; Alt-B (TERATERM) or S2+RESET (I2C_Master) to quit
 
 ; Since there is no difference in behaviour whether the TERMINAL is connected to the Master