/MSP-EXP430FR5969/MSP-EXP430FR5969_I2CF_SoftM_to_LCD_2x20.4th
Forth | 673 lines | 614 code | 59 blank | 0 comment | 24 complexity | f2239982a2b867dafadcac6e17ffeea8 MD5 | raw file
Possible License(s): GPL-3.0
- ; -------------------------------------------
- ; MSP-EXP430FR5969_I2CF_SoftM_to_LCD_2x20.4th
- ; -------------------------------------------
- STOP ; to stop any interrupt in progress
- WIPE ;
- NOECHO ; comment to debug
- ; FORTH source file
- ; Copyright (C) <2016> <J.M. THOORENS>
- ;
- ; 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 <http://www.gnu.org/licenses/>.
- ; ========================================
- ; DEMO : I2C_SLAVE WRITE & I2C_MASTER READ
- ; I2C_MASTER PART
- ; ========================================
- ; load this MSP-EXP430FR5969_I2C_Soft_Master_to_LCD_2x20.4th file on the first LAUNCHPAD
- ; load MSP-EXP430FR5969_RC5_to_I2C_Slave.4th on the other LAUNCHPAD
- ; target : MSP-EXP430fr5969 LAUNCHPAD
- ; ===================================================================================
- ; in case of 3.3V powered by UARTtoUSB bridge, open J13 straps {RST,TST,V+,5V} BEFORE
- ; ===================================================================================
- ; -----------------------------------------------
- ; MSP - MSP-EXP430fr5969 <--> OUTPUT WORLD
- ; -----------------------------------------------
- ; P4.6 - J6 - LED1 red
- ; P1.0 - LED2 green
- ; P4.5 - Switch S1 <--- LCD contrast + (finger :-)
- ; P1.1 - Switch S2 <--- LCD contrast - (finger ;-)
-
- ; GND - J1.2 <-------+---0V0----------> 1 LCD_Vss
- ; VCC - J1.3 >------ | --3V6-----+----> 2 LCD_Vdd
- ; | |
- ; |___ 470n ---
- ; ^ | ---
- ; / \ BAT54 |
- ; --- |
- ; 100n | 2k2 |
- ; P2.2 - J4.7 UCB0 CLK TB0.2 >---||--+--^/\/\/v--+----> 3 LCD_Vo (=0V6 without modulation)
- ; P3.4 - J4.8 -------------------------> 4 LCD_RS
- ; P3.5 - J4.9 -------------------------> 5 LCD_R/W
- ; P3.6 - J4.10 -------------------------> 6 LCD_EN0
- ; PJ.0 - J3.1 <------------------------> 11 LCD_DB4
- ; PJ.1 - J3.3 <------------------------> 12 LCD_DB5
- ; PJ.2 - J3.5 <------------------------> 13 LCD_DB5
- ; PJ.3 - J3.7 <------------------------> 14 LCD_DB7
-
- ; P2.0 - J13.8 UCA0 TXD ---> RX UARTtoUSB bridge
- ; P2.1 - J13.10 UCA0 RXD <--- TX UARTtoUSB bridge
- ; P4.1 - J13.14 RTS ---> CTS UARTtoUSB bridge (optional hardware control flow)
- ; VCC - J13.16 <--- VCC (optional supply from UARTtoUSB bridge - WARNING ! 3.3V !)
- ; GND - J13.20 <--> GND (optional supply from UARTtoUSB bridge)
-
- ; VCC - J11.1 ---> VCC SD_CardAdapter
- ; GND - J12.3 <--> GND SD_CardAdapter
- ; P2.4 - J4.6 UCA1 CLK ---> CLK SD_CardAdapter (SCK)
- ; P4.3 - J4.5 ---> CS SD_CardAdapter (Card Select)
- ; P2.5 - J4.4 UCA1 TXD/SIMO ---> SDI SD_CardAdapter (MOSI)
- ; P2.6 - J4.3 UCA1 RXD/SOMI <--- SDO SD_CardAdapter (MISO)
- ; P4.2 - J4.2 <--- CD SD_CardAdapter (Card Detect)
-
- ; P4.0 - J3.10 \\\<--- OUT IR_Receiver (1 TSOP32236)
- ; VCC - J3.2 \\\---> VCC IR_Receiver (2 TSOP32236)
- ; GND - J3.9 \\\<--> GND IR_Receiver (3 TSOP32236)
-
- ; PJ.4 - LFXI 32768Hz quartz
- ; PJ.5 - LFXO 32768Hz quartz
- ; PJ.6 - HFXI
- ; PJ.7 - HFXO
-
- ; P1.2 - J5.19 Soft I2C_Master <--> SDA <--------------------------------------------------> SDA other LAUNCHPAD
- ; P1.3 - J5.11 Soft I2C_Master ---> SCL ---------------------------------------------------> SCL other LAUNCHPAD
- ; P1.4 - J5.12 TB0.1 <--> free
- ; P1.5 - J5.13 UCA0 CLK TB0.2 <--> free
- ; P1.6 - J5.15 UCB0 SDA/SIMO <--> SDA
- ; P1.7 - J5.14 UCB0 SCL/SOMI ---> SCL
- ; P3.0 - J5.7 <--- free
- ; P2.3 - NC
- ; P2.7 - NC
- ; P3.1 - NC
- ; P3.2 - NC
- ; P3.3 - NC
- ; P3.7 - NC
- ; P4.4 - NC
- ; P4.7 - NC
- ; HERE ; general minidump, part 1
- ; ******************************;
- CODE INT_P1 ; PORT1 interrupt routine, warning : not FORTH executable !
- ; ******************************;
- BIC #0xF8,0(RSP) ; CPU on, GIE off in retSR
- ; ------------------------------;
- BIT.B #0x02,&0x200 ; test P1IN.1 = switch S2
- BIC.B #0x02,&0x21C ; P1IFG.1 clear
- 0= IF ; case of switch S2 pressed
- CMP #34,&0x3D6 ; TB0CCR2 ; maxi Ton = 34/40 & VDD=3V6 ==> LCD_Vo = -2V2
- U< IF
- ADD #1,&0x3D6 ; TB0CCR2 ; action for switch S2 (P1.1) : 78 mV / increment
- THEN
- THEN
- RETI ;
- ENDCODE
- ; ******************************;
- CODE INT_P4 ; PORT4 interrupt routine, warning : not FORTH executable !
- ; ******************************;
- BIC #0xF8,0(RSP) ; CPU on, GIE off in retSR
- ; ------------------------------;
- BIT.B #0x20,&0x220 ; test P4IN.5 = switch S1
- BIC.B #0x20,&0x23D ; P4IFG.5 clear
- 0= IF ; case of Switch S1 pressed
- CMP #7,&0x3D6 ; TB0CCR2 ; mini Ton = 6/40 & VDD=3V6 ==> LCD_Vo = 0V
- U>= IF ;
- SUB #1,&0x3D6 ; TB0CCR2 ; action for switch S1 (P4.5) : -78 mV / decrement
- THEN ;
- THEN ;
- RETI ;
- ENDCODE
- ; ------------------------------;
- CODE 20_us ; n -- n * 20 us
- ; ------------------------------;
- BEGIN ; 3 cycles loop + 6~
- ; MOV #5,W ; 3 MCLK = 1 MHz
- ; MOV #23,W ; 3 MCLK = 4 MHz
- MOV #51,W ; 3 MCLK = 8 MHz
- ; MOV #104,W ; 3 MCLK = 16 MHz
- ; MOV #158,W ; 3 MCLK = 24 MHz
- BEGIN ; 3 cycles loop ==> 3 * W / F us = 100 us - 1 @ 8 MHz
- SUB #1,W ; 1
- 0= UNTIL ; 2
- SUB #1,TOS ; 1
- 0= UNTIL ; 2
- MOV @PSP+,TOS ; 2
- MOV @IP+,PC ; 4
- ENDCODE
- ; ------------------------------;
- CODE TOP_LCD ; LCD Sample
- ; ------------------------------; if write : 0bxxxxWWWW --
- ; ; if read : -- 0b0000RRRR
- BIS.B #0x40,&0x222 ; P3OUT.6 LCD_EN 0-->1
- BIT.B #0x20,&0x220 ; P3IN.5 LCD_RW test
- 0= IF ; write LCD bits pattern
- AND #0x0F,TOS ;
- MOV.B TOS, &0x322 ; MOVE LCD_Data bits to PJ(0-3)
- BIC.B #0x40,&0x222 ; P3OUT.6 LCD_EN 1-->0 ==> strobe data
- MOV @PSP+,TOS ;
- MOV @IP+,PC
- THEN ; read LCD bits pattern
- SUB #2,PSP
- MOV TOS,0(PSP)
- BIC.B #0x40,&0x222 ; P3OUT.6 LCD_EN 1-->0 ==> strobe data
- MOV.B &0x320,TOS ; get LCD_Data from PJ(0-3)
- AND.B #0x0F,TOS
- MOV @IP+,PC
- ENDCODE
- ; ------------------------------;
- CODE LCD_W ; byte -- write byte
- ; ------------------------------;
- SUB #2,PSP ;
- MOV TOS,0(PSP) ; -- 0bxxxxLLLL 0bHHHHLLLL
- RRUM #4,TOS ; -- 0bxxxxLLLL 0bxxxxHHHH
- BIC.B #0x20,&0x222 ; P3OUT.5 LCD_RW=0
- BIS.B #0x0F,&0x324 ; PJDIR.(0-3) LCD_Data as output
- PUSH IP
- ASM>FORTH
- TOP_LCD 2 20_us \ write high nibble first
- TOP_LCD 2 20_us ;
- ; ------------------------------;
- CODE LCD_R ; -- byte read byte
- ; ------------------------------;
- BIC.B #0x0F,&0x324 ; PJ.(0-3) LCD_Data as intput
- BIS.B #0x20,&0x222 ; P3.5 LCD_RW=1
- PUSH IP
- ASM>FORTH
- TOP_LCD 2 20_us \ read high nibble first
- TOP_LCD 2 20_us
- FORTH>ASM ; -- 0b0000HHHH 0b0000LLLL
- MOV @RSP+,IP
- MOV @PSP+,W ; W = high nibble
- RLAM #4,W ; -- 0b0000LLLL W = 0bHHHH0000
- ADD.B W,TOS
- MOV @IP+,PC
- ENDCODE
- ; ------------------------------;
- CODE LCD_WrF ; func -- Write fonction
- ; ------------------------------;
- BIC.B #0x10,&0x222 ; P3OUT.4 LCD_RS=0
- JMP LCD_W
- ENDCODE
- ; ------------------------------;
- CODE LCD_RdS ; -- status Read Status
- ; ------------------------------;
- BIC.B #0x10,&0x222 ; P3OUT.4 LCD_RS=0
- JMP LCD_R
- ENDCODE
- ; ------------------------------;
- CODE LCD_WrC ; char -- Write char
- ; ------------------------------;
- BIS.B #0x10,&0x222 ; P3OUT.4 LCD_RS=1
- JMP LCD_W
- ENDCODE
- ; ------------------------------;
- CODE LCD_RdC ; -- char Read char
- ; ------------------------------;
- BIS.B #0x10,&0x222 ; P3OUT.4 LCD_RS=1
- JMP LCD_R
- ENDCODE
- ; ------------------------------;
- \ : LCD_Clear 0x01 LCD_WrF 80 20_us ; bad init !
- : LCD_Clear 0x01 LCD_WrF 100 20_us ;
- ; ------------------------------;
- : LCD_Home 0x02 LCD_WrF 80 20_us ;
- ; ------------------------------;
- ; : LCD_Entry_set 0x04 OR LCD_WrF ;
- ; : LCD_Display_Ctrl 0x08 OR LCD_WrF ;
- ; : LCD_Display_Shift 0x10 OR LCD_WrF ;
- ; : LCD_Fn_Set 0x20 OR LCD_WrF ;
- ; : LCD_CGRAM_Set 0x40 OR LCD_WrF ;
- ; : LCD_Goto 0x80 OR LCD_WrF ;
- ; -------------------------------------------------------------------------------------------------------------------;
- ; I2C soft MASTER, FAST MODE, 8MHz
- ; -------------------------------------------------------------------------------------------------------------------;
- ; P1.2 = SDA
- ; P1.3 = SCL
- ; use Px.0 to Px.3 for good timing at 8 MHz
- ; tested in RX and TX at 8 MHZ with 3k3 external pullup resistors
- ; results : speed in RX = TX = 270 kHz
- VARIABLE I2CSLV_ADR ; contents slave address & R/W
- VARIABLE I2CM_OUT ; buffer output, lentgh,DATA (low,HIGH)
- VARIABLE I2CM_IN ; buffer input, lentgh,DATA (low,HIGH)
- 2 ALLOT
- ; ; ------------------------------; _
- ; CODE M_SCL ; SCL _| |_
- ; ; ------------------------------; _
- ; BIC.B #0x08,&0x204 ; 3 l _^ P1DIR.3 release SCL (high)
- ; BEGIN ;
- ; BIT.B #0x08,&0x200 ; 3 h test if SCL is released
- ; 0<> UNTIL ; 2 h
- ; BIT.B #0x04,&0x200 ; 3 h _ P1IN.2 : get SDA
- ; BIS.B #0x08,&0x204 ; 3 h v_ P1DIR.3 as output : force SCL low
- ; MOV @RSP+,PC ; 4 l return: C = SDA pin
- ; ENDCODE ; l Z = slave Nack/Ack
- ; ; ------------------------------;
- ; ------------------------------;
- CODE I2C_MTX ; MASTER TX one byte ; shared code for address and TX data
- ; ------------------------------;
- BEGIN ;
- ADD.B X,X ; 1 l shift one left
- U>= IF ; 2 l carry set ?
- BIC.B #0x04,&0x204 ; 4 l yes : P1DIR.2 as input ==> SDA high because pull up resistor
- ELSE ; 2 l
- BIS.B #0x04,&0x204 ; 4 l no : P1DIR.2 as output ==> SDA low
- THEN ; l _
- BIC.B #0x08,&0x204 ; 4 l _^ P1DIR.3 release SCL (high)
- BEGIN ; 14/16~l
- BIT.B #0x08,&0x200 ; 3 h test if SCL is released
- 0<> UNTIL ; 2 h _
- BIS.B #0x08,&0x204 ; 4 h v_ P1DIR.3 as output : force SCL low
- SUB #1,W ; 1 l dec count of bits
- 0= UNTIL ; 2 l
- ; ------------------------------;
- ; I2C_Master_TXreadAckOrNack ; here, SDA is indetermined, SCL is strech low by master
- ; ------------------------------;
- BIC.B #0x04,&0x204 ; 3 l P1DIR.2 as input : release SDA high
- ; JMP M_SCL ; 2 l
- MOV @RSP+,PC ; 4 l
- ENDCODE ;
- ; ------------------------------;
- ; example of Fast_I2C_Soft_Master_8MHz routine under interrput
- ; first prepare interrupt return in normal mode by modifying retSR on first cell return stack
- ; then remplace all RET occurrence by RETI
- ; notice : with FastForthForMSP430fr5xxx, no need to save IP,U,W,X,V registers under interrupt
- ; ******************************;
- CODE I2C_M ; soft I2C_Master driver under WDT interrupt
- ; ******************************;
- BIC #0xF8,0(RSP) ; CPU on, GIE off in oldSR
- ; ------------------------------;
- ; ; in : I2CSLV_ADR & (R/W)
- ; ; : I2CM_IN/I2CM_OUT as requested by I2C_SLA_ADR(0)
- ; ; : I2CM_IN/I2CM_OUT(0) = count of datas to be TX/RX
- ; ; : I2CM_IN/I2CM_OUT(0) = 0 ==> send only I2C address
- ; ; used: U BUF_PTR
- ; ; V count of I2C datas exchanged
- ; ; W count of bits
- ; ; X data
- ; ; Y BUF_ORG
- ; ; out : I2CSLV_ADR & (R/W) unchanged
- ; ; Y = BUF_ORG
- ; ; U = BUF_PTR pointing on first data not exchanged
- ; ; V = count+1 of TX/RX datas exchanged (if ack on addr)
- ; ; I2CM_IN/OUT(0) = count of data not exchanged (normally = 0)
- ; ; I2CM_IN/OUT(0) = -1 <==> Nack on address
- ; ------------------------------;
- ; I2C_Master_Start_Cond: ; here, SDA and SCL are in idle state
- ; ------------------------------;
- BIS.B #0x04,&0x204 ; 4 l P1DIR.2 force SDA output (low)
- MOV.B &I2CSLV_ADR,X ; 3 h @ in X
- MOV #I2CM_OUT,U ; 2 h buffer out by default
- BIT.B #1,X ; 1 h test I2C R/w flag
- 0<> IF ; 2 h
- MOV #I2CM_IN,U ; 2 h buffer in
- THEN ;
- MOV U,Y ; 1 h U=BUF_ptr Y=BUF_org
- MOV.B @U+,V ; 2 h V = count of datas
- ; ; ------------------------------;
- ; ; Init M_TI2C first ! ; IP must be initialized
- ; ; ------------------------------;
- ; MOV #2,IP ; 1 h tHD:STA=4us, 15~ complement @ 8MHz
- ; ; MOV #13,IP ; 2 h tHD:STA=4us, 48~ complement @ 16MHz
- ; ; MOV #23,IP ; 2 h tHD:STA=4us, 78~ complement @ 24MHz
- ; ; ------------------------------;
- ; CALL #M_TI2C ; wait tHD;STA
- BIS.B #0x08,&0x204 ; 4 h P1DIR.3 force SCL output (low)
- ; ------------------------------; l
- ; I2C_Master_Start_EndOf: ;
- ; ------------------------------;
- ; I2C_Master_Send_address ; may be SCL is held low by slave
- ; ------------------------------;
- ADD #1,V ; 1 l to add address in count
- MOV #8,W ; 1 l prepare 8 bit Master writing
- ; ; ADD #0,IP ; 2 l tLOW=4,7us, 15~ complement @ 8MHz
- ; ; ADD #3,IP ; 2 l tLOW=4,7us, 54~ complement @ 16MHz
- ; ; ADD #4,IP ; 2 l tLOW=4,7us, 90~ complement @ 24MHz
- ; ------------------------------;
- CALL #I2C_MTX ; 4 l to send address
- ; ------------------------------;
- BEGIN ;
- ; ; ADD #0,IP ; 2 l +15~ complement @ 8MHz
- ; ; ADD #0,IP ; 2 l +45~ complement @ 16MHz
- ; ; ADD #0,IP ; 2 l +78~ complement @ 24MHz
- ; CALL #M_TI2C ; wait still tLOW=4,7us
- ; ------------------------------; l
- ; Master TX/RX ACK/NACK ;
- ; ------------------------------; l _
- ; CALL #M_SCL ; SCL _| |_ C flag = NACK
- BIC.B #0x08,&0x204 ; 3 l _^ P1DIR.3 release SCL (high)
- BEGIN ;
- BIT.B #0x08,&0x200 ; 3 h test if SCL is released
- 0<> UNTIL ; 2 h
- BIT.B #0x04,&0x200 ; 3 h _ P1IN.2 : get SDA
- BIS.B #0x08,&0x204 ; 3 h v_ P1DIR.3 as output : force SCL low
- ; ------------------------------; l
- ; I2C_Master_Loop_Data ;
- ; ------------------------------;
- 0<> IF BIS #2,SR ; 5 l if Nack (TX), force Z+1 ==> StopCond
- ELSE SUB.B #1,V ; 3 l else dec count
- THEN ; l
- ; --------------------------;
- ; I2C_Master_CheckCountDown ; count=0 or Nack received
- ; --------------------------;
- 0= IF ; 2 l count reached or Nack
- ; ----------------------;
- ; I2C_Master_StopCond ;
- ; ----------------------; _
- BIS.B #0x04,&0x204 ; SDA |_ P1DIR.2 as output ==> SDA low
- SUB.B V,0(Y) ; 4 l _ refresh buffer length
- BIC.B #0x08,&0x204 ; SCL _| P1DIR.3 release SCL (high)
- BEGIN ;
- BIT.B #0x08,&0x200 ; 3 h SCL released ?
- 0<> UNTIL ; 2 h
- ; CALL #M_TI2C ; _ wait tSU:STO=0.6us
- BIC.B #0x04,&0x204 ; SDA _| P1DIR.2 as input ==> SDA high with pull up resistor
- ; ----------------------;
- ; I2C_Master_Endof ;
- ; ----------------------;
- CMP.B #0,V ; V = 0 <==> count of read bytes = as expected
- = IF
- ; ------------------;
- BIS.B #0x40,&0x0223 ; P4.6 OUT high ==> switch ON LED1 to test
- ; display IR_RC5 command
- SUB #4,PSP ;
- MOV &BASE,2(PSP) ; save base
- MOV TOS,0(PSP) ;
- MOV.B 1(Y),TOS ;
- ASM>FORTH \ ; IP is free
- ['] LCD_CLEAR IS CR
- ['] LCD_WrC IS EMIT
- CR ." 0x" HEX 2 U.R
- ['] (CR) IS CR
- ['] (EMIT) IS EMIT
- FORTH>ASM ; nice code, right ?
- MOV @PSP+,&BASE
- ; endof display
- BIC.B #0x40,&0x0223 ; P4.6 OUT low ==> switch OFF LED1 to test
- THEN
- ; ----------------------;
- RETI ; ====> out of RC5_I2C interrupt toutine
- ; --------------------------;
- THEN ;
- ; --------------------------;
- MOV.B #8,W ; 1 l prepare 8 bits transaction
- BIT #1,&I2CSLV_ADR ; 3 l I2C_Master Read/write bit test
- 0= IF ; 2 l write flag test
- ; ======================;
- ; I2C_Master_TX ;
- ; ======================;
- MOV.B @U+,X ; 2 l next byte to transmit
- ; ; ADD #0,IP ; 2 l tLOW=4,7us, 15~ complement @ 8MHz
- ; ; SUB #3,IP ; 2 l tLOW=4,7us, 36~ complement @ 16MHz
- ; ; SUB #2,IP ; 2 l tLOW=4,7us, 72~ complement @ 24MHz
- ; ----------------------; 17 l
- CALL #I2C_MTX ; Master send 8 bits of address then release SDA
- ; ----------------------; 4 l
- ELSE ; l
- ; ======================;
- ; I2C_Master_RX: ; here, SDA is indetermined, SCL is strech low by master
- ; ======================;
- BEGIN ;
- BIC.B #0x04,&0x204 ; 4 l P1DIR.2 as input ==> release SDA high because pull up resistor
- ; ; ADD #0,IP ; 2 l tLOW=4,7us, 6~ complement @ 8MHz
- ; ; SUB #1,IP ; 2 l tLOW=4,7us, 42~ complement @ 16MHz
- ; ; ADD #1,IP ; 2 l tLOW=4,7us, 81~ complement @ 24MHz
- ; ; CALL #M_TI2C ; wait still tLOW
- ; --------------------; 8 l _
- ; CALL #M_SCL ; SCL _| |_
- BIC.B #0x08,&0x204 ; 3 l _^ P1DIR.3 release SCL (high)
- BEGIN ;
- BIT.B #0x08,&0x200 ; 3 h test if SCL is released
- 0<> UNTIL ; 2 h
- BIT.B #0x04,&0x200 ; 3 h _ P1IN.2 : get SDA
- BIS.B #0x08,&0x204 ; 3 h v_ P1DIR.3 as output : force SCL low
- ; --------------------; 4 l
- ADDC.B X,X ; 1 l C <-- X <--- C
- SUB #1,W ; 1 l count of bits
- 0= UNTIL ; 2 l
- MOV.B X,0(U) ; 3 l store byte @ BUF_ptr
- ADD #1,U ; 1 l
- ; ----------------------;
- ; I2C_MSendAckOrNack ; here, SDA is released by slave, SCL is strech low by master
- ; ----------------------;
- SUB.B #1,V ;
- 0<> IF ; 2
- BIS.B #0x04,&0x204 ; 4 l send Ack if byte count <> 1
- THEN ;
- THEN ;
- AGAIN ; 2 l
- ENDCODE ;
- ; ------------------------------;
- ; PORTA (P2:P1) MSP-EXP430FR5969 default I/O state : input with pullup resistors
- ; init PORTA (P2:P1) usage
- ; P1.0 --> LED2
- ; P1.1 <-- Switch S2
- ; P1.2 <-- SCL Soft MASTER
- ; P1.3 <-- SDA Soft MASTER
- ; P1.4 <-- free
- ; P1.5 <-- free
- ; P1.6 <-> SLAVE SDA
- ; P1.7 --> SLAVE SCL
-
- ; P2.0 --> UART0 TX
- ; P2.1 <-- UART0 RX
- ; P2.2 --> LCD_Vo
- ; P2.3 NC
- ; P2.4 <->
- ; P2.5 -->
- ; P2.6 <--
- ; P2.7 NC
- ; PORTB (P3:P4) MSP-EXP430FR5969 default I/O state : input with pullup resistors
- ; P3.0 <-- ADC12
- ; P3.1 NC
- ; P3.2 NC
- ; P3.3 NC
- ; P3.4 --> LCD_RS
- ; P3.5 --> LCD_RW
- ; P3.6 --> LCD_EN
- ; P3.7 NC
- ; P4.0 <-- TSOP32236 (IR_RC5 receiver)
- ; P4.1 --> UART0 /RTS
- ; P4.2 <--
- ; P4.3 -->
- ; P4.5 <-- Switch S1
- ; P4.6 --> LED1
- ; P4.7 NC
- ; PJ.0 <-- LCD_DB4
- ; PJ.1 <-- LCD_DB5
- ; PJ.2 <-- LCD_DB6
- ; PJ.3 <-- LCD_DB7
- ; PJ.4 <-- LFXIN 32.7638kHz
- ; PJ.5 --> LFXOUT 32.7638kHz
- ; PJ.6 <-> LFXIN free
- ; PJ.7 <-> LFXOUT free
- ; ------------------------------;
- CODE START ; initialize I2C_Soft_Master_to_LCD_2x20
- ; ------------------------------;
- ; ; set TimerB to generate LCD_V0 via TB0.1 and P1.4/P2.6
- ; MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int (8MHZ)
- ; ; MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (8 MHZ)
- ; MOV #1,&0x03E0 ; predivide by 2 in TB0EX0 register (16 MHZ)
- ; ; MOV #2,&0x03E0 ; predivide by 3 in TB0EX0 register (24 MHZ)
- ; MOV #40,&0x3D2 ; TB0CCR0 = 40*0.5us=20us
- ; MOV #0b1100000,&0x3C4 ; TB0CCTL1 output mode = set/reset
- ; MOV #20,&0x3D4 ; TB0CCR1 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
- ; ; ------------------------------;
- ; set TimerB to generate LCD_V0 via TB0.2 and P1.5/P2.2
- MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int (8MHZ)
- MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (8 MHZ)
- ; MOV #1,&0x03E0 ; predivide by 2 in TB0EX0 register (16 MHZ)
- ; MOV #2,&0x03E0 ; predivide by 3 in TB0EX0 register (24 MHZ)
- MOV #40,&0x3D2 ; TB0CCR0 = 40*0.5us=20us
- MOV #0b1100000,&0x3C6 ; TB0CCTL2 output mode = set/reset
- MOV #20,&0x3D6 ; TB0CCR2 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
- ; set TimerB to make 50kHz PWM ;
- ; ------------------------------;
- ; MOV #0b1000010100,&0x3C0 ; TB0CTL = SMCLK/1, up mode, clear timer, no int
- ; MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (1 MHZ) (25 kHz PWM)
- ; ------------------------------;
- ; MOV #0b1000010100,&0x3C0 ; TB0CTL = SMCLK/1, up mode, clear timer, no int
- ; MOV #2,&0x03E0 ; predivide by 2 in TB0EX0 register (4 MHZ)
- ; ------------------------------;
- MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int
- MOV #0,&0x03E0 ; predivide by 1 in TB0EX0 register (8 MHZ)
- ; ------------------------------;
- ; MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int
- ; MOV #1,&0x03E0 ; predivide by 2 in TB0EX0 register (16 MHZ)
- ; ------------------------------;
- ; MOV #0b1010010100,&0x3C0 ; TB0CTL = SMCLK/4, up mode, clear timer, no int
- ; MOV #3,&0x03E0 ; predivide by 3 in TB0EX0 register (24 MHZ)
- ; ------------------------------;
- MOV #40,&0x3D2 ; TB0CCR0 = 40*0.5us=20us (40us @ 1MHz)
- ; ------------------------------;
- ; set TimerB to generate LCD_V0 via TB0.2 and P1.5/P2.2
- ; ------------------------------;
- MOV #0b1100000,&0x3C6 ; TB0CCTL2 output mode = set/reset ; clear CCIFG
- MOV #20,&0x3D6 ; TB0CCR2 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
- ; ------------------------------;
- ; set TimerB to generate LCD_V0 via TB0.1 and P1.4/P2.6
- ; ------------------------------;
- ; MOV #0b1100000,&0x3C4 ; TB0CCTL1 output mode = set/reset
- ; MOV #20,&0x3D4 ; TB0CCR1 ; contrast adjust : 20/40 ==> LCD_Vo = -1V1
- ; ------------------------------;
- ; I2C_MASTER init part ;
- ; ------------------------------;
- MOV #0b0010100,&I2CSLV_ADR ; MSP430FR5738 slave address
- BIS #1,&I2CSLV_ADR ; to read slave
- MOV #1,&I2CM_IN ; one data expected
- ; ------------------------------;
- ; WDT interval init part ;
- ; ------------------------------;
- ; MOV #0x5A5E,&0x15C ; init WDT Vloclk source 10kHz /2^9 (50 ms), interval mode
- ; MOV #0x5A5D,&0x15C ; init WDT Vloclk source 10kHz /2^13 (820 ms), interval mode
- ; ------------------------------;
- BIS.B #0x10,&0x32A ; PJSEL0.4 = 1 starts LFXT on ACLK
- MOV #0x5A3D,&0x15C ; init WDT ACLK source 32.768kHz /2^13 (250 ms), interval mode
- ; ------------------------------;
- BIS #1,&0x100 ; enable WDT interval mode interrupt in SFRIE
- ; ------------------------------;
- ; init interrupt vectors
- MOV #I2C_M,&0xFFF2 ; init WDT interval vector interrupt
- MOV #INT_P1,&0xFFDE ; init P1 interrupt vector
- MOV #INT_P4,&0xFFD0 ; init P4 interrupt vector
- ; ------------------------------;
- ; init PORTA (P2:P1) (complement) when reset occurs all I/O are set in input with resistors pullup
- BIC.B #0x0C,&0x202 ; P1OUT.23 preset SDA + SCL output low
- BIC.B #0x0C,&0x206 ; P1REN.23 SDA + SCL pullup/down disable
- BIS.B #0x02,&0x218 ; P1IES.1 high to low edge select (S2)
- BIC.B #0x02,&0x21C ; P1IFG.1 clear (after IES select) (S2)
- BIS.B #0x02,&0x21A ; P1IE.1 enable interrupt (S2)
- BIS.B #0x04,&0x205 ; P2DIR.2 TB0.2 output
- BIS.B #0x04,&0x20B ; P2SEL0.2 TB0.2
- ; ------------------------------;
- ; init PORTB (P4:P3) (complement) when reset occurs all I/O are set in input with resistors pullup
- BIS.B #0x70,&0x224 ; P3DIR.456 as outputs, wired to LCD_RS LCD_RW LCD_EN
- BIC.B #0x70,&0x226 ; P3REN.456 LCD_RS, LCD_RW, LCD_EN, pullup/down disable
- BIC.B #0x30,&0x222 ; P3OUT.45 LCD_RW = LCD_RS = 0
- BIS.B #0x20,&0x239 ; P4IES.5 high to low edge select
- BIC.B #0x20,&0x23D ; P4IFG.5 clear (after IES select)
- BIS.B #0x20,&0x23B ; P4IE.5 enable interrupt for S1
- ; ------------------------------;
- ; init PORTJ (PJ) (complement) when reset occurs all I/O are set in input with resistors pullup
- BIS.B #0x0F,&0x324 ; PJDIR.0123 as output, wired to DB.4567 LCD_Data
- BIC.B #0x0F,&0x326 ; PJREN.0123 LCD_Data pullup/down disable
- ; ------------------------------;
- ; Init LCD 2x20 ;
- ; ------------------------------;
- ASM>FORTH
- 0x03E8 20_us \ ; 1- wait 20 ms
- 0x03 TOP_LCD \ ; 2- send DB5=DB4=1
- 0xCD 20_us \ ; 3- wait 4,1 ms
- 0x03 TOP_LCD \ ; 4- send again DB5=DB4=1
- 5 20_us \ ; 5- wait 0,1 ms
- 0x03 TOP_LCD \ ; 6- send again again DB5=DB4=1
- 2 20_us \ ; wait 40 us = LCD cycle
- 0x02 TOP_LCD \ ; 7- send DB5=1 DB4=0
- 2 20_us \ ; wait 40 us = LCD cycle
- 0x28 LCD_WrF \ ; 8- 0b001DNFxx "FonctionSet" : D=8/4 DataBus width, Number of lines=2/1, Font bold/normal
- 0x08 LCD_WrF \ ; 9- 0b1DCB "DisplayControl" : Display off, Cursor off, Blink off.
- LCD_Clear \ ; 10- "LCD_Clear"
- 0x06 LCD_WrF \ ; 11- 0b01xx "LCD_EntrySet" : address and cursor shift after writing in RAM
- 0x0C LCD_WrF \ ; 12- 0b1DCB "DisplayControl" : Display on, Cursor off, Blink off.
- ['] LCD_WrC IS EMIT \ ;EMIT is redirected to LCD_WrC
- ." SYSRSTIV = " \ ;
- 0x1800 @ \ ;print SAVE_SYSRSTIV
- HEX 2 U.R \ ;(WARM) reinit decimal BASE and reset SAVE_SYSRSTIV
- ['] (EMIT) IS EMIT \ ;restore EMIT
- ." Type STOP to quit I2C_Fast_SoftMaster_to_LCD"
- LIT RECURSE IS WARM \ ; redirect WARM to START...
- (WARM) ; ; ...and finish START with (WARM)
- CODE STOP
- MOV #0b1010000100,&0x3C0 ; TB0CTL = SMCLK/4, STOP mode, clear timer, no int
- BIC.B #0x02,&0x21A ; P1IE.1 disable interrupt for S2
- BIC.B #0x20,&0x23B ; P4IE.5 disable interrupt for S1
- BIC #1,&0x100 ; disable WDT interval mode interrupt in SFRIE
- ASM>FORTH
- ['] (WARM) IS WARM \ ; reconnect WARM to (WARM)
- -1 ABORT"
- ; ; above, ABORT" followed by CRLF allows to compile an empty string...
- ; DUP HERE SWAP - DUMP ; general minidump, part 2
- FORGET INT_P1 FORGET INT_P4 ; not FORTH executable
- FORGET I2C_MTX FORGET I2C_M ; because not FORTH executable
- FORGET 20_us FORGET LCD_W ; because they are not necessary
- FORGET LCD_R FORGET TOP_LCD ; because they are not necessary
- ECHO
- RST_HERE
- START