8000 Merge pull request #751 from espressif/longReads · RickyPenang/arduino-esp32@2a1a62a · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 2a1a62a

Browse files
authored
Merge pull request espressif#751 from espressif/longReads
Add initial handling for long I2C reads.
2 parents 4470e28 + 1270f40 commit 2a1a62a

File tree

2 files changed

+72
-54
lines changed

2 files changed

+72
-54
lines changed

cores/esp32/esp32-hal-i2c.c

Lines changed: 70 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define DR_REG_I2C_EXT_BASE_FIXED 0x60013000
3232
#define DR_REG_I2C1_EXT_BASE_FIXED 0x60027000
3333

34+
#define COMMAND_BUFFER_LENGTH 16
35+
3436
struct i2c_struct_t {
3537
i2c_dev_t * dev;
3638
#if !CONFIG_DISABLE_HAL_LOCKS
@@ -1 8000 27,26 +129,25 @@ void i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bo
127129
i2c->dev->command[index].op_code = op_code;
128130
}
129131

130-
void i2cResetCmd(i2c_t * i2c){
131-
int i;
132+
void i2cResetCmd(i2c_t * i2c) {
133+
uint8_t i;
132134
for(i=0;i<16;i++){
133135
i2c->dev->command[i].val = 0;
134136
}
135137
}
136138

137-
void i2cResetFiFo(i2c_t * i2c)
138-
{
139+
void i2cResetFiFo(i2c_t * i2c) {
139140
i2c->dev->fifo_conf.tx_fifo_rst = 1;
140141
i2c->dev->fifo_conf.tx_fifo_rst = 0;
141142
i2c->dev->fifo_conf.rx_fifo_rst = 1;
142143
i2c->dev->fifo_conf.rx_fifo_rst = 0;
143144
}
144145

145-
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop)
146+
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint16_t len, bool sendStop)
146147
{
147148
int i;
148-
uint8_t index = 0;
149-
uint8_t dataLen = len + (addr_10bit?2:1);
149+
uint16_t index = 0;
150+
uint16_t dataLen = len + (addr_10bit?2:1);
150151
address = (address << 1);
151152

152153
if(i2c == NULL){
@@ -244,12 +245,25 @@ i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * dat
244245
return I2C_ERROR_OK;
245246
}
246247

247-
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop)
248+
uint8_t inc( uint8_t* index )
249+
{
250+
uint8_t i = index[ 0 ];
251+
if (++index[ 0 ] == COMMAND_BUFFER_LENGTH)
252+
{
253+
index[ 0 ] = 0;
254+
}
255+
256+
return i;
257+
}
258+
259+
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint16_t len, bool sendStop)
248260
{
249261
address = (address << 1) | 1;
250262
uint8_t addrLen = (addr_10bit?2:1);
251-
uint8_t index = 0;
252-
uint8_t cmdIdx;
263+
uint8_t amountRead[16];
264+
uint16_t index = 0;
265+
uint8_t cmdIdx = 0, currentCmdIdx = 0, nextCmdCount;
266+
bool stopped = false, isEndNear = false;
253267
uint8_t willRead;
254268

255269
if(i2c == NULL){
@@ -269,86 +283,90 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data
269283
i2cResetCmd(i2c);
270284

271285
//CMD START
272-
i2cSetCmd(i2c, 0, I2C_CMD_RSTART, 0, false, false, false);
286+
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_RSTART, 0, false, false, false);
273287

274288
//CMD WRITE ADDRESS
275289
i2c->dev->fifo_data.val = address & 0xFF;
276290
if(addr_10bit) {
277291
i2c->dev->fifo_data.val = (address >> 8) & 0xFF;
278292
}
279-
i2cSetCmd(i2c, 1, I2C_CMD_WRITE, addrLen, false, false, true);
293+
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_WRITE, addrLen, false, false, true);
294+
nextCmdCount = cmdIdx;
280295

281-
while(len) {
282-
cmdIdx = (index)?0:2;
283-
willRead = (len > 32)?32:(len-1);
284-
if(cmdIdx){
285-
i2cResetFiFo(i2c);
286-
}
287-
288-
if(willRead){
289-
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_READ, willRead, false, false, false);
290-
}
291-
292-
if((len - willRead) > 1) {
293-
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_END, 0, false, false, false);
294-
} else {
295-
willRead++;
296-
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_READ, 1, true, false, false);
297-
if(sendStop) {
298-
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_STOP, 0, false, false, false);
299-
}
300-
}
301-
302-
//Clear Interrupts
303-
i2c->dev->int_clr.val = 0xFFFFFFFF;
304-
305-
//START Transmission
306-
i2c->dev->ctr.trans_start = 1;
296+
//Clear Interrupts
297+
i2c->dev->int_clr.val = 0x00001FFF;
307298

