@@ -491,6 +491,18 @@ static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
491
491
492
492
if (!full || (a >= i2c -> queueCount )) { // disable IRQ, the next dq will re-enable it
493
493
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
+ }
494
506
}
495
507
496
508
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
563
575
if (i2c -> dq [i2c -> queuePos ].ctrl .mode == 1 ) {
564
576
emptyRxFifo (i2c ); // grab last few characters
565
577
}
566
-
578
+ // log_d("raw=0x%05x status=0x%05x",i2c->dev->int_raw.val,i2c->dev->int_status.val);
567
579
i2c -> dev -> int_ena .val = 0 ; // shutdown interrupts
568
- i2c -> dev -> int_clr .val = 0x1FFFF ;
580
+ i2c -> dev -> int_clr .val = 0x1FFF ;
569
581
i2c -> stage = I2C_DONE ;
570
582
i2c -> exitCode = exitCode ; //true eventcode
571
583
@@ -586,12 +598,16 @@ static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal
586
598
static void IRAM_ATTR i2c_isr_handler_default (void * arg )
587
599
{
588
600
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 ;
592
602
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 );
595
611
p_i2c -> dev -> int_ena .val = 0 ;
596
612
p_i2c -> dev -> int_clr .val = activeInt ; //0x1FFF;
597
613
return ;
@@ -610,8 +626,7 @@ static void IRAM_ATTR i2c_isr_handler_default(void* arg)
610
626
intBuff [intPos [p_i2c -> num ]][2 ][p_i2c -> num ] = xTaskGetTickCountFromISR (); // when IRQ fired
611
627
612
628
#endif
613
- //uint32_t oldInt =activeInt;
614
-
629
+
615
630
if (activeInt & I2C_TRANS_START_INT_ST_M ) {
616
631
// p_i2c->byteCnt=0;
617
632
if (p_i2c -> stage == I2C_STARTUP ) {
@@ -871,18 +886,21 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
871
886
f .rx_fifo_rst = 1 ; // fifo in reset
872
887
f .tx_fifo_rst = 1 ; // fifo in reset
873
888
f .nonfifo_en = 0 ; // use fifo mode
889
+ f .nonfifo_tx_thres = 63 ;
874
890
// need to adjust threshold based on I2C clock rate, at 100k, 30 usually works,
875
891
// sometimes the emptyRx() actually moves 31 bytes
876
892
// it hasn't overflowed yet, I cannot tell if the new byte is added while
877
893
// 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;
879
897
f .fifo_addr_cfg_en = 0 ; // no directed access
880
898
i2c -> dev -> fifo_conf .val = f .val ; // post them all
881
899
882
900
f .rx_fifo_rst = 0 ; // release fifo
883
901
f .tx_fifo_rst = 0 ;
884
902
i2c -> dev -> fifo_conf .val = f .val ; // post them all
885
-
903
+
886
904
i2c -> dev -> int_clr .val = 0xFFFFFFFF ; // kill them All!
887
905
i2c -> dev -> ctr .ms_mode = 1 ; // master!
888
906
i2c -> queuePos = 0 ;
@@ -936,9 +954,9 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
936
954
ESP_INTR_FLAG_LOWMED ; //< Low and medium prio interrupts. These can be handled in C.
937
955
938
956
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 );
940
958
} 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 );
942
960
}
943
961
944
962
if (ret != ESP_OK ) {
@@ -1326,12 +1344,23 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
1326
1344
if (i2c == NULL ) {
1327
1345
return I2C_ERROR_DEV ;
1328
1346
}
1329
-
1347
+ I2C_FIFO_CONF_t f ;
1348
+
1330
1349
uint32_t period = (APB_CLK_FREQ /clk_speed ) / 2 ;
1331
1350
uint32_t halfPeriod = period /2 ;
1332
1351
uint32_t quarterPeriod = period /4 ;
1333
1352
1334
1353
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
+
1335
1364
//the clock num during SCL is low level
1336
1365
i2c -> dev -> scl_low_period .period = period ;
1337
1366
//the clock num during SCL is high level
0 commit comments