@@ -51,7 +51,7 @@ static void i2c3_vec(void);
51
51
static void i2c4_vec (void );
52
52
static void i2c_irq (i2c_t * obj );
53
53
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 );
55
55
56
56
static struct nu_i2c_var i2c0_var = {
57
57
.obj = NULL ,
@@ -87,8 +87,6 @@ static const struct nu_modinit_s i2c_modinit_tab[] = {
87
87
};
88
88
89
89
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 );
92
90
static int i2c_do_trsn (i2c_t * obj , uint32_t i2c_ctl , int sync );
93
91
#define NU_I2C_TIMEOUT_STAT_INT 500000
94
92
#define NU_I2C_TIMEOUT_STOP 500000
@@ -115,6 +113,7 @@ static void i2c_rollback_vector_interrupt(i2c_t *obj);
115
113
116
114
#define TRANCTRL_STARTED (1)
117
115
#define TRANCTRL_NAKLASTDATA (1 << 1)
116
+ #define TRANCTRL_LASTDATANAKED (1 << 2)
118
117
119
118
uint32_t us_ticker_read (void );
120
119
@@ -186,7 +185,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
186
185
return I2C_ERROR_BUS_BUSY ;
187
186
}
188
187
189
- if (i2c_do_write (obj , i2c_addr2data (address , 1 ), 0 ) ) {
188
+ if (i2c_byte_write (obj , i2c_addr2data (address , 1 )) != 1 ) {
190
189
i2c_stop (obj );
191
190
return I2C_ERROR_NO_SLAVE ;
192
191
}
@@ -209,7 +208,7 @@ int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
209
208
return I2C_ERROR_BUS_BUSY ;
210
209
}
211
210
212
- if (i2c_do_write (obj , i2c_addr2data (address , 0 ), 0 ) ) {
211
+ if (i2c_byte_write (obj , i2c_addr2data (address , 0 )) != 1 ) {
213
212
i2c_stop (obj );
214
213
return I2C_ERROR_NO_SLAVE ;
215
214
}
@@ -232,14 +231,22 @@ void i2c_reset(i2c_t *obj)
232
231
int i2c_byte_read (i2c_t * obj , int last )
233
232
{
234
233
char data = 0 ;
235
-
236
- i2c_do_read (obj , & data , last );
234
+ i2c_do_tran (obj , & data , 1 , 1 , last );
237
235
return data ;
238
236
}
239
237
240
238
int i2c_byte_write (i2c_t * obj , int data )
241
239
{
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
+ }
243
250
}
244
251
245
252
#if DEVICE_I2CSLAVE
@@ -391,7 +398,6 @@ static int i2c_do_tran(i2c_t *obj, char *buf, int length, int read, int naklastd
391
398
}
392
399
else {
393
400
i2c_disable_int (obj );
394
- obj -> i2c .tran_ctrl = 0 ;
395
401
tran_len = obj -> i2c .tran_pos - obj -> i2c .tran_beg ;
396
402
obj -> i2c .tran_beg = NULL ;
397
403
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
402
408
return tran_len ;
403
409
}
404
410
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
-
417
411
static int i2c_do_trsn (i2c_t * obj , uint32_t i2c_ctl , int sync )
418
412
{
419
413
I2C_T * i2c_base = (I2C_T * ) NU_MODBASE (obj -> i2c .i2c );
@@ -655,19 +649,19 @@ static void i2c_irq(i2c_t *obj)
655
649
break ;
656
650
657
651
case 0x30 : // Master Transmit Data NACK
658
- i2c_fsm_tranfini (obj , 0 );
652
+ i2c_fsm_tranfini (obj , 1 );
659
653
break ;
660
654
661
655
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 );
663
657
break ;
664
658
665
659
case 0x38 : // Master Arbitration Lost
666
660
i2c_fsm_reset (obj , I2C_CTL_SI_Msk | I2C_CTL_AA_Msk );
667
661
break ;
668
662
669
663
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 );
671
665
break ;
672
666
673
667
case 0x40 : // Master Receive Address ACK
@@ -686,7 +680,7 @@ static void i2c_irq(i2c_t *obj)
686
680
while (1 );
687
681
}
688
682
#endif
689
- i2c_fsm_tranfini (obj , 0 );
683
+ i2c_fsm_tranfini (obj , 1 );
690
684
}
691
685
else {
692
686
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)
853
847
obj -> i2c .slaveaddr_state = NoData ;
854
848
}
855
849
856
- static void i2c_fsm_tranfini (i2c_t * obj , int tran_pos_adv )
850
+ static void i2c_fsm_tranfini (i2c_t * obj , int lastdatanaked )
857
851
{
858
- if (obj -> i2c . tran_pos ) {
859
- obj -> i2c .tran_pos += tran_pos_adv ;
852
+ if (lastdatanaked ) {
853
+ obj -> i2c .tran_ctrl |= TRANCTRL_LASTDATANAKED ;
860
854
}
861
855
862
856
obj -> i2c .tran_ctrl &= ~TRANCTRL_STARTED ;
0 commit comments