@@ -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
586598static 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