34 #if defined(I2C_COUNT) && (I2C_COUNT > 0)
65 #define I2C_REF_VALID(ref) ((ref) == I2C0)
66 #elif (I2C_COUNT == 2)
67 #define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1))
68 #elif (I2C_COUNT == 3)
69 #define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1)|| (ref == I2C2))
77 #define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
80 #if defined( _SILICON_LABS_32B_SERIES_0 )
82 #elif defined( _SILICON_LABS_32B_SERIES_1 )
85 #warning "Max I2C transmission rate constant is not defined"
99 i2cStateStartAddrSend,
100 i2cStateAddrWFAckNack,
101 i2cStateAddrWF2ndAckNack,
102 i2cStateRStartAddrSend,
103 i2cStateRAddrWFAckNack,
105 i2cStateDataWFAckNack,
109 } I2C_TransferState_TypeDef;
123 I2C_TransferState_TypeDef state;
136 } I2C_Transfer_TypeDef;
150 static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 6, 4 + 4 };
153 static I2C_Transfer_TypeDef i2cTransfer[
I2C_COUNT];
186 return (freqHfper / ((n * (i2c->
CLKDIV + 1)) + I2C_CR_MAX));
260 #if defined( _SILICON_LABS_32B_SERIES_0 )
261 minFreq = 4200000;
break;
262 #elif defined( _SILICON_LABS_32B_SERIES_1 )
263 minFreq = 2000000;
break;
266 #if defined( _SILICON_LABS_32B_SERIES_0 )
267 minFreq = 11000000;
break;
268 #elif defined( _SILICON_LABS_32B_SERIES_1 )
269 minFreq = 5000000;
break;
272 #if defined( _SILICON_LABS_32B_SERIES_0 )
273 minFreq = 24400000;
break;
274 #elif defined( _SILICON_LABS_32B_SERIES_1 )
275 minFreq = 14000000;
break;
286 minFreq = 2000000;
break;
288 minFreq = 9000000;
break;
290 minFreq = 20000000;
break;
295 EFM_ASSERT(freqRef > minFreq);
307 n = (uint32_t)(i2cNSum[i2cMode]);
308 div = ((freqRef - (I2C_CR_MAX * freqScl)) / (n * freqScl)) - 1;
309 EFM_ASSERT(div >= 0);
318 i2c->
CLKDIV = (uint32_t)div;
337 EFM_ASSERT(I2C_REF_VALID(i2c));
355 EFM_ASSERT(I2C_REF_VALID(i2c));
432 I2C_Transfer_TypeDef *transfer;
435 EFM_ASSERT(I2C_REF_VALID(i2c));
440 transfer = i2cTransfer;
443 else if (i2c == I2C1)
445 transfer = i2cTransfer + 1;
459 if (pending & I2C_IF_ERRORS)
478 transfer->state = i2cStateDone;
482 switch (transfer->state)
487 case i2cStateStartAddrSend:
490 tmp = (((uint32_t)(seq->
addr) >> 8) & 0x06) | 0xf0;
497 tmp = (uint32_t)(seq->
addr) & 0xfe;
506 transfer->state = i2cStateAddrWFAckNack;
514 case i2cStateAddrWFAckNack:
519 transfer->state = i2cStateWFStopSent;
529 transfer->state = i2cStateAddrWF2ndAckNack;
537 transfer->state = i2cStateWFData;
538 if(seq->
buf[transfer->bufIndx].
len==1)
545 transfer->state = i2cStateDataSend;
555 case i2cStateAddrWF2ndAckNack:
556 if (pending & I2C_IF_NACK)
560 transfer->state = i2cStateWFStopSent;
563 else if (pending & I2C_IF_ACK)
571 transfer->state = i2cStateRStartAddrSend;
576 transfer->state = i2cStateDataSend;
585 case i2cStateRStartAddrSend:
588 tmp = ((seq->
addr >> 8) & 0x06) | 0xf0;
592 tmp = seq->
addr & 0xfe;
602 transfer->state = i2cStateRAddrWFAckNack;
612 case i2cStateRAddrWFAckNack:
613 if (pending & I2C_IF_NACK)
617 transfer->state = i2cStateWFStopSent;
620 else if (pending & I2C_IF_ACK)
627 transfer->state = i2cStateWFData;
631 transfer->state = i2cStateDataSend;
640 case i2cStateDataSend:
642 if (transfer->offset >= seq->
buf[transfer->bufIndx].
len)
645 transfer->offset = 0;
651 transfer->state = i2cStateRStartAddrSend;
658 transfer->state = i2cStateWFStopSent;
668 i2c->
TXDATA = (uint32_t)(seq->
buf[transfer->bufIndx].
data[transfer->offset++]);
669 transfer->state = i2cStateDataWFAckNack;
675 case i2cStateDataWFAckNack:
676 if (pending & I2C_IF_NACK)
680 transfer->state = i2cStateWFStopSent;
683 else if (pending & I2C_IF_ACK)
686 transfer->state = i2cStateDataSend;
698 unsigned int rxLen = seq->
buf[transfer->bufIndx].
len;
701 data = (uint8_t)(i2c->
RXDATA);
704 if (transfer->offset < rxLen)
706 seq->
buf[transfer->bufIndx].
data[transfer->offset++] = data;
710 if (transfer->offset >= rxLen)
719 transfer->state = i2cStateWFStopSent;
727 if ( (1<rxLen) && (transfer->offset == (rxLen-1)) )
741 case i2cStateWFStopSent:
745 transfer->state = i2cStateDone;
754 transfer->state = i2cStateDone;
761 if (transfer->state == i2cStateDone)
778 return transfer->result;
810 I2C_Transfer_TypeDef *transfer;
812 EFM_ASSERT(I2C_REF_VALID(i2c));
818 transfer = i2cTransfer;
821 else if (i2c == I2C1)
823 transfer = i2cTransfer + 1;
850 transfer->state = i2cStateStartAddrSend;
852 transfer->offset = 0;
853 transfer->bufIndx = 0;
Clock management unit (CMU) API.
#define _I2C_SADDRMASK_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_DIV_MASK
void I2C_Enable(I2C_TypeDef *i2c, bool enable)
Enable/disable I2C.
#define I2C_FLAG_WRITE
Indicate plain write sequence: S+ADDR(W)+DATA0+P.
I2C_TransferReturn_TypeDef
#define _I2C_IEN_RESETVALUE
#define I2C_FLAG_10BIT_ADDR
void I2C_Reset(I2C_TypeDef *i2c)
Reset I2C to same state as after a HW reset.
#define _I2C_CTRL_CLHR_SHIFT
#define _I2C_CTRL_CLHR_MASK
I2C_ClockHLR_TypeDef clhr
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
Initialize I2C.
#define _I2C_CTRL_SLAVE_SHIFT
struct I2C_TransferSeq_TypeDef::@0 buf[2]
#define _I2C_CTRL_RESETVALUE
void I2C_BusFreqSet(I2C_TypeDef *i2c, uint32_t freqRef, uint32_t freqScl, I2C_ClockHLR_TypeDef i2cMode)
Set I2C bus frequency.
Master mode transfer message structure used to define a complete I2C transfer sequence (from start to...
#define _I2C_CLKDIV_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_CTRL_EN_SHIFT
#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.
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).
#define _I2C_SADDR_RESETVALUE