Skip to content

Commit 8cdf387

Browse files
author
Chuck Todd
committed
Memory Leak, Reset() cleanup, add UserSelectable Timeout
Calling Wire.reset() would cause a heap memory leak, also, possible failure because I did not release the ISR. And not releasing the EventGroup Added a Wire.setTimeout(millis) to allow user selectable Gross Timeout instead of the hardwired 50ms.
1 parent e5f56eb commit 8cdf387

File tree

4 files changed

+25
-8
lines changed

4 files changed

+25
-8
lines changed

cores/esp32/esp32-hal-i2c.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ for(uint32_t a=1;a<=INTBUFFMAX;a++){
906906
}
907907
}
908908

909-
i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount){
909+
i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis){
910910
/* do the hard stuff here
911911
install ISR if necessary
912912
setup EventGroup
@@ -1028,9 +1028,9 @@ if(!i2c->intr_handle){ // create ISR I2C_0 only,
10281028
//hang until it completes.
10291029

10301030
// how many ticks should it take to transfer totalBytes thru the I2C hardware,
1031-
// add 50ms just for kicks
1031+
// add user supplied timeOutMillis to Calc Value
10321032

1033-
portTickType ticksTimeOut = ((totalBytes /(i2cGetFrequency(i2c)/(10*1000)))+50)/portTICK_PERIOD_MS;
1033+
portTickType ticksTimeOut = ((totalBytes /(i2cGetFrequency(i2c)/(10*1000)))+timeOutMillis)/portTICK_PERIOD_MS;
10341034
portTickType tBefore=xTaskGetTickCount();
10351035

10361036
//log_e("before startup @tick=%d will wait=%d",xTaskGetTickCount(),ticksTimeOut);
@@ -1052,7 +1052,7 @@ if(i2c->exitCode!=eBits){ // try to recover from O/S failure
10521052
eBits=i2c->exitCode;
10531053
}
10541054

1055-
if(!(eBits==EVENT_DONE)&&(eBits&~(EVENT_ERROR_NAK|EVENT_ERROR|EVENT_DONE))){ // not only Done, therefore error, exclude ADDR NAK
1055+
if(!(eBits==EVENT_DONE)&&(eBits&~(EVENT_ERROR_NAK|EVENT_ERROR_DATA_NAK|EVENT_ERROR|EVENT_DONE))){ // not only Done, therefore error, exclude ADDR NAK, DATA_NAK
10561056
dumpI2c(i2c);
10571057
i2cDumpInts();
10581058
}
@@ -1087,7 +1087,7 @@ else { // GROSS timeout, shutdown ISR , report Timeout
10871087
i2c->dev->int_clr.val = 0x1FFF;
10881088
reason = I2C_ERROR_TIMEOUT;
10891089
eBits = eBits | EVENT_ERROR_TIMEOUT|EVENT_ERROR|EVENT_DONE;
1090-
log_e(" Gross Timeout Dead st=%d, ed=%d, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error);
1090+
log_e(" Gross Timeout Dead st=0x%x, ed=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error);
10911091
dumpI2c(i2c);
10921092
i2cDumpInts();
10931093
}
@@ -1130,7 +1130,11 @@ if(i2c->intr_handle){
11301130
// log_e("released ISR=%d",error);
11311131
i2c->intr_handle=NULL;
11321132
}
1133-
return I2C_ERROR_OK;
1133+
if(i2c->i2c_event){
1134+
vEventGroupDelete(i2c->i2c_event);
1135+
i2c->i2c_event = NULL;
1136+
}
1137+
return i2cFreeQueue(i2c);
11341138
}
11351139

11361140
/* todo

cores/esp32/esp32-hal-i2c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda);
162162
i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda);
163163

164164
//Stickbreakers ISR Support
165-
i2c_err_t i2cProcQueue(i2c_t *i2c, uint32_t *readCount);
165+
i2c_err_t i2cProcQueue(i2c_t *i2c, uint32_t *readCount, uint16_t timeOutMillis);
166166
i2c_err_t i2cAddQueueWrite(i2c_t *i2c, uint16_t i2cDeviceAddr, uint8_t *dataPtr, uint16_t dataLen, bool SendStop, EventGroupHandle_t event);
167167
i2c_err_t i2cAddQueueRead(i2c_t *i2c, uint16_t i2cDeviceAddr, uint8_t *dataPtr, uint16_t dataLen, bool SendStop, EventGroupHandle_t event);
168168
i2c_err_t i2cFreeQueue(i2c_t *i2c);

libraries/Wire/src/Wire.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ TwoWire::TwoWire(uint8_t bus_num)
6969
,transmitting(0)
7070
,txQueued(0)
7171
,rxQueued(0)
72+
,_timeOutMillis(50)
7273
{}
7374
/* slave Mode, no yet Stickbreaker
7475
void TwoWire::onRequestService(void){}
@@ -124,6 +125,14 @@ void TwoWire::begin(int sdaPin, int sclPin, uint32_t frequency)
124125
i2cInitFix(i2c);
125126
}
126127

128+
void TwoWire::setTimeOut(uint16_t timeOutMillis){
129+
_timeOutMillis = timeOutMillis;
130+
}
131+
132+
uint16_t TwoWire::getTimeOut(){
133+
return _timeOutMillis;
134+
}
135+
127136
void TwoWire::setClock(uint32_t frequency)
128137
{
129138
i2cSetFrequency(i2c, frequency);
@@ -146,7 +155,7 @@ size_t TwoWire::requestFrom(uint8_t address, size_t size, bool sendStop)
146155
/*@StickBreaker common handler for processing the queued commands
147156
*/
148157
i2c_err_t TwoWire::processQueue(uint32_t * readCount){
149-
last_error=i2cProcQueue(i2c,readCount);
158+
last_error=i2cProcQueue(i2c,readCount,_timeOutMillis);
150159
rxIndex = 0;
151160
rxLength = rxQueued;
152161
rxQueued = 0;
@@ -484,6 +493,7 @@ void TwoWire::flush(void)
484493

485494
void TwoWire::reset(void)
486495
{
496+
i2cReleaseISR(i2c); // remove ISR from Interrupt chain,Delete EventGroup,Free Heap memory
487497
i2cReset( i2c );
488498
i2c = NULL;
489499
begin( sda, scl );

libraries/Wire/src/Wire.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class TwoWire: public Stream
6262
*/
6363
i2c_err_t last_error; // @stickBreaker from esp32-hal-i2c.h
6464
i2c_err_t processQueue(uint32_t *readCount);
65+
uint16_t _timeOutMillis;
6566

6667
public:
6768
TwoWire(uint8_t bus_num);
@@ -81,6 +82,8 @@ class TwoWire: public Stream
8182
char * getErrorText(uint8_t err);
8283
void dumpInts();
8384
size_t getClock();
85+
void setTimeOut(uint16_t timeOutMillis);
86+
uint16_t getTimeOut();
8487
//
8588
uint8_t requestFrom(uint8_t, uint8_t);
8689
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);

0 commit comments

Comments
 (0)