mirror of
https://github.com/licsber/micropython.git
synced 2024-09-20 00:50:24 +08:00
renesas-ra/ra/ra_i2c: Fix 1 byte and 2 bytes read issue.
Tested on Portenta C33 with AT24256B (addrsize=16) and SSD1306. Fixes issue #13280. Signed-off-by: Takeo Takahashi <takeo.takahashi.xv@renesas.com>
This commit is contained in:
parent
28b18c43fe
commit
81049edf7c
@ -426,7 +426,7 @@ void ra_i2c_init(R_IIC0_Type *i2c_inst, uint32_t scl, uint32_t sda, uint32_t bau
|
|||||||
i2c_inst->ICCR1_b.ICE = 1; // I2C enable
|
i2c_inst->ICCR1_b.ICE = 1; // I2C enable
|
||||||
ra_i2c_set_baudrate(i2c_inst, baudrate);
|
ra_i2c_set_baudrate(i2c_inst, baudrate);
|
||||||
i2c_inst->ICSER = 0x00; // I2C reset bus status enable register
|
i2c_inst->ICSER = 0x00; // I2C reset bus status enable register
|
||||||
i2c_inst->ICMR3_b.ACKWP = 0x01; // I2C allow to write ACKBT (transfer acknowledge bit)
|
i2c_inst->ICMR3_b.ACKWP = 0x00; // I2C not allow to write ACKBT (transfer acknowledge bit)
|
||||||
i2c_inst->ICIER = 0xFF; // Enable all interrupts
|
i2c_inst->ICIER = 0xFF; // Enable all interrupts
|
||||||
i2c_inst->ICCR1_b.IICRST = 0; // I2C internal reset
|
i2c_inst->ICCR1_b.IICRST = 0; // I2C internal reset
|
||||||
ra_i2c_irq_enable(i2c_inst);
|
ra_i2c_irq_enable(i2c_inst);
|
||||||
@ -480,6 +480,7 @@ void ra_i2c_xunit_read_byte(R_IIC0_Type *i2c_inst, xaction_unit_t *unit) {
|
|||||||
void ra_i2c_xunit_init(xaction_unit_t *unit, uint8_t *buf, uint32_t size, bool fread, void *next) {
|
void ra_i2c_xunit_init(xaction_unit_t *unit, uint8_t *buf, uint32_t size, bool fread, void *next) {
|
||||||
unit->m_bytes_transferred = 0;
|
unit->m_bytes_transferred = 0;
|
||||||
unit->m_bytes_transfer = size;
|
unit->m_bytes_transfer = size;
|
||||||
|
unit->m_bytes_total = size;
|
||||||
unit->m_fread = fread;
|
unit->m_fread = fread;
|
||||||
unit->buf = buf;
|
unit->buf = buf;
|
||||||
unit->next = (void *)next;
|
unit->next = (void *)next;
|
||||||
@ -531,6 +532,37 @@ static void ra_i2c_iceri_isr(R_IIC0_Type *i2c_inst) {
|
|||||||
static void ra_i2c_icrxi_isr(R_IIC0_Type *i2c_inst) {
|
static void ra_i2c_icrxi_isr(R_IIC0_Type *i2c_inst) {
|
||||||
xaction_unit_t *unit = current_xaction_unit;
|
xaction_unit_t *unit = current_xaction_unit;
|
||||||
xaction_t *action = current_xaction;
|
xaction_t *action = current_xaction;
|
||||||
|
// 1 byte or 2 bytes
|
||||||
|
if (unit->m_bytes_total <= 2) {
|
||||||
|
if (action->m_status == RA_I2C_STATUS_AddrWriteCompleted) {
|
||||||
|
action->m_status = RA_I2C_STATUS_FirstReceiveCompleted;
|
||||||
|
i2c_inst->ICMR3_b.WAIT = 1;
|
||||||
|
// need dummy read processes for 1 byte and 2 bytes receive
|
||||||
|
if (unit->m_bytes_total == 2) {
|
||||||
|
(void)i2c_inst->ICDRR; // dummy read for 2 bytes receive
|
||||||
|
} else { // m_bytes_total == 1
|
||||||
|
i2c_inst->ICMR3_b.ACKWP = 0x01; // enable write ACKBT (transfer acknowledge bit)
|
||||||
|
i2c_inst->ICMR3_b.ACKBT = 1;
|
||||||
|
i2c_inst->ICMR3_b.ACKWP = 0x00; // disable write ACKBT (transfer acknowledge bit)
|
||||||
|
(void)i2c_inst->ICDRR; // dummy read for 1 byte receive
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (unit->m_bytes_transfer == 2) { // last two data
|
||||||
|
i2c_inst->ICMR3_b.ACKWP = 0x01; // enable write ACKBT (transfer acknowledge bit)
|
||||||
|
i2c_inst->ICMR3_b.ACKBT = 1;
|
||||||
|
i2c_inst->ICMR3_b.ACKWP = 0x00; // disable write ACKBT (transfer acknowledge bit)
|
||||||
|
ra_i2c_xunit_read_byte(i2c_inst, unit);
|
||||||
|
} else { // last data
|
||||||
|
action->m_status = RA_I2C_STATUS_LastReceiveCompleted;
|
||||||
|
if (action->m_stop == true) {
|
||||||
|
i2c_inst->ICCR2_b.SP = 1; // request top condition
|
||||||
|
}
|
||||||
|
ra_i2c_xunit_read_byte(i2c_inst, unit);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 3 bytes or more
|
||||||
if (action->m_status == RA_I2C_STATUS_AddrWriteCompleted) {
|
if (action->m_status == RA_I2C_STATUS_AddrWriteCompleted) {
|
||||||
(void)i2c_inst->ICDRR; // dummy read
|
(void)i2c_inst->ICDRR; // dummy read
|
||||||
action->m_status = RA_I2C_STATUS_FirstReceiveCompleted;
|
action->m_status = RA_I2C_STATUS_FirstReceiveCompleted;
|
||||||
@ -542,7 +574,9 @@ static void ra_i2c_icrxi_isr(R_IIC0_Type *i2c_inst) {
|
|||||||
}
|
}
|
||||||
ra_i2c_xunit_read_byte(i2c_inst, unit);
|
ra_i2c_xunit_read_byte(i2c_inst, unit);
|
||||||
} else if (unit->m_bytes_transfer == 2) {
|
} else if (unit->m_bytes_transfer == 2) {
|
||||||
|
i2c_inst->ICMR3_b.ACKWP = 0x01; // enable write ACKBT (transfer acknowledge bit)
|
||||||
i2c_inst->ICMR3_b.ACKBT = 1;
|
i2c_inst->ICMR3_b.ACKBT = 1;
|
||||||
|
i2c_inst->ICMR3_b.ACKWP = 0x00; // disable write ACKBT (transfer acknowledge bit)
|
||||||
ra_i2c_xunit_read_byte(i2c_inst, unit);
|
ra_i2c_xunit_read_byte(i2c_inst, unit);
|
||||||
} else {
|
} else {
|
||||||
// last data
|
// last data
|
||||||
|
@ -47,9 +47,9 @@ typedef enum
|
|||||||
RA_I2C_STATUS_AddrWriteCompleted = 3,
|
RA_I2C_STATUS_AddrWriteCompleted = 3,
|
||||||
RA_I2C_STATUS_DataWriteCompleted = 4,
|
RA_I2C_STATUS_DataWriteCompleted = 4,
|
||||||
RA_I2C_STATUS_DataSendCompleted = 5,
|
RA_I2C_STATUS_DataSendCompleted = 5,
|
||||||
RA_I2C_STATUS_FirstReceiveCompleted = 5,
|
RA_I2C_STATUS_FirstReceiveCompleted = 6,
|
||||||
RA_I2C_STATUS_LastReceiveCompleted = 6,
|
RA_I2C_STATUS_LastReceiveCompleted = 7,
|
||||||
RA_I2C_STATUS_Stopped = 7,
|
RA_I2C_STATUS_Stopped = 8,
|
||||||
} xaction_status_t;
|
} xaction_status_t;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
@ -64,6 +64,7 @@ typedef enum
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
volatile uint32_t m_bytes_transferred;
|
volatile uint32_t m_bytes_transferred;
|
||||||
volatile uint32_t m_bytes_transfer;
|
volatile uint32_t m_bytes_transfer;
|
||||||
|
uint32_t m_bytes_total;
|
||||||
bool m_fread;
|
bool m_fread;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
void *next;
|
void *next;
|
||||||
@ -75,7 +76,7 @@ typedef struct {
|
|||||||
uint32_t m_current;
|
uint32_t m_current;
|
||||||
uint32_t m_address;
|
uint32_t m_address;
|
||||||
volatile xaction_status_t m_status;
|
volatile xaction_status_t m_status;
|
||||||
xaction_error_t m_error;
|
volatile xaction_error_t m_error;
|
||||||
bool m_stop;
|
bool m_stop;
|
||||||
} xaction_t;
|
} xaction_t;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user