34 #if defined(I2C_COUNT) && (I2C_COUNT > 0)
61 #define I2C_REF_VALID(ref) ((ref) == I2C0)
62 #elif (I2C_COUNT == 2)
63 #define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1))
64 #elif (I2C_COUNT == 3)
65 #define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1)|| (ref == I2C2))
73 #define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
76 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
78 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
81 #warning "Max I2C transmission rate constant is not defined"
95 i2cStateStartAddrSend,
96 i2cStateAddrWFAckNack,
97 i2cStateAddrWF2ndAckNack,
98 i2cStateRStartAddrSend,
99 i2cStateRAddrWFAckNack,
101 i2cStateDataWFAckNack,
105 } I2C_TransferState_TypeDef;
119 I2C_TransferState_TypeDef state;
132 } I2C_Transfer_TypeDef;
146 static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 6, 4 + 4 };
149 static I2C_Transfer_TypeDef i2cTransfer[
I2C_COUNT];
182 return (freqHfper / ((n * (i2c->
CLKDIV + 1)) + I2C_CR_MAX));
256 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
257 minFreq = 4200000;
break;
258 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
259 minFreq = 2000000;
break;
262 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
263 minFreq = 11000000;
break;
264 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
265 minFreq = 5000000;
break;
268 #if defined( _SILICON_LABS_32B_PLATFORM_1 )
269 minFreq = 24400000;
break;
270 #elif defined( _SILICON_LABS_32B_PLATFORM_2 )
271 minFreq = 14000000;
break;
282 minFreq = 2000000;
break;
284 minFreq = 9000000;
break;
286 minFreq = 20000000;
break;
291 EFM_ASSERT(freqRef > minFreq);
303 n = (uint32_t)(i2cNSum[i2cMode]);
304 div = ((freqRef - (I2C_CR_MAX * freqScl)) / (n * freqScl)) - 1;
305 EFM_ASSERT(div >= 0);
314 i2c->
CLKDIV = (uint32_t)div;
333 EFM_ASSERT(I2C_REF_VALID(i2c));
351 EFM_ASSERT(I2C_REF_VALID(i2c));
428 I2C_Transfer_TypeDef *transfer;
431 EFM_ASSERT(I2C_REF_VALID(i2c));
436 transfer = i2cTransfer;
439 else if (i2c ==
I2C1)
441 transfer = i2cTransfer + 1;
455 if (pending & I2C_IF_ERRORS)
474 transfer->state = i2cStateDone;
478 switch (transfer->state)
483 case i2cStateStartAddrSend:
486 tmp = (((uint32_t)(seq->
addr) >> 8) & 0x06) | 0xf0;
493 tmp = (uint32_t)(seq->
addr) & 0xfe;
502 transfer->state = i2cStateAddrWFAckNack;
510 case i2cStateAddrWFAckNack:
515 transfer->state = i2cStateWFStopSent;
525 transfer->state = i2cStateAddrWF2ndAckNack;
533 transfer->state = i2cStateWFData;
534 if(seq->
buf[transfer->bufIndx].
len==1)
541 transfer->state = i2cStateDataSend;
551 case i2cStateAddrWF2ndAckNack:
552 if (pending & I2C_IF_NACK)
556 transfer->state = i2cStateWFStopSent;
559 else if (pending & I2C_IF_ACK)
567 transfer->state = i2cStateRStartAddrSend;
572 transfer->state = i2cStateDataSend;
581 case i2cStateRStartAddrSend:
584 tmp = ((seq->
addr >> 8) & 0x06) | 0xf0;
588 tmp = seq->
addr & 0xfe;
598 transfer->state = i2cStateRAddrWFAckNack;
608 case i2cStateRAddrWFAckNack:
609 if (pending & I2C_IF_NACK)
613 transfer->state = i2cStateWFStopSent;
616 else if (pending & I2C_IF_ACK)
623 transfer->state = i2cStateWFData;
627 transfer->state = i2cStateDataSend;
636 case i2cStateDataSend:
638 if (transfer->offset >= seq->
buf[transfer->bufIndx].
len)
641 transfer->offset = 0;
647 transfer->state = i2cStateRStartAddrSend;
654 transfer->state = i2cStateWFStopSent;
664 i2c->
TXDATA = (uint32_t)(seq->
buf[transfer->bufIndx].
data[transfer->offset++]);
665 transfer->state = i2cStateDataWFAckNack;
671 case i2cStateDataWFAckNack:
672 if (pending & I2C_IF_NACK)
676 transfer->state = i2cStateWFStopSent;
679 else if (pending & I2C_IF_ACK)
682 transfer->state = i2cStateDataSend;
694 unsigned int rxLen = seq->
buf[transfer->bufIndx].
len;
697 data = (uint8_t)(i2c->
RXDATA);
700 if (transfer->offset < rxLen)
702 seq->
buf[transfer->bufIndx].
data[transfer->offset++] = data;
706 if (transfer->offset >= rxLen)
715 transfer->state = i2cStateWFStopSent;
723 if ( (1<rxLen) && (transfer->offset == (rxLen-1)) )
737 case i2cStateWFStopSent:
741 transfer->state = i2cStateDone;
750 transfer->state = i2cStateDone;
757 if (transfer->state == i2cStateDone)
774 return transfer->result;
806 I2C_Transfer_TypeDef *transfer;
808 EFM_ASSERT(I2C_REF_VALID(i2c));
814 transfer = i2cTransfer;
817 else if (i2c ==
I2C1)
819 transfer = i2cTransfer + 1;
846 transfer->state = i2cStateStartAddrSend;
848 transfer->offset = 0;
849 transfer->bufIndx = 0;
Clock management unit (CMU) API.
#define _I2C_IEN_RESETVALUE
Emlib peripheral API "assert" implementation.
#define I2C_FLAG_READ
Indicate plain read sequence: S+ADDR(R)+DATA0+P.
RAM and peripheral bit-field set and clear API.
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq)
Prepare and start an I2C transfer (single master mode only).
#define _I2C_CLKDIV_RESETVALUE
void I2C_Enable(I2C_TypeDef *i2c, bool enable)
Enable/disable I2C.
#define _I2C_CTRL_CLHR_MASK
#define I2C_FLAG_WRITE
Indicate plain write sequence: S+ADDR(W)+DATA0+P.
I2C_TransferReturn_TypeDef
#define I2C_FLAG_10BIT_ADDR
void I2C_Reset(I2C_TypeDef *i2c)
Reset I2C to same state as after a HW reset.
#define _I2C_SADDR_RESETVALUE
I2C_ClockHLR_TypeDef clhr
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
Initialize I2C.
#define _I2C_CTRL_RESETVALUE
#define _I2C_CLKDIV_DIV_MASK
struct I2C_TransferSeq_TypeDef::@0 buf[2]
void I2C_BusFreqSet(I2C_TypeDef *i2c, uint32_t freqRef, uint32_t freqScl, I2C_ClockHLR_TypeDef i2cMode)
Set I2C bus frequency.
#define _I2C_CTRL_EN_SHIFT
Master mode transfer message structure used to define a complete I2C transfer sequence (from start to...
#define _I2C_CTRL_CLHR_SHIFT
#define _I2C_SADDRMASK_RESETVALUE
__STATIC_INLINE void BUS_RegMaskedWrite(volatile uint32_t *addr, uint32_t mask, uint32_t val)
Perform peripheral register masked clear and value write.
#define I2C_FLAG_WRITE_READ
Indicate combined write/read sequence: S+ADDR(W)+DATA0+Sr+ADDR(R)+DATA1+P.
Inter-intergrated circuit (I2C) peripheral API.
__STATIC_INLINE void BUS_RegBitWrite(volatile uint32_t *addr, unsigned int bit, unsigned int val)
Perform a single-bit write operation on a peripheral register.
#define _I2C_CTRL_SLAVE_SHIFT
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c)
Get current configured I2C bus frequency.
uint16_t addr
Address to use after (repeated) start.
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
Continue an initiated I2C transfer (single master mode only).