1 /* --COPYRIGHT--,BSD
2  * Copyright (c) 2017, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * --/COPYRIGHT--*/
32 #include <ti/devices/msp432p4xx/driverlib/i2c.h>
33 #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
34 #include <ti/devices/msp432p4xx/driverlib/debug.h>
35 
I2C_initMaster(uint32_t moduleInstance,const eUSCI_I2C_MasterConfig * config)36 void I2C_initMaster(uint32_t moduleInstance,
37         const eUSCI_I2C_MasterConfig *config)
38 {
39     uint_fast16_t preScalarValue;
40 
41     ASSERT(
42             (EUSCI_B_I2C_CLOCKSOURCE_ACLK == config->selectClockSource)
43                     || (EUSCI_B_I2C_CLOCKSOURCE_SMCLK
44                             == config->selectClockSource));
45 
46     ASSERT(
47             (EUSCI_B_I2C_SET_DATA_RATE_400KBPS == config->dataRate)
48                     || (EUSCI_B_I2C_SET_DATA_RATE_100KBPS == config->dataRate)
49                     || (EUSCI_B_I2C_SET_DATA_RATE_1MBPS == config->dataRate));
50 
51     ASSERT(
52             (EUSCI_B_I2C_NO_AUTO_STOP == config->autoSTOPGeneration)
53                     || (EUSCI_B_I2C_SET_BYTECOUNT_THRESHOLD_FLAG
54                             == config->autoSTOPGeneration)
55                     || (EUSCI_B_I2C_SEND_STOP_AUTOMATICALLY_ON_BYTECOUNT_THRESHOLD
56                             == config->autoSTOPGeneration));
57 
58     /* Disable the USCI module and clears the other bits of control register */
59     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
60             1;
61 
62     /* Configure Automatic STOP condition generation */
63     EUSCI_B_CMSIS(moduleInstance)->CTLW1 = (EUSCI_B_CMSIS(moduleInstance)->CTLW1
64             & ~EUSCI_B_CTLW1_ASTP_MASK) | (config->autoSTOPGeneration);
65 
66     /* Byte Count Threshold */
67     EUSCI_B_CMSIS(moduleInstance)->TBCNT = config->byteCounterThreshold;
68 
69     /*
70      * Configure as I2C master mode.
71      * UCMST = Master mode
72      * UCMODE_3 = I2C mode
73      * UCSYNC = Synchronous mode
74      */
75     EUSCI_B_CMSIS(moduleInstance)->CTLW0 = (EUSCI_B_CMSIS(moduleInstance)->CTLW0
76             & ~EUSCI_B_CTLW0_SSEL_MASK)
77             | (config->selectClockSource | EUSCI_B_CTLW0_MST
78                     | EUSCI_B_CTLW0_MODE_3 | EUSCI_B_CTLW0_SYNC
79                     | EUSCI_B_CTLW0_SWRST);
80 
81     /*
82      * Compute the clock divider that achieves the fastest speed less than or
83      * equal to the desired speed.  The numerator is biased to favor a larger
84      * clock divider so that the resulting clock is always less than or equal
85      * to the desired clock, never greater.
86      */
87     preScalarValue = (uint16_t) (config->i2cClk / config->dataRate);
88 
89     EUSCI_B_CMSIS(moduleInstance)->BRW = preScalarValue;
90 }
91 
I2C_initSlave(uint32_t moduleInstance,uint_fast16_t slaveAddress,uint_fast8_t slaveAddressOffset,uint32_t slaveOwnAddressEnable)92 void I2C_initSlave(uint32_t moduleInstance, uint_fast16_t slaveAddress,
93         uint_fast8_t slaveAddressOffset, uint32_t slaveOwnAddressEnable)
94 {
95     ASSERT(
96             (EUSCI_B_I2C_OWN_ADDRESS_OFFSET0 == slaveAddressOffset)
97                     || (EUSCI_B_I2C_OWN_ADDRESS_OFFSET1 == slaveAddressOffset)
98                     || (EUSCI_B_I2C_OWN_ADDRESS_OFFSET2 == slaveAddressOffset)
99                     || (EUSCI_B_I2C_OWN_ADDRESS_OFFSET3 == slaveAddressOffset));
100 
101     /* Disable the USCI module */
102     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
103             1;
104 
105     /* Clear USCI master mode */
106     EUSCI_B_CMSIS(moduleInstance)->CTLW0 = (EUSCI_B_CMSIS(moduleInstance)->CTLW0
107             & (~EUSCI_B_CTLW0_MST))
108             | (EUSCI_B_CTLW0_MODE_3 + EUSCI_B_CTLW0_SYNC);
109 
110     /* Set up the slave address. */
111     HWREG16(
112             (uint32_t) &EUSCI_B_CMSIS(moduleInstance)->I2COA0
113                     + slaveAddressOffset) = slaveAddress
114             + slaveOwnAddressEnable;
115 }
116 
I2C_enableModule(uint32_t moduleInstance)117 void I2C_enableModule(uint32_t moduleInstance)
118 {
119     /* Reset the UCSWRST bit to enable the USCI Module */
120     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
121             0;
122 }
123 
I2C_disableModule(uint32_t moduleInstance)124 void I2C_disableModule(uint32_t moduleInstance)
125 {
126     /* Set the UCSWRST bit to disable the USCI Module */
127     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
128             1;
129     ;
130 }
131 
I2C_setSlaveAddress(uint32_t moduleInstance,uint_fast16_t slaveAddress)132 void I2C_setSlaveAddress(uint32_t moduleInstance, uint_fast16_t slaveAddress)
133 {
134     /* Set the address of the slave with which the master will communicate */
135     EUSCI_B_CMSIS(moduleInstance)->I2CSA = (slaveAddress);
136 }
137 
I2C_setMode(uint32_t moduleInstance,uint_fast8_t mode)138 void I2C_setMode(uint32_t moduleInstance, uint_fast8_t mode)
139 {
140     ASSERT(
141             (EUSCI_B_I2C_TRANSMIT_MODE == mode)
142                     || (EUSCI_B_I2C_RECEIVE_MODE == mode));
143 
144     EUSCI_B_CMSIS(moduleInstance)->CTLW0 = (EUSCI_B_CMSIS(moduleInstance)->CTLW0
145             & (~EUSCI_B_I2C_TRANSMIT_MODE)) | mode;
146 
147 }
148 
I2C_masterReceiveSingleByte(uint32_t moduleInstance)149 uint8_t I2C_masterReceiveSingleByte(uint32_t moduleInstance)
150 {
151     //Set USCI in Receive mode
152     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TR_OFS) =
153             0;
154 
155     //Send start
156     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= (EUSCI_B_CTLW0_TXSTT
157             + EUSCI_B_CTLW0_TXSTP);
158 
159     //Poll for receive interrupt flag.
160     while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
161             EUSCI_B_IFG_RXIFG_OFS))
162         ;
163 
164     //Send single byte data.
165     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
166 }
167 
I2C_slavePutData(uint32_t moduleInstance,uint8_t transmitData)168 void I2C_slavePutData(uint32_t moduleInstance, uint8_t transmitData)
169 {
170     //Send single byte data.
171     EUSCI_B_CMSIS(moduleInstance)->TXBUF = transmitData;
172 }
173 
I2C_slaveGetData(uint32_t moduleInstance)174 uint8_t I2C_slaveGetData(uint32_t moduleInstance)
175 {
176     //Read a byte.
177     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
178 }
179 
I2C_isBusBusy(uint32_t moduleInstance)180 uint8_t I2C_isBusBusy(uint32_t moduleInstance)
181 {
182     //Return the bus busy status.
183     return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->STATW,
184             EUSCI_B_STATW_BBUSY_OFS);
185 }
186 
I2C_masterSendSingleByte(uint32_t moduleInstance,uint8_t txData)187 void I2C_masterSendSingleByte(uint32_t moduleInstance, uint8_t txData)
188 {
189     //Store current TXIE status
190     uint16_t txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
191 
192     //Disable transmit interrupt enable
193     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
194 
195     //Send start condition.
196     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
197             + EUSCI_B_CTLW0_TXSTT;
198 
199     //Poll for transmit interrupt flag and start condition flag.
200     while ((BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
201                 EUSCI_B_CTLW0_TXSTT_OFS)
202                 || !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
203                         EUSCI_B_IFG_TXIFG0_OFS)));
204 
205     //Send single byte data.
206     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
207 
208     //Poll for transmit interrupt flag.
209     while (!(EUSCI_B_CMSIS(moduleInstance)->IFG & EUSCI_B_IFG_TXIFG))
210         ;
211 
212     //Send stop condition.
213     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TXSTP;
214 
215     //Clear transmit interrupt flag before enabling interrupt again
216     EUSCI_B_CMSIS(moduleInstance)->IFG &= ~(EUSCI_B_IFG_TXIFG);
217 
218     //Reinstate transmit interrupt enable
219     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
220 }
221 
I2C_masterSendSingleByteWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)222 bool I2C_masterSendSingleByteWithTimeout(uint32_t moduleInstance,
223         uint8_t txData, uint32_t timeout)
224 {
225     uint_fast16_t txieStatus;
226     uint32_t timeout2 = timeout;
227 
228     ASSERT(timeout > 0);
229 
230     //Store current TXIE status
231     txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
232 
233     //Disable transmit interrupt enable
234     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
235 
236     //Send start condition.
237     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
238             + EUSCI_B_CTLW0_TXSTT;
239 
240     //Poll for transmit interrupt flag.
241     while ((!(EUSCI_B_CMSIS(moduleInstance)->IFG & EUSCI_B_IFG_TXIFG))
242             && --timeout)
243         ;
244 
245     //Check if transfer timed out
246     if (timeout == 0)
247         return false;
248 
249     //Send single byte data.
250     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
251 
252     //Poll for transmit interrupt flag.
253     while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
254             EUSCI_B_IFG_TXIFG0_OFS)) && --timeout2)
255         ;
256 
257     //Check if transfer timed out
258     if (timeout2 == 0)
259         return false;
260 
261     //Send stop condition.
262     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
263             1;
264 
265     //Clear transmit interrupt flag before enabling interrupt again
266     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS) =
267             0;
268 
269     //Reinstate transmit interrupt enable
270     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
271 
272     return true;
273 }
274 
I2C_masterSendMultiByteStart(uint32_t moduleInstance,uint8_t txData)275 void I2C_masterSendMultiByteStart(uint32_t moduleInstance, uint8_t txData)
276 {
277     //Store current transmit interrupt enable
278     uint16_t txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
279 
280     //Disable transmit interrupt enable
281     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
282 
283     //Send start condition.
284     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
285             + EUSCI_B_CTLW0_TXSTT;
286 
287     //Poll for transmit interrupt flag and start condition flag.
288     while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
289                 EUSCI_B_CTLW0_TXSTT_OFS)
290                 || !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
291                         EUSCI_B_IFG_TXIFG0_OFS));
292 
293     //Send single byte data.
294     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
295 
296     //Reinstate transmit interrupt enable
297     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
298 }
299 
I2C_masterSendMultiByteStartWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)300 bool I2C_masterSendMultiByteStartWithTimeout(uint32_t moduleInstance,
301         uint8_t txData, uint32_t timeout)
302 {
303     uint_fast16_t txieStatus;
304 
305     ASSERT(timeout > 0);
306 
307     //Store current transmit interrupt enable
308     txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
309 
310     //Disable transmit interrupt enable
311     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
312 
313     //Send start condition.
314     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
315             + EUSCI_B_CTLW0_TXSTT;
316 
317     //Poll for transmit interrupt flag and start condition flag.
318     while ((BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
319                 EUSCI_B_CTLW0_TXSTT_OFS)
320                 || !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
321                         EUSCI_B_IFG_TXIFG0_OFS)) && --timeout);
322 
323 
324     //Check if transfer timed out
325     if (timeout == 0)
326         return false;
327 
328     //Send single byte data.
329     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
330 
331     //Reinstate transmit interrupt enable
332     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
333 
334     return true;
335 }
336 
I2C_masterSendMultiByteNext(uint32_t moduleInstance,uint8_t txData)337 void I2C_masterSendMultiByteNext(uint32_t moduleInstance, uint8_t txData)
338 {
339     //If interrupts are not used, poll for flags
340     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
341     {
342         //Poll for transmit interrupt flag.
343         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
344                 EUSCI_B_IFG_TXIFG0_OFS))
345             ;
346     }
347 
348     //Send single byte data.
349     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
350 }
351 
I2C_masterSendMultiByteNextWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)352 bool I2C_masterSendMultiByteNextWithTimeout(uint32_t moduleInstance,
353         uint8_t txData, uint32_t timeout)
354 {
355     ASSERT(timeout > 0);
356 
357     //If interrupts are not used, poll for flags
358     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
359     {
360         //Poll for transmit interrupt flag.
361         while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
362                 EUSCI_B_IFG_TXIFG0_OFS)) && --timeout)
363             ;
364 
365         //Check if transfer timed out
366         if (timeout == 0)
367             return false;
368     }
369 
370     //Send single byte data.
371     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
372 
373     return true;
374 }
375 
I2C_masterSendMultiByteFinish(uint32_t moduleInstance,uint8_t txData)376 bool I2C_masterSendMultiByteFinish(uint32_t moduleInstance, uint8_t txData)
377 {
378     //If interrupts are not used, poll for flags
379     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
380     {
381         //Poll for transmit interrupt flag.
382         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
383                 EUSCI_B_IFG_TXIFG0_OFS))
384             ;
385     }
386 
387     //Send single byte data.
388     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
389 
390     //Poll for transmit interrupt flag.
391     while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
392             EUSCI_B_IFG_TXIFG0_OFS)
393             && !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
394                     EUSCI_B_IFG_NACKIFG_OFS))
395         ;
396     if(BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_NACKIFG_OFS))
397         return false;
398 
399     //Send stop condition.
400     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
401             1;
402 
403     return true;
404 }
405 
I2C_masterSendMultiByteFinishWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)406 bool I2C_masterSendMultiByteFinishWithTimeout(uint32_t moduleInstance,
407         uint8_t txData, uint32_t timeout)
408 {
409     uint32_t timeout2 = timeout;
410 
411     ASSERT(timeout > 0);
412 
413     //If interrupts are not used, poll for flags
414     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
415     {
416         //Poll for transmit interrupt flag.
417         while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
418                 EUSCI_B_IFG_TXIFG0_OFS)) && --timeout)
419             ;
420 
421         //Check if transfer timed out
422         if (timeout == 0)
423             return false;
424     }
425 
426     //Send single byte data.
427     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
428 
429     //Poll for transmit interrupt flag.
430     while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
431             EUSCI_B_IFG_TXIFG0_OFS)) && --timeout2
432             && !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
433                     EUSCI_B_IFG_NACKIFG_OFS))
434         ;
435 
436     //Check if transfer timed out
437     if (timeout2 == 0)
438         return false;
439 
440     //Send stop condition.
441     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
442             1;
443 
444     return true;
445 }
446 
I2C_masterSendMultiByteStop(uint32_t moduleInstance)447 void I2C_masterSendMultiByteStop(uint32_t moduleInstance)
448 {
449     //If interrupts are not used, poll for flags
450     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
451     {
452         //Poll for transmit interrupt flag.
453         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
454                 EUSCI_B_IFG_TXIFG0_OFS))
455             ;
456     }
457 
458     //Send stop condition.
459     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
460             1;
461 }
462 
I2C_masterSendMultiByteStopWithTimeout(uint32_t moduleInstance,uint32_t timeout)463 bool I2C_masterSendMultiByteStopWithTimeout(uint32_t moduleInstance,
464         uint32_t timeout)
465 {
466     ASSERT(timeout > 0);
467 
468     //If interrupts are not used, poll for flags
469     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
470     {
471         //Poll for transmit interrupt flag.
472         while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
473                 EUSCI_B_IFG_TXIFG0_OFS)) && --timeout)
474             ;
475 
476         //Check if transfer timed out
477         if (timeout == 0)
478             return false;
479     }
480 
481     //Send stop condition.
482     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
483             1;
484 
485     return 0x01;
486 }
487 
I2C_masterReceiveStart(uint32_t moduleInstance)488 void I2C_masterReceiveStart(uint32_t moduleInstance)
489 {
490     //Set USCI in Receive mode
491     EUSCI_B_CMSIS(moduleInstance)->CTLW0 = (EUSCI_B_CMSIS(moduleInstance)->CTLW0
492             & (~EUSCI_B_CTLW0_TR)) | EUSCI_B_CTLW0_TXSTT;
493 }
494 
I2C_masterReceiveMultiByteNext(uint32_t moduleInstance)495 uint8_t I2C_masterReceiveMultiByteNext(uint32_t moduleInstance)
496 {
497     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
498 }
499 
I2C_masterReceiveMultiByteFinish(uint32_t moduleInstance)500 uint8_t I2C_masterReceiveMultiByteFinish(uint32_t moduleInstance)
501 {
502     //Send stop condition.
503     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
504             1;
505 
506     //Wait for Stop to finish
507     while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
508             EUSCI_B_CTLW0_TXSTP_OFS))
509     {
510         // Wait for RX buffer
511         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
512                 EUSCI_B_IFG_RXIFG_OFS))
513             ;
514     }
515 
516     /* Capture data from receive buffer after setting stop bit due to
517      MSP430 I2C critical timing. */
518     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
519 }
520 
I2C_masterReceiveMultiByteFinishWithTimeout(uint32_t moduleInstance,uint8_t * txData,uint32_t timeout)521 bool I2C_masterReceiveMultiByteFinishWithTimeout(uint32_t moduleInstance,
522         uint8_t *txData, uint32_t timeout)
523 {
524     uint32_t timeout2 = timeout;
525 
526     ASSERT(timeout > 0);
527 
528     //Send stop condition.
529     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
530             1;
531 
532     //Wait for Stop to finish
533     while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
534             EUSCI_B_CTLW0_TXSTP_OFS) && --timeout)
535         ;
536 
537     //Check if transfer timed out
538     if (timeout == 0)
539         return false;
540 
541     // Wait for RX buffer
542     while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
543             EUSCI_B_IFG_RXIFG_OFS)) && --timeout2)
544         ;
545 
546     //Check if transfer timed out
547     if (timeout2 == 0)
548         return false;
549 
550     //Capture data from receive buffer after setting stop bit due to
551     //MSP430 I2C critical timing.
552     *txData = (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
553 
554     return true;
555 }
556 
I2C_masterReceiveMultiByteStop(uint32_t moduleInstance)557 void I2C_masterReceiveMultiByteStop(uint32_t moduleInstance)
558 {
559     //Send stop condition.
560     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
561             1;
562 }
563 
I2C_masterReceiveSingle(uint32_t moduleInstance)564 uint8_t I2C_masterReceiveSingle(uint32_t moduleInstance)
565 {
566     //Polling RXIFG0 if RXIE is not enabled
567     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_RXIE0_OFS))
568     {
569         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
570                 EUSCI_B_IFG_RXIFG0_OFS))
571             ;
572     }
573 
574     //Read a byte.
575     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
576 }
577 
I2C_getReceiveBufferAddressForDMA(uint32_t moduleInstance)578 uint32_t I2C_getReceiveBufferAddressForDMA(uint32_t moduleInstance)
579 {
580     return (uint32_t) &EUSCI_B_CMSIS(moduleInstance)->RXBUF;
581 }
582 
I2C_getTransmitBufferAddressForDMA(uint32_t moduleInstance)583 uint32_t I2C_getTransmitBufferAddressForDMA(uint32_t moduleInstance)
584 {
585     return (uint32_t) &EUSCI_B_CMSIS(moduleInstance)->TXBUF;
586 }
587 
I2C_masterIsStopSent(uint32_t moduleInstance)588 uint8_t I2C_masterIsStopSent(uint32_t moduleInstance)
589 {
590     return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
591             EUSCI_B_CTLW0_TXSTP_OFS);
592 }
593 
I2C_masterIsStartSent(uint32_t moduleInstance)594 bool I2C_masterIsStartSent(uint32_t moduleInstance)
595 {
596     return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
597             EUSCI_B_CTLW0_TXSTT_OFS);
598 }
599 
I2C_masterSendStart(uint32_t moduleInstance)600 void I2C_masterSendStart(uint32_t moduleInstance)
601 {
602     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTT_OFS) =
603             1;
604 }
605 
I2C_enableMultiMasterMode(uint32_t moduleInstance)606 void I2C_enableMultiMasterMode(uint32_t moduleInstance)
607 {
608     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
609             1;
610     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_MM_OFS) =
611             1;
612 }
613 
I2C_disableMultiMasterMode(uint32_t moduleInstance)614 void I2C_disableMultiMasterMode(uint32_t moduleInstance)
615 {
616     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
617             1;
618     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_MM_OFS) =
619             0;
620 }
621 
I2C_enableInterrupt(uint32_t moduleInstance,uint_fast16_t mask)622 void I2C_enableInterrupt(uint32_t moduleInstance, uint_fast16_t mask)
623 {
624     ASSERT(
625             0x00
626                     == (mask
627                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
628                                     + EUSCI_B_I2C_START_INTERRUPT
629                                     + EUSCI_B_I2C_NAK_INTERRUPT
630                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
631                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
632                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
633                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
634                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
635                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
636                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
637                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
638                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
639                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
640                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
641                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
642 
643     //Enable the interrupt masked bit
644     EUSCI_B_CMSIS(moduleInstance)->IE |= mask;
645 }
646 
I2C_disableInterrupt(uint32_t moduleInstance,uint_fast16_t mask)647 void I2C_disableInterrupt(uint32_t moduleInstance, uint_fast16_t mask)
648 {
649     ASSERT(
650             0x00
651                     == (mask
652                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
653                                     + EUSCI_B_I2C_START_INTERRUPT
654                                     + EUSCI_B_I2C_NAK_INTERRUPT
655                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
656                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
657                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
658                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
659                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
660                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
661                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
662                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
663                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
664                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
665                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
666                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
667 
668     //Disable the interrupt masked bit
669     EUSCI_B_CMSIS(moduleInstance)->IE &= ~(mask);
670 }
671 
I2C_clearInterruptFlag(uint32_t moduleInstance,uint_fast16_t mask)672 void I2C_clearInterruptFlag(uint32_t moduleInstance, uint_fast16_t mask)
673 {
674     ASSERT(
675             0x00
676                     == (mask
677                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
678                                     + EUSCI_B_I2C_START_INTERRUPT
679                                     + EUSCI_B_I2C_NAK_INTERRUPT
680                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
681                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
682                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
683                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
684                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
685                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
686                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
687                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
688                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
689                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
690                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
691                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
692     //Clear the I2C interrupt source.
693     EUSCI_B_CMSIS(moduleInstance)->IFG &= ~(mask);
694 }
695 
I2C_getInterruptStatus(uint32_t moduleInstance,uint16_t mask)696 uint_fast16_t I2C_getInterruptStatus(uint32_t moduleInstance, uint16_t mask)
697 {
698     ASSERT(
699             0x00
700                     == (mask
701                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
702                                     + EUSCI_B_I2C_START_INTERRUPT
703                                     + EUSCI_B_I2C_NAK_INTERRUPT
704                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
705                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
706                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
707                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
708                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
709                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
710                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
711                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
712                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
713                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
714                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
715                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
716     //Return the interrupt status of the request masked bit.
717     return EUSCI_B_CMSIS(moduleInstance)->IFG & mask;
718 }
719 
I2C_getEnabledInterruptStatus(uint32_t moduleInstance)720 uint_fast16_t I2C_getEnabledInterruptStatus(uint32_t moduleInstance)
721 {
722     return I2C_getInterruptStatus(moduleInstance,
723             EUSCI_B_CMSIS(moduleInstance)->IE);
724 }
725 
I2C_getMode(uint32_t moduleInstance)726 uint_fast16_t I2C_getMode(uint32_t moduleInstance)
727 {
728     //Read the I2C mode.
729     return (EUSCI_B_CMSIS(moduleInstance)->CTLW0 & EUSCI_B_CTLW0_TR);
730 }
731 
I2C_registerInterrupt(uint32_t moduleInstance,void (* intHandler)(void))732 void I2C_registerInterrupt(uint32_t moduleInstance, void (*intHandler)(void))
733 {
734     switch (moduleInstance)
735     {
736     case EUSCI_B0_BASE:
737         Interrupt_registerInterrupt(INT_EUSCIB0, intHandler);
738         Interrupt_enableInterrupt(INT_EUSCIB0);
739         break;
740     case EUSCI_B1_BASE:
741         Interrupt_registerInterrupt(INT_EUSCIB1, intHandler);
742         Interrupt_enableInterrupt(INT_EUSCIB1);
743         break;
744 #ifdef EUSCI_B2_BASE
745         case EUSCI_B2_BASE:
746         Interrupt_registerInterrupt(INT_EUSCIB2, intHandler);
747         Interrupt_enableInterrupt(INT_EUSCIB2);
748         break;
749 #endif
750 #ifdef EUSCI_B3_BASE
751         case EUSCI_B3_BASE:
752         Interrupt_registerInterrupt(INT_EUSCIB3, intHandler);
753         Interrupt_enableInterrupt(INT_EUSCIB3);
754         break;
755 #endif
756     default:
757         ASSERT(false);
758     }
759 }
760 
I2C_unregisterInterrupt(uint32_t moduleInstance)761 void I2C_unregisterInterrupt(uint32_t moduleInstance)
762 {
763     switch (moduleInstance)
764     {
765     case EUSCI_B0_BASE:
766         Interrupt_disableInterrupt(INT_EUSCIB0);
767         Interrupt_unregisterInterrupt(INT_EUSCIB0);
768         break;
769     case EUSCI_B1_BASE:
770         Interrupt_disableInterrupt(INT_EUSCIB1);
771         Interrupt_unregisterInterrupt(INT_EUSCIB1);
772         break;
773 #ifdef EUSCI_B2_BASE
774         case EUSCI_B2_BASE:
775         Interrupt_disableInterrupt(INT_EUSCIB2);
776         Interrupt_unregisterInterrupt(INT_EUSCIB2);
777         break;
778 #endif
779 #ifdef EUSCI_B3_BASE
780         case EUSCI_B3_BASE:
781         Interrupt_disableInterrupt(INT_EUSCIB3);
782         Interrupt_unregisterInterrupt(INT_EUSCIB3);
783         break;
784 #endif
785     default:
786         ASSERT(false);
787     }
788 }
789 
I2C_slaveSendNAK(uint32_t moduleInstance)790 void I2C_slaveSendNAK(uint32_t moduleInstance)
791 {
792     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXNACK_OFS) =
793             1;
794 }
795