@@ -176,7 +176,7 @@ i2c_err_t i2cAttachSCL(i2c_t * i2c, int8_t scl)
176176 return I2C_ERROR_DEV ;
177177 }
178178 digitalWrite (scl , HIGH );
179- pinMode (scl , OPEN_DRAIN | PULLUP );
179+ pinMode (scl , OPEN_DRAIN | PULLUP | INPUT | OUTPUT );
180180 pinMatrixOutAttach (scl , I2C_SCL_IDX (i2c -> num ), false, false);
181181 pinMatrixInAttach (scl , I2C_SCL_IDX (i2c -> num ), false);
182182 return I2C_ERROR_OK ;
@@ -189,7 +189,7 @@ i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl)
189189 }
190190 pinMatrixOutDetach (scl , false, false);
191191 pinMatrixInDetach (I2C_SCL_IDX (i2c -> num ), false, false);
192- pinMode (scl , INPUT );
192+ pinMode (scl , INPUT | PULLUP );
193193 return I2C_ERROR_OK ;
194194}
195195
@@ -199,7 +199,7 @@ i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda)
199199 return I2C_ERROR_DEV ;
200200 }
201201 digitalWrite (sda , HIGH );
202- pinMode (sda , OPEN_DRAIN | PULLUP );
202+ pinMode (sda , OPEN_DRAIN | PULLUP | INPUT | OUTPUT );
203203 pinMatrixOutAttach (sda , I2C_SDA_IDX (i2c -> num ), false, false);
204204 pinMatrixInAttach (sda , I2C_SDA_IDX (i2c -> num ), false);
205205 return I2C_ERROR_OK ;
@@ -212,7 +212,7 @@ i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda)
212212 }
213213 pinMatrixOutDetach (sda , false, false);
214214 pinMatrixInDetach (I2C_SDA_IDX (i2c -> num ), false, false);
215- pinMode (sda , INPUT );
215+ pinMode (sda , INPUT | PULLUP );
216216 return I2C_ERROR_OK ;
217217}
218218
@@ -287,8 +287,13 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
287287 if (i2c == NULL ){
288288 return 0 ;
289289 }
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 ;
292297}
293298
294299/*
@@ -297,7 +302,7 @@ uint32_t i2cGetFrequency(i2c_t * i2c)
297302 * addr_10bit_en - enable slave 10bit address mode.
298303 * */
299304// 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
301306{
302307 if (i2c_num > 1 ){
303308 return NULL ;
@@ -313,16 +318,18 @@ i2c_t * i2cInit(uint8_t i2c_num)
313318 }
314319 }
315320#endif
321+ I2C_MUTEX_LOCK ();
322+ uint32_t old_clock = i2cGetFrequency (i2c );
316323
317324 if (i2c_num == 0 ) {
325+ DPORT_SET_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT0_RST ); //reset hardware
318326 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
320328 } else {
329+ DPORT_SET_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST ); //reset Hardware
321330 DPORT_SET_PERI_REG_MASK (DPORT_PERIP_CLK_EN_REG ,DPORT_I2C_EXT1_CLK_EN );
322331 DPORT_CLEAR_PERI_REG_MASK (DPORT_PERIP_RST_EN_REG ,DPORT_I2C_EXT1_RST );
323332 }
324-
325- I2C_MUTEX_LOCK ();
326333 i2c -> dev -> ctr .val = 0 ;
327334 i2c -> dev -> ctr .ms_mode = 1 ;
328335 i2c -> dev -> ctr .sda_force_out = 1 ;
@@ -336,6 +343,8 @@ i2c_t * i2cInit(uint8_t i2c_num)
336343
337344 i2c -> dev -> slave_addr .val = 0 ;
338345 I2C_MUTEX_UNLOCK ();
346+
347+ if (old_clock ) i2cSetFrequency (i2c ,old_clock ); // reconfigure
339348
340349 return i2c ;
341350}
@@ -376,10 +385,10 @@ void i2cReset(i2c_t* i2c){
376385
377386/* Stickbreaker ISR mode debug support
378387*/
379- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
388+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
380389#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 } ;
383392#endif
384393
385394/* 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
645654 overlap is not an issue, just keep them full/empty the status_reg.xx_fifo_cnt
646655 tells the truth. And the INT's fire correctly
647656*/
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.
651657uint16_t a = i2c -> queuePos ; // currently executing dq,
652658bool full = !(i2c -> dev -> status_reg .tx_fifo_cnt < 31 );
653659uint8_t cnt ;
654- while ((a < i2c -> queueCount )&& !( full || readEncountered ) ){
660+ while ((a < i2c -> queueCount ) && ! full ){
655661 I2C_DATA_QUEUE_t * tdq = & i2c -> dq [a ];
656662 cnt = 0 ;
657663// add to address to fifo ctrl.addr already has R/W bit positioned correctly
@@ -697,22 +703,19 @@ while((a < i2c->queueCount)&&!(full || readEncountered)){
697703 }
698704 }
699705 }
700- //11/23/2017 overlap tx/rx/tx
701- // else readEncountered = true;
702-
703- if (full ) readEncountered = false; //tx possibly needs more
704706
705- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
707+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
706708
707709// 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+
710713#endif
711714
712- if (!( full || readEncountered ) ) a ++ ; // check next buffer for tx
715+ if (!full ) a ++ ; // check next buffer for tx
713716 }
714717
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
716719 i2c -> dev -> int_ena .tx_fifo_empty = 0 ;
717720 }
718721
@@ -746,10 +749,10 @@ if(tdq->ctrl.mode==1) { // read
746749 moveCnt = (tdq -> length - tdq -> position );
747750 }
748751 }
749- #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
752+ #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
750753// 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 ;
753756#endif
754757 }
755758else {
@@ -813,23 +816,22 @@ if(p_i2c->stage==I2C_DONE){ //get Out
813816 log_e ("eject int=%p, ena=%p" ,activeInt ,p_i2c -> dev -> int_ena .val );
814817 p_i2c -> dev -> int_ena .val = 0 ;
815818 p_i2c -> dev -> int_clr .val = activeInt ; //0x1FFF;
816- // i2cDumpI2c(p_i2c);
817- // i2cDumpInts();
818819 return ;
819820 }
820821while (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 ;
824825 }
825826 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 ;
830831 }
831832
832- intBuff [intPos ][2 ] = xTaskGetTickCountFromISR (); // when IRQ fired
833+ intBuff [intPos [p_i2c -> num ]][2 ][p_i2c -> num ] = xTaskGetTickCountFromISR (); // when IRQ fired
834+
833835#endif
834836 uint32_t oldInt = activeInt ;
835837
@@ -940,13 +942,13 @@ while (activeInt != 0) { // Ordering of 'if(activeInt)' statements is important,
940942 }
941943}
942944
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
945947uint32_t b ;
946- log_e ("row count INTR TX RX" );
948+ log_e ("%u row count INTR TX RX" , num );
947949for (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 ]);
950952 }
951953#else
952954log_n ("enable Core Debug Level \"Error\"" );
@@ -965,7 +967,10 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
965967if (i2c == NULL ){
966968 return I2C_ERROR_DEV ;
967969 }
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+ }
969974I2C_MUTEX_LOCK ();
970975/* what about co-existance with SLAVE mode?
971976 Should I check if a slaveMode xfer is in progress and hang
@@ -974,9 +979,13 @@ I2C_MUTEX_LOCK();
974979*/
975980i2c -> stage = I2C_DONE ; // until ready
976981
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 ;
980989#endif
981990// EventGroup is used to signal transmisison completion from ISR
982991// not always reliable. Sometimes, the FreeRTOS scheduler is maxed out and refuses request
@@ -1063,9 +1072,19 @@ i2c->dev->int_ena.val =
10631072 I2C_TXFIFO_EMPTY_INT_ENA | // (BIT(1)) triggers fillTxFifo()
10641073 I2C_RXFIFO_FULL_INT_ENA ; // (BIT(0)) trigger emptyRxFifo()
10651074
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+
10691088 if (ret != ESP_OK ){
10701089 log_e ("install interrupt handler Failed=%d" ,ret );
10711090 I2C_MUTEX_UNLOCK ();
@@ -1101,11 +1120,11 @@ if(i2c->exitCode!=eBits){ // try to recover from O/S failure
11011120 }
11021121
11031122if (!(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
11051124 i2cDumpI2c (i2c );
1106- i2cDumpInts ();
1125+ i2cDumpInts (i2c -> num );
11071126#else
1108- log_n ("I2C exitCode=%u " ,eBits );
1127+ log_n ("I2C exitCode=0x%x " ,eBits );
11091128#endif
11101129 }
11111130
@@ -1116,7 +1135,7 @@ if(eBits&EVENT_DONE){ // no gross timeout
11161135 // expected can be zero due to small packets
11171136 log_e ("TimeoutRecovery: expected=%ums, actual=%ums" ,expected ,(tAfter - tBefore ));
11181137 i2cDumpI2c (i2c );
1119- i2cDumpInts ();
1138+ i2cDumpInts (i2c -> num );
11201139 }
11211140#endif
11221141 switch (i2c -> error ){
@@ -1152,7 +1171,7 @@ else { // GROSS timeout, shutdown ISR , report Timeout
11521171#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
11531172 log_e (" Busy Timeout start=0x%x, end=0x%x, =%d, max=%d error=%d" ,tBefore ,tAfter ,(tAfter - tBefore ),ticksTimeOut ,i2c -> error );
11541173 i2cDumpI2c (i2c );
1155- i2cDumpInts ();
1174+ i2cDumpInts (i2c -> num );
11561175#endif
11571176 }
11581177 else { // just a timeout, some data made it out or in.
@@ -1162,7 +1181,7 @@ else { // GROSS timeout, shutdown ISR , report Timeout
11621181#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
11631182 log_e (" Gross Timeout Dead start=0x%x, end=0x%x, =%d, max=%d error=%d" ,tBefore ,tAfter ,(tAfter - tBefore ),ticksTimeOut ,i2c -> error );
11641183 i2cDumpI2c (i2c );
1165- i2cDumpInts ();
1184+ i2cDumpInts (i2c -> num );
11661185#endif
11671186 }
11681187 }
0 commit comments