xref: /btstack/port/msp432p401lp-cc256x/ti/devices/msp432p4xx/driverlib/i2c.c (revision 5fd0122a3e19d95e11e1f3eb8a08a2b2acb2557e)
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_setTimeout(uint32_t moduleInstance,uint_fast16_t timeout)149 void I2C_setTimeout(uint32_t moduleInstance, uint_fast16_t timeout)
150 {
151     uint_fast16_t swrstValue;
152 
153     ASSERT(
154             (EUSCI_B_I2C_TIMEOUT_DISABLE == timeout)
155                     || (EUSCI_B_I2C_TIMEOUT_28_MS == timeout)
156                     || (EUSCI_B_I2C_TIMEOUT_31_MS == timeout)
157                     || (EUSCI_B_I2C_TIMEOUT_34_MS == timeout));
158 
159     /* Save value of UCSWRST bit and disable USCI module */
160     swrstValue = BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS);
161     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
162             1;
163 
164     /* Set timeout */
165     EUSCI_B_CMSIS(moduleInstance)->CTLW1 = (EUSCI_B_CMSIS(moduleInstance)->CTLW1
166             & (~EUSCI_B_CTLW1_CLTO_3)) | timeout;
167 
168     /* Restore value of UCSWRST bit */
169     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
170             swrstValue;
171 }
172 
I2C_masterReceiveSingleByte(uint32_t moduleInstance)173 uint8_t I2C_masterReceiveSingleByte(uint32_t moduleInstance)
174 {
175 
176     uint_fast16_t rxieStatus;
177 
178     //Store current RXIE status
179     rxieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_RXIE0;
180 
181     //Disable receive interrupt enable
182     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_RXIE0_OFS) = 0;
183 
184     //Set USCI in Receive mode
185     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TR_OFS) =
186             0;
187 
188     //Send start
189     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= (EUSCI_B_CTLW0_TXSTT
190             + EUSCI_B_CTLW0_TXSTP);
191 
192     //Poll for receive interrupt flag.
193     while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
194             EUSCI_B_IFG_RXIFG_OFS))
195         ;
196 
197     //Receive single byte data.
198     uint8_t receivedByte = (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
199 
200     //Clear receive interrupt flag before enabling interrupt again
201     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_RXIFG0_OFS) =
202             0;
203 
204     //Reinstate receive interrupt enable
205     EUSCI_B_CMSIS(moduleInstance)->IE |= rxieStatus;
206 
207     return receivedByte;
208 }
209 
I2C_slavePutData(uint32_t moduleInstance,uint8_t transmitData)210 void I2C_slavePutData(uint32_t moduleInstance, uint8_t transmitData)
211 {
212     //Send single byte data.
213     EUSCI_B_CMSIS(moduleInstance)->TXBUF = transmitData;
214 }
215 
I2C_slaveGetData(uint32_t moduleInstance)216 uint8_t I2C_slaveGetData(uint32_t moduleInstance)
217 {
218     //Read a byte.
219     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
220 }
221 
I2C_isBusBusy(uint32_t moduleInstance)222 uint8_t I2C_isBusBusy(uint32_t moduleInstance)
223 {
224     //Return the bus busy status.
225     return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->STATW,
226             EUSCI_B_STATW_BBUSY_OFS);
227 }
228 
I2C_masterSendSingleByte(uint32_t moduleInstance,uint8_t txData)229 void I2C_masterSendSingleByte(uint32_t moduleInstance, uint8_t txData)
230 {
231     //Store current TXIE status
232     uint16_t txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
233 
234     //Disable transmit interrupt enable
235     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
236 
237     //Send start condition.
238     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
239             + EUSCI_B_CTLW0_TXSTT;
240 
241     //Poll for transmit interrupt flag and start condition flag.
242     while ((BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
243                 EUSCI_B_CTLW0_TXSTT_OFS)
244                 || !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
245                         EUSCI_B_IFG_TXIFG0_OFS)));
246 
247     //Send single byte data.
248     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
249 
250     //Poll for transmit interrupt flag.
251     while (!(EUSCI_B_CMSIS(moduleInstance)->IFG & EUSCI_B_IFG_TXIFG))
252         ;
253 
254     //Send stop condition.
255     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TXSTP;
256 
257     //Clear transmit interrupt flag before enabling interrupt again
258     EUSCI_B_CMSIS(moduleInstance)->IFG &= ~(EUSCI_B_IFG_TXIFG);
259 
260     //Reinstate transmit interrupt enable
261     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
262 }
263 
I2C_masterSendSingleByteWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)264 bool I2C_masterSendSingleByteWithTimeout(uint32_t moduleInstance,
265         uint8_t txData, uint32_t timeout)
266 {
267     uint_fast16_t txieStatus;
268     uint32_t timeout2 = timeout;
269 
270     ASSERT(timeout > 0);
271 
272     //Store current TXIE status
273     txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
274 
275     //Disable transmit interrupt enable
276     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
277 
278     //Send start condition.
279     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
280             + EUSCI_B_CTLW0_TXSTT;
281 
282     //Poll for transmit interrupt flag.
283     while ((!(EUSCI_B_CMSIS(moduleInstance)->IFG & EUSCI_B_IFG_TXIFG))
284             && --timeout)
285         ;
286 
287     //Check if transfer timed out
288     if (timeout == 0)
289         return false;
290 
291     //Send single byte data.
292     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
293 
294     //Poll for transmit interrupt flag.
295     while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
296             EUSCI_B_IFG_TXIFG0_OFS)) && --timeout2)
297         ;
298 
299     //Check if transfer timed out
300     if (timeout2 == 0)
301         return false;
302 
303     //Send stop condition.
304     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
305             1;
306 
307     //Clear transmit interrupt flag before enabling interrupt again
308     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS) =
309             0;
310 
311     //Reinstate transmit interrupt enable
312     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
313 
314     return true;
315 }
316 
I2C_masterSendMultiByteStart(uint32_t moduleInstance,uint8_t txData)317 void I2C_masterSendMultiByteStart(uint32_t moduleInstance, uint8_t txData)
318 {
319     //Store current transmit interrupt enable
320     uint16_t txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
321 
322     //Disable transmit interrupt enable
323     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
324 
325     //Send start condition.
326     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
327             + EUSCI_B_CTLW0_TXSTT;
328 
329     //Poll for transmit interrupt flag and start condition flag.
330     while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
331                 EUSCI_B_CTLW0_TXSTT_OFS)
332                 || !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
333                         EUSCI_B_IFG_TXIFG0_OFS));
334 
335     //Send single byte data.
336     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
337 
338     //Reinstate transmit interrupt enable
339     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
340 }
341 
I2C_masterSendMultiByteStartWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)342 bool I2C_masterSendMultiByteStartWithTimeout(uint32_t moduleInstance,
343         uint8_t txData, uint32_t timeout)
344 {
345     uint_fast16_t txieStatus;
346 
347     ASSERT(timeout > 0);
348 
349     //Store current transmit interrupt enable
350     txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0;
351 
352     //Disable transmit interrupt enable
353     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0;
354 
355     //Send start condition.
356     EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR
357             + EUSCI_B_CTLW0_TXSTT;
358 
359     //Poll for transmit interrupt flag and start condition flag.
360     while ((BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
361                 EUSCI_B_CTLW0_TXSTT_OFS)
362                 || !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
363                         EUSCI_B_IFG_TXIFG0_OFS)) && --timeout);
364 
365 
366     //Check if transfer timed out
367     if (timeout == 0)
368         return false;
369 
370     //Send single byte data.
371     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
372 
373     //Reinstate transmit interrupt enable
374     EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus;
375 
376     return true;
377 }
378 
I2C_masterSendMultiByteNext(uint32_t moduleInstance,uint8_t txData)379 void I2C_masterSendMultiByteNext(uint32_t moduleInstance, uint8_t txData)
380 {
381     //If interrupts are not used, poll for flags
382     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
383     {
384         //Poll for transmit interrupt flag.
385         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
386                 EUSCI_B_IFG_TXIFG0_OFS))
387             ;
388     }
389 
390     //Send single byte data.
391     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
392 }
393 
I2C_masterSendMultiByteNextWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)394 bool I2C_masterSendMultiByteNextWithTimeout(uint32_t moduleInstance,
395         uint8_t txData, uint32_t timeout)
396 {
397     ASSERT(timeout > 0);
398 
399     //If interrupts are not used, poll for flags
400     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
401     {
402         //Poll for transmit interrupt flag.
403         while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
404                 EUSCI_B_IFG_TXIFG0_OFS)) && --timeout)
405             ;
406 
407         //Check if transfer timed out
408         if (timeout == 0)
409             return false;
410     }
411 
412     //Send single byte data.
413     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
414 
415     return true;
416 }
417 
I2C_masterSendMultiByteFinish(uint32_t moduleInstance,uint8_t txData)418 bool I2C_masterSendMultiByteFinish(uint32_t moduleInstance, uint8_t txData)
419 {
420     //If interrupts are not used, poll for flags
421     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
422     {
423         //Poll for transmit interrupt flag.
424         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
425                 EUSCI_B_IFG_TXIFG0_OFS))
426             ;
427     }
428 
429     //Send single byte data.
430     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
431 
432     //Poll for transmit interrupt flag.
433     while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
434             EUSCI_B_IFG_TXIFG0_OFS)
435             && !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
436                     EUSCI_B_IFG_NACKIFG_OFS))
437         ;
438     if(BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_NACKIFG_OFS))
439         return false;
440 
441     //Send stop condition.
442     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
443             1;
444 
445     return true;
446 }
447 
I2C_masterSendMultiByteFinishWithTimeout(uint32_t moduleInstance,uint8_t txData,uint32_t timeout)448 bool I2C_masterSendMultiByteFinishWithTimeout(uint32_t moduleInstance,
449         uint8_t txData, uint32_t timeout)
450 {
451     uint32_t timeout2 = timeout;
452 
453     ASSERT(timeout > 0);
454 
455     //If interrupts are not used, poll for flags
456     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
457     {
458         //Poll for transmit interrupt flag.
459         while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
460                 EUSCI_B_IFG_TXIFG0_OFS)) && --timeout)
461             ;
462 
463         //Check if transfer timed out
464         if (timeout == 0)
465             return false;
466     }
467 
468     //Send single byte data.
469     EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData;
470 
471     //Poll for transmit interrupt flag.
472     while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
473             EUSCI_B_IFG_TXIFG0_OFS)) && --timeout2
474             && !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
475                     EUSCI_B_IFG_NACKIFG_OFS))
476         ;
477 
478     //Check if transfer timed out
479     if (timeout2 == 0)
480         return false;
481 
482     //Send stop condition.
483     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
484             1;
485 
486     return true;
487 }
488 
I2C_masterSendMultiByteStop(uint32_t moduleInstance)489 void I2C_masterSendMultiByteStop(uint32_t moduleInstance)
490 {
491     //If interrupts are not used, poll for flags
492     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
493     {
494         //Poll for transmit interrupt flag.
495         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
496                 EUSCI_B_IFG_TXIFG0_OFS))
497             ;
498     }
499 
500     //Send stop condition.
501     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
502             1;
503 }
504 
I2C_masterSendMultiByteStopWithTimeout(uint32_t moduleInstance,uint32_t timeout)505 bool I2C_masterSendMultiByteStopWithTimeout(uint32_t moduleInstance,
506         uint32_t timeout)
507 {
508     ASSERT(timeout > 0);
509 
510     //If interrupts are not used, poll for flags
511     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS))
512     {
513         //Poll for transmit interrupt flag.
514         while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
515                 EUSCI_B_IFG_TXIFG0_OFS)) && --timeout)
516             ;
517 
518         //Check if transfer timed out
519         if (timeout == 0)
520             return false;
521     }
522 
523     //Send stop condition.
524     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
525             1;
526 
527     return 0x01;
528 }
529 
I2C_masterReceiveStart(uint32_t moduleInstance)530 void I2C_masterReceiveStart(uint32_t moduleInstance)
531 {
532     //Set USCI in Receive mode
533     EUSCI_B_CMSIS(moduleInstance)->CTLW0 = (EUSCI_B_CMSIS(moduleInstance)->CTLW0
534             & (~EUSCI_B_CTLW0_TR)) | EUSCI_B_CTLW0_TXSTT;
535 }
536 
I2C_masterReceiveMultiByteNext(uint32_t moduleInstance)537 uint8_t I2C_masterReceiveMultiByteNext(uint32_t moduleInstance)
538 {
539     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
540 }
541 
I2C_masterReceiveMultiByteFinish(uint32_t moduleInstance)542 uint8_t I2C_masterReceiveMultiByteFinish(uint32_t moduleInstance)
543 {
544     //Send stop condition.
545     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
546             1;
547 
548     //Wait for Stop to finish
549     while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
550             EUSCI_B_CTLW0_TXSTP_OFS))
551     {
552         // Wait for RX buffer
553         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
554                 EUSCI_B_IFG_RXIFG_OFS))
555             ;
556     }
557 
558     /* Capture data from receive buffer after setting stop bit due to
559      MSP430 I2C critical timing. */
560     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
561 }
562 
I2C_masterReceiveMultiByteFinishWithTimeout(uint32_t moduleInstance,uint8_t * txData,uint32_t timeout)563 bool I2C_masterReceiveMultiByteFinishWithTimeout(uint32_t moduleInstance,
564         uint8_t *txData, uint32_t timeout)
565 {
566     uint32_t timeout2 = timeout;
567 
568     ASSERT(timeout > 0);
569 
570     //Send stop condition.
571     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
572             1;
573 
574     //Wait for Stop to finish
575     while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
576             EUSCI_B_CTLW0_TXSTP_OFS) && --timeout)
577         ;
578 
579     //Check if transfer timed out
580     if (timeout == 0)
581         return false;
582 
583     // Wait for RX buffer
584     while ((!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
585             EUSCI_B_IFG_RXIFG_OFS)) && --timeout2)
586         ;
587 
588     //Check if transfer timed out
589     if (timeout2 == 0)
590         return false;
591 
592     //Capture data from receive buffer after setting stop bit due to
593     //MSP430 I2C critical timing.
594     *txData = (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
595 
596     return true;
597 }
598 
I2C_masterReceiveMultiByteStop(uint32_t moduleInstance)599 void I2C_masterReceiveMultiByteStop(uint32_t moduleInstance)
600 {
601     //Send stop condition.
602     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTP_OFS) =
603             1;
604 }
605 
I2C_masterReceiveSingle(uint32_t moduleInstance)606 uint8_t I2C_masterReceiveSingle(uint32_t moduleInstance)
607 {
608     //Polling RXIFG0 if RXIE is not enabled
609     if (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_RXIE0_OFS))
610     {
611         while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG,
612                 EUSCI_B_IFG_RXIFG0_OFS))
613             ;
614     }
615 
616     //Read a byte.
617     return (EUSCI_B_CMSIS(moduleInstance)->RXBUF & EUSCI_B_RXBUF_RXBUF_MASK);
618 }
619 
I2C_getReceiveBufferAddressForDMA(uint32_t moduleInstance)620 uint32_t I2C_getReceiveBufferAddressForDMA(uint32_t moduleInstance)
621 {
622     return (uint32_t) &EUSCI_B_CMSIS(moduleInstance)->RXBUF;
623 }
624 
I2C_getTransmitBufferAddressForDMA(uint32_t moduleInstance)625 uint32_t I2C_getTransmitBufferAddressForDMA(uint32_t moduleInstance)
626 {
627     return (uint32_t) &EUSCI_B_CMSIS(moduleInstance)->TXBUF;
628 }
629 
I2C_masterIsStopSent(uint32_t moduleInstance)630 uint8_t I2C_masterIsStopSent(uint32_t moduleInstance)
631 {
632     return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
633             EUSCI_B_CTLW0_TXSTP_OFS);
634 }
635 
I2C_masterIsStartSent(uint32_t moduleInstance)636 bool I2C_masterIsStartSent(uint32_t moduleInstance)
637 {
638     return BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0,
639             EUSCI_B_CTLW0_TXSTT_OFS);
640 }
641 
I2C_masterSendStart(uint32_t moduleInstance)642 void I2C_masterSendStart(uint32_t moduleInstance)
643 {
644     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTT_OFS) =
645             1;
646 }
647 
I2C_enableMultiMasterMode(uint32_t moduleInstance)648 void I2C_enableMultiMasterMode(uint32_t moduleInstance)
649 {
650     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
651             1;
652     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_MM_OFS) =
653             1;
654 }
655 
I2C_disableMultiMasterMode(uint32_t moduleInstance)656 void I2C_disableMultiMasterMode(uint32_t moduleInstance)
657 {
658     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_SWRST_OFS) =
659             1;
660     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_MM_OFS) =
661             0;
662 }
663 
I2C_enableInterrupt(uint32_t moduleInstance,uint_fast16_t mask)664 void I2C_enableInterrupt(uint32_t moduleInstance, uint_fast16_t mask)
665 {
666     ASSERT(
667             0x00
668                     == (mask
669                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
670                                     + EUSCI_B_I2C_START_INTERRUPT
671                                     + EUSCI_B_I2C_NAK_INTERRUPT
672                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
673                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
674                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
675                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
676                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
677                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
678                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
679                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
680                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
681                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
682                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
683                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
684 
685     //Enable the interrupt masked bit
686     EUSCI_B_CMSIS(moduleInstance)->IE |= mask;
687 }
688 
I2C_disableInterrupt(uint32_t moduleInstance,uint_fast16_t mask)689 void I2C_disableInterrupt(uint32_t moduleInstance, uint_fast16_t mask)
690 {
691     ASSERT(
692             0x00
693                     == (mask
694                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
695                                     + EUSCI_B_I2C_START_INTERRUPT
696                                     + EUSCI_B_I2C_NAK_INTERRUPT
697                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
698                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
699                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
700                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
701                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
702                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
703                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
704                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
705                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
706                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
707                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
708                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
709 
710     //Disable the interrupt masked bit
711     EUSCI_B_CMSIS(moduleInstance)->IE &= ~(mask);
712 }
713 
I2C_clearInterruptFlag(uint32_t moduleInstance,uint_fast16_t mask)714 void I2C_clearInterruptFlag(uint32_t moduleInstance, uint_fast16_t mask)
715 {
716     ASSERT(
717             0x00
718                     == (mask
719                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
720                                     + EUSCI_B_I2C_START_INTERRUPT
721                                     + EUSCI_B_I2C_NAK_INTERRUPT
722                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
723                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
724                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
725                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
726                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
727                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
728                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
729                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
730                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
731                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
732                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
733                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
734     //Clear the I2C interrupt source.
735     EUSCI_B_CMSIS(moduleInstance)->IFG &= ~(mask);
736 }
737 
I2C_getInterruptStatus(uint32_t moduleInstance,uint16_t mask)738 uint_fast16_t I2C_getInterruptStatus(uint32_t moduleInstance, uint16_t mask)
739 {
740     ASSERT(
741             0x00
742                     == (mask
743                             & ~(EUSCI_B_I2C_STOP_INTERRUPT
744                                     + EUSCI_B_I2C_START_INTERRUPT
745                                     + EUSCI_B_I2C_NAK_INTERRUPT
746                                     + EUSCI_B_I2C_ARBITRATIONLOST_INTERRUPT
747                                     + EUSCI_B_I2C_BIT9_POSITION_INTERRUPT
748                                     + EUSCI_B_I2C_CLOCK_LOW_TIMEOUT_INTERRUPT
749                                     + EUSCI_B_I2C_BYTE_COUNTER_INTERRUPT
750                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT0
751                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT1
752                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT2
753                                     + EUSCI_B_I2C_TRANSMIT_INTERRUPT3
754                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT0
755                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT1
756                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT2
757                                     + EUSCI_B_I2C_RECEIVE_INTERRUPT3)));
758     //Return the interrupt status of the request masked bit.
759     return EUSCI_B_CMSIS(moduleInstance)->IFG & mask;
760 }
761 
I2C_getEnabledInterruptStatus(uint32_t moduleInstance)762 uint_fast16_t I2C_getEnabledInterruptStatus(uint32_t moduleInstance)
763 {
764     return I2C_getInterruptStatus(moduleInstance,
765             EUSCI_B_CMSIS(moduleInstance)->IE);
766 }
767 
I2C_getMode(uint32_t moduleInstance)768 uint_fast16_t I2C_getMode(uint32_t moduleInstance)
769 {
770     //Read the I2C mode.
771     return (EUSCI_B_CMSIS(moduleInstance)->CTLW0 & EUSCI_B_CTLW0_TR);
772 }
773 
I2C_registerInterrupt(uint32_t moduleInstance,void (* intHandler)(void))774 void I2C_registerInterrupt(uint32_t moduleInstance, void (*intHandler)(void))
775 {
776     switch (moduleInstance)
777     {
778     case EUSCI_B0_BASE:
779         Interrupt_registerInterrupt(INT_EUSCIB0, intHandler);
780         Interrupt_enableInterrupt(INT_EUSCIB0);
781         break;
782     case EUSCI_B1_BASE:
783         Interrupt_registerInterrupt(INT_EUSCIB1, intHandler);
784         Interrupt_enableInterrupt(INT_EUSCIB1);
785         break;
786 #ifdef EUSCI_B2_BASE
787         case EUSCI_B2_BASE:
788         Interrupt_registerInterrupt(INT_EUSCIB2, intHandler);
789         Interrupt_enableInterrupt(INT_EUSCIB2);
790         break;
791 #endif
792 #ifdef EUSCI_B3_BASE
793         case EUSCI_B3_BASE:
794         Interrupt_registerInterrupt(INT_EUSCIB3, intHandler);
795         Interrupt_enableInterrupt(INT_EUSCIB3);
796         break;
797 #endif
798     default:
799         ASSERT(false);
800     }
801 }
802 
I2C_unregisterInterrupt(uint32_t moduleInstance)803 void I2C_unregisterInterrupt(uint32_t moduleInstance)
804 {
805     switch (moduleInstance)
806     {
807     case EUSCI_B0_BASE:
808         Interrupt_disableInterrupt(INT_EUSCIB0);
809         Interrupt_unregisterInterrupt(INT_EUSCIB0);
810         break;
811     case EUSCI_B1_BASE:
812         Interrupt_disableInterrupt(INT_EUSCIB1);
813         Interrupt_unregisterInterrupt(INT_EUSCIB1);
814         break;
815 #ifdef EUSCI_B2_BASE
816         case EUSCI_B2_BASE:
817         Interrupt_disableInterrupt(INT_EUSCIB2);
818         Interrupt_unregisterInterrupt(INT_EUSCIB2);
819         break;
820 #endif
821 #ifdef EUSCI_B3_BASE
822         case EUSCI_B3_BASE:
823         Interrupt_disableInterrupt(INT_EUSCIB3);
824         Interrupt_unregisterInterrupt(INT_EUSCIB3);
825         break;
826 #endif
827     default:
828         ASSERT(false);
829     }
830 }
831 
I2C_slaveSendNAK(uint32_t moduleInstance)832 void I2C_slaveSendNAK(uint32_t moduleInstance)
833 {
834     BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXNACK_OFS) =
835             1;
836 }
837