Skip to content

Commit d24c71f

Browse files
committed
[NUC472/M453] Correct return of i2c_byte_write() on NAK
1 parent 57a22cd commit d24c71f

File tree

2 files changed

+44
-56
lines changed

2 files changed

+44
-56
lines changed

targets/TARGET_NUVOTON/TARGET_M451/i2c_api.c

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static void i2c0_vec(void);
4848
static void i2c1_vec(void);
4949
static void i2c_irq(i2c_t *obj);
5050
static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl);
51-
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv);
51+
static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked);
5252

5353
static struct nu_i2c_var i2c0_var = {
5454
.obj = NULL,
@@ -69,8 +69,6 @@ static const struct nu_modinit_s i2c_modinit_tab[] = {
6969
};
7070

7171
static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata);
72-
static int i2c_do_write(i2c_t *obj, char data, int naklastdata);
73-
static int i2c_do_read(i2c_t *obj, char *data, int naklastdata);
7472
static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync);
7573
#define NU_I2C_TIMEOUT_STAT_INT 500000
7674
#define NU_I2C_TIMEOUT_STOP 500000
@@ -98,6 +96,7 @@ static void i2c_rollback_vector_interrupt(i2c_t *obj);
9896

9997
#define TRANCTRL_STARTED (1)
10098
#define TRANCTRL_NAKLASTDATA (1 << 1)
99+
#define TRANCTRL_LASTDATANAKED (1 << 2)
101100

102101
uint32_t us_ticker_read(void);
103102

@@ -169,7 +168,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
169168
return I2C_ERROR_BUS_BUSY;
170169
}
171170

172-
if (i2c_do_write(obj, i2c_addr2data(address, 1), 0)) {
171+
if (i2c_byte_write(obj, i2c_addr2data(address, 1)) != 1) {
173172
i2c_stop(obj);
174173
return I2C_ERROR_NO_SLAVE;
175174
}
@@ -192,7 +191,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
192191
return I2C_ERROR_BUS_BUSY;
193192
}
194193

195-
if (i2c_do_write(obj, i2c_addr2data(address, 0), 0)) {
194+
if (i2c_byte_write(obj, i2c_addr2data(address, 0)) != 1) {
196195
i2c_stop(obj);
197196
return I2C_ERROR_NO_SLAVE;
198197
}
@@ -215,14 +214,22 @@ void i2c_reset(i2c_t *obj)
215214
int i2c_byte_read(i2c_t *obj, int last)
216215
{
217216
char data = 0;
218-
219-
i2c_do_read(obj, &data, last);
217+
i2c_do_tran(obj, &data, 1, 1, last);
220218
return data;
221219
}
222220

223221
int i2c_byte_write(i2c_t *obj, int data)
224222
{
225-
return i2c_do_write(obj, (data & 0xFF), 0) == 0 ? 1 : 0;
223+
char data_[1];
224+
data_[0] = data & 0xFF;
225+
226+
if (i2c_do_tran(obj, data_, 1, 0, 0) == 1 &&
227+
! (obj->i2c.tran_ctrl & TRANCTRL_LASTDATANAKED)) {
228+
return 1;
229+
}
230+
else {
231+
return 0;
232+
}
226233
}
227234

228235
#if DEVICE_I2CSLAVE
@@ -374,7 +381,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd
374381
}
375382
else {
376383
i2c_disable_int(obj);
377-
obj->i2c.tran_ctrl = 0;
378384
tran_len = obj->i2c.tran_pos - obj->i2c.tran_beg;
379385
obj->i2c.tran_beg = NULL;
380386
obj->i2c.tran_pos = NULL;
@@ -385,18 +391,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd
385391
return tran_len;
386392
}
387393

