int i2c_byte_write(i2c_t *obj, int data) { int ack = 0; int status; int timeout = 0; status = i2c_do_write(obj, (data & 0xFF)); if (status != 0) { i2c_set_SR2_NACKF_STOP(obj); } else { while (((i2c_status(obj) & SR2_RDRF) == 0) && ((i2c_status(obj) & SR2_TEND) == 0)) { timeout++; if (timeout >= WAIT_TIMEOUT) { return ack; } } /* check ACK/NACK */ if ((REG(SR2.UINT32) & SR2_NACKF) != 0) { /* NACK */ i2c_set_SR2_NACKF_STOP(obj); } else { ack = 1; } } return ack; }
int i2c_slave_write(i2c_t *obj, const char *data, int length) { int count = 0; int status = 0; if(length <= 0) { return 0; } while ((count < length) && (status == 0)) { status = i2c_do_write(obj, data[count]); if(status == 0) { /* Wait send end */ status = i2c_wait_TEND(obj); if ((status != 0) || ((count < (length - 1)) && ((REG(SR2.UINT32) & SR2_NACKF) != 0))) { /* NACK */ break; } } count++; } /* dummy read */ (void)REG(DRR.UINT32); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); return count; }
inline int i2c_stop(i2c_t *obj) { (void)i2c_set_STOP(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); return 0; }
static void i2c_tx_irq(IRQn_Type irq_num, uint32_t index) { i2c_t *obj = i2c_data[index].async_obj; if ((REG(SR2.UINT32) & SR2_NACKF)) { /* Slave sends NACK */ i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } if (obj->tx_buff.pos == obj->tx_buff.length) { /* All datas have tranferred */ /* Clear TEND */ REG(SR2.UINT32) &= ~(SR2_TEND); /* If not repeated start, send stop. */ if (i2c_data[index].shouldStop && obj->rx_buff.length == 0) { (void)i2c_set_STOP(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); i2c_transfer_finished(obj); } else { (void)i2c_restart(obj); (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; if (obj->rx_buff.length) { /* Ready to read */ i2c_set_MR3_ACK(obj); /* Disable INTRIICTEI */ REG(IER.UINT8[0]) &= ~(1 << 6); /* Send Slave address */ if (i2c_read_address_write(obj, (i2c_data[index].address | 0x01)) != 0) { i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } } else { i2c_transfer_finished(obj); } } } else { /* Send next 1 byte */ if (i2c_do_write(obj, *(uint8_t *)obj->tx_buff.buffer) != 0) { i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_ERROR_NO_SLAVE; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } obj->tx_buff.buffer = (uint8_t *)obj->tx_buff.buffer + 1; ++obj->tx_buff.pos; } }
int i2c_slave_write(i2c_t *obj, const char *data, int length) { int count = 0; int status = 0; if(length <= 0) { return 0; } while ((count < length) && (status == 0)) { status = i2c_do_write(obj, data[count]); count++; } if (status == 0) { /* Wait send end */ status = i2c_wait_TEND(obj); if (status != 0) { i2c_set_err_noslave(obj, 1); return 0; } } /* dummy read */ (void)REG(DRR.UINT32); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); return count; }
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) { int cnt; int status; /* There is a STOP condition for last processing */ if (obj->last_stop_flag != 0) { status = i2c_start(obj); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_BUS_BUSY; } } obj->last_stop_flag = stop; /* Send Slave address */ status = i2c_do_write(obj, address); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } /* Wait send end */ status = i2c_wait_TEND(obj); if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) { /* Slave sends NACK */ i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } /* Send Write data */ for (cnt=0; cnt<length; cnt++) { status = i2c_do_write(obj, data[cnt]); if(status != 0) { i2c_set_err_noslave(obj); return cnt; } else { /* Wait send end */ status = i2c_wait_TEND(obj); if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) { /* Slave sends NACK */ i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } } } /* If not repeated start, send stop. */ if (stop) { (void)i2c_set_STOP(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); } else { (void)i2c_restart(obj); (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; } return length; }
static void i2c_set_err_noslave(i2c_t *obj, int stop) { if (stop) { (void)i2c_stop(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); } else { (void)i2c_restart(obj); (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; } }
int i2c_byte_read(i2c_t *obj, int last) { int status; int data; data = i2c_do_read(obj, last); /* wait for it to arrive */ status = i2c_wait_RDRF(obj); if (status != 0) { i2c_set_SR2_NACKF_STOP(obj); return I2C_ERROR_NO_SLAVE; } return data; }
void i2c_reset(i2c_t *obj) { (void)i2c_set_STOP(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); }
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) { int count = 0; int status; int value; volatile uint32_t work_reg = 0; if(length <= 0) { return 0; } i2c_set_MR3_ACK(obj); /* There is a STOP condition for last processing */ if (obj->last_stop_flag != 0) { status = i2c_start(obj); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_BUS_BUSY; } } obj->last_stop_flag = stop; /* Send Slave address */ status = i2c_read_address_write(obj, (address | 0x01)); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } /* wait RDRF */ status = i2c_wait_RDRF(obj); /* check ACK/NACK */ if ((status != 0) || ((REG(SR2.UINT32) & SR2_NACKF) != 0)) { /* Slave sends NACK */ (void)i2c_set_STOP(obj); /* dummy read */ value = REG(DRR.UINT32); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); obj->last_stop_flag = 1; return I2C_ERROR_NO_SLAVE; } /* Read in all except last byte */ if (length > 2) { /* dummy read */ value = REG(DRR.UINT32); for (count = 0; count < (length - 1); count++) { /* wait for it to arrive */ status = i2c_wait_RDRF(obj); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } /* Recieve the data */ if (count == (length - 2)) { value = i2c_do_read(obj, 1); } else if ((length >= 3) && (count == (length - 3))) { value = i2c_do_read(obj, 2); } else { value = i2c_do_read(obj, 0); } data[count] = (char)value; } } else if (length == 2) { /* Set MR3 WATI bit is 1 */ REG(MR3.UINT32) |= MR3_WAIT; /* dummy read */ value = REG(DRR.UINT32); /* wait for it to arrive */ status = i2c_wait_RDRF(obj); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } i2c_set_MR3_NACK(obj); data[count] = (char)REG(DRR.UINT32); count++; } else { /* length == 1 */ /* Set MR3 WATI bit is 1 */; REG(MR3.UINT32) |= MR3_WAIT; i2c_set_MR3_NACK(obj); /* dummy read */ value = REG(DRR.UINT32); } /* wait for it to arrive */ status = i2c_wait_RDRF(obj); if (status != 0) { i2c_set_err_noslave(obj); return I2C_ERROR_NO_SLAVE; } /* If not repeated start, send stop. */ if (stop) { (void)i2c_set_STOP(obj); /* RIICnDRR read */ value = (REG(DRR.UINT32) & 0xFF); data[count] = (char)value; /* RIICnMR3.WAIT = 0 */ REG(MR3.UINT32) &= ~MR3_WAIT; (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); } else { (void)i2c_restart(obj); /* RIICnDRR read */ value = (REG(DRR.UINT32) & 0xFF); data[count] = (char)value; /* RIICnMR3.WAIT = 0 */ REG(MR3.UINT32) &= ~MR3_WAIT; (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; } return length; }
static void i2c_set_err_noslave(i2c_t *obj) { (void)i2c_set_STOP(obj); (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); obj->last_stop_flag = 1; }
static void i2c_rx_irq(IRQn_Type irq_num, uint32_t index) { i2c_t *obj = i2c_data[index].async_obj; if (obj->rx_buff.pos == SIZE_MAX) { if ((REG(SR2.UINT32) & SR2_NACKF) != 0) { /* Slave sends NACK */ (void)i2c_set_STOP(obj); /* dummy read */ if (REG(DRR.UINT32)) {} (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); obj->i2c.last_stop_flag = 1; i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } if (obj->rx_buff.length == 1) { /* length == 1 */ /* Set MR3 WAIT bit is 1 */; REG(MR3.UINT32) |= MR3_WAIT; i2c_set_MR3_NACK(obj); } else if (obj->rx_buff.length == 2) { /* Set MR3 WAIT bit is 1 */ REG(MR3.UINT32) |= MR3_WAIT; } /* dummy read */ if (REG(DRR.UINT32)) {} obj->rx_buff.pos = 0; return; } if ((REG(SR2.UINT32) & SR2_NACKF) != 0) { /* Slave sends NACK */ i2c_set_err_noslave(obj); i2c_data[index].event = I2C_EVENT_ERROR | I2C_EVENT_TRANSFER_EARLY_NACK; i2c_abort_asynch(obj); ((void (*)())i2c_data[index].async_callback)(); return; } else { switch (obj->rx_buff.length - obj->rx_buff.pos) { case 1: /* Finished */ /* If not repeated start, send stop. */ if (i2c_data[index].shouldStop) { (void)i2c_set_STOP(obj); /* RIICnDRR read */ *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF; /* RIICnMR3.WAIT = 0 */ REG(MR3.UINT32) &= ~MR3_WAIT; (void)i2c_wait_STOP(obj); i2c_set_SR2_NACKF_STOP(obj); } else { (void)i2c_restart(obj); /* RIICnDRR read */ *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF; /* RIICnMR3.WAIT = 0 */ REG(MR3.UINT32) &= ~MR3_WAIT; (void)i2c_wait_START(obj); /* SR2.START = 0 */ REG(SR2.UINT32) &= ~SR2_START; } i2c_transfer_finished(obj); return; case 2: i2c_set_MR3_NACK(obj); break; case 3: /* this time is befor last byte read */ /* Set MR3 WAIT bit is 1 */ REG(MR3.UINT32) |= MR3_WAIT; break; default: i2c_set_MR3_ACK(obj); break; } *(uint8_t *)obj->rx_buff.buffer = REG(DRR.UINT32) & 0xFF; obj->rx_buff.buffer = (uint8_t *)obj->rx_buff.buffer + 1; ++obj->rx_buff.pos; } }