- int chdrv_read_byte(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data) {
- return (chbsp_i2c_mem_read(dev_ptr, mem_addr, data, 1));
- }
- int chbsp_i2c_mem_read(ch_dev_t *dev_ptr, uint16_t u16_mem_addr, uint8_t *pu8_data, uint16_t u16_num_bytes)
- {
- int i32_error = 1; // default is error return
- uint8_t u8_i2c_addr = ch_get_i2c_address(dev_ptr);
- i32_error = i2c_master_read_register(u8_i2c_addr, u16_mem_addr, u16_num_bytes, pu8_data);
- return i32_error;
- }
- uint64_t i2c_master_read_register(uint8_t u8_Address, uint8_t u8_RegisterAddr, uint16_t u16_RegisterLen, uint8_t *pu8_RegisterValue)
- {
- return !(u16_RegisterLen == I2C_ReadMultiBytesOneReg(I2C0, u8_Address, u8_RegisterAddr, pu8_RegisterValue, u16_RegisterLen));
- }
- uint32_t I2C_ReadMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t au8Rdata[], uint32_t u32rLen)
- {
- uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
- uint32_t u32rxLen = 0u;
- I2C_START(i2c); /* Send START */
- while (u8Xfering && (u8Err == 0u))
- {
- I2C_WAIT_READY(i2c) {}
- switch (I2C_GET_STATUS(i2c))
- {
- case 0x08u:
- I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
- u8Ctrl = I2C_CTL_SI; /* Clear SI */
- break;
- case 0x18u: /* Slave Address ACK */
- I2C_SET_DATA(i2c, u8DataAddr); /* Write Lo byte address of register */
- break;
- case 0x20u: /* Slave Address NACK */
- case 0x30u: /* Master transmit data NACK */
- u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
- u8Err = 1u;
- break;
- case 0x28u:
- u8Ctrl = I2C_CTL_STA_SI; /* Send repeat START */
- break;
- case 0x10u:
- I2C_SET_DATA(i2c, (uint8_t)((u8SlaveAddr << 1u) | 0x01u)); /* Write SLA+R to Register I2CDAT */
- u8Ctrl = I2C_CTL_SI; /* Clear SI */
- break;
- case 0x40u: /* Slave Address ACK */
- u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
- break;
- case 0x48u: /* Slave Address NACK */
- u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
- u8Err = 1u;
- break;
- case 0x50u:
- au8Rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
- if (u32rxLen < (u32rLen - 1u))
- {
- u8Ctrl = I2C_CTL_SI_AA; /* Clear SI and set ACK */
- }
- else
- {
- u8Ctrl = I2C_CTL_SI; /* Clear SI */
- }
- break;
- case 0x58u:
- au8Rdata[u32rxLen++] = (uint8_t) I2C_GET_DATA(i2c); /* Receive Data */
- u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
- u8Xfering = 0u;
- break;
- case 0x38u: /* Arbitration Lost */
- default: /* Unknow status */
- u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
- u8Err = 1u;
- break;
- }
- I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
- }
- return u32rxLen; /* Return bytes length that have been received */
- }
以上代码来自于新唐m263的例子,功能是从I2C设备读取内部寄存器一个字节。
- ret_val = chdrv_write_byte(dev_ptr, 0x07, 2);
- int chdrv_write_byte(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t data_value) {
- uint8_t message[] = { sizeof(data_value), data_value }; // insert byte count (1) at start of data
- int ch_err = chbsp_i2c_mem_write(dev_ptr, mem_addr, message, sizeof(message));
- return ch_err;
- }
- int chbsp_i2c_mem_write(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *pu8_data, uint16_t u16_num_bytes)
- {
- int i32_error = 0;
- i32_error = i2c_master_write_register(dev_ptr->i2c_address, mem_addr, u16_num_bytes, pu8_data);
- return i32_error;
- }
- uint64_t i2c_master_write_register(uint8_t u8_Address, uint8_t u8_RegisterAddr, uint16_t u16_RegisterLen, uint8_t *pu8_RegisterValue)
- {
- return !(u16_RegisterLen == I2C_WriteMultiBytesOneReg(I2C0, u8_Address, u8_RegisterAddr, pu8_RegisterValue, u16_RegisterLen));
- }
- uint32_t I2C_WriteMultiBytesOneReg(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t u8DataAddr, uint8_t au8Data[], uint32_t u32wLen)
- {
- uint8_t u8Xfering = 1u, u8Err = 0u, u8Ctrl = 0u;
- uint32_t u32txLen = 0u;
- I2C_START(i2c); /* Send START */
- while (u8Xfering && (u8Err == 0u))
- {
- I2C_WAIT_READY(i2c) {}
- switch (I2C_GET_STATUS(i2c))
- {
- case 0x08u:
- I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1u | 0x00u)); /* Write SLA+W to Register I2CDAT */
- u8Ctrl = I2C_CTL_SI;
- break;
- case 0x18u: /* Slave Address ACK */
- I2C_SET_DATA(i2c, u8DataAddr); /* Write Lo byte address of register */
- break;
- case 0x20u: /* Slave Address NACK */
- case 0x30u: /* Master transmit data NACK */
- u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
- u8Err = 1u;
- break;
- case 0x28u:
- if (u32txLen < u32wLen)
- {
- I2C_SET_DATA(i2c, au8Data[u32txLen++]);
- }
- else
- {
- u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
- u8Xfering = 0u;
- }
- break;
- case 0x38u: /* Arbitration Lost */
- default: /* Unknow status */
- u8Ctrl = I2C_CTL_STO_SI; /* Clear SI and send STOP */
- u8Err = 1u;
- break;
- }
- I2C_SET_CONTROL_REG(i2c, u8Ctrl); /* Write controlbit to I2C_CTL register */
- }
- return u32txLen; /* Return bytes length that have been transmitted */
- }
以上代码来自于新唐m263的例子,功能是从I2C设备写入内部寄存器2个字节。感觉好绕,最后底层的I2C代码我已看不出时序,现在用arduino来取代,代码如下:
- int chbsp_i2c_mem_write(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes){
- TwoWire* pWire;
- pWire=chbsp_i2c_get_device(dev_ptr);
- if (pWire != NULL) {
- pWire->beginTransmission(dev_ptr->i2c_address);
- pWire->write(lowByte(mem_addr)); // LSB
- pWire->write(data,num_bytes);
- info = pWire->endTransmission();
- }
- }
- int chbsp_i2c_mem_read(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes){
- TwoWire* pWire = NULL;
- int retval = 0;
- pWire=chbsp_i2c_get_device(dev_ptr);
- if (pWire != NULL) {
- pWire->beginTransmission(dev_ptr->i2c_address);
- pWire->write(lowByte(mem_addr));
- pWire->endTransmission();
- int receivedBytes = pWire->requestFrom((int)dev_ptr->i2c_address,(int)num_bytes,1);
- if(receivedBytes != num_bytes)
- {
- Serial.printf("did not receive enough bytes %dmem %dnum %drec %d\n.",mem_addr,num_bytes,receivedBytes,dev_ptr->i2c_address);
- retval = 1;
- }else{
- for(int i = 0; i < num_bytes; i++)
- {
- data[i] = pWire->read(); // receive a byte as character
- }
- }
- }else{
- retval = 1;
- }
- return retval;
- }
但是我的arduino代码执行不正确,写入收到NACK,读出返回0字节,新唐的底层I2C实在看不懂,有大侠帮看看问题出在哪里,谢谢!