/ MCUME_esp32 / espboot / components / Wire / esp32-hal-i2c.c
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