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 28a410d

Browse filesBrowse files
stickbreakerme-no-dev
authored andcommitted
Spurious Interrupts Temporary fix 20180711 (espressif#1625)
the 'eject' ERROR is and indication of an interrupt triggering without an source. I am working to eliminate these serviceable interrupt. This update increase stability on a HelTek Wifi Lora 32 board. with a SSD1306 OLED. This update fixes a glaring error in the interrupt allocation code, the Interrupt mask was wrong. I also dynamically adjust the FiFo thresholds based on Bus clockrate. The change to FiFo thresholds has reduced the number for 'eject' events. I also change 'eject' from and ERROR to DEBUG. An 'eject' event does not compromise i2c transmissions. It happens after a transaction has completed. Chuck.
1 parent ddfeae9 commit 28a410d
Copy full SHA for 28a410d

File tree

1 file changed

+43
-14
lines changed
Filter options

1 file changed

+43
-14
lines changed

‎cores/esp32/esp32-hal-i2c.c

Copy file name to clipboardExpand all lines: cores/esp32/esp32-hal-i2c.c
+43-14Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,18 @@ static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
491491

492492
if(!full || (a >= i2c->queueCount)) { // disable IRQ, the next dq will re-enable it
493493
i2c->dev->int_ena.tx_fifo_empty=0;
494+
495+
if(!full) { // add a byte to keep spurious tx_empty int
496+
uint8_t filler=i2c->dev->fifo_conf.tx_fifo_empty_thrhd;
497+
if(filler >( 31 - i2c->dev->status_reg.tx_fifo_cnt)){
498+
filler = ( 31 - i2c->dev->status_reg.tx_fifo_cnt);
499+
}
500+
501+
while(filler > 0){
502+
i2c->dev->fifo_data.val = 0xFE; // Just a dummy byte
503+
filler--;
504+
}
505+
}
494506
}
495507

496508
i2c->dev->int_clr.tx_fifo_empty=1;
@@ -563,9 +575,9 @@ static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal
563575
if(i2c->dq[i2c->queuePos].ctrl.mode == 1) {
564576
emptyRxFifo(i2c); // grab last few characters
565577
}
566-
578+
// log_d("raw=0x%05x status=0x%05x",i2c->dev->int_raw.val,i2c->dev->int_status.val);
567579
i2c->dev->int_ena.val = 0; // shutdown interrupts
568-
i2c->dev->int_clr.val = 0x1FFFF;
580+
i2c->dev->int_clr.val = 0x1FFF;
569581
i2c->stage = I2C_DONE;
570582
i2c->exitCode = exitCode; //true eventcode
571583

@@ -586,12 +598,16 @@ static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal
586598
static void IRAM_ATTR i2c_isr_handler_default(void* arg)
587599
{
588600
i2c_t* p_i2c = (i2c_t*) arg; // recover data
589-
uint32_t activeInt = p_i2c->dev->int_status.val&0x1FFF;
590-
591-
//portBASE_TYPE HPTaskAwoken = pdFALSE,xResult;
601+
uint32_t activeInt = p_i2c->dev->int_status.val&0x7FF;
592602

593-
if(p_i2c->stage==I2C_DONE) { //get Out
594-
log_e("eject int=%p, ena=%p",activeInt,p_i2c->dev->int_ena.val);
603+
if(!activeInt){ //spurious interrupt, possibly bus relate 20180711
604+
log_d("raw=0x%05x status=0x%05x",p_i2c->dev->int_raw.val,p_i2c->dev->int_status.val);
605+
}
606+
if(p_i2c->stage==I2C_DONE) { //get Out, can't service, not configured
607+
// this error is some kind of a race condition at high clock >400khz
608+
// see #1588. it does not compromise i2c communications though, just
609+
// a poke in the eye
610+
log_d("eject raw=%p, int=%p",p_i2c->dev->int_raw.val,activeInt);
595611
p_i2c->dev->int_ena.val = 0;
596612
p_i2c->dev->int_clr.val = activeInt; //0x1FFF;
597613
return;
@@ -610,8 +626,7 @@ static void IRAM_ATTR i2c_isr_handler_default(void* arg)
610626
intBuff[intPos[p_i2c->num]][2][p_i2c->num] = xTaskGetTickCountFromISR(); // when IRQ fired
611627

612628
#endif
613-
//uint32_t oldInt =activeInt;
614-
629+
615630
if (activeInt & I2C_TRANS_START_INT_ST_M) {
616631
// p_i2c->byteCnt=0;
617632
if(p_i2c->stage==I2C_STARTUP) {
@@ -871,18 +886,21 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
871886
f.rx_fifo_rst = 1; // fifo in reset
872887
f.tx_fifo_rst = 1; // fifo in reset
873888
f.nonfifo_en = 0; // use fifo mode
889+
f.nonfifo_tx_thres =63;
874890
// need to adjust threshold based on I2C clock rate, at 100k, 30 usually works,
875891
// sometimes the emptyRx() actually moves 31 bytes
876892
// it hasn't overflowed yet, I cannot tell if the new byte is added while
877893
// emptyRX() is executing or before?
878-
f.rx_fifo_full_thrhd = 30; // 30 bytes before INT is issued
894+
// let i2cSetFrequency() set thrhds
895+
// f.rx_fifo_full_thrhd = 30; // 30 bytes before INT is issued
896+
// f.tx_fifo_empty_thrhd = 0;
879897
f.fifo_addr_cfg_en = 0; // no directed access
880898
i2c->dev->fifo_conf.val = f.val; // post them all
881899

882900
f.rx_fifo_rst = 0; // release fifo
883901
f.tx_fifo_rst = 0;
884902
i2c->dev->fifo_conf.val = f.val; // post them all
885-
903+
886904
i2c->dev->int_clr.val = 0xFFFFFFFF; // kill them All!
887905
i2c->dev->ctr.ms_mode = 1; // master!
888906
i2c->queuePos=0;
@@ -936,9 +954,9 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
936954
ESP_INTR_FLAG_LOWMED; //< Low and medium prio interrupts. These can be handled in C.
937955

938956
if(i2c->num) {
939-
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT1_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x1FFF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
957+
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT1_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x7FF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
940958
} else {
941-
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT0_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x1FFF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
959+
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT0_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x7FF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
942960
}
943961

944962
if(ret!=ESP_OK) {
@@ -1326,12 +1344,23 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
13261344
if(i2c == NULL) {
13271345
return I2C_ERROR_DEV;
13281346
}
1329-
1347+
I2C_FIFO_CONF_t f;
1348+
13301349
uint32_t period = (APB_CLK_FREQ/clk_speed) / 2;
13311350
uint32_t halfPeriod = period/2;
13321351
uint32_t quarterPeriod = period/4;
13331352

13341353
I2C_MUTEX_LOCK();
1354+
1355+
// Adjust Fifo thresholds based on frequency
1356+
f.val = i2c->dev->fifo_conf.val;
1357+
uint32_t a = (clk_speed / 50000L )+1;
1358+
if (a > 24) a=24;
1359+
f.rx_fifo_full_thrhd = 32 - a;
1360+
f.tx_fifo_empty_thrhd = a;
1361+
i2c->dev->fifo_conf.val = f.val; // set thresholds
1362+
log_v("threshold=%d",a);
1363+
13351364
//the clock num during SCL is low level
13361365
i2c->dev->scl_low_period.period = period;
13371366
//the clock num during SCL is high level

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.