3434
3535#define I2C_PRIORITY 1
3636
37- typedef enum {
38- I2C_FREE = 0 ,
39- I2C_BUSY ,
40- I2C_NEVER_RESET ,
41- } i2c_status_t ;
42-
4337// Set each bit to indicate an active I2c
4438static uint8_t i2c_active = 0 ;
45- static i2c_status_t i2c_status [NUM_I2C ];
4639static volatile int i2c_err ;
4740
4841// I2C struct for configuring GPIO pins
@@ -68,7 +61,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
6861 self -> i2c_regs = MXC_I2C_GET_I2C (temp );
6962 }
7063
64+ // Check for valid I2C controller
7165 assert ((self -> i2c_id >= 0 ) && (self -> i2c_id < NUM_I2C ));
66+ assert (!(i2c_active & (1 << self -> i2c_id )));
7267
7368 // Init I2C as main / controller node (0x00 is ignored)
7469 if ((scl != NULL ) && (sda != NULL )) {
@@ -132,48 +127,43 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
132127
133128// Probe device in I2C bus
134129bool common_hal_busio_i2c_probe (busio_i2c_obj_t * self , uint8_t addr ) {
135- int32_t flags = 0x0 ;
136- bool ret = false ;
130+ uint32_t int_fl0 , int_fl1 ;
131+ bool ret = 0 ;
137132
138- MXC_I2C_ClearFlags (self -> i2c_regs , 0xFF , 0xFF );
139- MXC_I2C_EnableInt (self -> i2c_regs , 0xFF , 0xFF );
133+ // Clear FIFOs & all interrupt flags
134+ MXC_I2C_ClearRXFIFO (self -> i2c_regs );
135+ MXC_I2C_ClearTXFIFO (self -> i2c_regs );
136+ MXC_I2C_ClearFlags (self -> i2c_regs , 0xFFFFFF , 0xFFFFFF );
140137
141138 // Pre-load target address into transmit FIFO
142139 addr = (addr << 1 );
143140 self -> i2c_regs -> fifo = addr ;
144141
145142 // Set start bit & wait for it to clear
146- self -> i2c_regs -> mstctrl |= MXC_F_I2C_MSTCTRL_START ;
143+ MXC_I2C_Start ( self -> i2c_regs ) ;
147144
148145 // wait for ACK/NACK
149- // if tx_lockout occurs, clear the error and re-load the target address
150146 while (!(self -> i2c_regs -> intfl0 & MXC_F_I2C_INTFL0_ADDR_ACK ) &&
151147 !(self -> i2c_regs -> intfl0 & MXC_F_I2C_INTFL0_ADDR_NACK_ERR )) {
152- if (self -> i2c_regs -> intfl0 & MXC_F_I2C_INTFL0_TX_LOCKOUT ) {
153- self -> i2c_regs -> intfl0 |= MXC_F_I2C_INTFL0_TX_LOCKOUT ;
154- self -> i2c_regs -> fifo = addr ;
155- }
156148 }
157- flags = self -> i2c_regs -> intfl0 ;
158- self -> i2c_regs -> intfl0 = MXC_F_I2C_INTFL0_ADDR_ACK | MXC_F_I2C_INTFL0_ADDR_NACK_ERR
159149
160- // Set / Wait for stop
161- self -> i2c_regs -> mstctrl |= MXC_F_I2C_MSTCTRL_STOP ;
162- while (( self -> i2c_regs -> mstctrl & MXC_F_I2C_MSTCTRL_STOP )) {
163- ;
164- }
150+ // Save interrupt flags for ACK/NACK checking
151+ int_fl0 = self -> i2c_regs -> intfl0 ;
152+
153+ // Set / Wait for stop
154+ MXC_I2C_Stop ( self -> i2c_regs );
165155
166156 // Wait for controller not busy, then clear flags
167157 while (self -> i2c_regs -> status & MXC_F_I2C_STATUS_BUSY ) {
168158 ;
169159 }
160+ MXC_I2C_ClearFlags (self -> i2c_regs , 0xFFFFFF , 0xFFFFFF );
170161
171- if (flags & MXC_F_I2C_INTFL0_ADDR_ACK ) {
162+ if (int_fl0 & MXC_F_I2C_INTFL0_ADDR_ACK ) {
172163 ret = true;
173164 } else {
174165 ret = false;
175166 }
176- MXC_I2C_ClearFlags (self -> i2c_regs , 0xff , 0xff );
177167 return ret ;
178168}
179169
0 commit comments