@@ -176,7 +176,7 @@ i2c_err_t i2cAttachSCL(i2c_t * i2c, int8_t scl)
176
176
return I2C_ERROR_DEV ;
177
177
}
178
178
digitalWrite (scl , HIGH );
179
- pinMode (scl , OPEN_DRAIN | PULLUP );
179
+ pinMode (scl , OPEN_DRAIN | PULLUP | INPUT | OUTPUT );
180
180
pinMatrixOutAttach (scl , I2C_SCL_IDX (i2c -> num ), false, false);
181
181
pinMatrixInAttach (scl , I2C_SCL_IDX (i2c -> num ), false);
182
182
return I2C_ERROR_OK ;
@@ -189,7 +189,7 @@ i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl)
189
189
}
190
190
pinMatrixOutDetach (scl , false, false);
191
191
pinMatrixInDetach (I2C_SCL_IDX (i2c -> num ), false, false);
192
- pinMode (scl , INPUT );
192
+ pinMode (scl , INPUT | PULLUP );
193
193
return I2C_ERROR_OK ;
194
194
}
195
195
@@ -199,7 +199,7 @@ i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda)
199
199
return I2C_ERROR_DEV ;
200
200
}
201
201
digitalWrite (sda , HIGH );
202
- pinMode (sda , OPEN_DRAIN | PULLUP );
202
+ pinMode (sda , OPEN_DRAIN | PULLUP | INPUT | OUTPUT );
203
203
pinMatrixOutAttach (sda , I2C_SDA_IDX (i2c -> num ), false, false);
204
204
pinMatrixInAttach (sda , I2C_SDA_IDX (i2c -> num ), false);
205
205
return I2C_ERROR_OK ;
@@ -212,7 +212,7 @@ i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda)
212
212
}
213
213
pinMatrixOutDetach (sda , false, false);
214
214
pinMatrixInDetach (I2C_SDA_IDX (i2c -> num ), false, false);
215
- pinMode (sda , INPUT );
215
+ pinMode (sda , INPUT | PULLUP );
216
216
return I2C_ERROR_OK ;
217
217
}
218
218
@@ -287,8 +287,13 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
287
287
if (i2c == NULL ){
288
288
return 0 ;
289
289
}
290
-
291
- return APB_CLK_FREQ /(i2c -> dev -> scl_low_period .period + i2c -> dev -> scl_high_period .period );
290
+ uint32_t result = 0 ;
291
+ uint32_t old_count = (i2c -> dev -> scl_low_period .period + i2c -> dev -> scl_high_period .period );
292
+ if (old_count > 0 ){
293
+ result = APB_CLK_FREQ / old_count ;
294
+ }
295
+ else result = 0 ;
296
+ return result ;
292
297
}
293
298
294
299
/*
@@ -297,7 +302,7 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
297
302
* addr_10bit_en - enable slave 10bit address mode.
298
303
* */
299
304
// 24Nov17 only supports Master Mode
300
- i2c_t * i2cInit (uint8_t i2c_num )
305
+ i2c_t * i2cInit (uint8_t i2c_num ) //before this is called, pins should be detached, else glitch
301
306
{
302
307
if (i2c_num > 1 ){
303
308
return NULL ;
@@ -313,16 +318,18 @@ i2c_t * i2cInit(uint8_t i2c_num)
313
318
}
314
319
}
315
320
#endif
321
+ I2C_MUTEX_LOCK ();
322
+ uint32_t old_clock = i2cGetFrequency (i2c );
316
323
317
324
if (i2c_num == 0 ) {
325
+ DPORT_SET_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT0_RST ); //reset hardware
318
326
DPORT_SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT0_CLK_EN );
319
- DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT0_RST );
327
+ DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT0_RST );// release reset
320
328
} else {
329
+ DPORT_SET_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST ); //reset Hardware
321
330
DPORT_SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT1_CLK_EN );
322
331
DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST );
323
332
}
324
-
325
- I2C_MUTEX_LOCK ();
326
333
i2c -> dev -> ctr .val = 0 ;
327
334
i2c -> dev -> ctr .ms_mode = 1 ;
328
335
i2c -> dev -> ctr .sda_force_out = 1 ;
@@ -336,6 +343,8 @@ i2c_t * i2cInit(uint8_t i2c_num)
336
343
337
344
i2c -> dev -> slave_addr .val = 0 ;
338
345
I2C_MUTEX_UNLOCK ();
346
+
347
+ if (old_clock ) i2cSetFrequency (i2c ,old_clock ); // reconfigure
339
348
340
349
return i2c ;
341
350
}
@@ -376,10 +385,10 @@ void i2cReset(i2c_t* i2c){
376
385
377
386
/* Stickbreaker ISR mode debug support
378
387
*/
379
- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
388
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
380
389
#define INTBUFFMAX 64
381
- static uint32_t intBuff [INTBUFFMAX ][3 ];
382
- static uint32_t intPos = 0 ;
390
+ static uint32_t intBuff [INTBUFFMAX ][3 ][ 2 ] ;
391
+ static uint32_t intPos [ 2 ] = { 0 , 0 } ;
383
392
#endif
384
393
385
394
/* Stickbreaker ISR mode debug support
@@ -645,13 +654,10 @@ enable txEmpty, filltx fires, but the SM has already sent a bogus byte out the B
645
654
overlap is not an issue, just keep them full/empty the status_reg.xx_fifo_cnt
646
655
tells the truth. And the INT's fire correctly
647
656
*/
648
- bool readEncountered = false; // 12/01/2017 this needs to be removed
649
- // it is nolonger necessary, the fifo's are independent. Run thru the dq's
650
- // until the cmd[] is full or the txFifo is full.
651
657
uint16_t a = i2c -> queuePos ; // currently executing dq,
652
658
bool full = !(i2c -> dev -> status_reg .tx_fifo_cnt < 31 );
653
659
uint8_t cnt ;
654
- while ((a < i2c -> queueCount )&& !( full || readEncountered ) ){
660
+ while ((a < i2c -> queueCount ) && ! full ){
655
661
I2C_DATA_QUEUE_t * tdq = & i2c -> dq [a ];
656
662
cnt = 0 ;
657
663
// add to address to fifo ctrl.addr already has R/W bit positioned correctly
@@ -697,22 +703,19 @@ while((a < i2c->queueCount)&&!(full || readEncountered)){
697
703
}
698
704
}
699
705
}
700
- //11/23/2017 overlap tx/rx/tx
701
- // else readEncountered = true;
702
-
703
- if (full ) readEncountered = false; //tx possibly needs more
704
706
705
- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
707
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
706
708
707
709
// update debug buffer tx counts
708
- cnt += intBuff [intPos ][1 ]>>16 ;
709
- intBuff [intPos ][1 ] = (intBuff [intPos ][1 ]& 0xFFFF )|(cnt <<16 );
710
+ cnt += intBuff [intPos [i2c -> num ]][1 ][i2c -> num ]>>16 ;
711
+ intBuff [intPos [i2c -> num ]][1 ][i2c -> num ] = (intBuff [intPos [i2c -> num ]][1 ][i2c -> num ]& 0xFFFF )|(cnt <<16 );
712
+
710
713
#endif
711
714
712
- if (!( full || readEncountered ) ) a ++ ; // check next buffer for tx
715
+ if (!full ) a ++ ; // check next buffer for tx
713
716
}
714
717
715
- if (( !full ) || readEncountered || (a >= i2c -> queueCount )){// disable IRQ, the next dq will re-enable it
718
+ if (!full || (a >= i2c -> queueCount )){// disable IRQ, the next dq will re-enable it
716
719
i2c -> dev -> int_ena .tx_fifo_empty = 0 ;
717
720
}
718
721
@@ -746,10 +749,10 @@ if(tdq->ctrl.mode==1) { // read
746
749
moveCnt = (tdq -> length - tdq -> position );
747
750
}
748
751
}
749
- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
752
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
750
753
// update Debug rxCount
751
- cnt += (intBuff [intPos ][ 1 ])&& 0xffFF ;
752
- intBuff [intPos ] [1 ] = (intBuff [intPos ][ 1 ]& 0xFFFF0000 )|cnt ;
754
+ cnt += (intBuff [intPos [ i2c -> num ]][ 1 ][ i2c -> num ])&& 0xffFF ;
755
+ intBuff [intPos [ i2c -> num ]] [1 ][ i2c -> num ] = (intBuff [intPos [ i2c -> num ]][ 1 ][ i2c -> num ]& 0xFFFF0000 )|cnt ;
753
756
#endif
754
757
}
755
758
else {
@@ -813,23 +816,22 @@ if(p_i2c->stage==I2C_DONE){ //get Out
813
816
log_e ("eject int=%p, ena=%p" ,activeInt ,p_i2c -> dev -> int_ena .val );
814
817
p_i2c -> dev -> int_ena .val = 0 ;
815
818
p_i2c -> dev -> int_clr .val = activeInt ; //0x1FFF;
816
- // i2cDumpI2c(p_i2c);
817
- // i2cDumpInts();
818
819
return ;
819
820
}
820
821
while (activeInt != 0 ) { // Ordering of 'if(activeInt)' statements is important, don't change
821
- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
822
- if (activeInt == (intBuff [intPos ][ 0 ]& 0x1fff )){
823
- intBuff [intPos ] [0 ] = (((intBuff [intPos ][ 0 ]>>16 )+ 1 )<<16 )|activeInt ;
822
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
823
+ if (activeInt == (intBuff [intPos [ p_i2c -> num ]][ 0 ][ p_i2c -> num ]& 0x1fff )){
824
+ intBuff [intPos [ p_i2c -> num ]] [0 ][ p_i2c -> num ] = (((intBuff [intPos [ p_i2c -> num ]][ 0 ][ p_i2c -> num ]>>16 )+ 1 )<<16 )|activeInt ;
824
825
}
825
826
else {
826
- intPos ++ ;
827
- intPos %= INTBUFFMAX ;
828
- intBuff [intPos ] [0 ]= (1 <<16 )| activeInt ;
829
- intBuff [intPos ][ 1 ] = 0 ;
827
+ intPos [ p_i2c -> num ] ++ ;
828
+ intPos [ p_i2c -> num ] %= INTBUFFMAX ;
829
+ intBuff [intPos [ p_i2c -> num ]] [0 ][ p_i2c -> num ] = (1 <<16 ) | activeInt ;
830
+ intBuff [intPos [ p_i2c -> num ]][ 1 ][ p_i2c -> num ] = 0 ;
830
831
}
831
832
832
- intBuff [intPos ][2 ] = xTaskGetTickCountFromISR (); // when IRQ fired
833
+ intBuff [intPos [p_i2c -> num ]][2 ][p_i2c -> num ] = xTaskGetTickCountFromISR (); // when IRQ fired
834
+
833
835
#endif
834
836
uint32_t oldInt = activeInt ;
835
837
@@ -940,13 +942,13 @@ while (activeInt != 0) { // Ordering of 'if(activeInt)' statements is important,
940
942
}
941
943
}
942
944
943
- void i2cDumpInts (){
944
- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
945
+ void i2cDumpInts (uint8_t num ){
946
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
945
947
uint32_t b ;
946
- log_e ("row count INTR TX RX" );
948
+ log_e ("%u row count INTR TX RX" , num );
947
949
for (uint32_t a = 1 ;a <=INTBUFFMAX ;a ++ ){
948
- b = (a + intPos )%INTBUFFMAX ;
949
- if (intBuff [b ][0 ]!= 0 ) log_e ("[%02d] 0x%04x 0x%04x 0x%04x 0x%04x 0x%08x" ,b ,((intBuff [b ][0 ]>>16 )& 0xFFFF ),(intBuff [b ][0 ]& 0xFFFF ),((intBuff [b ][1 ]>>16 )& 0xFFFF ),(intBuff [b ][1 ]& 0xFFFF ),intBuff [b ][2 ]);
950
+ b = (a + intPos [ num ] )%INTBUFFMAX ;
951
+ if (intBuff [b ][0 ][ num ] != 0 ) log_e ("[%02d] 0x%04x 0x%04x 0x%04x 0x%04x 0x%08x" ,b ,((intBuff [b ][0 ][ num ] >>16 )& 0xFFFF ),(intBuff [b ][0 ][ num ] & 0xFFFF ),((intBuff [b ][1 ][ num ] >>16 )& 0xFFFF ),(intBuff [b ][1 ][ num ] & 0xFFFF ),intBuff [b ][2 ][ num ]);
950
952
}
951
953
#else
952
954
log_n ("enable Core Debug Level \"Error\"" );
@@ -965,7 +967,10 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
965
967
if (i2c == NULL ){
966
968
return I2C_ERROR_DEV ;
967
969
}
968
-
970
+ if (i2c -> dev -> status_reg .bus_busy ){ // return error, let TwoWire() handle resetting the hardware.
971
+ log_i ("Bus busy, reinit" );
972
+ return I2C_ERROR_BUSY ;
973
+ }
969
974
I2C_MUTEX_LOCK ();
970
975
/* what about co-existance with SLAVE mode?
971
976
Should I check if a slaveMode xfer is in progress and hang
@@ -974,9 +979,13 @@ I2C_MUTEX_LOCK();
974
979
*/
975
980
i2c -> stage = I2C_DONE ; // until ready
976
981
977
- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
978
- memset (intBuff ,0 ,sizeof (intBuff ));
979
- intPos = 0 ;
982
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
983
+ for (uint16_t i = 0 ;i < INTBUFFMAX ;i ++ ){
984
+ intBuff [i ][0 ][i2c -> num ] = 0 ;
985
+ intBuff [i ][1 ][i2c -> num ] = 0 ;
986
+ intBuff [i ][2 ][i2c -> num ] = 0 ;
987
+ }
988
+ intPos [i2c -> num ] = 0 ;
980
989
#endif
981
990
// EventGroup is used to signal transmisison completion from ISR
982
991
// not always reliable. Sometimes, the FreeRTOS scheduler is maxed out and refuses request
@@ -1063,9 +1072,19 @@ i2c->dev->int_ena.val =
1063
1072
I2C_TXFIFO_EMPTY_INT_ENA | // (BIT(1)) triggers fillTxFifo()
1064
1073
I2C_RXFIFO_FULL_INT_ENA ; // (BIT(0)) trigger emptyRxFifo()
1065
1074
1066
- if (!i2c -> intr_handle ){ // create ISR I2C_0 only,
1067
- // log_e("create ISR");
1068
- uint32_t ret = esp_intr_alloc (ETS_I2C_EXT0_INTR_SOURCE , 0 , & i2c_isr_handler_default , i2c , & i2c -> intr_handle );
1075
+ if (!i2c -> intr_handle ){ // create ISR for either peripheral
1076
+ log_i ("create ISR" );
1077
+ uint32_t ret ;
1078
+ switch (i2c -> num ){
1079
+ case 0 :
1080
+ ret = esp_intr_alloc (ETS_I2C_EXT0_INTR_SOURCE , 0 , & i2c_isr_handler_default , i2c , & i2c -> intr_handle );
1081
+ break ;
1082
+ case 1 :
1083
+ ret = esp_intr_alloc (ETS_I2C_EXT1_INTR_SOURCE , 0 , & i2c_isr_handler_default , i2c , & i2c -> intr_handle );
1084
+ break ;
1085
+ default :;
1086
+ }
1087
+
1069
1088
if (ret != ESP_OK ){
1070
1089
log_e ("install interrupt handler Failed=%d" ,ret );
1071
1090
I2C_MUTEX_UNLOCK ();
@@ -1101,11 +1120,11 @@ if(i2c->exitCode!=eBits){ // try to recover from O/S failure
1101
1120
}
1102
1121
1103
1122
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
1104
- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
1123
+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
1105
1124
i2cDumpI2c (i2c );
1106
- i2cDumpInts ();
1125
+ i2cDumpInts (i2c -> num );
1107
1126
#else
1108
- log_n ("I2C exitCode=%u " ,eBits );
1127
+ log_n ("I2C exitCode=0x%x " ,eBits );
1109
1128
#endif
1110
1129
}
1111
1130
@@ -1116,7 +1135,7 @@ if(eBits&EVENT_DONE){ // no gross timeout
1116
1135
// expected can be zero due to small packets
1117
1136
log_e ("TimeoutRecovery: expected=%ums, actual=%ums" ,expected ,(tAfter - tBefore ));
1118
1137
i2cDumpI2c (i2c );
1119
- i2cDumpInts ();
1138
+ i2cDumpInts (i2c -> num );
1120
1139
}
1121
1140
#endif
1122
1141
switch (i2c -> error ){
@@ -1152,7 +1171,7 @@ else { // GROSS timeout, shutdown ISR , report Timeout
1152
1171
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
1153
1172
log_e (" Busy Timeout start=0x%x, end=0x%x, =%d, max=%d error=%d" ,tBefore ,tAfter ,(tAfter - tBefore ),ticksTimeOut ,i2c -> error );
1154
1173
i2cDumpI2c (i2c );
1155
- i2cDumpInts ();
1174
+ i2cDumpInts (i2c -> num );
1156
1175
#endif
1157
1176
}
1158
1177
else { // just a timeout, some data made it out or in.
@@ -1162,7 +1181,7 @@ else { // GROSS timeout, shutdown ISR , report Timeout
1162
1181
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
1163
1182
log_e (" Gross Timeout Dead start=0x%x, end=0x%x, =%d, max=%d error=%d" ,tBefore ,tAfter ,(tAfter - tBefore ),ticksTimeOut ,i2c -> error );
1164
1183
i2cDumpI2c (i2c );
1165
- i2cDumpInts ();
1184
+ i2cDumpInts (i2c -> num );
1166
1185
#endif
1167
1186
}
1168
1187
}
0 commit comments