/****************************************************************************** * 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_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_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(I2C_DELAY); i2c_master_setDC(m_nLastSDA, 0); // sda 1, scl 0 for (i = 0; i < 8; i++) { i2c_master_wait(I2C_DELAY); i2c_master_setDC(1, 0); // sda 1, scl 0 i2c_master_setDC(1, 1); // sda 1, scl 1 k = i2c_master_getDC(); if (i == 7) { i2c_master_wait(I2C_DELAY); // extra delay } k <<= (7 - i); retVal |= k; } i2c_master_setDC(1, 0); // sda 1, scl 0 return retVal; }
/****************************************************************************** * 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(5); // when SCL = 0, toggle SDA to clear up i2c_master_setDC(0, 0) ; i2c_master_wait(5); i2c_master_setDC(1, 0) ; i2c_master_wait(5); // set data_cnt to max value for (i = 0; i < 28; i++) { 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 } // reset all i2c_master_stop(); return; }
/****************************************************************************** * 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_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); 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_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_FULL); i2c_master_setDC(0, m_nLastSCL); i2c_master_wait(I2C_DELAY_FULL); // sda 0 i2c_master_setDC(0, 1); i2c_master_wait(I2C_DELAY_FULL); // sda 0, scl 1 i2c_master_setDC(1, 1); i2c_master_wait(I2C_DELAY_FULL); // sda 1, scl 1 }
/****************************************************************************** * FunctionName : i2c_master_stop * Description : set i2c to stop sending state * Parameters : NONE * Returns : NONE *******************************************************************************/ void ICACHE_RAM_ATTR i2c_master_stop(void) { i2c_master_wait(5); i2c_master_setDC(0, m_nLastSCL); i2c_master_wait(5); // sda 0 i2c_master_setDC(0, 1); i2c_master_wait(5); // sda 0, scl 1 i2c_master_setDC(1, 1); i2c_master_wait(5); // sda 1, 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(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_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_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(I2C_DELAY_FULL); i2c_master_setDC(level, 0); i2c_master_wait(I2C_DELAY_FULL); // sda level, scl 0 i2c_master_setDC(level, 1); i2c_master_wait(I2C_DELAY_LONG); // sda level, scl 1 i2c_master_setDC(level, 0); i2c_master_wait(I2C_DELAY_FULL); // sda level, scl 0 i2c_master_setDC(1, 0); i2c_master_wait(I2C_DELAY_FULL); }
/****************************************************************************** * 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); }
LOCAL void ICACHE_FLASH_ATTR read_cb(void) { uint8_t ack, low, high; wdt_feed(); os_printf("Time=%ld\n", system_get_time()); i2c_master_start(); i2c_master_writeByte(BH1750_ADDR); ack = i2c_master_getAck(); if (ack) { os_printf("I2C:No ack after sending address\n"); i2c_master_stop(); return; } i2c_master_stop(); i2c_master_wait(40000); // why? i2c_master_start(); i2c_master_writeByte(BH1750_ADDR + 1); ack = i2c_master_getAck(); if (ack) { os_printf("I2C:No ack after write command\n"); i2c_master_stop(); return; } low = i2c_master_readByte(); high = i2c_master_readByte(); i2c_master_setAck(1); i2c_master_stop(); os_printf("I2C:read(L/H)=(0x%02x/0x%02x)\n", low, high); }
/****************************************************************************** * FunctionName : i2c_master_getDC * Description : Internal used function - * get i2c SDA bit value * Parameters : NONE * Returns : uint8 - SDA bit value *******************************************************************************/ LOCAL uint8 ICACHE_FLASH_ATTR i2c_master_getDC(void) { uint8 sda_out; sda_out = GPIO_INPUT_GET(GPIO_ID_PIN(I2C_MASTER_SDA_GPIO)); i2c_master_wait(I2C_DELAY); return sda_out; }
/****************************************************************************** * 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_FLASH_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(1); i2c_master_setDC(dat, 1); i2c_master_wait(5); i2c_master_setDC(dat, 0); i2c_master_wait(2); } }
/****************************************************************************** * 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_FULL); i2c_master_setDC(m_nLastSDA, 0); i2c_master_wait(I2C_DELAY_FULL); for (i = 7; i >= 0; i--) { dat = wrdata >> i; i2c_master_setDC(dat, 0); i2c_master_wait(I2C_DELAY_FULL); i2c_master_setDC(dat, 1); i2c_master_wait(I2C_DELAY_FULL); if (i == 0) { i2c_master_wait(I2C_DELAY_HALF); //// } i2c_master_setDC(dat, 0); i2c_master_wait(I2C_DELAY_FULL); } }
/****************************************************************************** * 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; }
/****************************************************************************** * 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; }
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; }
/****************************************************************************** * FunctionName : user_mvh3004_burst_read * Description : burst read mvh3004's internal data * Parameters : uint8 addr - mvh3004's address * uint8 *pData - data point to put read data * uint16 len - read length * Returns : bool - true or false *******************************************************************************/ LOCAL bool ICACHE_FLASH_ATTR user_mvh3004_burst_read(uint8 addr, uint8 *pData, uint16 len) { uint8 ack; uint16 i; i2c_master_start(); i2c_master_writeByte(addr); ack = i2c_master_getAck(); if (ack) { os_printf("addr not ack when tx write cmd \n"); i2c_master_stop(); return false; } i2c_master_stop(); i2c_master_wait(40000); i2c_master_start(); i2c_master_writeByte(addr + 1); ack = i2c_master_getAck(); if (ack) { os_printf("addr not ack when tx write cmd \n"); i2c_master_stop(); return false; } for (i = 0; i < len; i++) { pData[i] = i2c_master_readByte(); i2c_master_setAck((i == (len - 1)) ? 1 : 0); } i2c_master_stop(); return true; }
/****************************************************************************** * FunctionName : i2c_master_setDC * Description : Internal used function - * set i2c SDA and SCL bit value for half clk cycle * Parameters : uint8 SDA * uint8 SCL * Returns : NONE *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR i2c_master_setDC(uint8 SDA, uint8 SCL) { SDA &= 0x01; SCL &= 0x01; m_nLastSDA = SDA; m_nLastSCL = SCL; if ((0 == SDA) && (0 == SCL)) { I2C_MASTER_SDA_LOW_SCL_LOW(); } else if ((0 == SDA) && (1 == SCL)) { do { I2C_MASTER_SDA_LOW_SCL_HIGH(); } while (GPIO_INPUT_GET(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO)) == 0); } else if ((1 == SDA) && (0 == SCL)) { I2C_MASTER_SDA_HIGH_SCL_LOW(); } else { do { I2C_MASTER_SDA_HIGH_SCL_HIGH(); } while (GPIO_INPUT_GET(GPIO_ID_PIN(I2C_MASTER_SCL_GPIO)) == 0); } i2c_master_wait(I2C_DELAY); }
static void i2c_master_cmd_begin_static(i2c_port_t i2c_num) { i2c_obj_t *p_i2c = p_i2c_obj[i2c_num]; i2c_cmd_t *cmd; uint8_t dat; uint8_t len; int8_t i, k; uint8_t retVal; // This should never happen if (p_i2c->mode != I2C_MODE_MASTER) { return; } while (p_i2c->cmd_link.head) { cmd = &p_i2c->cmd_link.head->cmd; switch (cmd->op_code) { case (I2C_CMD_RESTART): { i2c_master_set_dc(i2c_num, 1, i2c_last_state[i2c_num]->scl); i2c_master_set_dc(i2c_num, 1, 1); i2c_master_wait(1); // sda 1, scl 1 i2c_master_set_dc(i2c_num, 0, 1); i2c_master_wait(1); // sda 0, scl 1 } break; case (I2C_CMD_WRITE): { p_i2c->status = I2C_STATUS_WRITE; for (len = 0; len < cmd->byte_num; len++) { dat = 0; retVal = 0; i2c_master_set_dc(i2c_num, i2c_last_state[i2c_num]->sda, 0); for (i = 7; i >= 0; i--) { if (cmd->byte_num == 1 && cmd->data == NULL) { dat = (cmd->byte_cmd) >> i; } else { dat = ((uint8_t) * (cmd->data + len)) >> i; } i2c_master_set_dc(i2c_num, dat, 0); i2c_master_wait(1); i2c_master_set_dc(i2c_num, dat, 1); i2c_master_wait(2); if (i == 0) { i2c_master_wait(1); // wait slaver ack } i2c_master_set_dc(i2c_num, dat, 0); } i2c_master_set_dc(i2c_num, i2c_last_state[i2c_num]->sda, 0); i2c_master_set_dc(i2c_num, 1, 0); i2c_master_set_dc(i2c_num, 1, 1); i2c_master_wait(1); retVal = i2c_master_get_dc(i2c_num); i2c_master_wait(1); i2c_master_set_dc(i2c_num, 1, 0); if (cmd->ack.en == 1) { if ((retVal & 0x01) != cmd->ack.exp) { p_i2c->status = I2C_STATUS_ACK_ERROR; return ; } } } } break; case (I2C_CMD_READ): { p_i2c->status = I2C_STATUS_READ; for (len = 0; len < cmd->byte_num; len++) { retVal = 0; i2c_master_set_dc(i2c_num, i2c_last_state[i2c_num]->sda, 0); for (i = 0; i < 8; i++) { i2c_master_set_dc(i2c_num, 1, 0); i2c_master_wait(2); i2c_master_set_dc(i2c_num, 1, 1); i2c_master_wait(1); // sda 1, scl 1 k = i2c_master_get_dc(i2c_num); i2c_master_wait(1); if (i == 7) { i2c_master_wait(1); } k <<= (7 - i); retVal |= k; } i2c_master_set_dc(i2c_num, 1, 0); memcpy((uint8_t *)(cmd->data + len), (uint8_t *)&retVal, 1); i2c_master_set_dc(i2c_num, i2c_last_state[i2c_num]->sda, 0); i2c_master_set_dc(i2c_num, cmd->ack.val, 0); i2c_master_set_dc(i2c_num, cmd->ack.val, 1); i2c_master_wait(4); // sda level, scl 1 i2c_master_set_dc(i2c_num, cmd->ack.val, 0); i2c_master_set_dc(i2c_num, 1, 0); i2c_master_wait(1); } } break; case (I2C_CMD_STOP): { i2c_master_wait(1); i2c_master_set_dc(i2c_num, 0, i2c_last_state[i2c_num]->scl); i2c_master_set_dc(i2c_num, 0, 1); i2c_master_wait(2); // sda 0, scl 1 i2c_master_set_dc(i2c_num, 1, 1); i2c_master_wait(2); // sda 1, scl 1 } break; }