Skip to content

Commit cbbf34d

Browse files
committed
Refactor ports/analog/common-hal/busio i2c probe function.
- Used direct hardware values to rely on common HW implementation - Accounted for TX Lockout conditions in Transmit FIFO causing errors Signed-off-by: Brandon Hurst <[email protected]>
1 parent a305ece commit cbbf34d

File tree

1 file changed

+39
-15
lines changed
  • ports/analog/common-hal/busio

1 file changed

+39
-15
lines changed

ports/analog/common-hal/busio/I2C.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,25 +132,49 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) {
132132

133133
// Probe device in I2C bus
134134
bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) {
135-
int nack = 0;
135+
int32_t flags = 0x0;
136+
bool ret = false;
137+
138+
MXC_I2C_ClearFlags(self->i2c_regs, 0xFF, 0xFF);
139+
MXC_I2C_EnableInt(self->i2c_regs, 0xFF, 0xFF);
140+
141+
// Pre-load target address into transmit FIFO
142+
addr = (addr << 1);
143+
self->i2c_regs->fifo = addr;
144+
145+
// Set start bit & wait for it to clear
146+
self->i2c_regs->mstctrl |= MXC_F_I2C_MSTCTRL_START;
147+
148+
// wait for ACK/NACK
149+
// if tx_lockout occurs, clear the error and re-load the target address
150+
while (!(self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_ADDR_ACK) &&
151+
!(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+
}
157+
flags = self->i2c_regs->intfl0;
158+
self->i2c_regs->intfl0 = MXC_F_I2C_INTFL0_ADDR_ACK | MXC_F_I2C_INTFL0_ADDR_NACK_ERR
136159

137-
mxc_i2c_req_t addr_req = {
138-
.addr = addr,
139-
.i2c = self->i2c_regs,
140-
.tx_len = 0,
141-
.tx_buf = NULL,
142-
.rx_len = 0,
143-
.rx_buf = NULL,
144-
.callback = NULL
145-
};
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+
}
146165

147-
// Probe the address
148-
nack = MXC_I2C_MasterTransaction(&addr_req);
149-
if (nack) {
150-
return false;
166+
// Wait for controller not busy, then clear flags
167+
while (self->i2c_regs->status & MXC_F_I2C_STATUS_BUSY) {
168+
;
169+
}
170+
171+
if (flags & MXC_F_I2C_INTFL0_ADDR_ACK) {
172+
ret = true;
151173
} else {
152-
return true;
174+
ret = false;
153175
}
176+
MXC_I2C_ClearFlags(self->i2c_regs, 0xff, 0xff);
177+
return ret;
154178
}
155179

156180
// Lock I2C bus

0 commit comments

Comments
 (0)