299+
//START Transmission
300+
i2c->dev->ctr.trans_start = 1;
301+
while (!stopped) {
308302
//WAIT Transmission
309303
uint32_t startAt = millis();
310304
while(1) {
311305
//have been looping for too long
312-
if((millis() - startAt)>50){
313-
log_e("Timeout! Addr: %x", address >> 1);
306+
if((millis() - startAt)>50) {
307+
log_e("Timeout! Addr: %x, index %d", (address >> 1), index);
314308
I2C_MUTEX_UNLOCK();
315309
return I2C_ERROR_BUS;
316310
}
317311

318312
//Bus failed (maybe check for this while waiting?
319313
if(i2c->dev->int_raw.arbitration_lost) {
320-
log_e("Bus Fail! Addr: %x", address >> 1);
314+
log_e("Bus Fail! Addr: %x", (address >> 1));
321315
I2C_MUTEX_UNLOCK();
322316
return I2C_ERROR_BUS;
323317
}
324318

325319
//Bus timeout
326320
if(i2c->dev->int_raw.time_out) {
327-
log_e("Bus Timeout! Addr: %x", address >> 1);
321+
log_e("Bus Timeout! Addr: %x, index %d", (address >> 1), index );
328322
I2C_MUTEX_UNLOCK();
329323
return I2C_ERROR_TIMEOUT;
330324
}
331325

332326
//Transmission did not finish and ACK_ERR is set
333327
if(i2c->dev->int_raw.ack_err) {
334328
log_w("Ack Error! Addr: %x", address >> 1);
329+
while((i2c->dev->status_reg.bus_busy) && ((millis() - startAt)<50));
335330
I2C_MUTEX_UNLOCK();
336331
return I2C_ERROR_ACK;
337332
}
338333

339-
if(i2c->dev->command[cmdIdx-1].done) {
340-
break;
334+
// Save bytes from the buffer as they arrive instead of doing them at the end of the loop since there is no
335+
// pause from an END operation in this approach.
336+
if((!isEndNear) && (nextCmdCount < 2)) {
337+
if (willRead = ((len>32)?32:len)) {
338+
if (willRead > 1) {
339+
i2cSetCmd(i2c, cmdIdx, I2C_CMD_READ, (amountRead[ inc( &cmdIdx ) ] = willRead -1), false, false, false);
340+
nextCmdCount++;
341+
}
342+
i2cSetCmd(i2c, cmdIdx, I2C_CMD_READ, (amountRead[ inc( &cmdIdx ) ] = 1), (len<=32), false, false);
343+
nextCmdCount++;
344+
len -= willRead;
345+
} else {
346+
i2cSetCmd(i2c, inc( &cmdIdx ), I2C_CMD_STOP, 0, false, false, false);
347+
isEndNear = true;
348+
nextCmdCount++;
349+
}
341350
}
342-
}
343351

344-
int i = 0;
345-
while(i<willRead) {
346-
i++;
347-
data[index++] = i2c->dev->fifo_data.val & 0xFF;
352+
if(i2c->dev->command[currentCmdIdx].done) {
353+
nextCmdCount--;
354+
if (i2c->dev->command[currentCmdIdx].op_code == I2C_CMD_READ) {
355+
while(amountRead[currentCmdIdx]>0) {
356+
data[index++] = i2c->dev->fifo_data.val & 0xFF;
357+
amountRead[currentCmdIdx]--;
358+
}
359+
i2cResetFiFo(i2c);
360+
} else if (i2c->dev->command[currentCmdIdx].op_code == I2C_CMD_STOP) {
361+
stopped = true;
362+
}
363+
inc( &currentCmdIdx );
364+
break;
365+
}
348366
}
349-
len -= willRead;
350367
}
351368
I2C_MUTEX_UNLOCK();
369+
352370
return I2C_ERROR_OK;
353371
}
354372

@@ -425,7 +443,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
425443
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT1_CLK_EN);
426444
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST);
427445
}
428-
446+
429447
I2C_MUTEX_LOCK();
430448
i2c->dev->ctr.val = 0;
431449
i2c->dev->ctr.ms_mode = (slave_addr == 0);
@@ -434,7 +452,7 @@ i2c_t * i2cInit(uint8_t i2c_num, uint16_t slave_addr, bool addr_10bit_en)
434452
i2c->dev->ctr.clk_en = 1;
435453

436454
//the max clock number of receiving a data
437-
i2c->dev->timeout.tout = 400000;//clocks max=1048575
455+
i2c->dev->timeout.tout = 1048575;//clocks max=1048575
438456
//disable apb nonfifo access
439457
i2c->dev->fifo_conf.nonfifo_en = 0;
440458

cores/esp32/esp32-hal-i2c.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl);
4848
i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda);
4949
i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda);
5050

51-
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop);
52-
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop);
51+
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint16_t len, bool sendStop);
52+
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint16_t len, bool sendStop);
5353

5454
void i2cReset(i2c_t* i2c);
5555

0 commit comments

Comments
 (0)
0