34
34
35
35
#define I2C_PRIORITY 1
36
36
37
- typedef enum {
38
- I2C_FREE = 0 ,
39
- I2C_BUSY ,
40
- I2C_NEVER_RESET ,
41
- } i2c_status_t ;
42
-
43
37
// Set each bit to indicate an active I2c
44
38
static uint8_t i2c_active = 0 ;
45
- static i2c_status_t i2c_status [NUM_I2C ];
46
39
static volatile int i2c_err ;
47
40
48
41
// I2C struct for configuring GPIO pins
@@ -68,7 +61,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self,
68
61
self -> i2c_regs = MXC_I2C_GET_I2C (temp );
69
62
}
70
63
64
+ // Check for valid I2C controller
71
65
assert ((self -> i2c_id >= 0 ) && (self -> i2c_id < NUM_I2C ));
66
+ assert (!(i2c_active & (1 << self -> i2c_id )));
72
67
73
68
// Init I2C as main / controller node (0x00 is ignored)
74
69
if ((scl != NULL ) && (sda != NULL )) {
@@ -132,48 +127,43 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
132
127
133
128
// Probe device in I2C bus
134
129
bool 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 ;
137
132
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 );
140
137
141
138
// Pre-load target address into transmit FIFO
142
139
addr = (addr << 1 );
143
140
self -> i2c_regs -> fifo = addr ;
144
141
145
142
// 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 ) ;
147
144
148
145
// wait for ACK/NACK
149
- // if tx_lockout occurs, clear the error and re-load the target address
150
146
while (!(self -> i2c_regs -> intfl0 & MXC_F_I2C_INTFL0_ADDR_ACK ) &&
151
147
!(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
- }
156
148
}
157
- flags = self -> i2c_regs -> intfl0 ;
158
- self -> i2c_regs -> intfl0 = MXC_F_I2C_INTFL0_ADDR_ACK | MXC_F_I2C_INTFL0_ADDR_NACK_ERR
159
149
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 );
165
155
166
156
// Wait for controller not busy, then clear flags
167
157
while (self -> i2c_regs -> status & MXC_F_I2C_STATUS_BUSY ) {
168
158
;
169
159
}
160
+ MXC_I2C_ClearFlags (self -> i2c_regs , 0xFFFFFF , 0xFFFFFF );
170
161
171
- if (flags & MXC_F_I2C_INTFL0_ADDR_ACK ) {
162
+ if (int_fl0 & MXC_F_I2C_INTFL0_ADDR_ACK ) {
172
163
ret = true;
173
164
} else {
174
165
ret = false;
175
166
}
176
- MXC_I2C_ClearFlags (self -> i2c_regs , 0xff , 0xff );
177
167
return ret ;
178
168
}
179
169
0 commit comments