esp32-hal-i2c.c
1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "esp32-hal-i2c.h" 16 #include "esp32-hal-gpio.h" 17 #include "esp32-hal-matrix.h" 18 #include "freertos/FreeRTOS.h" 19 #include "freertos/task.h" 20 #include "freertos/semphr.h" 21 #include "freertos/event_groups.h" 22 #include "rom/ets_sys.h" 23 #include "driver/periph_ctrl.h" 24 #include "soc/i2c_reg.h" 25 #include "soc/i2c_struct.h" 26 #include "soc/dport_reg.h" 27 #include "esp_attr.h" 28 29 #include <string.h> 30 31 #define NOP() asm volatile ("nop") 32 33 unsigned long IRAM_ATTR micros() 34 { 35 return (unsigned long) esp_timer_get_time(); 36 } 37 38 unsigned long IRAM_ATTR millis() 39 { 40 return (unsigned long) (esp_timer_get_time() / 1000); 41 } 42 43 void delay(uint32_t ms) 44 { 45 vTaskDelay(ms / portTICK_PERIOD_MS); 46 } 47 48 void IRAM_ATTR delayMicroseconds(uint32_t us) 49 { 50 uint32_t m = micros(); 51 if(us){ 52 uint32_t e = (m + us); 53 if(m > e){ //overflow 54 while(micros() > e){ 55 NOP(); 56 } 57 } 58 while(micros() < e){ 59 NOP(); 60 } 61 } 62 } 63 //#define I2C_DEV(i) (volatile i2c_dev_t *)((i)?DR_REG_I2C1_EXT_BASE:DR_REG_I2C_EXT_BASE) 64 //#define I2C_DEV(i) ((i2c_dev_t *)(REG_I2C_BASE(i))) 65 #define I2C_SCL_IDX(p) ((p==0)?I2CEXT0_SCL_OUT_IDX:((p==1)?I2CEXT1_SCL_OUT_IDX:0)) 66 #define I2C_SDA_IDX(p) ((p==0)?I2CEXT0_SDA_OUT_IDX:((p==1)?I2CEXT1_SDA_OUT_IDX:0)) 67 68 #define DR_REG_I2C_EXT_BASE_FIXED 0x60013000 69 #define DR_REG_I2C1_EXT_BASE_FIXED 0x60027000 70 71 /* Stickbreaker ISR mode debug support 72 73 ENABLE_I2C_DEBUG_BUFFER 74 Enable debug interrupt history buffer, fifoTx history buffer. 75 Setting this define will result in 2570 bytes of RAM being used whenever CORE_DEBUG_LEVEL 76 is higher than WARNING. Unless you are debugging a problem in the I2C subsystem, 77 I would recommend you leave it commented out. 78 */ 79 80 //#define ENABLE_I2C_DEBUG_BUFFER 81 82 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER) 83 #define INTBUFFMAX 64 84 #define FIFOMAX 512 85 static uint32_t intBuff[INTBUFFMAX][3][2]; 86 static uint32_t intPos[2]= {0,0}; 87 static uint16_t fifoBuffer[FIFOMAX]; 88 static uint16_t fifoPos = 0; 89 #endif 90 91 // start from tools/sdk/include/soc/soc/i2c_struct.h 92 93 typedef union { 94 struct { 95 uint32_t byte_num: 8; /*Byte_num represent the number of data need to be send or data need to be received.*/ 96 uint32_t ack_en: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/ 97 uint32_t ack_exp: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/ 98 uint32_t ack_val: 1; /*ack_check_en ack_exp and ack value are used to control the ack bit.*/ 99 uint32_t op_code: 3; /*op_code is the command 0:RSTART 1:WRITE 2:READ 3:STOP . 4:END.*/ 100 uint32_t reserved14: 17; 101 uint32_t done: 1; /*When command0 is done in I2C Master mode this bit changes to high level.*/ 102 }; 103 uint32_t val; 104 } I2C_COMMAND_t; 105 106 typedef union { 107 struct { 108 uint32_t rx_fifo_full_thrhd: 5; 109 uint32_t tx_fifo_empty_thrhd:5; //Config tx_fifo empty threhd value when using apb fifo access * / 110 uint32_t nonfifo_en: 1; //Set this bit to enble apb nonfifo access. * / 111 uint32_t fifo_addr_cfg_en: 1; //When this bit is set to 1 then the byte after address represent the offset address of I2C Slave's ram. * / 112 uint32_t rx_fifo_rst: 1; //Set this bit to reset rx fifo when using apb fifo access. * / 113 // chuck while this bit is 1, the RX fifo is held in REST, Toggle it * / 114 uint32_t tx_fifo_rst: 1; //Set this bit to reset tx fifo when using apb fifo access. * / 115 // chuck while this bit is 1, the TX fifo is held in REST, Toggle it * / 116 uint32_t nonfifo_rx_thres: 6; //when I2C receives more than nonfifo_rx_thres data it will produce rx_send_full_int_raw interrupt and update the current offset address of the receiving data.* / 117 uint32_t nonfifo_tx_thres: 6; //when I2C sends more than nonfifo_tx_thres data it will produce tx_send_empty_int_raw interrupt and update the current offset address of the sending data. * / 118 uint32_t reserved26: 6; 119 }; 120 uint32_t val; 121 } I2C_FIFO_CONF_t; 122 123 typedef union { 124 struct { 125 uint32_t rx_fifo_start_addr: 5; /*This is the offset address of the last receiving data as described in nonfifo_rx_thres_register.*/ 126 uint32_t rx_fifo_end_addr: 5; /*This is the offset address of the first receiving data as described in nonfifo_rx_thres_register.*/ 127 uint32_t tx_fifo_start_addr: 5; /*This is the offset address of the first sending data as described in nonfifo_tx_thres register.*/ 128 uint32_t tx_fifo_end_addr: 5; /*This is the offset address of the last sending data as described in nonfifo_tx_thres register.*/ 129 uint32_t reserved20: 12; 130 }; 131 uint32_t val; 132 } I2C_FIFO_ST_t; 133 134 // end from tools/sdk/include/soc/soc/i2c_struct.h 135 136 // sync between dispatch(i2cProcQueue) and worker(i2c_isr_handler_default) 137 typedef enum { 138 //I2C_NONE=0, 139 I2C_STARTUP=1, 140 I2C_RUNNING, 141 I2C_DONE 142 } I2C_STAGE_t; 143 144 typedef enum { 145 I2C_NONE=0, 146 I2C_MASTER, 147 I2C_SLAVE, 148 I2C_MASTERSLAVE 149 } I2C_MODE_t; 150 151 // internal Error condition 152 typedef enum { 153 // I2C_NONE=0, 154 I2C_OK=1, 155 I2C_ERROR, 156 I2C_ADDR_NAK, 157 I2C_DATA_NAK, 158 I2C_ARBITRATION, 159 I2C_TIMEOUT 160 } I2C_ERROR_t; 161 162 // i2c_event bits for EVENTGROUP bits 163 // needed to minimize change events, FreeRTOS Daemon overload, so ISR will only set values 164 // on Exit. Dispatcher will set bits for each dq before/after ISR completion 165 #define EVENT_ERROR_NAK (BIT(0)) 166 #define EVENT_ERROR (BIT(1)) 167 #define EVENT_ERROR_BUS_BUSY (BIT(2)) 168 #define EVENT_RUNNING (BIT(3)) 169 #define EVENT_DONE (BIT(4)) 170 #define EVENT_IN_END (BIT(5)) 171 #define EVENT_ERROR_PREV (BIT(6)) 172 #define EVENT_ERROR_TIMEOUT (BIT(7)) 173 #define EVENT_ERROR_ARBITRATION (BIT(8)) 174 #define EVENT_ERROR_DATA_NAK (BIT(9)) 175 #define EVENT_MASK 0x3F 176 177 // control record for each dq entry 178 typedef union { 179 struct { 180 uint32_t addr: 16; // I2C address, if 10bit must have 0x7800 mask applied, else 8bit 181 uint32_t mode: 1; // transaction direction 0 write, 1 read 182 uint32_t stop: 1; // sendStop 0 no, 1 yes 183 uint32_t startCmdSent: 1; // START cmd has been added to command[] 184 uint32_t addrCmdSent: 1; // addr WRITE cmd has been added to command[] 185 uint32_t dataCmdSent: 1; // all necessary DATA(READ/WRITE) cmds added to command[] 186 uint32_t stopCmdSent: 1; // completed all necessary commands 187 uint32_t addrReq: 2; // number of addr bytes need to send address 188 uint32_t addrSent: 2; // number of addr bytes added to FIFO 189 uint32_t reserved_31: 6; 190 }; 191 uint32_t val; 192 } I2C_DATA_CTRL_t; 193 194 // individual dq element 195 typedef struct { 196 uint8_t *data; // data pointer for read/write buffer 197 uint16_t length; // size of data buffer 198 uint16_t position; // current position for next char in buffer (<length) 199 uint16_t cmdBytesNeeded; // used to control number of I2C_COMMAND_t blocks added to queue 200 I2C_DATA_CTRL_t ctrl; 201 EventGroupHandle_t queueEvent; // optional user supplied for Async feedback EventBits 202 } I2C_DATA_QUEUE_t; 203 204 struct i2c_struct_t { 205 i2c_dev_t * dev; 206 #if !CONFIG_DISABLE_HAL_LOCKS 207 xSemaphoreHandle lock; 208 #endif 209 uint8_t num; 210 int8_t sda; 211 int8_t scl; 212 I2C_MODE_t mode; 213 I2C_STAGE_t stage; 214 I2C_ERROR_t error; 215 EventGroupHandle_t i2c_event; // a way to monitor ISR process 216 // maybe use it to trigger callback for OnRequest() 217 intr_handle_t intr_handle; /*!< I2C interrupt handle*/ 218 I2C_DATA_QUEUE_t * dq; 219 uint16_t queueCount; // number of dq entries in queue. 220 uint16_t queuePos; // current queue that still has or needs data (out/in) 221 int16_t errorByteCnt; // byte pos where error happened, -1 devId, 0..(length-1) data 222 uint16_t errorQueue; // errorByteCnt is in this queue,(for error locus) 223 uint32_t exitCode; 224 uint32_t debugFlags; 225 }; 226 227 enum { 228 I2C_CMD_RSTART, 229 I2C_CMD_WRITE, 230 I2C_CMD_READ, 231 I2C_CMD_STOP, 232 I2C_CMD_END 233 }; 234 235 #if CONFIG_DISABLE_HAL_LOCKS 236 #define I2C_MUTEX_LOCK() 237 #define I2C_MUTEX_UNLOCK() 238 239 static i2c_t _i2c_bus_array[2] = { 240 {(volatile i2c_dev_t *)(DR_REG_I2C_EXT_BASE_FIXED), 0, -1, -1,I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0}, 241 {(volatile i2c_dev_t *)(DR_REG_I2C1_EXT_BASE_FIXED), 1, -1, -1,I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0} 242 }; 243 #else 244 #define I2C_MUTEX_LOCK() do {} while (xSemaphoreTake(i2c->lock, portMAX_DELAY) != pdPASS) 245 #define I2C_MUTEX_UNLOCK() xSemaphoreGive(i2c->lock) 246 247 static i2c_t _i2c_bus_array[2] = { 248 {(volatile i2c_dev_t *)(DR_REG_I2C_EXT_BASE_FIXED), NULL, 0, -1, -1, I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0,0}, 249 {(volatile i2c_dev_t *)(DR_REG_I2C1_EXT_BASE_FIXED), NULL, 1, -1, -1,I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0,0} 250 }; 251 #endif 252 253 /* 254 * index - command index (0 to 15) 255 * op_code - is the command 256 * byte_num - This register is to store the amounts of data that is read and written. byte_num in RSTART, STOP, END is null. 257 * ack_val - Each data byte is terminated by an ACK bit used to set the bit level. 258 * ack_exp - This bit is to set an expected ACK value for the transmitter. 259 * ack_check - This bit is to decide whether the transmitter checks ACK bit. 1 means yes and 0 means no. 260 * */ 261 262 263 /* Stickbreaker ISR mode debug support 264 */ 265 static void IRAM_ATTR i2cDumpCmdQueue(i2c_t *i2c) 266 { 267 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR)&&(defined ENABLE_I2C_DEBUG_BUFFER) 268 static const char * const cmdName[] ={"RSTART","WRITE","READ","STOP","END"}; 269 uint8_t i=0; 270 while(i<16) { 271 I2C_COMMAND_t c; 272 c.val=i2c->dev->command[i].val; 273 i++; 274 } 275 #endif 276 } 277 278 /* Stickbreaker ISR mode debug support 279 */ 280 static void i2cDumpDqData(i2c_t * i2c) 281 { 282 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&&(defined ENABLE_I2C_DEBUG_BUFFER) 283 uint16_t a=0; 284 char buff[140]; 285 I2C_DATA_QUEUE_t *tdq; 286 int digits=0,lenDigits=0; 287 a = i2c->queueCount; 288 while(a>0) { 289 digits++; 290 a /= 10; 291 } 292 while(a<i2c->queueCount) { // find maximum number of len decimal digits for formatting 293 if (i2c->dq[a].length > lenDigits ) lenDigits = i2c->dq[a].length; 294 a++; 295 } 296 a=0; 297 while(lenDigits>0){ 298 a++; 299 lenDigits /= 10; 300 } 301 lenDigits = a; 302 a = 0; 303 while(a<i2c->queueCount) { 304 tdq=&i2c->dq[a]; 305 char buf1[10],buf2[10]; 306 sprintf(buf1,"%0*d",lenDigits,tdq->length); 307 sprintf(buf2,"%0*d",lenDigits,tdq->position); 308 (tdq->ctrl.addr>0x100)?"10":"7", 309 (tdq->ctrl.addr>0x100)?(((tdq->ctrl.addr&0x600)>>1)|(tdq->ctrl.addr&0xff)):(tdq->ctrl.addr>>1), 310 (tdq->ctrl.mode)?'R':'W', 311 (tdq->ctrl.stop)?"STOP":"", 312 tdq->data, 313 buf1,buf2, 314 tdq->ctrl.startCmdSent,tdq->ctrl.addrCmdSent,tdq->ctrl.dataCmdSent,(tdq->ctrl.stop)?tdq->ctrl.stopCmdSent:0,tdq->ctrl.addrSent 315 ); 316 uint16_t offset = 0; 317 while(offset<tdq->length) { 318 memset(buff,' ',140); 319 buff[139]='\0'; 320 uint16_t i = 0,j; 321 j=sprintf(buff,"0x%04x: ",offset); 322 while((i<32)&&(offset < tdq->length)) { 323 char ch = tdq->data[offset]; 324 sprintf((char*)&buff[(i*3)+41],"%02x ",ch); 325 if((ch<32)||(ch>126)) { 326 ch='.'; 327 } 328 j+=sprintf((char*)&buff[j],"%c",ch); 329 buff[j]=' '; 330 i++; 331 offset++; 332 } 333 } 334 a++; 335 } 336 #endif 337 } 338 339 static void i2cDumpI2c(i2c_t * i2c) 340 { 341 #if !CONFIG_DISABLE_HAL_LOCKS 342 #endif 343 344 if(i2c->dq) { 345 i2cDumpDqData(i2c); 346 } 347 } 348 349 static void i2cDumpInts(uint8_t num) 350 { 351 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER) 352 353 uint32_t b; 354 for(uint32_t a=1; a<=INTBUFFMAX; a++) { 355 b=(a+intPos[num])%INTBUFFMAX; 356 if(intBuff[b][0][num]!=0) { 357 //log_i("[%02d]\t0x%04x\t0x%04x\t0x%04x\t0x%04x\t0x%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]); 358 } 359 } 360 #else 361 #endif 362 } 363 364 static void IRAM_ATTR i2cDumpStatus(i2c_t * i2c){ 365 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&&(defined ENABLE_I2C_DEBUG_BUFFER) 366 typedef union { 367 struct { 368 uint32_t ack_rec: 1; /*This register stores the value of ACK bit.*/ 369 uint32_t slave_rw: 1; /*when in slave mode 1:master read slave 0: master write slave.*/ 370 uint32_t time_out: 1; /*when I2C takes more than time_out_reg clocks to receive a data then this register changes to high level.*/ 371 uint32_t arb_lost: 1; /*when I2C lost control of SDA line this register changes to high level.*/ 372 uint32_t bus_busy: 1; /*1:I2C bus is busy transferring data. 0:I2C bus is in idle state.*/ 373 uint32_t slave_addressed: 1; /*when configured as i2c slave and the address send by master is equal to slave's address then this bit will be high level.*/ 374 uint32_t byte_trans: 1; /*This register changes to high level when one byte is transferred.*/ 375 uint32_t reserved7: 1; 376 uint32_t rx_fifo_cnt: 6; /*This register represent the amount of data need to send.*/ 377 uint32_t reserved14: 4; 378 uint32_t tx_fifo_cnt: 6; /*This register stores the amount of received data in ram.*/ 379 uint32_t scl_main_state_last: 3; /*This register stores the value of state machine for i2c module. 3'h0: SCL_MAIN_IDLE 3'h1: SCL_ADDRESS_SHIFT 3'h2: SCL_ACK_ADDRESS 3'h3: SCL_RX_DATA 3'h4 SCL_TX_DATA 3'h5:SCL_SEND_ACK 3'h6:SCL_WAIT_ACK*/ 380 uint32_t reserved27: 1; 381 uint32_t scl_state_last: 3; /*This register stores the value of state machine to produce SCL. 3'h0: SCL_IDLE 3'h1:SCL_START 3'h2:SCL_LOW_EDGE 3'h3: SCL_LOW 3'h4:SCL_HIGH_EDGE 3'h5:SCL_HIGH 3'h6:SCL_STOP*/ 382 uint32_t reserved31: 1; 383 }; 384 uint32_t val; 385 } status_reg; 386 387 status_reg sr; 388 sr.val= i2c->dev->status_reg.val; 389 390 #endif 391 } 392 393 static void i2cDumpFifo(i2c_t * i2c){ 394 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&&(defined ENABLE_I2C_DEBUG_BUFFER) 395 char buf[64]; 396 uint16_t k = 0; 397 uint16_t i = fifoPos+1; 398 i %=FIFOMAX; 399 while((fifoBuffer[i]==0)&&(i!=fifoPos)){ 400 i++; 401 i %=FIFOMAX; 402 } 403 if(i != fifoPos){// actual data 404 do{ 405 if(fifoBuffer[i] & 0x8000){ // address byte 406 if(fifoBuffer[i] & 0x100) { // read 407 if(fifoBuffer[i] & 0x1) { // valid read dev id 408 k+= sprintf(&buf[k],"READ 0x%02X",(fifoBuffer[i]&0xff)>>1); 409 } else { // invalid read dev id 410 k+= sprintf(&buf[k],"Bad READ 0x%02X",(fifoBuffer[i]&0xff)); 411 } 412 } else { // write 413 if(fifoBuffer[i] & 0x1) { // bad write dev id 414 k+= sprintf(&buf[k],"bad WRITE 0x%02X",(fifoBuffer[i]&0xff)); 415 } else { // good Write 416 k+= sprintf(&buf[k],"WRITE 0x%02X",(fifoBuffer[i]&0xff)>>1); 417 } 418 } 419 } else k += sprintf(&buf[k],"% 4X ",fifoBuffer[i]); 420 421 i++; 422 i %= FIFOMAX; 423 bool outBuffer=false; 424 if( fifoBuffer[i] & 0x8000){ 425 outBuffer=true; 426 k=0; 427 } 428 outBuffer = false; 429 if(k>50) { 430 k=sprintf(buf,"-> "); 431 } 432 }while( i!= fifoPos); 433 } 434 #endif 435 } 436 437 static void IRAM_ATTR i2cTriggerDumps(i2c_t * i2c, uint8_t trigger, const char locus[]){ 438 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&&(defined ENABLE_I2C_DEBUG_BUFFER) 439 if( trigger ){ 440 //log_i("%s",locus); 441 if(trigger & 1) i2cDumpI2c(i2c); 442 if(trigger & 2) i2cDumpInts(i2c->num); 443 if(trigger & 4) i2cDumpCmdQueue(i2c); 444 if(trigger & 8) i2cDumpStatus(i2c); 445 if(trigger & 16) i2cDumpFifo(i2c); 446 } 447 #endif 448 } 449 // end of debug support routines 450 451 static void IRAM_ATTR i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bool ack_val, bool ack_exp, bool ack_check) 452 { 453 I2C_COMMAND_t cmd; 454 cmd.val=0; 455 cmd.ack_en = ack_check; 456 cmd.ack_exp = ack_exp; 457 cmd.ack_val = ack_val; 458 cmd.byte_num = byte_num; 459 cmd.op_code = op_code; 460 i2c->dev->command[index].val = cmd.val; 461 } 462 463 464 static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS) 465 { 466 /* this function is called on initial i2cProcQueue() or when a I2C_END_DETECT_INT occurs 467 */ 468 uint16_t cmdIdx = 0; 469 uint16_t qp = i2c->queuePos; // all queues before queuePos have been completely processed, 470 // so look start by checking the 'current queue' so see if it needs commands added to 471 // hardware peripheral command list. walk through each queue entry until all queues have been 472 // checked 473 bool done; 474 bool needMoreCmds = false; 475 bool ena_rx=false; // if we add a read op, better enable Rx_Fifo IRQ 476 bool ena_tx=false; // if we add a Write op, better enable TX_Fifo IRQ 477 478 while(!needMoreCmds&&(qp < i2c->queueCount)) { // check if more possible cmds 479 if(i2c->dq[qp].ctrl.stopCmdSent) {// marks that all required cmds[] have been added to peripheral 480 qp++; 481 } else { 482 needMoreCmds=true; 483 } 484 } 485 486 done=(!needMoreCmds)||(cmdIdx>14); 487 488 while(!done) { // fill the command[] until either 0..14 filled or out of cmds and last cmd is STOP 489 //CMD START 490 I2C_DATA_QUEUE_t *tdq=&i2c->dq[qp]; // simpler coding 491 492 if((!tdq->ctrl.startCmdSent) && (cmdIdx < 14)) { // has this dq element's START command been added? 493 // (cmdIdx<14) because a START op cannot directly precede an END op, else a time out cascade occurs 494 i2cSetCmd(i2c, cmdIdx++, I2C_CMD_RSTART, 0, false, false, false); 495 tdq->ctrl.startCmdSent=1; 496 } 497 498 //CMD WRITE ADDRESS 499 if((!done)&&(tdq->ctrl.startCmdSent)) { // have to leave room for continue(END), and START must have been sent! 500 if(!tdq->ctrl.addrCmdSent) { 501 i2cSetCmd(i2c, cmdIdx++, I2C_CMD_WRITE, tdq->ctrl.addrReq, false, false, true); //load address in cmdlist, validate (low) ack 502 tdq->ctrl.addrCmdSent=1; 503 done =(cmdIdx>14); 504 ena_tx=true; // tx Data necessary 505 } 506 } 507 508 /* Can I have another Sir? 509 ALL CMD queues must be terminated with either END or STOP. 510 511 If END is used, when refilling the cmd[] next time, no entries from END to [15] can be used. 512 AND the cmd[] must be filled starting at [0] with commands. Either fill all 15 [0]..[14] and leave the 513 END in [15] or include a STOP in one of the positions [0]..[14]. Any entries after a STOP are IGNORED by the StateMachine. 514 The END operation does not complete until ctr->trans_start=1 has been issued. 515 516 So, only refill from [0]..[14], leave [15] for a continuation(END) if necessary. 517 As a corollary, once END exists in [15], you do not need to overwrite it for the 518 next continuation. It is never modified. But, I update it every time because it might 519 actually be the first time! 520 521 23NOV17 START cannot proceed END. if START is in[14], END cannot be in [15]. 522 So, if END is moved to [14], [14] and [15] can no longer be used for anything other than END. 523 If a START is found in [14] then a prior READ or WRITE must be expanded so that there is no START element in [14]. 524 */ 525 526 if((!done)&&(tdq->ctrl.addrCmdSent)) { //room in command[] for at least One data (read/Write) cmd 527 uint8_t blkSize=0; // max is 255 528 while(( tdq->cmdBytesNeeded > tdq->ctrl.mode )&&(!done )) { // more bytes needed and room in cmd queue, leave room for END 529 blkSize = (tdq->cmdBytesNeeded > 255)?255:(tdq->cmdBytesNeeded - tdq->ctrl.mode); // Last read cmd needs different ACK setting, so leave 1 byte remainder on reads 530 tdq->cmdBytesNeeded -= blkSize; 531 if(tdq->ctrl.mode==1) { //read mode 532 i2cSetCmd(i2c, (cmdIdx)++, I2C_CMD_READ, blkSize,false,false,false); // read cmd, this can't be the last read. 533 ena_rx=true; // need to enable rxFifo IRQ 534 } else { // write 535 i2cSetCmd(i2c, cmdIdx++, I2C_CMD_WRITE, blkSize, false, false, true); // check for Nak 536 ena_tx=true; // need to enable txFifo IRQ 537 } 538 done = cmdIdx>14; //have to leave room for END 539 } 540 541 if(!done) { // buffer is not filled completely 542 if((tdq->ctrl.mode==1)&&(tdq->cmdBytesNeeded==1)) { //special last read byte NAK 543 i2cSetCmd(i2c, (cmdIdx)++, I2C_CMD_READ, 1,true,false,false); 544 // send NAK to mark end of read 545 tdq->cmdBytesNeeded=0; 546 done = cmdIdx > 14; 547 ena_rx=true; 548 } 549 } 550 551 tdq->ctrl.dataCmdSent=(tdq->cmdBytesNeeded==0); // enough command[] to send all data 552 553 if((!done)&&(tdq->ctrl.dataCmdSent)) { // possibly add stop 554 if(!tdq->ctrl.stopCmdSent){ 555 if(tdq->ctrl.stop) { //send a stop 556 i2cSetCmd(i2c, (cmdIdx)++,I2C_CMD_STOP,0,false,false,false); 557 done = cmdIdx > 14; 558 } 559 tdq->ctrl.stopCmdSent = 1; 560 } 561 } 562 } 563 564 if((cmdIdx==14)&&(!tdq->ctrl.startCmdSent)) { 565 // START would have preceded END, causes SM TIMEOUT 566 // need to stretch out a prior WRITE or READ to two Command[] elements 567 done = false; // reuse it 568 uint16_t i = 13; // start working back until a READ/WRITE has >1 numBytes 569 cmdIdx =15; 570 while(!done) { 571 i2c->dev->command[i+1].val = i2c->dev->command[i].val; // push it down 572 if (((i2c->dev->command[i].op_code == 1)||(i2c->dev->command[i].op_code==2))) { 573 /* add a dummy read/write cmd[] with num_bytes set to zero,just a place holder in the cmd[]list 574 */ 575 i2c->dev->command[i].byte_num = 0; 576 done = true; 577 578 } else { 579 if(i > 0) { 580 i--; 581 } else { // unable to stretch, fatal 582 i2cDumpCmdQueue(i2c); 583 done = true; 584 } 585 } 586 } 587 588 } 589 590 591 if(cmdIdx==15) { //need continuation, even if STOP is in 14, it will not matter 592 // cmd buffer is almost full, Add END as a continuation feature 593 i2cSetCmd(i2c, (cmdIdx)++,I2C_CMD_END, 0,false,false,false); 594 i2c->dev->int_ena.end_detect=1; 595 i2c->dev->int_clr.end_detect=1; 596 done = true; 597 } 598 599 if(!done) { 600 if(tdq->ctrl.stopCmdSent) { // this queue element has been completely added to command[] buffer 601 qp++; 602 if(qp < i2c->queueCount) { 603 tdq = &i2c->dq[qp]; 604 } else { 605 done = true; 606 } 607 } 608 } 609 610 }// while(!done) 611 if(INTS) { // don't want to prematurely enable fifo ints until ISR is ready to handle them. 612 if(ena_rx) { 613 i2c->dev->int_ena.rx_fifo_full = 1; 614 } 615 if(ena_tx) { 616 i2c->dev->int_ena.tx_fifo_empty = 1; 617 } 618 } 619 } 620 621 static void IRAM_ATTR fillTxFifo(i2c_t * i2c) 622 { 623 /* 624 12/01/2017 The Fifo's are independent, 32 bytes of tx and 32 bytes of Rx. 625 overlap is not an issue, just keep them full/empty the status_reg.xx_fifo_cnt 626 tells the truth. And the INT's fire correctly 627 */ 628 uint16_t a=i2c->queuePos; // currently executing dq, 629 bool full=!(i2c->dev->status_reg.tx_fifo_cnt<31); 630 uint8_t cnt; 631 bool rxQueueEncountered = false; 632 while((a < i2c->queueCount) && !full) { 633 I2C_DATA_QUEUE_t *tdq = &i2c->dq[a]; 634 cnt=0; 635 // add to address to fifo ctrl.addr already has R/W bit positioned correctly 636 if(tdq->ctrl.addrSent < tdq->ctrl.addrReq) { // need to send address bytes 637 if(tdq->ctrl.addrReq==2) { //10bit 638 if(tdq->ctrl.addrSent==0) { //10bit highbyte needs sent 639 if(!full) { // room in fifo 640 i2c->dev->fifo_data.val = ((tdq->ctrl.addr>>8)&0xFF); 641 cnt++; 642 tdq->ctrl.addrSent=1; //10bit highbyte sent 643 } 644 } 645 full=!(i2c->dev->status_reg.tx_fifo_cnt<31); 646 647 if(tdq->ctrl.addrSent==1) { //10bit Lowbyte needs sent 648 if(!full) { // room in fifo 649 i2c->dev->fifo_data.val = tdq->ctrl.addr&0xFF; 650 cnt++; 651 tdq->ctrl.addrSent=2; //10bit lowbyte sent 652 } 653 } 654 } else { // 7bit} 655 if(tdq->ctrl.addrSent==0) { // 7bit Lowbyte needs sent 656 if(!full) { // room in fifo 657 i2c->dev->fifo_data.val = tdq->ctrl.addr&0xFF; 658 cnt++; 659 tdq->ctrl.addrSent=1; // 7bit lowbyte sent 660 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER) 661 uint16_t a = 0x8000 | tdq->ctrl.addr | (tdq->ctrl.mode<<8); 662 fifoBuffer[fifoPos++] = a; 663 fifoPos %= FIFOMAX; 664 #endif 665 } 666 } 667 } 668 } 669 // add write data to fifo 670 if(tdq->ctrl.mode==0) { // write 671 if(tdq->ctrl.addrSent == tdq->ctrl.addrReq) { //address has been sent, is Write Mode! 672 uint32_t moveCnt = 32 - i2c->dev->status_reg.tx_fifo_cnt; // how much room in txFifo? 673 while(( moveCnt>0)&&(tdq->position < tdq->length)) { 674 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER) 675 fifoBuffer[fifoPos++] = tdq->data[tdq->position]; 676 fifoPos %= FIFOMAX; 677 #endif 678 i2c->dev->fifo_data.val = tdq->data[tdq->position++]; 679 cnt++; 680 moveCnt--; 681 682 } 683 } 684 } else { // read Queue Encountered, can't update QueuePos past this point, emptyRxfifo will do it 685 if( ! rxQueueEncountered ) { 686 rxQueueEncountered = true; 687 if(a > i2c->queuePos){ 688 i2c->queuePos = a; 689 } 690 } 691 } 692 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER) 693 694 // update debug buffer tx counts 695 cnt += intBuff[intPos[i2c->num]][1][i2c->num]>>16; 696 intBuff[intPos[i2c->num]][1][i2c->num] = (intBuff[intPos[i2c->num]][1][i2c->num]&0xFFFF)|(cnt<<16); 697 698 #endif 699 full=!(i2c->dev->status_reg.tx_fifo_cnt<31); 700 if(!full) { 701 a++; // check next buffer for address tx, or write data 702 } 703 } 704 705 if(a >= i2c->queueCount ) { // disable TX IRQ, all tx Data has been queued 706 i2c->dev->int_ena.tx_fifo_empty= 0; 707 } 708 709 i2c->dev->int_clr.tx_fifo_empty=1; 710 } 711 712 713 static void IRAM_ATTR emptyRxFifo(i2c_t * i2c) 714 { 715 uint32_t d, cnt=0, moveCnt; 716 717 moveCnt = i2c->dev->status_reg.rx_fifo_cnt;//no need to check the reg until this many are read 718 719 while((moveCnt > 0)&&(i2c->queuePos < i2c->queueCount)){ // data to move 720 721 I2C_DATA_QUEUE_t *tdq =&i2c->dq[i2c->queuePos]; //short cut 722 723 while((tdq->position >= tdq->length)&&( i2c->queuePos < i2c->queueCount)){ // find were to store 724 i2c->queuePos++; 725 tdq = &i2c->dq[i2c->queuePos]; 726 } 727 728 if(i2c->queuePos >= i2c->queueCount){ // bad stuff, rx data but no place to put it! 729 // discard 730 while(moveCnt>0){ 731 d = i2c->dev->fifo_data.val; 732 moveCnt--; 733 cnt++; 734 } 735 break; 736 } 737 738 if(tdq->ctrl.mode == 1){ // read command 739 if(moveCnt > (tdq->length - tdq->position)) { //make sure they go in this dq 740 // part of these reads go into the next dq 741 moveCnt = (tdq->length - tdq->position); 742 } 743 } else {// error 744 // discard 745 while(moveCnt>0){ 746 d = i2c->dev->fifo_data.val; 747 moveCnt--; 748 cnt++; 749 } 750 break; 751 } 752 753 while(moveCnt > 0) { // store data 754 d = i2c->dev->fifo_data.val; 755 moveCnt--; 756 cnt++; 757 tdq->data[tdq->position++] = (d&0xFF); 758 } 759 760 moveCnt = i2c->dev->status_reg.rx_fifo_cnt; //any more out there? 761 } 762 763 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&& (defined ENABLE_I2C_DEBUG_BUFFER) 764 // update Debug rxCount 765 cnt += (intBuff[intPos[i2c->num]][1][i2c->num])&0xffFF; 766 intBuff[intPos[i2c->num]][1][i2c->num] = (intBuff[intPos[i2c->num]][1][i2c->num]&0xFFFF0000)|cnt; 767 #endif 768 } 769 770 static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal) 771 { 772 773 switch(eventCode) { 774 case EVENT_DONE: 775 i2c->error = I2C_OK; 776 break; 777 case EVENT_ERROR_NAK : 778 i2c->error =I2C_ADDR_NAK; 779 break; 780 case EVENT_ERROR_DATA_NAK : 781 i2c->error =I2C_DATA_NAK; 782 break; 783 case EVENT_ERROR_TIMEOUT : 784 i2c->error = I2C_TIMEOUT; 785 break; 786 case EVENT_ERROR_ARBITRATION: 787 i2c->error = I2C_ARBITRATION; 788 break; 789 default : 790 i2c->error = I2C_ERROR; 791 } 792 uint32_t exitCode = EVENT_DONE | eventCode |(Fatal?EVENT_ERROR:0); 793 if((i2c->queuePos < i2c->queueCount) && (i2c->dq[i2c->queuePos].ctrl.mode == 1)) { 794 emptyRxFifo(i2c); // grab last few characters 795 } 796 i2c->dev->int_ena.val = 0; // shut down interrupts 797 i2c->dev->int_clr.val = 0x1FFF; 798 i2c->stage = I2C_DONE; 799 i2c->exitCode = exitCode; //true eventcode 800 801 portBASE_TYPE HPTaskAwoken = pdFALSE,xResult; 802 // try to notify Dispatch we are done, 803 // else the 50ms time out will recover the APP, just a little slower 804 HPTaskAwoken = pdFALSE; 805 xResult = xEventGroupSetBitsFromISR(i2c->i2c_event, exitCode, &HPTaskAwoken); 806 if(xResult == pdPASS) { 807 if(HPTaskAwoken==pdTRUE) { 808 portYIELD_FROM_ISR(); 809 } 810 } 811 812 } 813 814 static void IRAM_ATTR i2c_update_error_byte_cnt(i2c_t * i2c) 815 { 816 /* i2c_update_error_byte_cnt 07/18/2018 817 Only called after an error has occurred, so, most of the time this function is never used. 818 This function obliterates the need to interrupt monitor each byte transferred, at high bitrates 819 the byte interrupts were overwhelming the OS. Spurious Interrupts were being generated. 820 it updates errorByteCnt, errorQueue. 821 */ 822 uint16_t a=0; // start at top of DQ, count how many bytes added to tx fifo, and received from rx_fifo. 823 int16_t bc = 0; 824 I2C_DATA_QUEUE_t *tdq; 825 i2c->errorByteCnt = 0; 826 while( a < i2c->queueCount){ // add up all bytes loaded into fifo's 827 tdq = &i2c->dq[a]; 828 i2c->errorByteCnt += tdq->ctrl.addrSent; 829 i2c->errorByteCnt += tdq->position; 830 a++; 831 } 832 // now errorByteCnt contains total bytes moved into and out of FIFO's 833 // but, there may still be bytes waiting in Fifo's 834 i2c->errorByteCnt -= i2c->dev->status_reg.tx_fifo_cnt; // waiting to go out; 835 i2c->errorByteCnt += i2c->dev->status_reg.rx_fifo_cnt; // already received 836 // now walk thru DQ again, find which byte is 'current' 837 bc = i2c->errorByteCnt; 838 i2c->errorQueue = 0; 839 while( i2c->errorQueue < i2c->queueCount ){ 840 tdq = &i2c->dq[i2c->errorQueue]; 841 if(bc>0){ // not found yet 842 if( tdq->ctrl.addrSent >= bc){ // in address 843 bc = -1; // in address 844 break; 845 } else { 846 bc -= tdq->ctrl.addrSent; 847 if( tdq->length > bc) { // data nak 848 break; 849 } else { // count down 850 bc -= tdq->length; 851 } 852 } 853 } else break; 854 855 i2c->errorQueue++; 856 } 857 858 i2c->errorByteCnt = bc; 859 } 860 861 static void IRAM_ATTR i2c_isr_handler_default(void* arg) 862 { 863 i2c_t* p_i2c = (i2c_t*) arg; // recover data 864 uint32_t activeInt = p_i2c->dev->int_status.val&0x7FF; 865 866 if(p_i2c->stage==I2C_DONE) { //get Out, can't service, not configured 867 p_i2c->dev->int_ena.val = 0; 868 p_i2c->dev->int_clr.val = 0x1FFF; 869 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE 870 uint32_t raw = p_i2c->dev->int_raw.val; 871 //log_w("eject raw=%p, int=%p",raw,activeInt); 872 #endif 873 return; 874 } 875 while (activeInt != 0) { // Ordering of 'if(activeInt)' statements is important, don't change 876 877 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER) 878 if(activeInt==(intBuff[intPos[p_i2c->num]][0][p_i2c->num]&0x1fff)) { 879 intBuff[intPos[p_i2c->num]][0][p_i2c->num] = (((intBuff[intPos[p_i2c->num]][0][p_i2c->num]>>16)+1)<<16)|activeInt; 880 } else { 881 intPos[p_i2c->num]++; 882 intPos[p_i2c->num] %= INTBUFFMAX; 883 intBuff[intPos[p_i2c->num]][0][p_i2c->num] = (1<<16) | activeInt; 884 intBuff[intPos[p_i2c->num]][1][p_i2c->num] = 0; 885 } 886 887 intBuff[intPos[p_i2c->num]][2][p_i2c->num] = xTaskGetTickCountFromISR(); // when IRQ fired 888 889 #endif 890 891 if (activeInt & I2C_TRANS_START_INT_ST_M) { 892 if(p_i2c->stage==I2C_STARTUP) { 893 p_i2c->stage=I2C_RUNNING; 894 } 895 896 activeInt &=~I2C_TRANS_START_INT_ST_M; 897 p_i2c->dev->int_ena.trans_start = 1; // already enabled? why Again? 898 p_i2c->dev->int_clr.trans_start = 1; // so that will trigger after next 'END' 899 } 900 901 if (activeInt & I2C_TXFIFO_EMPTY_INT_ST) {//should this be before Trans_start? 902 fillTxFifo(p_i2c); //fillTxFifo will enable/disable/clear interrupt 903 activeInt&=~I2C_TXFIFO_EMPTY_INT_ST; 904 } 905 906 if(activeInt & I2C_RXFIFO_FULL_INT_ST) { 907 emptyRxFifo(p_i2c); 908 p_i2c->dev->int_clr.rx_fifo_full=1; 909 p_i2c->dev->int_ena.rx_fifo_full=1; //why? 910 911 activeInt &=~I2C_RXFIFO_FULL_INT_ST; 912 } 913 914 if (activeInt & I2C_ACK_ERR_INT_ST_M) {//fatal error, abort i2c service 915 if (p_i2c->mode == I2C_MASTER) { 916 i2c_update_error_byte_cnt(p_i2c); // calc which byte caused ack Error, check if address or data 917 if(p_i2c->errorByteCnt < 0 ) { // address 918 i2cIsrExit(p_i2c,EVENT_ERROR_NAK,true); 919 } else { 920 i2cIsrExit(p_i2c,EVENT_ERROR_DATA_NAK,true); //data 921 } 922 } 923 return; 924 } 925 926 if (activeInt & I2C_TIME_OUT_INT_ST_M) { 927 // let Gross timeout occur, Slave may release SCL before the configured timeout expires 928 // the Statemachine only has a 13.1ms max timout, some Devices >500ms 929 p_i2c->dev->int_clr.time_out =1; 930 activeInt &=~I2C_TIME_OUT_INT_ST; 931 // since a timeout occurred, capture the rxFifo data 932 emptyRxFifo(p_i2c); 933 p_i2c->dev->int_clr.rx_fifo_full=1; 934 p_i2c->dev->int_ena.rx_fifo_full=1; //why? 935 936 } 937 938 if (activeInt & I2C_TRANS_COMPLETE_INT_ST_M) { 939 p_i2c->dev->int_clr.trans_complete = 1; 940 i2cIsrExit(p_i2c,EVENT_DONE,false); 941 return; // no more work to do 942 /* 943 // how does slave mode act? 944 if (p_i2c->mode == I2C_SLAVE) { // STOP detected 945 // empty fifo 946 // dispatch callback 947 */ 948 } 949 950 if (activeInt & I2C_ARBITRATION_LOST_INT_ST_M) { //fatal 951 i2cIsrExit(p_i2c,EVENT_ERROR_ARBITRATION,true); 952 return; // no more work to do 953 } 954 955 if (activeInt & I2C_SLAVE_TRAN_COMP_INT_ST_M) { 956 p_i2c->dev->int_clr.slave_tran_comp = 1; 957 // need to complete this ! 958 } 959 960 if (activeInt & I2C_END_DETECT_INT_ST_M) { 961 p_i2c->dev->int_ena.end_detect = 0; 962 p_i2c->dev->int_clr.end_detect = 1; 963 p_i2c->dev->ctr.trans_start=0; 964 fillCmdQueue(p_i2c,true); // enable interrupts 965 p_i2c->dev->ctr.trans_start=1; // go for it 966 activeInt&=~I2C_END_DETECT_INT_ST_M; 967 } 968 969 if(activeInt) { // clear unhandled if possible? What about Disabling interrupt? 970 p_i2c->dev->int_clr.val = activeInt; 971 // disable unhandled IRQ, 972 p_i2c->dev->int_ena.val = p_i2c->dev->int_ena.val & (~activeInt); 973 } 974 975 // activeInt = p_i2c->dev->int_status.val; // start all over if another interrupt happened 976 // 01AUG2018 if another interrupt happened, the OS will schedule another interrupt 977 // this is the source of spurious interrupts 978 } 979 } 980 981 /* Stickbreaker added for ISR 11/2017 982 functional with Silicon date=0x16042000 983 */ 984 static i2c_err_t i2cAddQueue(i2c_t * i2c,uint8_t mode, uint16_t i2cDeviceAddr, uint8_t *dataPtr, uint16_t dataLen,bool sendStop, bool dataOnly, EventGroupHandle_t event) 985 { 986 // need to grab a MUTEX for exclusive Queue, 987 // what about if ISR is running? 988 989 if(i2c==NULL) { 990 return I2C_ERROR_DEV; 991 } 992 993 I2C_DATA_QUEUE_t dqx; 994 dqx.data = dataPtr; 995 dqx.length = dataLen; 996 dqx.position = 0; 997 dqx.cmdBytesNeeded = dataLen; 998 dqx.ctrl.val = 0; 999 if( dataOnly) { 1000 /* special case to add a queue data only element. 1001 START and devAddr will not be sent, this dq element can have a STOP. 1002 allows multiple buffers to be used for one transaction. 1003 sequence: normal transaction(sendStop==false), [dataonly(sendStop==false)],dataOnly(sendStop==true) 1004 *** Currently only works with WRITE, final byte NAK an READ will cause a fail between dq buffer elements. (in progress 30JUL2018) 1005 */ 1006 dqx.ctrl.startCmdSent = 1; // mark as already sent 1007 dqx.ctrl.addrCmdSent = 1; 1008 } else { 1009 dqx.ctrl.addrReq = ((i2cDeviceAddr&0xFC00)==0x7800)?2:1; // 10bit or 7bit address 1010 } 1011 dqx.ctrl.addr = i2cDeviceAddr; 1012 dqx.ctrl.mode = mode; 1013 dqx.ctrl.stop= sendStop; 1014 dqx.queueEvent = event; 1015 1016 if(event) { // an eventGroup exist, so, initialize it 1017 xEventGroupClearBits(event, EVENT_MASK); // all of them 1018 } 1019 1020 if(i2c->dq!=NULL) { // expand 1021 //log_i("expand"); 1022 I2C_DATA_QUEUE_t* tq =(I2C_DATA_QUEUE_t*)realloc(i2c->dq,sizeof(I2C_DATA_QUEUE_t)*(i2c->queueCount +1)); 1023 if(tq!=NULL) { // ok 1024 i2c->dq = tq; 1025 memmove(&i2c->dq[i2c->queueCount++],&dqx,sizeof(I2C_DATA_QUEUE_t)); 1026 } else { // bad stuff, unable to allocate more memory! 1027 return I2C_ERROR_MEMORY; 1028 } 1029 } else { // first Time 1030 //log_i("new"); 1031 i2c->queueCount=0; 1032 i2c->dq =(I2C_DATA_QUEUE_t*)malloc(sizeof(I2C_DATA_QUEUE_t)); 1033 if(i2c->dq!=NULL) { 1034 memmove(&i2c->dq[i2c->queueCount++],&dqx,sizeof(I2C_DATA_QUEUE_t)); 1035 } else { 1036 return I2C_ERROR_MEMORY; 1037 } 1038 } 1039 return I2C_ERROR_OK; 1040 } 1041 1042 i2c_err_t i2cAddQueueWrite(i2c_t * i2c, uint16_t i2cDeviceAddr, uint8_t *dataPtr, uint16_t dataLen,bool sendStop,EventGroupHandle_t event) 1043 { 1044 return i2cAddQueue(i2c,0,i2cDeviceAddr,dataPtr,dataLen,sendStop,false,event); 1045 } 1046 1047 i2c_err_t i2cAddQueueRead(i2c_t * i2c, uint16_t i2cDeviceAddr, uint8_t *dataPtr, uint16_t dataLen,bool sendStop,EventGroupHandle_t event) 1048 { 1049 //10bit read is kind of weird, first you do a 0byte Write with 10bit 1050 // address, then a ReSTART then a 7bit Read using the the upper 7bit + 1051 // readBit. 1052 1053 // this might cause an internal register pointer problem with 10bit 1054 // devices, But, Don't have any to test against. 1055 // this is the Industry Standard specification. 1056 1057 if((i2cDeviceAddr &0xFC00)==0x7800) { // ten bit read 1058 i2c_err_t err = i2cAddQueue(i2c,0,i2cDeviceAddr,NULL,0,false,false,event); 1059 if(err==I2C_ERROR_OK) { 1060 return i2cAddQueue(i2c,1,(i2cDeviceAddr>>8),dataPtr,dataLen,sendStop,false,event); 1061 } else { 1062 return err; 1063 } 1064 } 1065 return i2cAddQueue(i2c,1,i2cDeviceAddr,dataPtr,dataLen,sendStop,false,event); 1066 } 1067 1068 i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis) 1069 { 1070 /* do the hard stuff here 1071 install ISR if necessary 1072 setup EventGroup 1073 handle bus busy? 1074 */ 1075 //log_e("procQueue i2c=%p",&i2c); 1076 if(readCount){ //total reads accomplished in all queue elements 1077 *readCount = 0; 1078 } 1079 if(i2c == NULL) { 1080 return I2C_ERROR_DEV; 1081 } 1082 if(i2c->debugFlags & 0xff000000) i2cTriggerDumps(i2c,(i2c->debugFlags>>24),"before ProcQueue"); 1083 if (i2c->dev->status_reg.bus_busy) { // return error, let TwoWire() handle resetting the hardware. 1084 /* if multi master then this if should be changed to this 03/12/2018 1085 if(multiMaster){// try to let the bus clear by its self 1086 uint32_t timeOutTick = millis(); 1087 while((i2c->dev->status_reg.bus_busy)&&(millis()-timeOutTick<timeOutMillis())){ 1088 delay(2); // allow task switch 1089 } 1090 } 1091 if(i2c->dev->status_reg.bus_busy){ // still busy, so die 1092 */ 1093 return I2C_ERROR_BUSY; 1094 } 1095 1096 I2C_MUTEX_LOCK(); 1097 /* what about co-existence with SLAVE mode? 1098 Should I check if a slaveMode xfer is in progress and hang 1099 until it completes? 1100 if i2c->stage == I2C_RUNNING or I2C_SLAVE_ACTIVE 1101 */ 1102 i2c->stage = I2C_DONE; // until ready 1103 1104 #if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER) 1105 for(uint16_t i=0; i<INTBUFFMAX; i++) { 1106 intBuff[i][0][i2c->num] = 0; 1107 intBuff[i][1][i2c->num] = 0; 1108 intBuff[i][2][i2c->num] = 0; 1109 } 1110 intPos[i2c->num] = 0; 1111 fifoPos = 0; 1112 memset(fifoBuffer,0,FIFOMAX); 1113 #endif 1114 // EventGroup is used to signal transmission completion from ISR 1115 // not always reliable. Sometimes, the FreeRTOS scheduler is maxed out and refuses request 1116 // if that happens, this call hangs until the timeout period expires, then it continues. 1117 if(!i2c->i2c_event) { 1118 i2c->i2c_event = xEventGroupCreate(); 1119 } 1120 if(i2c->i2c_event) { 1121 xEventGroupClearBits(i2c->i2c_event, 0xFF); 1122 } else { // failed to create EventGroup 1123 I2C_MUTEX_UNLOCK(); 1124 return I2C_ERROR_MEMORY; 1125 } 1126 1127 i2c_err_t reason = I2C_ERROR_OK; 1128 i2c->mode = I2C_MASTER; 1129 i2c->dev->ctr.trans_start=0; // Pause Machine 1130 i2c->dev->timeout.tout = 0xFFFFF; // max 13ms 1131 i2c->dev->int_clr.val = 0x1FFF; // kill them All! 1132 1133 i2c->dev->ctr.ms_mode = 1; // master! 1134 i2c->queuePos=0; 1135 i2c->errorByteCnt=0; 1136 i2c->errorQueue = 0; 1137 uint32_t totalBytes=0; // total number of bytes to be Moved! 1138 // convert address field to required I2C format 1139 while(i2c->queuePos < i2c->queueCount) { // need to push these address modes upstream, to AddQueue 1140 I2C_DATA_QUEUE_t *tdq = &i2c->dq[i2c->queuePos++]; 1141 uint16_t taddr=0; 1142 if(tdq->ctrl.addrReq ==2) { // 10bit address 1143 taddr =((tdq->ctrl.addr >> 7) & 0xFE) 1144 |tdq->ctrl.mode; 1145 taddr = (taddr <<8) || (tdq->ctrl.addr&0xFF); 1146 } else { // 7bit address 1147 taddr = ((tdq->ctrl.addr<<1)&0xFE) 1148 |tdq->ctrl.mode; 1149 } 1150 tdq->ctrl.addr = taddr; // all fixed with R/W bit 1151 totalBytes += tdq->length + tdq->ctrl.addrReq; // total number of byte to be moved! 1152 } 1153 i2c->queuePos=0; 1154 1155 fillCmdQueue(i2c,false); // don't enable Tx/RX irq's 1156 // start adding command[], END irq will keep it full 1157 //Data Fifo will be filled after trans_start is issued 1158 i2c->exitCode=0; 1159 1160 I2C_FIFO_CONF_t f; 1161 f.val = i2c->dev->fifo_conf.val; 1162 f.rx_fifo_rst = 1; // fifo in reset 1163 f.tx_fifo_rst = 1; // fifo in reset 1164 f.nonfifo_en = 0; // use fifo mode 1165 f.nonfifo_tx_thres = 31; 1166 // need to adjust threshold based on I2C clock rate, at 100k, 30 usually works, 1167 // sometimes the emptyRx() actually moves 31 bytes 1168 // it hasn't overflowed yet, I cannot tell if the new byte is added while 1169 // emptyRX() is executing or before? 1170 // let i2cSetFrequency() set thrhds 1171 // f.rx_fifo_full_thrhd = 30; // 30 bytes before INT is issued 1172 // f.tx_fifo_empty_thrhd = 0; 1173 f.fifo_addr_cfg_en = 0; // no directed access 1174 i2c->dev->fifo_conf.val = f.val; // post them all 1175 1176 f.rx_fifo_rst = 0; // release fifo 1177 f.tx_fifo_rst = 0; 1178 i2c->dev->fifo_conf.val = f.val; // post them all 1179 1180 i2c->stage = I2C_STARTUP; // everything configured, now start the I2C StateMachine, and 1181 // As soon as interrupts are enabled, the ISR will start handling them. 1182 // it should receive a TXFIFO_EMPTY immediately, even before it 1183 // receives the TRANS_START 1184 1185 1186 uint32_t interruptsEnabled = 1187 I2C_ACK_ERR_INT_ENA | // (BIT(10)) Causes Fatal Error Exit 1188 I2C_TRANS_START_INT_ENA | // (BIT(9)) Triggered by trans_start=1, initial,END 1189 I2C_TIME_OUT_INT_ENA | //(BIT(8)) Trigger by SLAVE SCL stretching, NOT an ERROR 1190 I2C_TRANS_COMPLETE_INT_ENA | // (BIT(7)) triggered by STOP, successful exit 1191 I2C_ARBITRATION_LOST_INT_ENA | // (BIT(5)) cause fatal error exit 1192 I2C_SLAVE_TRAN_COMP_INT_ENA | // (BIT(4)) unhandled 1193 I2C_END_DETECT_INT_ENA | // (BIT(3)) refills cmd[] list 1194 I2C_RXFIFO_OVF_INT_ENA | //(BIT(2)) unhandled 1195 I2C_TXFIFO_EMPTY_INT_ENA | // (BIT(1)) triggers fillTxFifo() 1196 I2C_RXFIFO_FULL_INT_ENA; // (BIT(0)) trigger emptyRxFifo() 1197 1198 i2c->dev->int_ena.val = interruptsEnabled; 1199 1200 if(!i2c->intr_handle) { // create ISR for either peripheral 1201 // log_i("create ISR %d",i2c->num); 1202 uint32_t ret = 0; 1203 uint32_t flags = ESP_INTR_FLAG_IRAM | //< ISR can be called if cache is disabled 1204 ESP_INTR_FLAG_LOWMED | //< Low and medium prio interrupts. These can be handled in C. 1205 ESP_INTR_FLAG_SHARED; //< Reduce resource requirements, Share interrupts 1206 1207 if(i2c->num) { 1208 ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT1_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, interruptsEnabled, &i2c_isr_handler_default,i2c, &i2c->intr_handle); 1209 } else { 1210 ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT0_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, interruptsEnabled, &i2c_isr_handler_default,i2c, &i2c->intr_handle); 1211 } 1212 1213 if(ret!=ESP_OK) { 1214 I2C_MUTEX_UNLOCK(); 1215 return I2C_ERROR_MEMORY; 1216 } 1217 } 1218 //hang until it completes. 1219 1220 // how many ticks should it take to transfer totalBytes through the I2C hardware, 1221 // add user supplied timeOutMillis to Calculated Value 1222 1223 portTickType ticksTimeOut = ((totalBytes*10*1000)/(i2cGetFrequency(i2c))+timeOutMillis)/portTICK_PERIOD_MS; 1224 1225 i2c->dev->ctr.trans_start=1; // go for it 1226 1227 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR 1228 portTickType tBefore=xTaskGetTickCount(); 1229 #endif 1230 1231 // wait for ISR to complete the transfer, or until timeOut in case of bus fault, hardware problem 1232 1233 uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut); 1234 1235 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR 1236 portTickType tAfter=xTaskGetTickCount(); 1237 #endif 1238 1239 1240 // if xEventGroupSetBitsFromISR() failed, the ISR could have succeeded but never been 1241 // able to mark the success 1242 1243 if(i2c->exitCode!=eBits) { // try to recover from O/S failure 1244 // log_e("EventGroup Failed:%p!=%p",eBits,i2c->exitCode); 1245 eBits=i2c->exitCode; 1246 } 1247 if((eBits&EVENT_ERROR)||(!(eBits & EVENT_DONE))){ // need accurate errorByteCnt for debug 1248 i2c_update_error_byte_cnt(i2c); 1249 } 1250 1251 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 1252 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO 1253 i2cDumpI2c(i2c); 1254 i2cDumpInts(i2c->num); 1255 #endif 1256 } 1257 1258 if(eBits&EVENT_DONE) { // no gross timeout 1259 switch(i2c->error) { 1260 case I2C_OK : 1261 reason = I2C_ERROR_OK; 1262 break; 1263 case I2C_ERROR : 1264 reason = I2C_ERROR_DEV; 1265 break; 1266 case I2C_ADDR_NAK: 1267 reason = I2C_ERROR_ACK; 1268 break; 1269 case I2C_DATA_NAK: 1270 reason = I2C_ERROR_ACK; 1271 break; 1272 case I2C_ARBITRATION: 1273 reason = I2C_ERROR_BUS; 1274 break; 1275 case I2C_TIMEOUT: 1276 reason = I2C_ERROR_TIMEOUT; 1277 break; 1278 default : 1279 reason = I2C_ERROR_DEV; 1280 } 1281 } else { // GROSS timeout, shutdown ISR , report Timeout 1282 i2c->stage = I2C_DONE; 1283 i2c->dev->int_ena.val =0; 1284 i2c->dev->int_clr.val = 0x1FFF; 1285 i2c_update_error_byte_cnt(i2c); 1286 if((i2c->errorByteCnt == 0)&&(i2c->errorQueue==0)) { // Bus Busy no bytes Moved 1287 reason = I2C_ERROR_BUSY; 1288 eBits = eBits | EVENT_ERROR_BUS_BUSY|EVENT_ERROR|EVENT_DONE; 1289 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG 1290 //log_d(" Busy Timeout start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error); 1291 i2cDumpI2c(i2c); 1292 i2cDumpInts(i2c->num); 1293 #endif 1294 } else { // just a timeout, some data made it out or in. 1295 reason = I2C_ERROR_TIMEOUT; 1296 eBits = eBits | EVENT_ERROR_TIMEOUT|EVENT_ERROR|EVENT_DONE; 1297 1298 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG 1299 //log_d(" Gross Timeout Dead start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error); 1300 i2cDumpI2c(i2c); 1301 i2cDumpInts(i2c->num); 1302 #endif 1303 } 1304 } 1305 1306 /* offloading all EventGroups to dispatch, EventGroups in ISR is not always successful 1307 11/20/2017 1308 if error, need to trigger all succeeding dataQueue events with the EVENT_ERROR_PREV 1309 07/22/2018 1310 Need to use the queueEvent value to identify transaction blocks, if an error occurs, 1311 all subsequent queue items with the same queueEvent value will receive the EVENT_ERROR_PREV. 1312 But, ProcQue should re-queue queue items that have a different queueEvent value(different transaction) 1313 This change will support multi-thread i2c usage. Use the queueEvent as the transaction event 1314 identifier. 1315 */ 1316 uint32_t b = 0; 1317 1318 while(b < i2c->queueCount) { 1319 if(i2c->dq[b].ctrl.mode==1 && readCount) { 1320 *readCount += i2c->dq[b].position; // number of data bytes received 1321 } 1322 if(b < i2c->queuePos) { // before any error 1323 if(i2c->dq[b].queueEvent) { // this data queue element has an EventGroup 1324 xEventGroupSetBits(i2c->dq[b].queueEvent,EVENT_DONE); 1325 } 1326 } else if(b == i2c->queuePos) { // last processed queue 1327 if(i2c->dq[b].queueEvent) { // this data queue element has an EventGroup 1328 xEventGroupSetBits(i2c->dq[b].queueEvent,eBits); 1329 } 1330 } else { // never processed queues 1331 if(i2c->dq[b].queueEvent) { // this data queue element has an EventGroup 1332 xEventGroupSetBits(i2c->dq[b].queueEvent,eBits|EVENT_ERROR_PREV); 1333 } 1334 } 1335 b++; 1336 } 1337 if(i2c->debugFlags & 0x00ff0000) i2cTriggerDumps(i2c,(i2c->debugFlags>>16),"after ProcQueue"); 1338 1339 I2C_MUTEX_UNLOCK(); 1340 return reason; 1341 } 1342 1343 static void i2cReleaseISR(i2c_t * i2c) 1344 { 1345 if(i2c->intr_handle) { 1346 esp_intr_free(i2c->intr_handle); 1347 i2c->intr_handle=NULL; 1348 } 1349 } 1350 1351 static bool i2cCheckLineState(int8_t sda, int8_t scl){ 1352 if(sda < 0 || scl < 0){ 1353 return false;//return false since there is nothing to do 1354 } 1355 // if the bus is not 'clear' try the cycling SCL until SDA goes High or 9 cycles 1356 digitalWrite(sda, HIGH); 1357 digitalWrite(scl, HIGH); 1358 pinMode(sda, PULLUP|OPEN_DRAIN|INPUT); 1359 pinMode(scl, PULLUP|OPEN_DRAIN|OUTPUT); 1360 1361 if(!digitalRead(sda) || !digitalRead(scl)) { // bus in busy state 1362 //log_w("invalid state sda(%d)=%d, scl(%d)=%d", sda, digitalRead(sda), scl, digitalRead(scl)); 1363 digitalWrite(scl, HIGH); 1364 for(uint8_t a=0; a<9; a++) { 1365 delayMicroseconds(5); 1366 digitalWrite(scl, LOW); 1367 delayMicroseconds(5); 1368 digitalWrite(scl, HIGH); 1369 if(digitalRead(sda)){ // bus recovered 1370 //log_d("Recovered after %d Cycles",a+1); 1371 break; 1372 } 1373 } 1374 } 1375 1376 if(!digitalRead(sda) || !digitalRead(scl)) { // bus in busy state 1377 return false; // bus is busy 1378 } 1379 return true; 1380 } 1381 1382 i2c_err_t i2cAttachSCL(i2c_t * i2c, int8_t scl) 1383 { 1384 if(i2c == NULL) { 1385 return I2C_ERROR_DEV; 1386 } 1387 digitalWrite(scl, HIGH); 1388 pinMode(scl, OPEN_DRAIN | PULLUP | INPUT | OUTPUT); 1389 pinMatrixOutAttach(scl, I2C_SCL_IDX(i2c->num), false, false); 1390 pinMatrixInAttach(scl, I2C_SCL_IDX(i2c->num), false); 1391 return I2C_ERROR_OK; 1392 } 1393 1394 i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl) 1395 { 1396 if(i2c == NULL) { 1397 return I2C_ERROR_DEV; 1398 } 1399 pinMatrixOutDetach(scl, false, false); 1400 pinMatrixInDetach(I2C_SCL_IDX(i2c->num), false, false); 1401 pinMode(scl, INPUT | PULLUP); 1402 return I2C_ERROR_OK; 1403 } 1404 1405 i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda) 1406 { 1407 if(i2c == NULL) { 1408 return I2C_ERROR_DEV; 1409 } 1410 digitalWrite(sda, HIGH); 1411 pinMode(sda, OPEN_DRAIN | PULLUP | INPUT | OUTPUT ); 1412 pinMatrixOutAttach(sda, I2C_SDA_IDX(i2c->num), false, false); 1413 pinMatrixInAttach(sda, I2C_SDA_IDX(i2c->num), false); 1414 return I2C_ERROR_OK; 1415 } 1416 1417 i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda) 1418 { 1419 if(i2c == NULL) { 1420 return I2C_ERROR_DEV; 1421 } 1422 pinMatrixOutDetach(sda, false, false); 1423 pinMatrixInDetach(I2C_SDA_IDX(i2c->num), false, false); 1424 pinMode(sda, INPUT | PULLUP); 1425 return I2C_ERROR_OK; 1426 } 1427 1428 /* 1429 * PUBLIC API 1430 * */ 1431 // 24Nov17 only supports Master Mode 1432 i2c_t * i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) //before this is called, pins should be detached, else glitch 1433 { 1434 //log_v("num=%d sda=%d scl=%d freq=%d",i2c_num, sda, scl, frequency); 1435 if(i2c_num > 1) { 1436 return NULL; 1437 } 1438 1439 i2c_t * i2c = &_i2c_bus_array[i2c_num]; 1440 1441 if(i2c->sda >= 0){ 1442 i2cDetachSDA(i2c, i2c->sda); 1443 } 1444 if(i2c->scl >= 0){ 1445 i2cDetachSCL(i2c, i2c->scl); 1446 } 1447 i2c->sda = sda; 1448 i2c->scl = scl; 1449 1450 #if !CONFIG_DISABLE_HAL_LOCKS 1451 if(i2c->lock == NULL) { 1452 i2c->lock = xSemaphoreCreateMutex(); 1453 if(i2c->lock == NULL) { 1454 return NULL; 1455 } 1456 } 1457 #endif 1458 I2C_MUTEX_LOCK(); 1459 1460 i2cReleaseISR(i2c); // ISR exists, release it before disabling hardware 1461 1462 if(frequency == 0) {// don't change existing frequency 1463 frequency = i2cGetFrequency(i2c); 1464 if(frequency == 0) { 1465 frequency = 100000L; // default to 100khz 1466 } 1467 } 1468 1469 if(i2c_num == 0) { 1470 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT0_RST); //reset hardware 1471 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT0_CLK_EN); 1472 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT0_RST);// release reset 1473 } else { 1474 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST); //reset Hardware 1475 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT1_CLK_EN); 1476 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST); 1477 } 1478 i2c->dev->ctr.val = 0; 1479 i2c->dev->ctr.ms_mode = 1; 1480 i2c->dev->ctr.sda_force_out = 1 ; 1481 i2c->dev->ctr.scl_force_out = 1 ; 1482 i2c->dev->ctr.clk_en = 1; 1483 1484 //the max clock number of receiving a data 1485 i2c->dev->timeout.tout = 400000;//clocks max=1048575 1486 //disable apb nonfifo access 1487 i2c->dev->fifo_conf.nonfifo_en = 0; 1488 1489 i2c->dev->slave_addr.val = 0; 1490 I2C_MUTEX_UNLOCK(); 1491 1492 i2cSetFrequency(i2c, frequency); // reconfigure 1493 1494 if(!i2cCheckLineState(i2c->sda, i2c->scl)){ 1495 return NULL; 1496 } 1497 1498 if(i2c->sda >= 0){ 1499 i2cAttachSDA(i2c, i2c->sda); 1500 } 1501 if(i2c->scl >= 0){ 1502 i2cAttachSCL(i2c, i2c->scl); 1503 } 1504 return i2c; 1505 } 1506 1507 void i2cRelease(i2c_t *i2c) // release all resources, power down peripheral 1508 { 1509 I2C_MUTEX_LOCK(); 1510 1511 if(i2c->sda >= 0){ 1512 i2cDetachSDA(i2c, i2c->sda); 1513 } 1514 if(i2c->scl >= 0){ 1515 i2cDetachSCL(i2c, i2c->scl); 1516 } 1517 1518 i2cReleaseISR(i2c); 1519 1520 if(i2c->i2c_event) { 1521 vEventGroupDelete(i2c->i2c_event); 1522 i2c->i2c_event = NULL; 1523 } 1524 1525 i2cFlush(i2c); 1526 1527 // reset the I2C hardware and shut off the clock, power it down. 1528 if(i2c->num == 0) { 1529 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT0_RST); //reset hardware 1530 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT0_CLK_EN); // shutdown hardware 1531 } else { 1532 DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG,DPORT_I2C_EXT1_RST); //reset Hardware 1533 DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG,DPORT_I2C_EXT1_CLK_EN); // shutdown Hardware 1534 } 1535 1536 I2C_MUTEX_UNLOCK(); 1537 } 1538 1539 i2c_err_t i2cFlush(i2c_t * i2c) 1540 { 1541 if(i2c==NULL) { 1542 return I2C_ERROR_DEV; 1543 } 1544 i2cTriggerDumps(i2c,i2c->debugFlags & 0xff, "FLUSH"); 1545 1546 // need to grab a MUTEX for exclusive Queue, 1547 // what out if ISR is running? 1548 i2c_err_t rc=I2C_ERROR_OK; 1549 if(i2c->dq!=NULL) { 1550 // log_i("free"); 1551 // what about EventHandle? 1552 free(i2c->dq); 1553 i2c->dq = NULL; 1554 } 1555 i2c->queueCount=0; 1556 i2c->queuePos=0; 1557 // release Mutex 1558 return rc; 1559 } 1560 1561 i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis){ 1562 i2c_err_t last_error = i2cAddQueueWrite(i2c, address, buff, size, sendStop, NULL); 1563 1564 if(last_error == I2C_ERROR_OK) { //queued 1565 if(sendStop) { //now actually process the queued commands, including READs 1566 last_error = i2cProcQueue(i2c, NULL, timeOutMillis); 1567 if(last_error == I2C_ERROR_BUSY) { // try to clear the bus 1568 if(i2cInit(i2c->num, i2c->sda, i2c->scl, 0)) { 1569 last_error = i2cProcQueue(i2c, NULL, timeOutMillis); 1570 } 1571 } 1572 i2cFlush(i2c); 1573 } else { // stop not received, so wait for I2C stop, 1574 last_error = I2C_ERROR_CONTINUE; 1575 } 1576 } 1577 return last_error; 1578 } 1579 1580 i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis, uint32_t *readCount){ 1581 i2c_err_t last_error=i2cAddQueueRead(i2c, address, buff, size, sendStop, NULL); 1582 1583 if(last_error == I2C_ERROR_OK) { //queued 1584 if(sendStop) { //now actually process the queued commands, including READs 1585 last_error = i2cProcQueue(i2c, readCount, timeOutMillis); 1586 if(last_error == I2C_ERROR_BUSY) { // try to clear the bus 1587 if(i2cInit(i2c->num, i2c->sda, i2c->scl, 0)) { 1588 last_error = i2cProcQueue(i2c, readCount, timeOutMillis); 1589 } 1590 } 1591 i2cFlush(i2c); 1592 } else { // stop not received, so wait for I2C stop, 1593 last_error = I2C_ERROR_CONTINUE; 1594 } 1595 } 1596 return last_error; 1597 } 1598 1599 i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) 1600 { 1601 if(i2c == NULL) { 1602 return I2C_ERROR_DEV; 1603 } 1604 I2C_FIFO_CONF_t f; 1605 1606 uint32_t period = (APB_CLK_FREQ/clk_speed) / 2; 1607 uint32_t halfPeriod = period/2; 1608 uint32_t quarterPeriod = period/4; 1609 1610 I2C_MUTEX_LOCK(); 1611 1612 // Adjust Fifo thresholds based on frequency 1613 f.val = i2c->dev->fifo_conf.val; 1614 uint32_t a = (clk_speed / 50000L )+1; 1615 if (a > 24) a=24; 1616 f.rx_fifo_full_thrhd = 32 - a; 1617 f.tx_fifo_empty_thrhd = a; 1618 i2c->dev->fifo_conf.val = f.val; // set thresholds 1619 //log_v("Fifo threshold=%d",a); 1620 1621 //the clock num during SCL is low level 1622 i2c->dev->scl_low_period.period = period; 1623 //the clock num during SCL is high level 1624 i2c->dev->scl_high_period.period = period; 1625 1626 //the clock num between the negedge of SDA and negedge of SCL for start mark 1627 i2c->dev->scl_start_hold.time = halfPeriod; 1628 //the clock num between the posedge of SCL and the negedge of SDA for restart mark 1629 i2c->dev->scl_rstart_setup.time = halfPeriod; 1630 1631 //the clock num after the STOP bit's posedge 1632 i2c->dev->scl_stop_hold.time = halfPeriod; 1633 //the clock num between the posedge of SCL and the posedge of SDA 1634 i2c->dev->scl_stop_setup.time = halfPeriod; 1635 1636 //the clock num I2C used to hold the data after the negedge of SCL. 1637 i2c->dev->sda_hold.time = quarterPeriod; 1638 //the clock num I2C used to sample data on SDA after the posedge of SCL 1639 i2c->dev->sda_sample.time = quarterPeriod; 1640 I2C_MUTEX_UNLOCK(); 1641 return I2C_ERROR_OK; 1642 } 1643 1644 uint32_t i2cGetFrequency(i2c_t * i2c) 1645 { 1646 if(i2c == NULL) { 1647 return 0; 1648 } 1649 uint32_t result = 0; 1650 uint32_t old_count = (i2c->dev->scl_low_period.period+i2c->dev->scl_high_period.period); 1651 if(old_count>0) { 1652 result = APB_CLK_FREQ / old_count; 1653 } else { 1654 result = 0; 1655 } 1656 return result; 1657 } 1658 1659 1660 uint32_t i2cDebug(i2c_t * i2c, uint32_t setBits, uint32_t resetBits){ 1661 if(i2c != NULL) { 1662 i2c->debugFlags = ((i2c->debugFlags | setBits) & ~resetBits); 1663 return i2c->debugFlags; 1664 } 1665 return 0; 1666 1667 } 1668 1669 uint32_t i2cGetStatus(i2c_t * i2c){ 1670 if(i2c != NULL){ 1671 return i2c->dev->status_reg.val; 1672 } 1673 else return 0; 1674 } 1675 /* todo 1676 22JUL18 1677 need to add multi-thread capability, use dq.queueEvent as the group marker. When multiple threads 1678 transactions are present in the same queue, and an error occurs, abort all succeeding unserviced transactions 1679 with the same dq.queueEvent value. Succeeding unserviced transactions with different dq.queueEvent values 1680 can be re-queued and processed independently. 1681 30JUL18 complete data only queue elements, this will allow transfers to use multiple data blocks, 1682 */ 1683