388-
static int i2c_do_write(i2c_t *obj, char data, int naklastdata)
389-
{
390-
char data_[1];
391-
data_[0] = data;
392-
return i2c_do_tran(obj, data_, 1, 0, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY;
393-
}
394-
395-
static int i2c_do_read(i2c_t *obj, char *data, int naklastdata)
396-
{
397-
return i2c_do_tran(obj, data, 1, 1, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY;
398-
}
399-
400394
static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync)
401395
{
402396
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
@@ -625,19 +619,19 @@ static void i2c_irq(i2c_t *obj)
625619
break;
626620

627621
case 0x30: // Master Transmit Data NACK
628-
i2c_fsm_tranfini(obj, 0);
622+
i2c_fsm_tranfini(obj, 1);
629623
break;
630624

631625
case 0x20: // Master Transmit Address NACK
632-
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
626+
i2c_fsm_tranfini(obj, 1);
633627
break;
634628

635629
case 0x38: // Master Arbitration Lost
636630
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
637631
break;
638632

639633
case 0x48: // Master Receive Address NACK
640-
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
634+
i2c_fsm_tranfini(obj, 1);
641635
break;
642636

643637
case 0x40: // Master Receive Address ACK
@@ -656,7 +650,7 @@ static void i2c_irq(i2c_t *obj)
656650
while (1);
657651
}
658652
#endif
659-
i2c_fsm_tranfini(obj, 0);
653+
i2c_fsm_tranfini(obj, 1);
660654
}
661655
else {
662656
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
@@ -823,10 +817,10 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl)
823817
obj->i2c.slaveaddr_state = NoData;
824818
}
825819

826-
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv)
820+
static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked)
827821
{
828-
if (obj->i2c.tran_pos) {
829-
obj->i2c.tran_pos += tran_pos_adv;
822+
if (lastdatanaked) {
823+
obj->i2c.tran_ctrl |= TRANCTRL_LASTDATANAKED;
830824
}
831825

832826
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;

targets/TARGET_NUVOTON/TARGET_NUC472/i2c_api.c

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static void i2c3_vec(void);
5151
static void i2c4_vec(void);
5252
static void i2c_irq(i2c_t *obj);
5353
static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl);
54-
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv);
54+
static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked);
5555

5656
static struct nu_i2c_var i2c0_var = {
5757
.obj = NULL,
@@ -87,8 +87,6 @@ static const struct nu_modinit_s i2c_modinit_tab[] = {
8787
};
8888

8989
static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastdata);
90-
static int i2c_do_write(i2c_t *obj, char data, int naklastdata);
91-
static int i2c_do_read(i2c_t *obj, char *data, int naklastdata);
9290
static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync);
9391
#define NU_I2C_TIMEOUT_STAT_INT 500000
9492
#define NU_I2C_TIMEOUT_STOP 500000
@@ -115,6 +113,7 @@ static void i2c_rollback_vector_interrupt(i2c_t *obj);
115113

116114
#define TRANCTRL_STARTED (1)
117115
#define TRANCTRL_NAKLASTDATA (1 << 1)
116+
#define TRANCTRL_LASTDATANAKED (1 << 2)
118117

119118
uint32_t us_ticker_read(void);
120119

@@ -186,7 +185,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
186185
return I2C_ERROR_BUS_BUSY;
187186
}
188187

189-
if (i2c_do_write(obj, i2c_addr2data(address, 1), 0)) {
188+
if (i2c_byte_write(obj, i2c_addr2data(address, 1)) != 1) {
190189
i2c_stop(obj);
191190
return I2C_ERROR_NO_SLAVE;
192191
}
@@ -209,7 +208,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
209208
return I2C_ERROR_BUS_BUSY;
210209
}
211210

