bool I2C_Write_NoAck(uint8_t addr, uint8_t reg, uint8_t data) { if (!I2C_Start_NoAck()) return false; I2C_SendByte(addr << 1 | I2C_Direction_Transmitter); I2C_NoAck(); //I2C_SendByte(reg); //I2C_NoAck(); I2C_SendByte(data); I2C_NoAck(); I2C_Stop(); return true; }
u8 Single_ReadI2C(u8 REG_Address) { u8 REG_data; I2C_Start(); I2C_SendByte(SlaveAddress); I2C_Slave_ACK(); I2C_SendByte(REG_Address); I2C_Slave_ACK(); I2C_Start(); I2C_SendByte(SlaveAddress + 1); I2C_Slave_ACK(); REG_data = I2C_RecvByte(); I2C_nack(); I2C_Stop(); return REG_data; }
bool i2cWrite(uint8_t addr, uint8_t reg, uint8_t data) { if (!I2C_Start()) return false; I2C_SendByte(addr << 1 | I2C_Direction_Transmitter); if (!I2C_WaitAck()) { I2C_Stop(); return false; } I2C_SendByte(reg); I2C_WaitAck(); I2C_SendByte(data); I2C_WaitAck(); I2C_Stop(); return true; }
/*********************************************************** * Function: // 函数名称 * Description: // 函数功能、性能等的描述 * Input: // 1.输入参数1,说明,包括每个参数的作用、取值说明及参数间关系 * Input: // 2.输入参数2,说明,包括每个参数的作用、取值说明及参数间关系 * Output: // 1.输出参数1,说明 * Return: // 函数返回值的说明 * Others: // 其它说明 ***********************************************************/ static uint8_t IIC_RegRead( uint8_t address, uint8_t reg, uint8_t *value ) { uint8_t err = ERR_NONE; err = I2C_Start( ); if( err ) { goto lbl_ERR_REG_RD_STOP; } I2C_SendByte( address << 1 ); err = I2C_WaitAck( ); if( err ) { goto lbl_ERR_REG_RD_STOP; } I2C_SendByte( reg ); err = I2C_WaitAck( ); if( err ) { goto lbl_ERR_REG_RD_STOP; } err = I2C_Start( ); if( err ) { goto lbl_ERR_REG_RD; } I2C_SendByte( ( address << 1 ) | 0x01 ); err = I2C_WaitAck( ); if( err ) { goto lbl_ERR_REG_RD_STOP; } *value = I2C_ReceiveByte( ); I2C_NoAck( ); I2C_Stop( ); return ERR_NONE; lbl_ERR_REG_RD_STOP: I2C_Stop( ); lbl_ERR_REG_RD: //rt_kprintf( "reg_rd error=%02x reg=%02x\r\n", err, reg ); return err; }
void WriteI2C(u8 ch, u8 address, u8 WriteAddress) { I2C_Start(); // 启动总线,开始传输数据; I2C_SendByte(WriteAddress); I2C_WaitAck(); //while(TestAck()); // 发送从器件硬件地址; I2C_SendByte(address); I2C_WaitAck(); //while(TestAck()); // 发送从器件存储器字节地址; I2C_SendByte(ch); I2C_WaitAck(); //while(TestAck()); // 发送数据; #if ENABLE_I2C_DELAY I2C_delay(); #endif I2C_Stop(); // 发送停止位,发送数据结束; #if ENABLE_I2C_DELAY I2C_delay(); #endif }
//************************************** //从I2C设备读取一个字节数据 //************************************** uint8_t Single_ReadI2C(uint8_t REG_Address) { uint8_t REG_data; I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress); //发送设备地址+写信号 I2C_SendByte(REG_Address); //发送存储单元地址,从0开始 I2C_Start(); //起始信号 I2C_SendByte(SlaveAddress + 1); //发送设备地址+读信号 REG_data = I2C_RecvByte(); //读出寄存器数据 SDA = 1; //写应答信号 SCL = 1; //拉高时钟线 Delay2us(); //延时 SCL = 0; //拉低时钟线 Delay2us(); //延时 I2C_Stop(); //停止信号 return REG_data; }
// I2C模拟读出两个字节 uint16_t I2C_Read_2Bytes(uint8_t DeviceAddr, uint8_t address) { uint8_t data_temp1,data_temp2; uint16_t data_16; I2C_START(); I2C_SendByte(DeviceAddr); I2C_SendByte(address); I2C_START(); I2C_SendByte(DeviceAddr + 1); data_temp1 = I2C_ReceiveByte_WithACK(); data_temp2 = I2C_ReceiveByte(); I2C_STOP(); data_16 = (data_temp1<<8) | data_temp2; return data_16; }
//单字节读取***************************************** unsigned char Single_Read(unsigned char SlaveAddress,unsigned char REG_Address) { unsigned char REG_data; if(!I2C_Start())return FALSE; I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址 if(!I2C_WaitAck()){I2C_Stop(); return FALSE;} I2C_SendByte((u8) REG_Address); //设置低起始地址 I2C_WaitAck(); I2C_Start(); I2C_SendByte(SlaveAddress+1); I2C_WaitAck(); REG_data= I2C_ReadByte(); I2C_NoAck(); I2C_Stop(); return REG_data; }
/***********************单字节读取******************/ uint8_t MPU6050_ReadByte(uint8_t SlaveAddress,uint8_t REG_Address) { unsigned char REG_data; I2C_Start();//if(!I2C_Start())return 0 I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址 I2C_WaitAck();//if(!I2C_WaitAck()){I2C_Stop();test=1; return 0;} I2C_SendByte((uint8_t) REG_Address); //设置低起始地址 I2C_WaitAck(); //if(!I2C_WaitAck()){I2C_Stop(); return 0;} I2C_Start();//if(!I2C_Start())return 0; I2C_SendByte(SlaveAddress+1); I2C_WaitAck();//if(!I2C_WaitAck()){I2C_Stop(); return 0;} REG_data= I2C_ReadByte(); I2C_NoAck(); I2C_Stop(); return REG_data; }
/****************************************************************************** / 函数功能:单字节写入 / 修改日期:none / 输入参数: / @arg SlaveAddress 从器件地址 / @arg REG_Address 寄存器地址 / 输出参数: 读出的字节数据 / 使用说明:这时一个完整的单字节读取函数 ******************************************************************************/ uint8_t Single_Read(uint8_t SlaveAddress,uint8_t REG_Address) { uint8_t REG_data; I2C_Start();//if(!I2C_Start())return 0 I2C_SendByte(SlaveAddress); //I2C_SendByte(((REG_Address & 0x0700) >>7) | REG_Address & 0xFFFE);//设置高起始地址+器件地址 I2C_WaitAck();//if(!I2C_WaitAck()){I2C_Stop();return 0;} I2C_SendByte((uint8_t) REG_Address); //设置低起始地址 I2C_WaitAck();//if(!I2C_WaitAck()){I2C_Stop();return 0;} I2C_Start();//if(!I2C_Start())return 0; I2C_SendByte(SlaveAddress+1); I2C_WaitAck();//if(!I2C_Start())return 0; REG_data = I2C_ReadByte(); I2C_NoAck(); I2C_Stop(); return REG_data; }
/* *函数名:I2C_ImByteRead *函数功能:将设备dadr的当前地址处数据读出 *输入:dadr *输出:dat */ unsigned char I2C_ImByteRead(unsigned char dadr) { unsigned char dat; I2C_Start(); I2C_SendByte(dadr | 0x01); dat = I2C_ReceiveByte(); I2C_Stop(); return dat; }
bool I2C_WriteBuffer_NoAck(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data) { int i; if (!I2C_Start_NoAck()) return false; I2C_SendByte(addr << 1 | I2C_Direction_Transmitter); I2C_NoAck(); //I2C_SendByte(reg); //I2C_NoAck(); for (i = 0; i < len; i++) { I2C_SendByte(data[i]); I2C_NoAck(); } I2C_Stop(); return true; }
// I2C模拟读出三个字节 uint32_t I2C_Read_3Bytes(uint8_t DeviceAddr, uint8_t address) { uint8_t data_temp1, data_temp2, data_temp3; uint32_t data_32; I2C_START(); I2C_SendByte(DeviceAddr); I2C_SendByte(address); I2C_START(); I2C_SendByte(DeviceAddr + 1); data_temp1 = I2C_ReceiveByte_WithACK(); data_temp2 = I2C_ReceiveByte_WithACK(); data_temp3 = I2C_ReceiveByte(); I2C_STOP(); data_32 = (data_temp1<<16) | (data_temp2<<8) | data_temp3; return data_32; }
u8 ReadI2C(u8 address, u8 WriteAddress) // 读出1串数据 { u8 ch; // 定义存储读出数据的临时变量; I2C_Start(); // 启动总线,开始传输数据; I2C_SendByte(WriteAddress); I2C_WaitAck(); // 发送从器件硬件地址; I2C_SendByte(address); I2C_WaitAck(); // 发送从器件内部数据存储器的地址; I2C_Start(); // 重新启动总线,开始传输数据; I2C_SendByte(WriteAddress + 1); I2C_WaitAck(); // 发送从器件内部数据存储器的地址; ch = I2C_ReceiveByte(); I2C_NoAck(); // 将读出的一个字节数据存入临时变量,发送非应答位; I2C_Stop(); // 发送停止信号,释放总路线; return (ch); }
/******************************************************************************* * Function Name : I2C_ReadByte * Description : 读取一串数据 * Input : - pBuffer: 存放读出数据 * - length: 待读出长度 * - ReadAddress: 待读出地址 * - DeviceAddress: 器件类型 * Output : None * Return : 返回为:=1成功读入,=0失败 * Attention : None *******************************************************************************/ int I2C_ReadByte(uint8_t* pBuffer, uint16_t length, uint8_t ReadAddress, uint8_t DeviceAddress) { if(!I2C_Start()) { return DISABLE; } I2C_SendByte( DeviceAddress ); /* 器件地址 */ if( !I2C_WaitAck() ) { I2C_Stop(); return DISABLE; } I2C_SendByte( ReadAddress ); /* 设置低起始地址 */ I2C_WaitAck(); I2C_Stop(); if(!I2C_Start()) { return DISABLE; } I2C_SendByte( DeviceAddress + 1 ); /* 器件地址 */ if(!I2C_WaitAck()) { I2C_Stop(); return DISABLE; } while(length) { *pBuffer = I2C_ReceiveByte(); if(length == 1) { I2C_NoAck(); } else { I2C_Ack(); } pBuffer++; length--; } I2C_Stop(); return ENABLE; }
// I2C模拟读出多个字节 u8 i2cread(u8 dev_addr, u8 reg_addr, u8 i2c_len, u8 *i2c_data_buf) { I2C_START(); I2C_SendByte(dev_addr << 1 | I2C_Direction_Transmitter); I2C_SendByte(reg_addr); I2C_START(); I2C_SendByte(dev_addr << 1 | I2C_Direction_Receiver); while (i2c_len) { if (i2c_len == 1) *i2c_data_buf = I2C_ReceiveByte(); else *i2c_data_buf = I2C_ReceiveByte_WithACK(); i2c_data_buf++; i2c_len--; } I2C_STOP(); return 0x00; }
bool i2cWrite(I2CDevice device, uint8_t addr, uint8_t reg, uint8_t data) { UNUSED(device); if (!I2C_Start()) { return false; } I2C_SendByte(addr << 1 | I2C_Direction_Transmitter); if (!I2C_WaitAck()) { I2C_Stop(); i2cErrorCount++; return false; } I2C_SendByte(reg); I2C_WaitAck(); I2C_SendByte(data); I2C_WaitAck(); I2C_Stop(); return true; }
int32_t i2cWriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data) { int i; if (!I2C_Start()) return false; I2C_SendByte(addr << 1 | I2C_Direction_Transmitter); if (!I2C_WaitAck()) { I2C_Stop(); return false; } I2C_SendByte(reg); I2C_WaitAck(); for (i = 0; i < len; i++) { I2C_SendByte(data[i]); if (!I2C_WaitAck()) { I2C_Stop(); return false; } } I2C_Stop(); return true; }
/** * @brief proble i2c bus * @param[in] instance instance of i2c moudle * \param[in] chipAddr i2c slave addr * @note see if it's available i2c slave on the bus * \retval 0 success * \retval 1 failure */ int I2C_Probe(uint32_t instance, uint8_t chipAddr) { uint8_t err; err = 0; chipAddr <<= 1; I2C_Start(); I2C_SendByte(chipAddr); err = I2C_WaitAck(); I2C_Stop(); return err; }
/*---------------------------------------------------------------- 向有子地址器件发送多字节数据函数 函数原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no); 功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件 地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。 如果返回1表示操作成功,否则操作有误。 注意: 使用前必须已结束总线。 ----------------------------------------------------------------*/ char I2C_SendStr(unsigned char ucAddr, unsigned char *pucStr, unsigned char ucCnt) { unsigned char i; I2C_Start(); //启动总线 I2C_SendByte(ucAddr); //发送器件地址 if(ack == 0) return (0); //I2C_SendByte(suba); //发送器件子地址 //if(ack == 0) // return (0); for(i = 0; i < ucCnt; i++) { I2C_SendByte(pucStr[i]); //发送数据 if(ack == 0) return (0); } I2C_Stop(); //结束总线 return (1); }
/*********************************************************** * Function: // 函数名称 * Description: // 函数功能、性能等的描述 * Input: // 1.输入参数1,说明,包括每个参数的作用、取值说明及参数间关系 * Input: // 2.输入参数2,说明,包括每个参数的作用、取值说明及参数间关系 * Output: // 1.输出参数1,说明 * Return: // 函数返回值的说明 * Others: // 其它说明 ***********************************************************/ static uint8_t IIC_RegWrite( uint8_t address, uint8_t reg, uint8_t val ) { uint8_t err = ERR_NONE; err = I2C_Start( ); if( err ) { goto lbl_ERR_REG_WR; } I2C_SendByte( MMA845X_ADDR << 1 ); err = I2C_WaitAck( ); if( err ) { goto lbl_ERR_REG_WR_STOP; } I2C_SendByte( reg ); err = I2C_WaitAck( ); if( err ) { goto lbl_ERR_REG_WR_STOP; } I2C_SendByte( val ); err = I2C_WaitAck( ); if( err ) { goto lbl_ERR_REG_WR_STOP; } I2C_Stop( ); //todo:这里需要延时5ms吗? return ERR_NONE; lbl_ERR_REG_WR_STOP: I2C_Stop( ); lbl_ERR_REG_WR: //rt_kprintf( "reg_wr error=%02x reg=%02x value=%02x\r\n", err, reg, val ); return err; }
/** * @brief I2C read mutiple data * \param[in] instance instance of i2c moudle * \param[in] chipAddr i2c slave addr * \param[in] addr i2c slave register offset * \param[in] addrLen len of slave register addr(in byte) * \param[out] buf data buf * \param[in] len data length * \retval 0 success * \retval 1 failure */ int I2C_BurstRead(uint32_t instance ,uint8_t chipAddr, uint32_t addr, uint32_t addrLen, uint8_t *buf, uint32_t len) { uint8_t *p; uint8_t err; p = (uint8_t*)&addr; err = 0; chipAddr <<= 1; I2C_Start(); I2C_SendByte(chipAddr); err += I2C_WaitAck(); while(addrLen--) { I2C_SendByte(*p++); err += I2C_WaitAck(); } I2C_Start(); I2C_SendByte(chipAddr+1); err += I2C_WaitAck(); while(len--) { *buf++ = I2C_GetByte(); if(len) { I2C_Ack(); } } I2C_NAck(); I2C_Stop(); return err; }
/******************************************************************************* * Function Name : I2C_WriteByte * Description : 写一字节数据 * Input : - WriteAddress: 待写入地址 * - SendByte: 待写入数据 * - DeviceAddress: 器件类型 * Output : None * Return : 返回为:=1成功写入,=0失败 * Attention : None *******************************************************************************/ int I2C_WriteByte( uint16_t WriteAddress , uint8_t SendByte , uint8_t DeviceAddress) { if(!I2C_Start()) { return DISABLE; } I2C_delay(); I2C_SendByte( DeviceAddress ); /* 器件地址 */ if( !I2C_WaitAck() ) { I2C_Stop(); return DISABLE; } I2C_delay(); I2C_SendByte((uint8_t)(WriteAddress & 0x00FF)); /* 设置低起始地址 */ I2C_WaitAck(); I2C_delay(); I2C_SendByte(SendByte); I2C_WaitAck(); I2C_delay(); I2C_Stop(); I2C_delay(); return ENABLE; }
/** * @brief SCCB(protocol,the same as i2c) read single register value * \param[in] instance instance of i2c moudle * \param[in] chipAddr i2c slave addr * \param[in] addr i2c slave register offset * \param[out] data data pointer * @note usually used on i2c sensor devices * \retval 0 success * \retval 1 failure */ int SCCB_ReadSingleRegister(uint32_t instance, uint8_t chipAddr, uint8_t addr, uint8_t* data) { uint8_t err; uint8_t retry; retry = 10; chipAddr <<= 1; while(retry--) { err = 0; I2C_Start(); I2C_SendByte(chipAddr); err += I2C_WaitAck(); I2C_SendByte(addr); err += I2C_WaitAck(); I2C_Stop(); I2C_Start(); I2C_SendByte(chipAddr+1); err += I2C_WaitAck(); *data = I2C_GetByte(); // err += I2C_WaitAck(); I2C_NAck(); I2C_Stop(); if(!err) { break; } } return err; }
inline uint8_t I2C_Send7BitAddress(uint8_t address, uint8_t rw) { return I2C_SendByte((address << 1) | (rw & 0x01)); }
Status ReadTMP102(u16 *TO_EEPROM,u16 *Data_ptr)//读取tmp101的2个字节温度 { u16 TMP102_Data=0x0000; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //send start------------------1 if(I2C_Start()!=BUS_READY){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_START); return ERROR_FAILED; } //send SlaveADDR with write I2C_SendByte(TMP102_WRITE_ADDR);//------------------2 if(I2C_WaitAck()!=BUS_ACK){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_DEVADDR);//------------------3 return ERROR_FAILED; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //send CONF_ADDR------------------4 I2C_SendByte(TMP102_TEMP_REG); if(I2C_WaitAck()!=BUS_ACK){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_TEMPADDR);//------------------5 return ERROR_FAILED; } I2C_Stop();//------------------NiMa没看到!!!!!!!!!!!!!! /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //send start------------------6 if(I2C_Start()!=BUS_READY){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RESTART); return ERROR_FAILED; } //send SlaveADDR with write I2C_SendByte(TMP102_READ_ADDR);//------------------7 if(I2C_WaitAck()!=BUS_ACK){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RDEVADDR);//------------------8 return ERROR_FAILED; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //read TEMP TMP102_Data=0x0000; TMP102_Data = I2C_ReceiveByte();//--Byte1-------9 I2C_Ack();//------------------10 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ TMP102_Data<<=8; TMP102_Data |= I2C_ReceiveByte();//---Byte2-----11 I2C_Ack();//------------------12 //send stop I2C_Stop();//------------------13 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Done ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ TMP102_Data>>=4; *Data_ptr = TMP102_Data; //============================================================== //-25~80 if(TMP102_Data&(0x800)){ //负数要转换 TMP102_Data-=(0x0E70-0x0500-1); } if(TMP102_Data<=0x690){ *TO_EEPROM = TMP102_Data*4; } else{ printf("Out of range from TMP102,TMP102=%X\t\r\n",*Data_ptr); *TO_EEPROM = TO_EEPROM_ERROR; } //printf("TMP102=%X\tEEPROM=%X\r\n",*Data_ptr,*TO_EEPROM); return OK_PASS; }
u16 ReadTMP102_REG(unsigned char reg) { u16 TMP102_Data=0x0000; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //send start------------------1 if(I2C_Start()!=BUS_READY){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_START); } //send SlaveADDR with write I2C_SendByte(TMP102_WRITE_ADDR);//------------------2 if(I2C_WaitAck()!=BUS_ACK){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_DEVADDR);//------------------3 } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //send CONF_ADDR------------------4 I2C_SendByte(reg); if(I2C_WaitAck()!=BUS_ACK){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_TEMPADDR);//------------------5 } I2C_Stop();//------------------NiMa没看到!!!!!!!!!!!!!! /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //send start------------------6 if(I2C_Start()!=BUS_READY){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RESTART); return ERROR_FAILED; } //send SlaveADDR with write I2C_SendByte(TMP102_READ_ADDR);//------------------7 if(I2C_WaitAck()!=BUS_ACK){ ERROR_MACRO(TMP102_DEV,RTMP_ERROR_SEND_RDEVADDR);//------------------8 return ERROR_FAILED; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //read TEMP TMP102_Data=0x0000; TMP102_Data = I2C_ReceiveByte();//--Byte1-------9 I2C_Ack();//------------------10 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Frame 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ TMP102_Data=(TMP102_Data<<8); TMP102_Data |=(u8)I2C_ReceiveByte();//---Byte2-----11 I2C_Ack();//------------------12 //send stop I2C_Stop();//------------------13 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~ Done ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ return TMP102_Data; }
/*--------------------------------------------------------------------------- TITLE : u8g_com_sw_i2c_fn WORK : ARG : void RET : void ---------------------------------------------------------------------------*/ uint8_t u8g_com_sw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { switch(msg) { case U8G_COM_MSG_STOP: break; case U8G_COM_MSG_INIT: //-- I2C 초기화 // I2C_SW_Init(NULL); I2C_Stop(); break; case U8G_COM_MSG_CHIP_SELECT: U8G_SSD_A0_STATE = 0; U8G_SSD_A0_SET = 1; if( arg_val == 0 ) { I2C_Stop(); } break; case U8G_COM_MSG_RESET: break; case U8G_COM_MSG_WRITE_BYTE: if ( u8g_com_ssd_start_sequence(u8g) == 0 ) { I2C_Stop(); return 0; } I2C_SendByte(arg_val); I2C_NoAck(); break; case U8G_COM_MSG_WRITE_SEQ: if ( u8g_com_ssd_start_sequence(u8g) == 0 ) { I2C_Stop(); return 0; } { register uint8_t *ptr = arg_ptr; while( arg_val > 0 ) { I2C_SendByte(*ptr++); I2C_NoAck(); arg_val--; } } break; case U8G_COM_MSG_WRITE_SEQ_P: if ( u8g_com_ssd_start_sequence(u8g) == 0 ) { I2C_Stop(); return 0; } { register uint8_t *ptr = arg_ptr; while( arg_val > 0 ) { I2C_SendByte(*ptr); I2C_NoAck(); ptr++; arg_val--; } } break; case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ U8G_SSD_A0_STATE = arg_val; U8G_SSD_A0_SET = 1; break; } return 1; }
/*********************************************************************//** * @brief Transmit and Receive data in master mode * @param[in] I2Cx I2C peripheral selected, should be: * - LPC_I2C0 * - LPC_I2C1 * - LPC_I2C2 * @param[in] TransferCfg Pointer to a I2C_M_SETUP_Type structure that * contains specified information about the * configuration for master transfer. * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for * interrupt or polling mode. * @return SUCCESS or ERROR * * Note: * - In case of using I2C to transmit data only, either transmit length set to 0 * or transmit data pointer set to NULL. * - In case of using I2C to receive data only, either receive length set to 0 * or receive data pointer set to NULL. * - In case of using I2C to transmit followed by receive data, transmit length, * transmit data pointer, receive length and receive data pointer should be set * corresponding. **********************************************************************/ Status I2C_MasterTransferData(LPC_I2C_TypeDef *I2Cx, I2C_M_SETUP_Type *TransferCfg, \ I2C_TRANSFER_OPT_Type Opt) { uint8_t *txdat; uint8_t *rxdat; uint32_t CodeStatus; uint8_t tmp; // reset all default state txdat = (uint8_t *) TransferCfg->tx_data; rxdat = (uint8_t *) TransferCfg->rx_data; // Reset I2C setup value to default state TransferCfg->tx_count = 0; TransferCfg->rx_count = 0; TransferCfg->status = 0; if (Opt == I2C_TRANSFER_POLLING){ /* First Start condition -------------------------------------------------------------- */ TransferCfg->retransmissions_count = 0; retry: // reset all default state txdat = (uint8_t *) TransferCfg->tx_data; rxdat = (uint8_t *) TransferCfg->rx_data; // Reset I2C setup value to default state TransferCfg->tx_count = 0; TransferCfg->rx_count = 0; CodeStatus = 0; // Start command CodeStatus = I2C_Start(I2Cx); if ((CodeStatus != I2C_I2STAT_M_TX_START) \ && (CodeStatus != I2C_I2STAT_M_TX_RESTART)){ TransferCfg->retransmissions_count++; if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ // save status TransferCfg->status = CodeStatus; goto error; } else { goto retry; } } /* In case of sending data first --------------------------------------------------- */ if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL)){ /* Send slave address + WR direction bit = 0 ----------------------------------- */ CodeStatus = I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1)); if (CodeStatus != I2C_I2STAT_M_TX_SLAW_ACK){ TransferCfg->retransmissions_count++; if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ // save status TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; goto error; } else { goto retry; } } /* Send a number of data bytes ---------------------------------------- */ while (TransferCfg->tx_count < TransferCfg->tx_length) { CodeStatus = I2C_SendByte(I2Cx, *txdat); if (CodeStatus != I2C_I2STAT_M_TX_DAT_ACK){ TransferCfg->retransmissions_count++; if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ // save status TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; goto error; } else { goto retry; } } txdat++; TransferCfg->tx_count++; } } /* Second Start condition (Repeat Start) ------------------------------------------- */ if ((TransferCfg->tx_length != 0) && (TransferCfg->tx_data != NULL) \ && (TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ CodeStatus = I2C_Start(I2Cx); if ((CodeStatus != I2C_I2STAT_M_RX_START) \ && (CodeStatus != I2C_I2STAT_M_RX_RESTART)){ TransferCfg->retransmissions_count++; if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ // Update status TransferCfg->status = CodeStatus; goto error; } else { goto retry; } } } /* Then, start reading after sending data -------------------------------------- */ if ((TransferCfg->rx_length != 0) && (TransferCfg->rx_data != NULL)){ /* Send slave address + RD direction bit = 1 ----------------------------------- */ CodeStatus = I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01)); if (CodeStatus != I2C_I2STAT_M_RX_SLAR_ACK){ TransferCfg->retransmissions_count++; if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ // update status TransferCfg->status = CodeStatus | I2C_SETUP_STATUS_NOACKF; goto error; } else { goto retry; } } /* Receive a number of data bytes ------------------------------------------------- */ while (TransferCfg->rx_count < TransferCfg->rx_length){ /* * Note that: if data length is only one, the master should not * issue an ACK signal on bus after reading to avoid of next data frame * on slave side */ if (TransferCfg->rx_count < (TransferCfg->rx_length - 1)){ // Issue an ACK signal for next data frame CodeStatus = I2C_GetByte(I2Cx, &tmp, TRUE); if (CodeStatus != I2C_I2STAT_M_RX_DAT_ACK){ TransferCfg->retransmissions_count++; if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ // update status TransferCfg->status = CodeStatus; goto error; } else { goto retry; } } } else { // Do not issue an ACK signal CodeStatus = I2C_GetByte(I2Cx, &tmp, FALSE); if (CodeStatus != I2C_I2STAT_M_RX_DAT_NACK){ TransferCfg->retransmissions_count++; if (TransferCfg->retransmissions_count > TransferCfg->retransmissions_max){ // update status TransferCfg->status = CodeStatus; goto error; } else { goto retry; } } } *rxdat++ = tmp; TransferCfg->rx_count++; } } /* Send STOP condition ------------------------------------------------- */ I2C_Stop(I2Cx); return SUCCESS; error: // Send stop condition I2C_Stop(I2Cx); return ERROR; } else if (Opt == I2C_TRANSFER_INTERRUPT){ // Setup tx_rx data, callback and interrupt handler tmp = I2C_getNum(I2Cx); i2cdat[tmp].txrx_setup = (uint32_t) TransferCfg; // Set direction phase, write first i2cdat[tmp].dir = 0; /* First Start condition -------------------------------------------------------------- */ I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; I2Cx->I2CONSET = I2C_I2CONSET_STA; I2C_IntCmd(I2Cx, TRUE); return (SUCCESS); } return ERROR; }
/*********************************************************************//** * @brief Handle I2C Master states. * @param[in] I2Cx I2C peripheral selected, should be: * - I2C_0 * - I2C_1 * - I2C_2 * @param[in] CodeStatus I2C state * @param[in] TransferCfg Pointer to a I2C_S_SETUP_Type structure that * contains specified information about the * configuration for master transfer. * @param[in] Opt a I2C_TRANSFER_OPT_Type type that selected for * interrupt or polling mode. * @return It can be * - I2C_OK * -I2C_BYTE_RECV * -I2C_BYTE_SENT * -I2C_SEND_END * -I2C_RECV_END * - I2C_ERR * - I2C_NAK_RECV **********************************************************************/ int32_t I2C_MasterHanleStates(en_I2C_unitId i2cId, uint32_t CodeStatus, I2C_M_SETUP_Type *TransferCfg, I2C_TRANSFER_OPT_Type Opt ) { LPC_I2C_TypeDef* I2Cx = I2C_GetPointer(i2cId); uint8_t *txdat; uint8_t *rxdat; uint8_t tmp; int32_t Ret = I2C_OK; //get buffer to send/receive txdat = (uint8_t *) &TransferCfg->tx_data[TransferCfg->tx_count]; rxdat = (uint8_t *) &TransferCfg->rx_data[TransferCfg->rx_count]; switch(CodeStatus) { case I2C_I2STAT_M_TX_START: case I2C_I2STAT_M_TX_RESTART: //case I2C_I2STAT_M_RX_START: //case I2C_I2STAT_M_RX_RESTART // Send data first if(TransferCfg->tx_count < TransferCfg->tx_length) { /* Send slave address + WR direction bit = 0 ----------------------------------- */ //I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit << 1));/////////////////////////////// I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit )); Ret = I2C_BYTE_SENT; } else if (TransferCfg->rx_count < TransferCfg->rx_length) { /* Send slave address + RD direction bit = 1 ----------------------------------- */ //I2C_SendByte(I2Cx, ((TransferCfg->sl_addr7bit << 1) | 0x01));//////////////// I2C_SendByte(I2Cx, (TransferCfg->sl_addr7bit)); Ret = I2C_BYTE_SENT; } // Clear STA bit after the slave address is sent I2Cx->CONCLR = I2C_I2CONCLR_STAC; break; case I2C_I2STAT_M_TX_SLAW_ACK: case I2C_I2STAT_M_TX_DAT_ACK: if(TransferCfg->tx_count < TransferCfg->tx_length) { I2C_SendByte(I2Cx, *txdat); txdat++; TransferCfg->tx_count++; Ret = I2C_BYTE_SENT; } else { if(TransferCfg->rx_count >= TransferCfg->rx_length) { I2C_Stop(I2Cx, Opt); } Ret = I2C_SEND_END; } break; case I2C_I2STAT_M_TX_DAT_NACK: if(TransferCfg->rx_count >= TransferCfg->rx_length) { I2C_Stop(I2Cx, Opt); } Ret = I2C_SEND_END; break; case I2C_I2STAT_M_RX_ARB_LOST: case I2C_I2STAT_S_RX_ARB_LOST_M_GENCALL: case I2C_I2STAT_S_TX_ARB_LOST_M_SLA: //case I2C_I2STAT_M_TX_ARB_LOST: I2C_Stop(I2Cx, Opt); Ret = I2C_ERR; break; case I2C_I2STAT_M_RX_SLAR_ACK: if(TransferCfg->rx_length > 1) I2Cx->CONSET = I2C_I2CONSET_AA; else I2Cx->CONCLR = I2C_I2CONCLR_AAC; I2Cx->CONCLR = I2C_I2CONCLR_SIC; Ret = I2C_BYTE_RECV; break; case I2C_I2STAT_M_RX_DAT_ACK: if (TransferCfg->rx_count <TransferCfg->rx_length) { if ((TransferCfg->rx_length > 1) && (TransferCfg->rx_count < (TransferCfg->rx_length - 2))) { I2C_GetByte(I2Cx, &tmp, TRUE); Ret = I2C_BYTE_RECV; } else // the next byte is the last byte, send NACK instead. { I2C_GetByte(I2Cx, &tmp, FALSE); Ret = I2C_BYTE_RECV; } *rxdat++ = tmp; TransferCfg->rx_count++; } else { I2C_Stop(I2Cx, Opt); Ret = I2C_RECV_END; } break; case I2C_I2STAT_M_RX_DAT_NACK: I2C_GetByte(I2Cx, &tmp, FALSE); if (TransferCfg->rx_count < TransferCfg->rx_length) { *rxdat++ = tmp; TransferCfg->rx_count++; } I2C_Stop(I2Cx, Opt); Ret = I2C_RECV_END; break; case I2C_I2STAT_M_RX_SLAR_NACK: case I2C_I2STAT_M_TX_SLAW_NACK: case I2C_I2STAT_BUS_ERROR: // Send STOP condition I2C_Stop(I2Cx, Opt); Ret = I2C_ERR; break; /* No status information */ case I2C_I2STAT_NO_INF: if ((TransferCfg->tx_count <TransferCfg->tx_length)|| (TransferCfg->rx_count <TransferCfg->rx_length)) { I2C_Stop(I2Cx, Opt); Ret = I2C_ERR; } else { Ret = I2C_RECV_END; } break; default: I2Cx->CONCLR = I2C_I2CONCLR_SIC; break; } return Ret; }