2 * Copyright (c) 2014, Texas Instruments Incorporated
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions
\r
9 * * Redistributions of source code must retain the above copyright
\r
10 * notice, this list of conditions and the following disclaimer.
\r
12 * * Redistributions in binary form must reproduce the above copyright
\r
13 * notice, this list of conditions and the following disclaimer in the
\r
14 * documentation and/or other materials provided with the distribution.
\r
16 * * Neither the name of Texas Instruments Incorporated nor the names of
\r
17 * its contributors may be used to endorse or promote products derived
\r
18 * from this software without specific prior written permission.
\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
\r
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
\r
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\r
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
\r
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
\r
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
\r
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
\r
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
32 //*****************************************************************************
\r
34 // eusci_b_i2c.c - Driver for the eusci_b_i2c Module.
\r
36 //*****************************************************************************
\r
38 //*****************************************************************************
\r
40 //! \addtogroup eusci_b_i2c_api eusci_b_i2c
\r
43 //*****************************************************************************
\r
45 #include "inc/hw_regaccess.h"
\r
46 #include "inc/hw_memmap.h"
\r
48 #ifdef __MSP430_HAS_EUSCI_Bx__
\r
49 #include "eusci_b_i2c.h"
\r
53 void EUSCI_B_I2C_initMaster(uint16_t baseAddress,
\r
54 EUSCI_B_I2C_initMasterParam *param)
\r
56 uint16_t preScalarValue;
\r
58 //Disable the USCI module and clears the other bits of control register
\r
59 HWREG16(baseAddress + OFS_UCBxCTLW0) = UCSWRST;
\r
61 //Configure Automatic STOP condition generation
\r
62 HWREG16(baseAddress + OFS_UCBxCTLW1) &= ~UCASTP_3;
\r
63 HWREG16(baseAddress + OFS_UCBxCTLW1) |= param->autoSTOPGeneration;
\r
65 //Byte Count Threshold
\r
66 HWREG16(baseAddress + OFS_UCBxTBCNT) = param->byteCounterThreshold;
\r
68 * Configure as I2C master mode.
\r
69 * UCMST = Master mode
\r
70 * UCMODE_3 = I2C mode
\r
71 * UCSYNC = Synchronous mode
\r
73 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCMST + UCMODE_3 + UCSYNC;
\r
75 //Configure I2C clock source
\r
76 HWREG16(baseAddress +
\r
77 OFS_UCBxCTLW0) |= (param->selectClockSource + UCSWRST);
\r
80 * Compute the clock divider that achieves the fastest speed less than or
\r
81 * equal to the desired speed. The numerator is biased to favor a larger
\r
82 * clock divider so that the resulting clock is always less than or equal
\r
83 * to the desired clock, never greater.
\r
85 preScalarValue = (uint16_t)(param->i2cClk / param->dataRate);
\r
86 HWREG16(baseAddress + OFS_UCBxBRW) = preScalarValue;
\r
89 void EUSCI_B_I2C_initSlave(uint16_t baseAddress,
\r
90 EUSCI_B_I2C_initSlaveParam *param)
\r
92 //Disable the USCI module
\r
93 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
\r
95 //Clear USCI master mode
\r
96 HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~UCMST;
\r
98 //Configure I2C as Slave and Synchronous mode
\r
99 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCMODE_3 + UCSYNC;
\r
101 //Set up the slave address.
\r
102 HWREG16(baseAddress + OFS_UCBxI2COA0 + param->slaveAddressOffset)
\r
103 = param->slaveAddress + param->slaveOwnAddressEnable;
\r
106 void EUSCI_B_I2C_enable(uint16_t baseAddress)
\r
108 //Reset the UCSWRST bit to enable the USCI Module
\r
109 HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~(UCSWRST);
\r
112 void EUSCI_B_I2C_disable(uint16_t baseAddress)
\r
114 //Set the UCSWRST bit to disable the USCI Module
\r
115 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
\r
118 void EUSCI_B_I2C_setSlaveAddress(uint16_t baseAddress,
\r
119 uint8_t slaveAddress)
\r
121 //Set the address of the slave with which the master will communicate.
\r
122 HWREG16(baseAddress + OFS_UCBxI2CSA) = (slaveAddress);
\r
125 void EUSCI_B_I2C_setMode(uint16_t baseAddress,
\r
128 HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~EUSCI_B_I2C_TRANSMIT_MODE;
\r
129 HWREG16(baseAddress + OFS_UCBxCTLW0) |= mode;
\r
132 uint8_t EUSCI_B_I2C_getMode(uint16_t baseAddress)
\r
134 //Read the I2C mode.
\r
135 return ((HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTR));
\r
138 void EUSCI_B_I2C_slavePutData(uint16_t baseAddress,
\r
139 uint8_t transmitData)
\r
141 //Send single byte data.
\r
142 HWREG16(baseAddress + OFS_UCBxTXBUF) = transmitData;
\r
145 uint8_t EUSCI_B_I2C_slaveGetData(uint16_t baseAddress)
\r
148 return (HWREG16(baseAddress + OFS_UCBxRXBUF));
\r
151 uint16_t EUSCI_B_I2C_isBusBusy(uint16_t baseAddress)
\r
153 //Return the bus busy status.
\r
154 return (HWREG16(baseAddress + OFS_UCBxSTATW) & UCBBUSY);
\r
157 uint16_t EUSCI_B_I2C_masterIsStopSent(uint16_t baseAddress)
\r
159 return (HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTP);
\r
162 uint16_t EUSCI_B_I2C_masterIsStartSent(uint16_t baseAddress)
\r
164 return (HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTT);
\r
167 void EUSCI_B_I2C_enableInterrupt(uint16_t baseAddress,
\r
170 //Enable the interrupt masked bit
\r
171 HWREG16(baseAddress + OFS_UCBxIE) |= mask;
\r
174 void EUSCI_B_I2C_disableInterrupt(uint16_t baseAddress,
\r
177 //Disable the interrupt masked bit
\r
178 HWREG16(baseAddress + OFS_UCBxIE) &= ~(mask);
\r
181 void EUSCI_B_I2C_clearInterrupt(uint16_t baseAddress,
\r
184 //Clear the I2C interrupt source.
\r
185 HWREG16(baseAddress + OFS_UCBxIFG) &= ~(mask);
\r
188 uint16_t EUSCI_B_I2C_getInterruptStatus(uint16_t baseAddress,
\r
191 //Return the interrupt status of the request masked bit.
\r
192 return (HWREG16(baseAddress + OFS_UCBxIFG) & mask);
\r
195 void EUSCI_B_I2C_masterSendSingleByte(uint16_t baseAddress,
\r
198 //Store current TXIE status
\r
199 uint16_t txieStatus = HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE;
\r
201 //Disable transmit interrupt enable
\r
202 HWREG16(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
\r
204 //Send start condition.
\r
205 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;
\r
207 //Poll for transmit interrupt flag.
\r
208 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
\r
213 //Send single byte data.
\r
214 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
216 //Poll for transmit interrupt flag.
\r
217 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
\r
222 //Send stop condition.
\r
223 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
225 //Clear transmit interrupt flag before enabling interrupt again
\r
226 HWREG16(baseAddress + OFS_UCBxIFG) &= ~(UCTXIFG);
\r
228 //Reinstate transmit interrupt enable
\r
229 HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus;
\r
232 uint8_t EUSCI_B_I2C_masterReceiveSingleByte(uint16_t baseAddress)
\r
234 //Set USCI in Receive mode
\r
235 HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~UCTR;
\r
238 HWREG16(baseAddress + OFS_UCBxCTLW0) |= (UCTXSTT + UCTXSTP);
\r
240 //Poll for receive interrupt flag.
\r
241 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCRXIFG))
\r
246 //Send single byte data.
\r
247 return (HWREG16(baseAddress + OFS_UCBxRXBUF));
\r
250 bool EUSCI_B_I2C_masterSendSingleByteWithTimeout(uint16_t baseAddress,
\r
254 // Creating variable for second timeout scenario
\r
255 uint32_t timeout2 = timeout;
\r
257 //Store current TXIE status
\r
258 uint16_t txieStatus = HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE;
\r
260 //Disable transmit interrupt enable
\r
261 HWREG16(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
\r
263 //Send start condition.
\r
264 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;
\r
266 //Poll for transmit interrupt flag.
\r
267 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout)
\r
272 //Check if transfer timed out
\r
275 return (STATUS_FAIL);
\r
278 //Send single byte data.
\r
279 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
281 //Poll for transmit interrupt flag.
\r
282 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout2)
\r
287 //Check if transfer timed out
\r
290 return (STATUS_FAIL);
\r
293 //Send stop condition.
\r
294 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
296 //Clear transmit interrupt flag before enabling interrupt again
\r
297 HWREG16(baseAddress + OFS_UCBxIFG) &= ~(UCTXIFG);
\r
299 //Reinstate transmit interrupt enable
\r
300 HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus;
\r
302 return (STATUS_SUCCESS);
\r
305 void EUSCI_B_I2C_masterSendMultiByteStart(uint16_t baseAddress,
\r
308 //Store current transmit interrupt enable
\r
309 uint16_t txieStatus = HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE;
\r
311 //Disable transmit interrupt enable
\r
312 HWREG16(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
\r
314 //Send start condition.
\r
315 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;
\r
317 //Poll for transmit interrupt flag.
\r
318 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
\r
323 //Send single byte data.
\r
324 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
326 //Reinstate transmit interrupt enable
\r
327 HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus;
\r
330 bool EUSCI_B_I2C_masterSendMultiByteStartWithTimeout(uint16_t baseAddress,
\r
334 //Store current transmit interrupt enable
\r
335 uint16_t txieStatus = HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE;
\r
337 //Disable transmit interrupt enable
\r
338 HWREG16(baseAddress + OFS_UCBxIE) &= ~(UCTXIE);
\r
340 //Send start condition.
\r
341 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTR + UCTXSTT;
\r
343 //Poll for transmit interrupt flag.
\r
344 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout)
\r
349 //Check if transfer timed out
\r
352 return (STATUS_FAIL);
\r
355 //Send single byte data.
\r
356 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
358 //Reinstate transmit interrupt enable
\r
359 HWREG16(baseAddress + OFS_UCBxIE) |= txieStatus;
\r
361 return(STATUS_SUCCESS);
\r
364 void EUSCI_B_I2C_masterSendMultiByteNext(uint16_t baseAddress,
\r
367 //If interrupts are not used, poll for flags
\r
368 if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE))
\r
370 //Poll for transmit interrupt flag.
\r
371 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
\r
377 //Send single byte data.
\r
378 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
381 bool EUSCI_B_I2C_masterSendMultiByteNextWithTimeout(uint16_t baseAddress,
\r
385 //If interrupts are not used, poll for flags
\r
386 if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE))
\r
388 //Poll for transmit interrupt flag.
\r
389 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout)
\r
394 //Check if transfer timed out
\r
397 return (STATUS_FAIL);
\r
401 //Send single byte data.
\r
402 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
404 return(STATUS_SUCCESS);
\r
407 void EUSCI_B_I2C_masterSendMultiByteFinish(uint16_t baseAddress,
\r
410 //If interrupts are not used, poll for flags
\r
411 if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE))
\r
413 //Poll for transmit interrupt flag.
\r
414 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
\r
420 //Send single byte data.
\r
421 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
423 //Poll for transmit interrupt flag.
\r
424 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
\r
429 //Send stop condition.
\r
430 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
433 bool EUSCI_B_I2C_masterSendMultiByteFinishWithTimeout(uint16_t baseAddress,
\r
437 uint32_t timeout2 = timeout;
\r
439 //If interrupts are not used, poll for flags
\r
440 if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE))
\r
442 //Poll for transmit interrupt flag.
\r
443 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout)
\r
448 //Check if transfer timed out
\r
451 return (STATUS_FAIL);
\r
455 //Send single byte data.
\r
456 HWREG16(baseAddress + OFS_UCBxTXBUF) = txData;
\r
458 //Poll for transmit interrupt flag.
\r
459 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout2)
\r
464 //Check if transfer timed out
\r
467 return (STATUS_FAIL);
\r
470 //Send stop condition.
\r
471 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
473 return(STATUS_SUCCESS);
\r
476 void EUSCI_B_I2C_masterSendStart(uint16_t baseAddress)
\r
478 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTT;
\r
481 void EUSCI_B_I2C_masterSendMultiByteStop(uint16_t baseAddress)
\r
483 //If interrupts are not used, poll for flags
\r
484 if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE))
\r
486 //Poll for transmit interrupt flag.
\r
487 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG))
\r
493 //Send stop condition.
\r
494 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
497 bool EUSCI_B_I2C_masterSendMultiByteStopWithTimeout(uint16_t baseAddress,
\r
500 //If interrupts are not used, poll for flags
\r
501 if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCTXIE))
\r
503 //Poll for transmit interrupt flag.
\r
504 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG)) && --timeout)
\r
509 //Check if transfer timed out
\r
512 return (STATUS_FAIL);
\r
516 //Send stop condition.
\r
517 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
519 return (STATUS_SUCCESS);
\r
522 void EUSCI_B_I2C_masterReceiveStart(uint16_t baseAddress)
\r
524 //Set USCI in Receive mode
\r
525 HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~UCTR;
\r
527 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTT;
\r
530 uint8_t EUSCI_B_I2C_masterReceiveMultiByteNext(uint16_t baseAddress)
\r
532 return (HWREG16(baseAddress + OFS_UCBxRXBUF));
\r
535 uint8_t EUSCI_B_I2C_masterReceiveMultiByteFinish(uint16_t baseAddress)
\r
537 //Send stop condition.
\r
538 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
540 //Wait for Stop to finish
\r
541 while(HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTP)
\r
543 // Wait for RX buffer
\r
544 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCRXIFG))
\r
550 //Capture data from receive buffer after setting stop bit due to
\r
551 //MSP430 I2C critical timing.
\r
552 return (HWREG16(baseAddress + OFS_UCBxRXBUF));
\r
555 bool EUSCI_B_I2C_masterReceiveMultiByteFinishWithTimeout(uint16_t baseAddress,
\r
559 uint32_t timeout2 = timeout;
\r
561 //Send stop condition.
\r
562 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
564 //Wait for Stop to finish
\r
565 while((HWREG16(baseAddress + OFS_UCBxCTLW0) & UCTXSTP) && --timeout)
\r
570 //Check if transfer timed out
\r
573 return (STATUS_FAIL);
\r
576 // Wait for RX buffer
\r
577 while((!(HWREG16(baseAddress + OFS_UCBxIFG) & UCRXIFG)) && --timeout2)
\r
582 //Check if transfer timed out
\r
585 return (STATUS_FAIL);
\r
588 //Capture data from receive buffer after setting stop bit due to
\r
589 //MSP430 I2C critical timing.
\r
590 *txData = (HWREG8(baseAddress + OFS_UCBxRXBUF));
\r
592 return (STATUS_SUCCESS);
\r
595 void EUSCI_B_I2C_masterReceiveMultiByteStop(uint16_t baseAddress)
\r
597 //Send stop condition.
\r
598 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCTXSTP;
\r
601 void EUSCI_B_I2C_enableMultiMasterMode(uint16_t baseAddress)
\r
603 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
\r
604 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCMM;
\r
607 void EUSCI_B_I2C_disableMultiMasterMode(uint16_t baseAddress)
\r
609 HWREG16(baseAddress + OFS_UCBxCTLW0) |= UCSWRST;
\r
610 HWREG16(baseAddress + OFS_UCBxCTLW0) &= ~UCMM;
\r
613 uint8_t EUSCI_B_I2C_masterReceiveSingle(uint16_t baseAddress)
\r
615 //Polling RXIFG0 if RXIE is not enabled
\r
616 if(!(HWREG16(baseAddress + OFS_UCBxIE) & UCRXIE0))
\r
618 while(!(HWREG16(baseAddress + OFS_UCBxIFG) & UCRXIFG0))
\r
625 return (HWREG16(baseAddress + OFS_UCBxRXBUF));
\r
628 uint32_t EUSCI_B_I2C_getReceiveBufferAddress(uint16_t baseAddress)
\r
630 return (baseAddress + OFS_UCBxRXBUF);
\r
633 uint32_t EUSCI_B_I2C_getTransmitBufferAddress(uint16_t baseAddress)
\r
635 return (baseAddress + OFS_UCBxTXBUF);
\r
639 //*****************************************************************************
\r
641 //! Close the doxygen group for eusci_b_i2c_api
\r
644 //*****************************************************************************
\r