/****************************************************************************** * FunctionName : i2c_master_readByte * Description : read Byte from i2c bus * Parameters : NONE * Returns : uint8 - readed value *******************************************************************************/ uint8 i2c_master_readByte(void) { uint8 retVal = 0; uint8 k, i; i2c_master_setDC(1, m_nLastSCL); for (i = 0; i < 8; i++) { i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(1, 0); i2c_master_wait(I2C_SLEEP_TIME);// sda 1, scl 0 i2c_master_setDC(1, 1); while(i2c_master_getCL()==0) ; // clock stretch i2c_master_wait(I2C_SLEEP_TIME);// sda 1, scl 1 k = i2c_master_getDC(); i2c_master_wait(I2C_SLEEP_TIME); //if (i == 7) { // i2c_master_wait(5); //// //} k <<= (7 - i); retVal |= k; } i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(I2C_SLEEP_TIME);// sda 1, scl 0 return retVal; }
/****************************************************************************** * FunctionName : i2c_master_start * Description : set i2c to send state * Parameters : NONE * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_start(void) { i2c_master_setDC(1, m_nLastSCL); // sda 1 i2c_master_setDC(1, 1); // sda 1, scl 1 i2c_master_setDC(0, 1); // sda 0, scl 1 }
/****************************************************************************** * FunctionName : i2c_master_init * Description : initilize I2C bus to enable i2c operations * Parameters : NONE * Returns : NONE *******************************************************************************/ void i2c_master_init(void) { uint8 i; i2c_master_setDC(1, 0); i2c_master_wait(I2C_SLEEP_TIME); // when SCL = 0, toggle SDA to clear up i2c_master_setDC(0, 0) ; i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(1, 0) ; i2c_master_wait(I2C_SLEEP_TIME); // set data_cnt to max value for (i = 0; i < 28; i++) { i2c_master_setDC(1, 0); i2c_master_wait(I2C_SLEEP_TIME);// sda 1, scl 0 i2c_master_setDC(1, 1); i2c_master_wait(I2C_SLEEP_TIME);// sda 1, scl 1 } // reset all i2c_master_stop(); return; }
/****************************************************************************** * FunctionName : i2c_master_init * Description : initilize I2C bus to enable i2c operations * Parameters : NONE * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_init(void) { uint8 i; i2c_master_setDC(1, 0); i2c_master_wait(I2C_DELAY_FULL); // when SCL = 0, toggle SDA to clear up i2c_master_setDC(0, 0) ; i2c_master_wait(I2C_DELAY_FULL); i2c_master_setDC(1, 0) ; i2c_master_wait(I2C_DELAY_FULL); // set data_cnt to max value for (i = 0; i < 28; i++) { i2c_master_setDC(1, 0); i2c_master_wait(I2C_DELAY_FULL); // sda 1, scl 0 i2c_master_setDC(1, 1); i2c_master_wait(I2C_DELAY_FULL); // sda 1, scl 1 } // reset all i2c_master_stop(); return; }
/****************************************************************************** * FunctionName : i2c_master_readByte * Description : read Byte from i2c bus * Parameters : NONE * Returns : uint8 - readed value *******************************************************************************/ uint8 ICACHE_FLASH_ATTR i2c_master_readByte(void) { uint8 retVal = 0; uint8 k, i; i2c_master_wait(5); i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(5); // sda 1, scl 0 for (i = 0; i < 8; i++) { i2c_master_wait(5); i2c_master_setDC(1, 0); i2c_master_wait(5); // sda 1, scl 0 i2c_master_setDC(1, 1); i2c_master_wait(5); // sda 1, scl 1 k = i2c_master_getDC(); i2c_master_wait(5); if (i == 7) { i2c_master_wait(3); //// } k <<= (7 - i); retVal |= k; } i2c_master_setDC(1, 0); i2c_master_wait(5); // sda 1, scl 0 return retVal; }
/****************************************************************************** * FunctionName : i2c_master_writeByte * Description : write wrdata value(one byte) into i2c * Parameters : uint8 wrdata - write value * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_writeByte(uint8 wrdata) { uint8 dat; sint8 i; i2c_master_wait(5); i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(5); for (i = 7; i >= 0; i--) { dat = wrdata >> i; i2c_master_setDC(dat, 0); i2c_master_wait(5); i2c_master_setDC(dat, 1); i2c_master_wait(5); if (i == 0) { i2c_master_wait(3); //// } i2c_master_setDC(dat, 0); i2c_master_wait(5); } }
/****************************************************************************** * FunctionName : i2c_master_writeByte * Description : write wrdata value(one byte) into i2c * Parameters : uint8 wrdata - write value * Returns : NONE *******************************************************************************/ void i2c_master_writeByte(uint8 wrdata) { uint8 dat; sint8 i; /* i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(m_nLastSDA, 0); */ i2c_master_wait(I2C_SLEEP_TIME); for (i = 7; i >= 0; i--) { dat = wrdata >> i; i2c_master_setDC(dat, 0); i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(dat, 1); i2c_master_wait(I2C_SLEEP_TIME); /* if (i == 0) { i2c_master_wait(5); //// } */ i2c_master_setDC(dat, 0); i2c_master_wait(I2C_SLEEP_TIME); } }
/****************************************************************************** * FunctionName : i2c_master_start * Description : set i2c to send state * Parameters : NONE * Returns : NONE *******************************************************************************/ void i2c_master_start(void) { i2c_master_setDC(1, m_nLastSCL); i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(1, 1); i2c_master_wait(I2C_SLEEP_TIME);// sda 1, scl 1 i2c_master_setDC(0, 1); i2c_master_wait(I2C_SLEEP_TIME);// sda 0, scl 1 }
/****************************************************************************** * FunctionName : i2c_master_stop * Description : set i2c to stop sending state * Parameters : NONE * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_stop(void) { i2c_master_wait(I2C_DELAY); i2c_master_setDC(0, m_nLastSCL); // sda 0 i2c_master_setDC(0, 1); // sda 0, scl 1 i2c_master_setDC(1, 1); // sda 1, scl 1 }
/****************************************************************************** * FunctionName : i2c_master_start * Description : set i2c to send state * Parameters : NONE * Returns : NONE *******************************************************************************/ void ICACHE_RAM_ATTR i2c_master_start(void) { i2c_master_setDC(1, m_nLastSCL); i2c_master_wait(5); i2c_master_setDC(1, 1); i2c_master_wait(5); // sda 1, scl 1 i2c_master_setDC(0, 1); i2c_master_wait(5); // sda 0, scl 1 }
/****************************************************************************** * FunctionName : i2c_master_setAck * Description : set ack to i2c bus as level value * Parameters : uint8 level - 0 or 1 * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_setAck(uint8 level) { i2c_master_setDC(m_nLastSDA, 0); i2c_master_setDC(level, 0); // sda level, scl 0 i2c_master_setDC(level, 1); // sda level, scl 1 i2c_master_wait(I2C_DELAY); // extra delay i2c_master_setDC(level, 0); // sda level, scl 0 i2c_master_setDC(1, 0); }
/****************************************************************************** * FunctionName : i2c_master_setAck * Description : set ack to i2c bus as level value * Parameters : uint8 level - 0 or 1 * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_setAck(uint8 level) { i2c_master_setDC(level, 0); i2c_master_wait(2); // sda level, scl 0 i2c_master_setDC(level, 1); i2c_master_wait(4); // sda level, scl 1 i2c_master_setDC(level, 0); i2c_master_wait(2); // sda level, scl 0 i2c_master_setDC(1, 0); i2c_master_wait(2); }
/****************************************************************************** * FunctionName : i2c_master_setAck * Description : set ack to i2c bus as level value * Parameters : uint8 level - 0 or 1 * Returns : NONE *******************************************************************************/ void i2c_master_setAck(uint8 level) { i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(level, 0); i2c_master_wait(I2C_SLEEP_TIME);// sda level, scl 0 i2c_master_setDC(level, 1); i2c_master_wait(8);// sda level, scl 1 i2c_master_setDC(level, 0); i2c_master_wait(I2C_SLEEP_TIME);// sda level, scl 0 i2c_master_setDC(1, 0); i2c_master_wait(I2C_SLEEP_TIME); }
/****************************************************************************** * FunctionName : i2c_master_setAck * Description : set ack to i2c bus as level value * Parameters : uint8 level - 0 or 1 * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_setAck(uint8 level) { i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(5); i2c_master_setDC(level, 0); i2c_master_wait(5); // sda level, scl 0 i2c_master_setDC(level, 1); i2c_master_wait(8); // sda level, scl 1 i2c_master_setDC(level, 0); i2c_master_wait(5); // sda level, scl 0 i2c_master_setDC(1, 0); i2c_master_wait(5); }
/****************************************************************************** * FunctionName : i2c_master_getAck * Description : confirm if peer send ack * Parameters : NONE * Returns : uint8 - ack value, 0 or 1 *******************************************************************************/ uint8 ICACHE_FLASH_ATTR i2c_master_getAck(void) { uint8 retVal; i2c_master_setDC(1, 0); i2c_master_wait(2); i2c_master_setDC(1, 1); i2c_master_wait(4); retVal = i2c_master_getDC(); i2c_master_setDC(1, 0); i2c_master_wait(2); return !retVal; // 0->true->ACK, 1->false->NACK }
/****************************************************************************** * FunctionName : i2c_master_getAck * Description : confirm if peer send ack * Parameters : NONE * Returns : uint8 - ack value, 0 or 1 *******************************************************************************/ uint8 ICACHE_FLASH_ATTR i2c_master_getAck(void) { uint8 retVal; i2c_master_setDC(m_nLastSDA, 0); i2c_master_setDC(1, 0); i2c_master_wait(I2C_DELAY); // extra delay i2c_master_setDC(1, 1); retVal = i2c_master_getDC(); i2c_master_setDC(1, 0); return retVal; }
/****************************************************************************** * FunctionName : i2c_master_gpio_init * Description : config SDA and SCL gpio to open-drain output mode, * mux and gpio num defined in i2c_master.h * Parameters : uint8 sda and scl pin numbers * Returns : bool, true if init okay *******************************************************************************/ bool i2c_master_gpio_init(uint8 sda, uint8 scl) { if((sda > GPIO_PIN_NUM) || (pin_func[sda] == GPIO_PIN_FUNC_INVALID)){ return false; } if((scl > GPIO_PIN_NUM) || (pin_func[scl] == GPIO_PIN_FUNC_INVALID)){ return false; } pinSDA = sda; pinSCL = scl; ETS_GPIO_INTR_DISABLE() ; // ETS_INTR_LOCK(); PIN_FUNC_SELECT(pin_mux[sda], pin_func[sda]); PIN_FUNC_SELECT(pin_mux[scl], pin_func[scl]); GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(sda)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(sda))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain; GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << sda)); GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(scl)), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(scl))) | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); //open drain; GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS, GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << scl)); i2c_master_setDC(1, 1); ETS_GPIO_INTR_ENABLE() ; // ETS_INTR_UNLOCK(); i2c_master_init(); return true; }
/****************************************************************************** * FunctionName : i2c_master_getAck * Description : confirm if peer send ack * Parameters : NONE * Returns : uint8 - ack value, 0 or 1 *******************************************************************************/ uint8 i2c_master_getAck(void) { uint8 retVal; i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(1, 0); i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(1, 1); i2c_master_wait(I2C_SLEEP_TIME); retVal = i2c_master_getDC(); i2c_master_wait(I2C_SLEEP_TIME); i2c_master_setDC(1, 0); i2c_master_wait(I2C_SLEEP_TIME); return retVal; }
/****************************************************************************** * FunctionName : i2c_master_getAck * Description : confirm if peer send ack * Parameters : NONE * Returns : uint8 - ack value, 0 or 1 *******************************************************************************/ uint8 ICACHE_FLASH_ATTR i2c_master_getAck(void) { uint8 retVal; i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(5); i2c_master_setDC(1, 0); i2c_master_wait(5); i2c_master_setDC(1, 1); i2c_master_wait(5); retVal = i2c_master_getDC(); i2c_master_wait(5); i2c_master_setDC(1, 0); i2c_master_wait(5); return retVal; }
/****************************************************************************** * FunctionName : i2c_master_writeByte * Description : write wrdata value(one byte) into i2c * Parameters : uint8 wrdata - write value * Returns : NONE *******************************************************************************/ void ICACHE_RAM_ATTR i2c_master_writeByte(uint8 wrdata) { uint8 dat; sint8 i; i2c_master_wait(2); i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(4); for (i = 7; i >= 0; i--) { dat = wrdata >> i; i2c_master_setDC(dat, 0); i2c_master_wait(2); i2c_master_setDC(dat, 1); i2c_master_wait(4); i2c_master_setDC(dat, 0); i2c_master_wait(1); } }
/****************************************************************************** * FunctionName : i2c_master_writeByte * Description : write wrdata value(one byte) into i2c * Parameters : uint8 wrdata - write value * Returns : NONE *******************************************************************************/ void ICACHE_FLASH_ATTR i2c_master_writeByte(uint8 wrdata) { uint8 dat; sint8 i; i2c_master_wait(I2C_DELAY); // extra delay i2c_master_setDC(m_nLastSDA, 0); for (i = 7; i >= 0; i--) { dat = wrdata >> i; i2c_master_setDC(dat, 0); i2c_master_setDC(dat, 1); i2c_master_wait(I2C_DELAY); // extra delay if (i == 0) { i2c_master_wait(I2C_DELAY); // extra delay } i2c_master_setDC(dat, 0); } }
/****************************************************************************** * FunctionName : i2c_master_readByte * Description : read Byte from i2c bus * Parameters : NONE * Returns : uint8 - readed value *******************************************************************************/ uint8 ICACHE_FLASH_ATTR i2c_master_readByte(void) { uint8 retVal = 0; uint8 i; i2c_master_wait(2); i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(4); // sda 1, scl 0 for (i = 0; i < 8; i++) { i2c_master_setDC(1, 0); i2c_master_wait(4); // sda 1, scl 0 i2c_master_setDC(1, 1); i2c_master_wait(3); // sda 1, scl 1 retVal = (retVal<<1) | (i2c_master_getDC()&1); } i2c_master_setDC(1, 0); i2c_master_wait(2); // sda 1, scl 0 return retVal; }
bool i2c_master_readBytes(uint8 address, uint8 *values, uint8 length) { if(values[0] > 0){ if(!i2c_master_writeBytes(address, values, 1)){ return false; } } uint8 timeout = 100; do{ i2c_master_start(); i2c_master_writeByte(address+1); if(!i2c_master_checkAck()){ i2c_master_stop(); i2c_master_wait(1000); continue; } break; }while(--timeout>0); if(timeout == 0){ return false; } #ifdef CONFIG_I2C_MASTER_DEBUG console_printf("Read: "); #endif uint8 readed = 0; while((readed < length) && (--timeout>0)){ uint8 byte = i2c_master_readByte(); values[readed++] = byte; i2c_master_setAck((readed == length)); // send the ACK or NAK as applicable i2c_master_setDC(1, 0); // release SDA #ifdef CONFIG_I2C_MASTER_DEBUG console_printf("%d ", byte); #endif } #ifdef CONFIG_I2C_MASTER_DEBUG console_printf("\n"); #endif i2c_master_stop(); return true; }