X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=MSP430-FORTH%2FUART2I2CS.f;fp=MSP430-FORTH%2FUART2I2CS.f;h=1c266b807b02464993db5b9cfeb259b3d5daba57;hb=1278e8b975b39652045fcc13f86782c7531bc83f;hp=0000000000000000000000000000000000000000;hpb=7b33a614a2400e45dd1565fdb2c4641e08de23aa;p=fast-forth%2Fmaster.git diff --git a/MSP430-FORTH/UART2I2CS.f b/MSP430-FORTH/UART2I2CS.f new file mode 100644 index 0000000..1c266b8 --- /dev/null +++ b/MSP430-FORTH/UART2I2CS.f @@ -0,0 +1,589 @@ +\ -*- coding: utf-8 -*- + +\ Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices +\ Copyright (C) <2019> +\ +\ This program is free software: you can redistribute it and/or modify +\ it under the terms of the GNU General Public License as published by +\ the Free Software Foundation, either version 3 of the License, or +\ (at your option) any later version. +\ +\ This program is distributed in the hope that it will be useful, +\ but WITHOUT ANY WARRANTY\ without even the implied warranty of +\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +\ GNU General Public License for more details. +\ +\ You should have received a copy of the GNU General Public License +\ along with this program. If not, see . +\ +; ---------------------------------------------------------------------- +; UART2I2CS.f +; ---------------------------------------------------------------------- +\ +\ TARGET SELECTION +\ MSP_EXP430FR5739 MSP_EXP430FR5969 MSP_EXP430FR5994 MSP_EXP430FR6989 +\ MSP_EXP430FR4133 MSP_EXP430FR2433 MSP_EXP430FR2355 CHIPSTICK_FR2433 +\ +\ FastForth kernel compilation minimal options: +\ DTC = 2, THREADS = 16, FREQUENCY = 16 +\ TERMINALBAUDRATE = 921600, TERMINAL3WIRES, TERMINAL4WIRES +\ MSP430ASSEMBLER, CONDCOMP +\ +\ +\ notebook USB to I2C_Slave bridge any I2C_slave +\ +---------------+ +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - --+ +\ | | | PL2303HXD master running UART2I2CS @ 16MHz | +\ | | +---------------+ +--------------------------------+ +-------------------------------+ +\ | | | | | | | | +\ | TERATERM -o--> USB -o--> USB2UART --o--> UART --o--> FAST FORTH ---> UART2I2CS --o--> I2C -o--> FAST FORTH with kernel | +\ | terminal | | | 921600Bds | | 450kHz | option TERMINAL_I2C | +\ | | +---------------+ +--------------------------------+ +-------------------------------+ +\ | | | | +\ +---------------+ +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - --+ +\ +\ +\ software I2C MASTER, you can use any I/O for SDA and SCL, +\ Preferably use a couple of I/O in the interval Px0...Px3. +\ don't forget to wire 3.3k pullup resitors on SDA and SCL. + + +\ the LEDs TX and RX work fine, uncomment if you want. + +\ Multi Master Mode work but is not tested in real word. + + +PWR_STATE + +[DEFINED] {FF_I2C} [IF] {FF_I2C} [THEN] + +MARKER {FF_I2C} + +[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] + +[UNDEFINED] CONSTANT [IF] +\ https://forth-standard.org/standard/core/CONSTANT +\ CONSTANT n -- define a Forth CONSTANT +: CONSTANT +CREATE +HI2LO +MOV TOS,-2(W) \ PFA = n +MOV @PSP+,TOS +MOV @RSP+,IP +MOV @IP+,PC +ENDCODE +[THEN] + +$1820 CONSTANT SLAVE_ADR \ to save I2C_Slave address in FRAM + + +ASM QUIT_I2C \ as ASM word, QUIT_I2C is hidden. +\ ------------------------------\ +BW1 \ STOP I2C \ +\ \ ------------------------------\ +\ BIC.B #LED2,&LED2_DIR \ RX green led OFF +\ BIC.B #LED2,&LED2_OUT \ RX green led OFF +\ BIC.B #LED1,&LED1_DIR \ TX red led OFF +\ BIC.B #LED1,&LED1_OUT \ TX red led OFF +\ \ ------------------------------\ + BIS #M_BUS,&I2CM_REN \ reset I/O as reset state + BIC #M_BUS,&I2CM_DIR \ + BIS #M_BUS,&I2CM_OUT \ + MOV #$5A88,&WDTCTL \ stop WDT + BIC #1,&SFRIE1 \ disable WDT int + MOV &$FFFA,&WDT_VEC \ [USER_NMI_vector] = COLD, restore default WDT_VEC value + MOV &TERMINAL_INT,&TERM_VEC \ restore default TERM_VEC value (in FRAM INFO) + MOV #WARM,X \ + ADD #4,X + MOV X,-2(X) \ restore default WARM +\ MOV @IP+,PC \ quiet return without COLD + MOV X,PC \ explicit return with COLD +ENDASM + +ASM WDT_INT \ enable Alt+B when I2C_Master is sleeping +BIT #8,&TERM_STATW \ UART break sent by TERATERM ? +0<> IF + ADD #4,RSP \ remove RETI + POPM #6,IP \ remove Y,X,W,T,S,IP from return stack, restore IP + GOTO BW1 \ +THEN +RETI +ENDASM + +\ \ vvvvvvvMulti-Master-Modevvvvvv\ +\ ASM DO_IDLE \ +\ MOV #4,W \ 1 wait bus idle time = 5 µs @ 16 MHz +\ BEGIN +\ BIT #8,&TERM_STATW \ 3 break sent by TERATERM ? +\ 0<> IF \ 2 +\ ADD #2,RSP \ remove RET +\ MOV #QUIT_I2C,PC \ STOP I2C +\ THEN +\ BIT.B #MSCL,&I2CM_IN \ 3 +\ 0= IF \ 2 +\ MOV #4,W \ 1 if SCL is LOW +\ THEN +\ BIT.B #MSDA,&I2CM_IN \ 3 +\ 0= IF \ 2 +\ MOV #4,W \ 1 if SDA is LOW +\ THEN +\ SUB #1,W \ 1 +\ 0= UNTIL \ 2 +\ MOV @RSP+,PC +\ ENDASM +\ \ ^^^^^^^Multi-Master-Mode^^^^^^\ + + +\ **************************************\ +ASM TERM_INT \ starts with first char of line input from TERMINAL +\ **************************************\ +ADD #4,RSP \ 1 remove RET and SR +POPM #6,IP \ 8 pop Y,X,W,T,S,IP +\ \ S = last char to RX from UART +\ \ T = UART RX buffer +\ \ W = flag NOECHO/ECHO to TERMINAL +\ \ X = UART RX char +\ \ Y = I2C TX buffer +\ --------------------------------------\ +BEGIN \ + BEGIN \ + BEGIN \ wait for a char or for a break + BIT #1,&TERM_IFG \ 3 received char ? + 0<> UNTIL \ 2 +BW1 MOV.B &TERM_RXBUF,X \ 3 received char in TERMRXBUF + MOV.B X,0(T) \ 3 fill I2C_input... ...buffer + CMP.B S,X \ 1 char = char end = $0A ? + 0= ?GOTO FW1 \ 2 goto out of UART RX loop + ADD #1,T \ 1 + CMP.B #$0D,X \ 2 CR ? + 0<> WHILE \ 2 32 cycles loop ==> up to 2.5Mbds @ 8MHz + CMP #0,W \ 1 + 0= IF \ 2 if echo ON requested by I2C_Slave + MOV.B X,&TERM_TXBUF \ 3 + THEN + REPEAT \ 2 + CALL &RXOFF \ stops UART RX after received char CR and before receive char LF +AGAIN \ then take again one loop back to get LF +\ --------------------------------------\ +FW1 \ END OF UART RX \ CR+LF ends the line input from TERMIANL +\ ======================================\ S = last char to transmit +\ ======================================\ T = last char transmitted +BW2 \ I2C MASTER TX \ W = bits count / delay count down +\ ======================================\ X = I2C_Address / I2C_Data +\ ======================================\ Y = buffer TX address +\ \ --------------------------------------\ +\ BIS.B #LED1,&LED1_DIR \ red led ON = I2C TX +\ BIS.B #LED1,&LED1_OUT \ red led ON = I2C TX +\ \ --------------------------------------\ +\ BW3 \ I2C_Master TX Start \ here, SDA and SCL must be in idle state +\ --------------------------------------\ +BIS.B #MSDA,&I2CM_DIR \ 4 l force SDA as output (low) +MOV.B &SLAVE_ADR,X \ 1 h X = Slave_Address +BIC.B #1,X \ 1 h Master TX +NOP3 \ 3 h +NOP3 \ 3 h +BIS.B #MSCL,&I2CM_DIR \ 4 h force SCL as output (low) +MOV S,T \ +XOR #-1,T \ 1 set T <> S before sending I2C address +\ --------------------------------------\ +BEGIN +\ ------------------------------------\ +\ I2C Master TX address/Data \ +\ ------------------------------------\ + MOV.B #8,W \ 1 l prepare 8 bits address + BEGIN \ + ADD.B X,X \ 1 l shift one left + U>= IF \ 2 l carry set ? + BIC.B #MSDA,&I2CM_DIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor + ELSE \ 2 l + BIS.B #MSDA,&I2CM_DIR \ 4 l no : SDA as output ==> SDA low + NOP2 \ 2 + THEN \ l _ + BIC.B #MSCL,&I2CM_DIR \ 4 l _^ release SCL (high) + BEGIN \ 9~h/16~l + BIT.B #MSCL,&I2CM_IN \ 3 h test if SCL is released + 0<> UNTIL \ 2 h +\ \ vvvvvvvvMulti-Master-Modevvvvvvv\ +\ BIT.B #MSDA,&I2CM_IN \ 3 h _ test SDA +\ \ ^^^^^^^^Multi-Master-Mode^^^^^^^\ + BIS.B #MSCL,&I2CM_DIR \ 4 h v_ SCL as output : force SCL low +\ \ vvvvvvvvvvvvMulti-Master-Modevvvvvvvvvvv\ +\ 0= IF \ 2 l +\ BIT.B #MSDA,&I2CM_DIR \ 3 l +\ 0= IF \ 2 l +\ \ --------------------------------\ +\ \ collision detected \ l collision if SDA(IN)=0 AND SDA(DIR)=0 +\ \ --------------------------------\ +\ BIS.B #MSCL,&I2CM_DIR \ 4 l release SCL first +\ CALL #DO_IDLE \ wait stable idle state +\ GOTO BW3 \ 2 l goto START TX +\ THEN +\ THEN +\ \ ^^^^^^^^^^^^Multi-Master-Mode^^^^^^^^^^^\ + SUB #1,W \ 1 l bits count-1 + 0= UNTIL \ 2 l +\ ------------------------------------\ + BIC.B #MSDA,&I2CM_DIR \ 4 l after TX byte we must release SDA to read Ack/Nack from Slave +\ ------------------------------------\ +\ I2C Master get Slave Ack/Nack \ +\ ------------------------------------\ _ + BIC.B #MSCL,&I2CM_DIR \ 3 l _^ release SCL (high) + BEGIN \ + BIT.B #MSCL,&I2CM_IN \ 3 h test if SCL is released + 0<> UNTIL \ 2 h + BIT.B #MSDA,&I2CM_IN \ 3 h _ get SDA state + BIS.B #MSCL,&I2CM_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 +\ ------------------------------------\ +\ I2C_Master_TX_data_loop \ +\ ------------------------------------\ + CMP.B S,T \ 1 T = S = last char to transmit ? +0<> WHILE \ 2 \ 2 goto beyond REPEAT; out of loop if = + 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 +\ ------------------------------------\ + NOP3 \ 3 l _ delay to reach I2C tLO + BIC.B #MSCL,&I2CM_DIR \ 4 l _^ release SCL to enable reSTART +\ \ --------------------------------------\ +\ BIC.B #LED1,&LED1_DIR \ red led OFF = endof I2C TX +\ BIC.B #LED1,&LED1_OUT \ red led OFF = endof I2C TX +\ \ --------------------------------------\ +\ ======================================\ +\ END OF I2C MASTER TX \ +\ ======================================\ +\ ======================================\ +\ I2C MASTER RX \ +\ ======================================\ +BW3 \ I2C_Master START RX \ +\ --------------------------------------\ +\ le driver I2C_Master envoie START RX en boucle. +\ le test d'un break en provenance de l'UART est intégré dans cette boucle. +\ --------------------------------------\ +BEGIN \ I2C MASTER RX +\ --------------------------------------\ + BEGIN \ I2C MASTER START RX +\ ------------------------------------\ +\ I2C_Master_Start_Cond \ here, SDA and SCL must be in idle state +\ --------------------------------\ + BIS.B #MSDA,&I2CM_DIR \ 4 l force SDA as output (low) + MOV.B &SLAVE_ADR,X \ 1 h X = Slave_Address + BIS.B #1,X \ 1 h Master RX + NOP3 \ 3 + NOP3 \ 3 + BIS.B #MSCL,&I2CM_DIR \ 4 h force SCL as output (low) +\ --------------------------------\ +\ I2C_Master_Send_address \ may be SCL is held low by slave +\ --------------------------------\ + MOV.B #8,W \ 1 l prepare 8 bits address + BEGIN \ + ADD.B X,X \ 1 l shift one left + U>= IF \ 2 l carry set ? + BIC.B #MSDA,&I2CM_DIR \ 4 l yes : SDA as input ==> SDA high because pull up resistor + ELSE \ 2 l + BIS.B #MSDA,&I2CM_DIR \ 4 l no : SDA as output ==> SDA low + NOP2 \ 2 l + THEN \ _ + BIC.B #MSCL,&I2CM_DIR \ 4 l _^ release SCL (high) + BEGIN \ + BIT.B #MSCL,&I2CM_IN \ 3 h test if SCL is released + 0<> UNTIL \ 2 h +\ \ vvvvvvMulti-Master-Modevvvvv\ +\ BIT.B #MSDA,&I2CM_IN \ 3 h _ test SDA +\ \ ^^^^^^Multi-Master-Mode^^^^^\ + BIS.B #MSCL,&I2CM_DIR \ 4 h v_ SCL as output : force SCL low +\ \ vvvvvvvvvvvvMulti-Master-Modevvvvvvvvvvv\ +\ 0= IF \ 2 l +\ BIT.B #MSDA,&I2CM_DIR \ 3 l +\ 0= IF \ 2 l +\ \ ------------------------------------\ +\ \ collision detection \ l collision if SDA(IN)=0 AND SDA(DIR)=0 +\ \ ------------------------------------\ +\ BIS.B #MSCL,&I2CM_DIR \ 4 l release SCL first +\ CALL #DO_IDLE \ wait stable idle state +\ GOTO BW3 \ 2 l goto START RX +\ THEN +\ THEN +\ \ ^^^^^^^^^^^^Multi-Master-Mode^^^^^^^^^^^\ + SUB #1,W \ 1 l bits count - 1 + 0= UNTIL \ 2 l +\ --------------------------------\ + BIC.B #MSDA,&I2CM_DIR \ 4 l _ after TX address we must release SDA to read Ack/Nack from Slave + BIC.B #MSCL,&I2CM_DIR \ 3 l _^ release SCL (high) + BEGIN \ + BIT.B #MSCL,&I2CM_IN \ 3 h test if SCL is released + 0<> UNTIL \ 2 h + BIT.B #MSDA,&I2CM_IN \ 3 h _ get SDA + BIS.B #MSCL,&I2CM_DIR \ 3 h v_ SCL as output : force SCL low +\ --------------------------------\ + 0<> WHILE \ Nack_On_Address \ 2 l +\ --------------------------------\ + NOP3 \ 3 l delay to reach tLO +\ --------------------------------\ +\ I2C_Master Send STOP \ after Nack_On_Address +\ --------------------------------\ _ + BIS.B #MSDA,&I2CM_DIR \ 4 l v_ SDA as output ==> SDA low + NOP3 \ 3 l _ + BIC.B #MSCL,&I2CM_DIR \ 4 l _^ release SCL (high) + NOP3 \ 3 h + NOP3 \ 3 h _ + BIC.B #MSDA,&I2CM_DIR \ 4 h _^ SDA as input ==> SDA high with pull up resistor +\ --------------------------------\ + BIT #8,&TERM_STATW \ 3 break sent by TERATERM ? + 0<> IF + MOV #QUIT_I2C,PC \ 2 STOP I2C + THEN +\ --------------------------------\ + REPEAT \ 2 loop back to MASTER START RX +\ \ ------------------------------------\ +\ BIS.B #LED2,&LED2_DIR \ green led ON = I2C RX +\ BIS.B #LED2,&LED2_OUT \ green led ON = I2C RX +\ \ ------------------------------------\ +\ I2C_Master_RX_data \ +\ ------------------------------------\ + BEGIN + BEGIN + MOV.B #8,W \ 1 l prepare 8 bits transaction +\ ----------------------------\ + BEGIN \ +\ ------------------------\ _ +\ do SCL pulse \ SCL _| |_ +\ ------------------------\ _ + BIC.B #MSCL,&I2CM_DIR \ 4 l _^ release SCL (high) + BEGIN \ 9/16~l + BIT.B #MSCL,&I2CM_IN \ 3 h test if SCL is released + 0<> UNTIL \ 2 h + BIT.B #MSDA,&I2CM_IN \ 3 h _ get SDA + BIS.B #MSCL,&I2CM_DIR \ 4 h v_ SCL as output : force SCL low 13~ + ADDC.B X,X \ 1 l C <--- X(7) ... X(0) <--- SDA + SUB #1,W \ 1 l count down of bits + 0= UNTIL \ 2 l +\ ----------------------------\ + CMP.B #8,X \ 1 l $08 = char BS +\ ----------------------------\ + U>= WHILE \ 2 l normal char received, comprizing BS +\ ----------------------------\ + BEGIN \ + BIT #2,&TERM_IFG \ 3 l TX buffer empty ? + 0<> UNTIL \ 2 l loop if no +\ ----------------------------\ + BIS.B #MSDA,&I2CM_DIR \ 4 l prepare Ack +\ ----------------------------\ _ + BIC.B #MSCL,&I2CM_DIR \ 3 l _^ release SCL (high) + BEGIN \ + BIT.B #MSCL,&I2CM_IN \ 3 h test if SCL is released + 0<> UNTIL \ 2 h + MOV.B X,&TERM_TXBUF \ 3 h _ send RX char to UART TERMINAL + BIS.B #MSCL,&I2CM_DIR \ 3 h v_ SCL as output : force SCL low +\ ----------------------------\ + BIC.B #MSDA,&I2CM_DIR \ 4 l before RX next byte, we must release SDA +\ ----------------------------\ + REPEAT \ 2 l loop back to I2C_Master_RX_data +\ --------------------------------\ +\ Ctrl_char received \ +\ --------------------------------\ + CMP.B #4,X \ 1 + U>= IF \ 2 +\ ----------------------------\ + BIS.B #MSDA,&I2CM_DIR \ 4 l prepare Ack for $04=NOECHO,$05=ECHO +\ ----------------------------\ + THEN +\ --------------------------------\ _ + BIC.B #MSCL,&I2CM_DIR \ 3 l _^ release SCL (high) + BEGIN \ + BIT.B #MSCL,&I2CM_IN \ 3 h test if SCL is released + 0<> UNTIL \ 2 h + BIT.B #MSDA,&I2CM_IN \ 3 h _ get SDA + BIS.B #MSCL,&I2CM_DIR \ 3 h v_ SCL as output : force SCL low +\ --------------------------------\ + 0= WHILE \ 2 l if Ack sent by Master (4 >= char < 8) +\ --------------------------------\ + BIC.B #MSDA,&I2CM_DIR \ before RX next byte, we must release SDA +\ --------------------------------\ + CMP.B #4,X \ +\ --------------------------------\ + 0= IF \ $04 = ctrl_char for NOECHO request + MOV #1,&TIB_I2CADR \ set NOECHO + ELSE \ $05 = ctrl_char for ECHO request + MOV #0,&TIB_I2CADR \ set ECHO + THEN + REPEAT \ loop back to I2C_Master_RX_data +\ ------------------------------------\ +\ if Nack sent by Master \ SDA is released HIGH +\ ------------------------------------\ + CMP.B #2,X \ 1 l $02 = ctrl_char for ABORT request +0= WHILE \ 2 l if Ctrl_char = $02 + MOV #0,&TIB_I2CADR \ set echo on I2C_Master side +\ ------------------------------------\ +\ UART_ABORT \ +\ ------------------------------------\ + CALL &RXON \ resume UART downloading source file + BEGIN \ + BIC #UCRXIFG,&TERM_IFG \ clear UCRXIFG ('ESC' char is lost) + MOV &FREQ_KHZ,Y \ 1000, 2000, 4000, 8000, 16000, 240000 + BEGIN MOV #32,X \ 2~ <-------+ windows 10 seems very slow... ==> ((32*3)+5) = 101ms delay + BEGIN SUB #1,X \ 1~ <---+ | + 0= UNTIL \ 2~ 3~ loop ---+ | to refill its USB buffer + SUB #1,Y \ 1~ | + 0= UNTIL \ 2~ 101~ loop -----+ + BIT #UCRXIFG,&TERM_IFG \ 4 new char in TERMRXBUF during this delay ? + 0= UNTIL \ 2 yes, the input stream may be still active: loop back +REPEAT \ loop back to I2C MASTER reSTART RX +\ --------------------------------------\ +\ I2C_Master Send STOP \ after RX Data(s) +\ --------------------------------------\ _ +BIC.B #MSCL,&I2CM_DIR \ 4 l _^ release SCL (high) +NOP3 \ 3 h +NOP3 \ 3 h _ +BIC.B #MSDA,&I2CM_DIR \ 4 h _^ SDA as input ==> SDA high with pull up resistor +\ \ --------------------------------------\ +\ BIC.B #LED2,&LED2_DIR \ 4 l green led OFF = endof I2C RX +\ BIC.B #LED2,&LED2_OUT \ 4 l green led OFF = endof I2C RX +\ \ --------------------------------------\ +\ ======================================\ +\ ======================================\ +\ END OF I2C MASTER RX \ here I2C_bus is free and Nack on Ctrl_char $00|$01 remains to be processed. +\ ======================================\ +\ ======================================\ +\ TERMINAL TX --> UART RX \ +\ --------------------------------------\ +\ I2C_Slave KEY ctl_char $01 \ I2C_Slave request for KEY input +\ --------------------------------------\ +CMP.B #1,X \ 1 l +\ Quand I2C_Master reçoit ce caractère de contrôle, +\ 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 + MOV #TIB_I2CCNT,Y \ Y = input buffer for I2C_Master TX + MOV Y,T \ T = input buffer for UART RX + BEGIN \ wait for a char or for a break + BIT #UCRXIFG,&TERM_IFG \ 3 received char ? + 0<> UNTIL \ 2 + MOV.B &TERM_RXBUF,X \ 3 X = UART RX char + MOV.B X,0(T) \ 3 fill I2C_input... ...buffer + MOV.B X,S \ 2 S = KEY char = last char to send with I2C_MASTER TX ! + CALL &RXOFF \ stops UART RX + GOTO BW2 \ goto I2C MASTER TX +THEN \ +\ --------------------------------------\ +\ I2C_Slave ACCEPT ctrl_char $00 \ I2C_Slave requests I2C_Master to stop RX and start TX +\ --------------------------------------\ +\ en début de sa routine ACCEPT, I2C_Slave envoie sur le bus I2C le caractère de contrôle $00 +\ avant de s'endormir avec SLEEP +\ I2C_Master envoie NACK + STOP pour signifier la fin de la transaction. +\ --------------------------------------\ +\ I2C_Slave SLEEP ctrl_char $00 \ as request to stop I2C_Master RX +\ --------------------------------------\ +\ si I2C_Slave est sorti de son sommeil par un START RX, idem. +\ --------------------------------------\ +\ I2C_Master envoie un XON sur l'UART, à destination de TERMINAL +\ I2C_Master attend un flux de caractères en provenance du TERMINAL +\ ou l'occurence d'un break qui génère la sortie du programme. +\ les caractères reçus de TERMINAL sont stockés dans un buffer. +\ A la réception du caractère CR, I2C_Master envoie XOFF à TERMINAL +\ et refait encore un tour pour capter LF. +\ pendant ce temps, I2C_Slave est dans l'état SLEEP, le bus I2C est libre +\ --------------------------------------\ +MOV #TIB_ORG,Y \ Y = input buffer for I2C_Master TX +MOV &TIB_I2CADR,W \ W = 0 if ECHO, 1 if NOECHO +MOV Y,T \ T = input buffer for UART RX +MOV #$0A,S \ S = last char to send with I2C_MASTER TX +PUSHM #6,IP \ push IP,S,T,W,X,Y, as ACCEPT +MOV #SLEEP,PC \ execute RXON then goto dodo +ENDASM \ +\ --------------------------------------\ + + + + + +\ --------------------------------------\ +ASM WARM_I2C \ replace default WARM +\ --------------------------------------\ +CMP #4,&SAVE_SYSRSTIV \ +0= IF + MOV #QUIT_I2C,PC \ if STOP I2C +THEN + CMP #$10,&SAVE_SYSRSTIV \ + U>= IF + MOV #QUIT_I2C,PC \ if other SYS failure >= $10 STOP I2C + THEN \ +MOV #0,&SAVE_SYSRSTIV \ +\ --------------------------------------\ +\ init WDT timer \ +\ --------------------------------------\ +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 +\ --------------------------------------\ +\ init TERMINAL UART \ +\ --------------------------------------\ +BIS #IE_TERM,&TERM_IE \ then enable RX interrupt for wake up on terminal input +BIS.B #TERM_BUS,&TERM_SEL \ Configure pins TXD & RXD for TERM_UART use, otherwise no TERMINAL ! +MOV #TERM_INT,&TERM_VEC \ replace TERM_VEC default value (TERMINAL_INT) by TERM_INT +\ --------------------------------------\ +\ initialisation I2C_MASTER \ I2CM_DIR(M_BUS) = 0, M_BUS as input +\ --------------------------------------\ +BIC #M_BUS,&I2CM_REN \ remove internal pullup resistors (presence of external pullup resistor 3.3k) +BIC #M_BUS,&I2CM_OUT \ preset SDA + SCL 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 ! +\ ======================================\ +\ ENDOF WARM part \ +\ ======================================\ +GOTO BW3 \ goto I2C_Master START RX +ENDASM + +\ ================================================================================ +\ Driver UART to I2CM : this FastForth launchpad becomes an USB to I2C_Slave bridge +\ ================================================================================ +\ +\ I2C = 450 kHz @ MCLK = 16 MHz, better than an hardware UCB0 I2C Master ! +\ I2C bus resistors pullup = 3.3k +\ type on TERMINAL "$10 UART2I2CS" to link TERMINAL with FastForth I2C_Slave at address hex $10 +\ +\ type Alt+B on TERATERM TERMINAL to send a break to quit, or on I2C_Master. + +\ UART to I2C_Master +CODE UART2I2CS \ SlaveAddress -- +MOV @RSP+,IP +MOV TOS,&SLAVE_ADR \ save in FRAM +MOV @PSP+,TOS +MOV #WARM,X +MOV #WARM_I2C,2(X) \ replace WARM by WARM_I2C, so POR execute WARM_I2C +MOV X,PC \ execute WARM_I2C +ENDCODE + +RST_HERE + +; Since there is no difference in behavior whether the TERMINAL is connected to the Master +; or to a Slave, the convenient way to check which target is connected to is to execute WARM, +; because WARM displays first the decimal I2C address when TERMINAL is connected to I2C FastForth. + +WARM \ to show the target linked to TERMINAL before: no I2C Slave address + +; v---- in forthMSP430FR.asm file search "I2CSLAVEADR" value used when compiling FastForth for TERMINAL_I2C + $10 UART2I2CS + +WARM \ to show the target linked to TERMINAL after: see the decimal I2C Slave address first. + +; remember: from scite menu or in the SendSourceFileToTarget.bat file, select the good target to download UART2I2CS +; then select the good target to download sources file to the target running FastForth I2C +; at the specified I2C address ! + +; Alt-B to quit UART2I2CS + +; ready for a cluster of FastForth(s) ?