212-
if (i2c_do_write(obj, i2c_addr2data(address, 0), 0)) {
211+
if (i2c_byte_write(obj, i2c_addr2data(address, 0)) != 1) {
213212
i2c_stop(obj);
214213
return I2C_ERROR_NO_SLAVE;
215214
}
@@ -232,14 +231,22 @@ void i2c_reset(i2c_t *obj)
232231
int i2c_byte_read(i2c_t *obj, int last)
233232
{
234233
char data = 0;
235-
236-
i2c_do_read(obj, &data, last);
234+
i2c_do_tran(obj, &data, 1, 1, last);
237235
return data;
238236
}
239237

240238
int i2c_byte_write(i2c_t *obj, int data)
241239
{
242-
return i2c_do_write(obj, (data & 0xFF), 0) == 0 ? 1 : 0;
240+
char data_[1];
241+
data_[0] = data & 0xFF;
242+
243+
if (i2c_do_tran(obj, data_, 1, 0, 0) == 1 &&
244+
! (obj->i2c.tran_ctrl & TRANCTRL_LASTDATANAKED)) {
245+
return 1;
246+
}
247+
else {
248+
return 0;
249+
}
243250
}
244251

245252
#if DEVICE_I2CSLAVE
@@ -391,7 +398,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd
391398
}
392399
else {
393400
i2c_disable_int(obj);
394-
obj->i2c.tran_ctrl = 0;
395401
tran_len = obj->i2c.tran_pos - obj->i2c.tran_beg;
396402
obj->i2c.tran_beg = NULL;
397403
obj->i2c.tran_pos = NULL;
@@ -402,18 +408,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd
402408
return tran_len;
403409
}
404410

405-
static int i2c_do_write(i2c_t *obj, char data, int naklastdata)
406-
{
407-
char data_[1];
408-
data_[0] = data;
409-
return i2c_do_tran(obj, data_, 1, 0, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY;
410-
}
411-
412-
static int i2c_do_read(i2c_t *obj, char *data, int naklastdata)
413-
{
414-
return i2c_do_tran(obj, data, 1, 1, naklastdata) == 1 ? 0 : I2C_ERROR_BUS_BUSY;
415-
}
416-
417411
static int i2c_do_trsn(i2c_t *obj, uint32_t i2c_ctl, int sync)
418412
{
419413
I2C_T *i2c_base = (I2C_T *) NU_MODBASE(obj->i2c.i2c);
@@ -655,19 +649,19 @@ static void i2c_irq(i2c_t *obj)
655649
break;
656650

657651
case 0x30: // Master Transmit Data NACK
658-
i2c_fsm_tranfini(obj, 0);
652+
i2c_fsm_tranfini(obj, 1);
659653
break;
660654

661655
case 0x20: // Master Transmit Address NACK
662-
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
656+
i2c_fsm_tranfini(obj, 1);
663657
break;
664658

665659
case 0x38: // Master Arbitration Lost
666660
i2c_fsm_reset(obj, I2C_CTL_SI_Msk | I2C_CTL_AA_Msk);
667661
break;
668662

669663
case 0x48: // Master Receive Address NACK
670-
i2c_fsm_tranfini(obj, -1); // Roll back data position to indicate slave address not ACKed
664+
i2c_fsm_tranfini(obj, 1);
671665
break;
672666

673667
case 0x40: // Master Receive Address ACK
@@ -686,7 +680,7 @@ static void i2c_irq(i2c_t *obj)
686680
while (1);
687681
}
688682
#endif
689-
i2c_fsm_tranfini(obj, 0);
683+
i2c_fsm_tranfini(obj, 1);
690684
}
691685
else {
692686
uint32_t i2c_ctl = I2C_CTL_SI_Msk | I2C_CTL_AA_Msk;
@@ -853,10 +847,10 @@ static void i2c_fsm_reset(i2c_t *obj, uint32_t i2c_ctl)
853847
obj->i2c.slaveaddr_state = NoData;
854848
}
855849

856-
static void i2c_fsm_tranfini(i2c_t *obj, int tran_pos_adv)
850+
static void i2c_fsm_tranfini(i2c_t *obj, int lastdatanaked)
857851
{
858-
if (obj->i2c.tran_pos) {
859-
obj->i2c.tran_pos += tran_pos_adv;
852+
if (lastdatanaked) {
853+
obj->i2c.tran_ctrl |= TRANCTRL_LASTDATANAKED;
860854
}
861855

862856
obj->i2c.tran_ctrl &= ~TRANCTRL_STARTED;

0 commit comments

Comments
 (0)