Skip to content

Commit fbb7b02

Browse files
Xie,Qisys_maker
Xie,Qi
authored and
sys_maker
committed
JIRA-640 I2C operations are sometimes timing out causing a long delay in between i2C operations
fix this issue by call complete callback if no stop command issue at the end of transfer.
1 parent 160751a commit fbb7b02

File tree

6 files changed

+38
-26
lines changed

6 files changed

+38
-26
lines changed

cores/arduino/i2c.c

+17-20
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ static void ss_i2c_err(uint32_t dev_id)
4848
i2c_err_source = dev_id;
4949
}
5050

51-
static int wait_rx_or_err(bool no_stop){
51+
static int wait_rx_or_err()
52+
{
5253
uint64_t timeout = TIMEOUT_MS * 200;
5354
while(timeout--) {
5455
if (i2c_err_detect) {
@@ -65,20 +66,17 @@ static int wait_rx_or_err(bool no_stop){
6566
return I2C_ERROR_OTHER; // other error
6667
}
6768
}
68-
if (!no_stop) {
69-
if (i2c_rx_complete) {
70-
return I2C_OK;
71-
}
69+
if (i2c_rx_complete) {
70+
return I2C_OK;
7271
}
7372
delayMicroseconds(10);
7473
}
75-
if (!no_stop)
76-
return I2C_TIMEOUT;
77-
else
78-
return I2C_OK;
74+
75+
return I2C_TIMEOUT;
7976
}
8077

81-
static int wait_tx_or_err(bool no_stop){
78+
static int wait_tx_or_err()
79+
{
8280
uint64_t timeout = TIMEOUT_MS * 200;
8381
while(timeout--) {
8482
if (i2c_err_detect) {
@@ -95,17 +93,12 @@ static int wait_tx_or_err(bool no_stop){
9593
return I2C_ERROR_OTHER; // other error
9694
}
9795
}
98-
if (!no_stop) {
99-
if (i2c_tx_complete) {
96+
if (i2c_tx_complete) {
10097
return I2C_OK;
101-
}
10298
}
10399
delayMicroseconds(10);
104100
}
105-
if (!no_stop)
106-
return I2C_TIMEOUT;
107-
else
108-
return I2C_OK;
101+
return I2C_TIMEOUT;
109102
}
110103

111104
static int wait_dev_ready(I2C_CONTROLLER controller_id, bool no_stop){
@@ -116,9 +109,13 @@ static int wait_dev_ready(I2C_CONTROLLER controller_id, bool no_stop){
116109
if (ret == I2C_OK) {
117110
return I2C_OK;
118111
}
119-
if (ret == I2C_BUSY) {
112+
else if (ret == I2C_BUSY) {
120113
delayMicroseconds(10);
121114
}
115+
else
116+
{
117+
return I2C_TIMEOUT - ret;
118+
}
122119
}
123120
return I2C_TIMEOUT - ret;
124121
}
@@ -202,7 +199,7 @@ int i2c_writebytes(uint8_t *bytes, uint8_t length, bool no_stop)
202199
i2c_err_detect = 0;
203200
i2c_err_source = 0;
204201
ss_i2c_transfer(I2C_SENSING_0, bytes, length, 0, 0, i2c_slave, no_stop);
205-
ret = wait_tx_or_err(no_stop);
202+
ret = wait_tx_or_err();
206203
if (ret)
207204
return ret;
208205
ret = wait_dev_ready(I2C_SENSING_0, no_stop);
@@ -219,7 +216,7 @@ int i2c_readbytes(uint8_t *buf, int length, bool no_stop)
219216
i2c_err_detect = 0;
220217
i2c_err_source = 0;
221218
ss_i2c_transfer(I2C_SENSING_0, 0, 0, buf, length, i2c_slave, no_stop);
222-
ret = wait_rx_or_err(no_stop);
219+
ret = wait_rx_or_err();
223220
if (ret)
224221
return ret;
225222
ret = wait_dev_ready(I2C_SENSING_0, no_stop);

libraries/Wire/examples/bus_scan/bus_scan.ino

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void setup()
4242
Wire.begin();
4343

4444
Serial.begin(115200);
45+
while(!Serial);
4546
}
4647

4748
boolean toggle = false; // state of the LED

system/libarc32_arduino101/drivers/i2c_priv.h

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ typedef struct i2c_info {
133133
uint8_t *i2c_write_buff;
134134
uint8_t *i2c_read_buff;
135135
uint8_t restart;
136+
uint8_t send_stop;
136137

137138
/* Callbacks */
138139
IO_CB_FUNC tx_cb;

system/libarc32_arduino101/drivers/ss_dw_i2c.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static void recv_data(i2c_info_pt dev)
9292
}
9393

9494

95-
void i2c_fill_fifo(i2c_info_pt dev, bool no_stop)
95+
void i2c_fill_fifo(i2c_info_pt dev)
9696
{
9797
uint32_t i, tx_cnt, data;
9898

@@ -114,7 +114,7 @@ void i2c_fill_fifo(i2c_info_pt dev, bool no_stop)
114114

115115
if( dev->tx_len == 1)
116116
{ // last byte to write
117-
if (! no_stop)
117+
if (dev->send_stop)
118118
data |= I2C_STOP_CMD;
119119
}
120120
dev->tx_len -= 1;
@@ -125,7 +125,7 @@ void i2c_fill_fifo(i2c_info_pt dev, bool no_stop)
125125
data = I2C_PUSH_DATA | I2C_READ_CMD;
126126
if (dev->rx_tx_len == 1)
127127
{ // last dummy byte to write
128-
if(! no_stop)
128+
if(dev->send_stop)
129129
data |= I2C_STOP_CMD;
130130
if(dev->restart)
131131
{
@@ -143,13 +143,17 @@ void i2c_fill_fifo(i2c_info_pt dev, bool no_stop)
143143
static void xmit_data(i2c_info_pt dev)
144144
{
145145
int mask;
146-
i2c_fill_fifo(dev, false);
146+
i2c_fill_fifo(dev);
147147
if (dev->rx_tx_len <= 0)
148148
{
149149
mask = REG_READ( I2C_INTR_MASK );
150150
mask &= ~(R_TX_EMPTY);
151151
mask |= R_STOP_DETECTED;
152152
REG_WRITE(I2C_INTR_MASK, mask);
153+
if ((dev->rx_len == 0) && (!dev->send_stop))
154+
{
155+
end_data_transfer( dev );
156+
}
153157
}
154158
}
155159

system/libarc32_arduino101/drivers/ss_dw_i2c.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#define SS_DW_I2C_H_
4040
#include <stdbool.h>
4141
void i2c_mst_err_ISR_proc(i2c_info_pt dev);
42-
void i2c_fill_fifo(i2c_info_pt dev, bool no_stop);
42+
void i2c_fill_fifo(i2c_info_pt dev);
4343
void i2c_mst_rx_avail_ISR_proc(i2c_info_pt dev);
4444
void i2c_mst_tx_req_ISR_proc(i2c_info_pt dev);
4545
void i2c_mst_stop_detected_ISR_proc(i2c_info_pt dev);

system/libarc32_arduino101/drivers/ss_i2c_iface.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,15 @@ DRIVER_API_RC ss_i2c_transfer(I2C_CONTROLLER controller_id, uint8_t *data_write,
347347
return DRV_RC_FAIL;
348348
}
349349

350+
if (!no_stop)
351+
{
352+
dev->send_stop = true;
353+
}
354+
else
355+
{
356+
dev->send_stop = false;
357+
}
358+
350359
if ((data_read_len == 0) && (data_write_len == 0))
351360
{
352361
//Workaround: we know that we are doing I2C bus scan.
@@ -376,7 +385,7 @@ DRIVER_API_RC ss_i2c_transfer(I2C_CONTROLLER controller_id, uint8_t *data_write,
376385
dev->i2c_read_buff = data_read;
377386
dev->total_read_bytes = 0;
378387
dev->total_write_bytes = 0;
379-
i2c_fill_fifo(dev, no_stop);
388+
i2c_fill_fifo(dev);
380389

381390
interrupt_unlock(saved);
382391

0 commit comments

Comments
 (0)