Skip to content

Commit cc7cfc7

Browse files
TakeoTakahashi2020dpgeorge
authored andcommitted
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 micropython#13280. Signed-off-by: Takeo Takahashi <[email protected]>
1 parent b979c5a commit cc7cfc7

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

ports/renesas-ra/ra/ra_i2c.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ void ra_i2c_init(R_IIC0_Type *i2c_inst, uint32_t scl, uint32_t sda, uint32_t bau
426426
i2c_inst->ICCR1_b.ICE = 1; // I2C enable
427427
ra_i2c_set_baudrate(i2c_inst, baudrate);
428428
i2c_inst->ICSER = 0x00; // I2C reset bus status enable register
429-
i2c_inst->ICMR3_b.ACKWP = 0x01; // I2C allow to write ACKBT (transfer acknowledge bit)
429+
i2c_inst->ICMR3_b.ACKWP = 0x00; // I2C not allow to write ACKBT (transfer acknowledge bit)
430430
i2c_inst->ICIER = 0xFF; // Enable all interrupts
431431
i2c_inst->ICCR1_b.IICRST = 0; // I2C internal reset
432432
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) {
480480
void ra_i2c_xunit_init(xaction_unit_t *unit, uint8_t *buf, uint32_t size, bool fread, void *next) {
481481
unit->m_bytes_transferred = 0;
482482
unit->m_bytes_transfer = size;
483+
unit->m_bytes_total = size;
483484
unit->m_fread = fread;
484485
unit->buf = buf;
485486
unit->next = (void *)next;
@@ -531,6 +532,37 @@ static void ra_i2c_iceri_isr(R_IIC0_Type *i2c_inst) {
531532
static void ra_i2c_icrxi_isr(R_IIC0_Type *i2c_inst) {
532533
xaction_unit_t *unit = current_xaction_unit;
533534
xaction_t *action = current_xaction;
535+
// 1 byte or 2 bytes
536+
if (unit->m_bytes_total <= 2) {
537+
if (action->m_status == RA_I2C_STATUS_AddrWriteCompleted) {
538+
action->m_status = RA_I2C_STATUS_FirstReceiveCompleted;
539+
i2c_inst->ICMR3_b.WAIT = 1;
540+
// need dummy read processes for 1 byte and 2 bytes receive
541+
if (unit->m_bytes_total == 2) {
542+
(void)i2c_inst->ICDRR; // dummy read for 2 bytes receive
543+
} else { // m_bytes_total == 1
544+
i2c_inst->ICMR3_b.ACKWP = 0x01; // enable write ACKBT (transfer acknowledge bit)
545+
i2c_inst->ICMR3_b.ACKBT = 1;
546+
i2c_inst->ICMR3_b.ACKWP = 0x00; // disable write ACKBT (transfer acknowledge bit)
547+
(void)i2c_inst->ICDRR; // dummy read for 1 byte receive
548+
}
549+
return;
550+
}
551+
if (unit->m_bytes_transfer == 2) { // last two data
552+
i2c_inst->ICMR3_b.ACKWP = 0x01; // enable write ACKBT (transfer acknowledge bit)
553+
i2c_inst->ICMR3_b.ACKBT = 1;
554+
i2c_inst->ICMR3_b.ACKWP = 0x00; // disable write ACKBT (transfer acknowledge bit)
555+
ra_i2c_xunit_read_byte(i2c_inst, unit);
556+
} else { // last data
557+
action->m_status = RA_I2C_STATUS_LastReceiveCompleted;
558+
if (action->m_stop == true) {
559+
i2c_inst->ICCR2_b.SP = 1; // request top condition
560+
}
561+
ra_i2c_xunit_read_byte(i2c_inst, unit);
562+
}
563+
return;
564+
}
565+
// 3 bytes or more
534566
if (action->m_status == RA_I2C_STATUS_AddrWriteCompleted) {
535567
(void)i2c_inst->ICDRR; // dummy read
536568
action->m_status = RA_I2C_STATUS_FirstReceiveCompleted;
@@ -542,7 +574,9 @@ static void ra_i2c_icrxi_isr(R_IIC0_Type *i2c_inst) {
542574
}
543575
ra_i2c_xunit_read_byte(i2c_inst, unit);
544576
} else if (unit->m_bytes_transfer == 2) {
577+
i2c_inst->ICMR3_b.ACKWP = 0x01; // enable write ACKBT (transfer acknowledge bit)
545578
i2c_inst->ICMR3_b.ACKBT = 1;
579+
i2c_inst->ICMR3_b.ACKWP = 0x00; // disable write ACKBT (transfer acknowledge bit)
546580
ra_i2c_xunit_read_byte(i2c_inst, unit);
547581
} else {
548582
// last data

ports/renesas-ra/ra/ra_i2c.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ typedef enum
4747
RA_I2C_STATUS_AddrWriteCompleted = 3,
4848
RA_I2C_STATUS_DataWriteCompleted = 4,
4949
RA_I2C_STATUS_DataSendCompleted = 5,
50-
RA_I2C_STATUS_FirstReceiveCompleted = 5,
51-
RA_I2C_STATUS_LastReceiveCompleted = 6,
52-
RA_I2C_STATUS_Stopped = 7,
50+
RA_I2C_STATUS_FirstReceiveCompleted = 6,
51+
RA_I2C_STATUS_LastReceiveCompleted = 7,
52+
RA_I2C_STATUS_Stopped = 8,
5353
} xaction_status_t;
5454

5555
typedef enum
@@ -64,6 +64,7 @@ typedef enum
6464
typedef struct {
6565
volatile uint32_t m_bytes_transferred;
6666
volatile uint32_t m_bytes_transfer;
67+
uint32_t m_bytes_total;
6768
bool m_fread;
6869
uint8_t *buf;
6970
void *next;
@@ -75,7 +76,7 @@ typedef struct {
7576
uint32_t m_current;
7677
uint32_t m_address;
7778
volatile xaction_status_t m_status;
78-
xaction_error_t m_error;
79+
volatile xaction_error_t m_error;
7980
bool m_stop;
8081
} xaction_t;
8182

0 commit comments

Comments
 (0)