1 \ name : msp430FR5xxx_I2C_Master.asm
3 \ Copyright (C) <2016> <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 \ I2C MASTER Standard Mode software driver without interrupt
20 \ Target: MSP-EXP430FR5969 @ 8,16MHz
21 \ version 1.1 2016-03-18
23 \ ---------------------------------------------------------------------------------------------------------------------;
24 \ SCL clock generation, timing, and test of data(s) number are made by I2C_Master.
25 \ slave can strech SCL low after Start Condition and after any bit.
27 \ address Ack/Nack is generated by the slave on SDA line (released by the master)
28 \ Two groups of eight addresses (000$xxy and 1111xxxy) are not allowed (reserved)
29 \ after address or data is sent, the transmitter (Master or Slave) must release SDA line to allow (N)Ack by the receiver
30 \ data Ack/Nack are generated by the receiver (master or slave) on SDA line
31 \ a master receiver must signal the end of data to the slave transmitter by sending a Nack bit
32 \ Stop or restart conditions must be generated by master after a Nack bit.
33 \ after Ack bit is sent, Slave must release SDA line to allow master to do stop or restart conditions
35 \ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK _
36 \ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X___/
37 \ _____ _ _ _ _ _ _ _ _ _ _ ___
38 \ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/
40 \ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
42 \ |Start Condition |stoP Condition
44 \ __ _____ _____ _..._ _____ _____ _NACK _____ _____ _..._ _____ _____ _NACK ___
45 \ SDA \____/_MSB_X_____X_..._X_LSB_X_R/W_x_ACK_x_MSB_X_____X_..._X_____X_LSB_X_ACK_X \____...
46 \ _____ _ _ _ _ _ _ _ _ _ _ ____
47 \ SCL \___/1\___/2\___...___/7\___/8\___/9\___/1\___/2\___...___/7\___/8\___/9\___/ \_...
49 \ | |Slave Stretch Low |SSL |SSL |SSL |SSL |
51 \ |Start Condition |reStart Condition
53 \ tHIGH : SCL high time
55 \ tBUF : SDA high time between Stop and Start conditions
56 \ tHD:STA : Start_Condition SCL high time after SDA is low
57 \ tSU:STO : Stop_Condition SCL high time before SDA rise
58 \ tSU:STA : Start_Condition SCL high time before SDA fall
59 \ tHD:DAT : SDA data change time after SCL is low
60 \ the SDA line must be strobe just after SCL is high
61 \ the SDA data must be change just after SCL is low
62 \ standard mode (up to 100 kHz) : tHIGH = tHD:STA = tSU:STO = 4µs
63 \ tLOW = tSU:STA = tBUF = 4,7µs
66 \ fast mode (up to 400 kHz) : tHIGH = tHD:STA = tSU:STO = 0,6µs
67 \ tLOW = tSU:STA = tBUF = 1,3µs
69 \ -------------------------------------------------------------------------------------------------------------------;
71 \ =================================================================
72 \ =================================================================
75 \ # # # # # ## ## ## #### ##### ###### #####
76 \ # # # # # # # # # # # # # #
77 \ # ##### # # # # # # #### # ##### # #
78 \ # # # # # ###### # # # #####
79 \ # # # # # # # # # # # # # #
80 \ ### ####### ##### # # # # #### # ###### # #
82 \ =================================================================
83 \ =================================================================
85 \ tested with P1.6 SDA, P1.7 SCL :
86 \ Start + Adr + Write 3 bytes + Stop + Start + adr + read 2 bytes + stop = 204us ==> 308 kHz (STOP=10us)
87 \ See MSP430FR5xxx_I2C_Master.png
91 VARIABLE I2CS_ADR \ low(I2CS_ADR) = slave I2C address with RW flag, high(I2CS_ADR) = RX buffer,data0
93 VARIABLE I2CM_BUF \ low(I2CM_BUF) = RX or TX lentgh, high(I2CM_BUF) = TX buffer,data0
99 \ ----------------------------------\
101 \ ----------------------------------\
102 \ \ in I2CS_ADR/I2CM_BUF as RX/TX buffer requested by I2CS_ADR(0(0))
103 \ \ I2CS_ADR(0) = I2C_Slave_addr&R/w
104 \ \ I2CM_BUF(0) = TX/RX count of datas
105 \ \ I2CM_BUF(0) = 0 ==> send only I2C address
108 \ \ out I2CSLA_ADR & (R/W) unCHNGd
109 \ \ S = BUF PTR pointing on first data not exCHNGd
110 \ \ T = count of TX/RX datas exCHNGd
111 \ \ T = -1 ==> NACK on address
112 \ \ I2CS_ADR(0) = unCHNGd
113 \ \ I2CM_BUF(0) = unCHNGd
114 BIS #1,&UCB0CTLW0 \ SWRST
115 MOV #$0FD3,&UCB0CTLW0 \ master mode + UCTR + START + SWRST, IFG=IE=0
116 MOV #$00C8,&UCB0CTLW1 \ set automatic stop (count byte reached)
117 MOV #$14,&UCB0BRW \ baudrate = SMCLK/20 = 400 kHz @8MHz ; 340 kHz measured
118 MOV #I2CM_BUF,S \ count & TX buf
119 MOV.B @S+,&UCB0TBCNT \
120 CMP.B #0,&UCB0TBCNT \
122 BIS #4,&UCB0CTLW0 \ add Stop cmd to Start cmd ==> Master send only I2C address
124 MOV #I2CS_ADR,T \ I2Cadr & RX buf
125 MOV.B @T+,&UCB0I2CSA \ UCB0I2CSA = slave_address & R/w bit
126 RRA &UCB0I2CSA \ UCB0I2CSA = slave_address, C flag = R/w flag
128 MOV T,S \ Master read : S = RX buffer
129 BIC #$10,&UCB0CTLW0 \ UCB0CTLW0 <-- UCTR=0
131 \ ------------------------------ \
133 \ ------------------------------ \
135 BIC #1,&UCB0CTLW0 \ UCB0CTLW0 : clear SWRST, start I2C MASTER
136 BIT.B #1,&I2CS_ADR \ R/W test
138 \ ---------------------------- \
140 \ ---------------------------- \
142 MOV.B &UCBCNT0,T \ store count of byte
143 BIT #8,&UCB0IFG \ test UCSTPIFG
145 MOV @RSP+,PC \ end of I2C_M TX driver
147 BIT #$20,&UCB0IFG \ test UCNACKIFG
149 BIS #4,&UCB0CTLW0 \ generate stop bit
150 MOV @RSP+,PC \ end of I2C_M TX driver
152 BIT #2,&UCB0IFG \ test UCTXIFG0
154 MOV.B @S+,&UCB0TXBUF \ load data into UCB0TXBUF
158 \ ------------------------------ \
160 \ ------------------------------ \
162 MOV.B &UCBCNT0,T \ store count of byte
163 BIT #8,&UCB0IFG \ test UCSTPIFG
165 MOV @RSP+,PC \ end of I2C_M RX driver
167 BIT #1,&UCB0IFG \ test UCRXIFG0
169 MOV.B &UCB0RXBUF,0(S) \ load data from UCB0RXBUF
173 ENDASM \ 62 words + 9 init words
176 \ ------------------------------\
178 \ ------------------------------\
180 \ ------------------------------\
181 \ %0000 1111 1101 0011 $640 = $0FD3
182 \ - UCMM = 1 : multi master mode
183 \ - UCMST = 1 : I2C_Master
184 \ -- UCMODE = %11 = I2C
185 \ _ USYNC=1 (always 1)
186 \ -- UCSSEL=SMCLK=8MHz
187 \ - UCTXACK=0 not auto ACK slave address
188 \ - UCTR=1/0 : TX/RX modes
190 \ - UCTXSTT send start
192 \ ------------------------------\
193 \ %0000 0000 1100 1000 $642 = $00C8
194 \ - UCETXINT=0 : UCTXIFG0 set address match UCxI2COAx and TX mode
195 \ -- UCCLTO=%11 : SCL low time out = 34 ms
196 \ - UCSWACK=1 : UCTXACK must be written to continue
197 \ -- UCASTP0=%10 : automatic Stop when UCBxTBCNT is reached
198 \ ------------------------------\
199 \ PORTX (PORTx:y) default values\ DIR0,REN1,OUT1 (input with pullup resistors)
200 \ ------------------------------\
201 \ notice : UCB0 I2C driver seems to control only DIR register !!!
202 BIC.B #M_BUS,&I2CM_REN \ REN0 : no_resistor
203 BIC.B #M_BUS,&I2CM_OUT \ OUT0 : preset output low
204 BIS.B #M_BUS,&I2CM_SEL1 \ SEL11 : enable I2C I/O
206 ." type stop to stop :-)"
207 LIT RECURSE IS WARM \ insert this starting routine between COLD and WARM...
208 (WARM) \ ...and continue with (WARM)
211 : STOP \ stops multitasking, must to be used before downloading app
212 ['] (WARM) IS WARM \ remove START app from FORTH init process
213 ECHO COLD \ reset CPU, interrupt vectors, and start FORTH