From 7ce92a9ae64ebbc099fc4c1cb7ac49b096c2da92 Mon Sep 17 00:00:00 2001 From: esea_info Date: Thu, 26 Oct 2023 17:32:57 +0800 Subject: [PATCH] bsp_i2c_soft update --- {bsp => device}/Inc/bsp_i2c_soft.h | 76 ++++++++++++------ {bsp => device}/Src/bsp_i2c_soft.c | 124 +++++++++++++++++++++++------ 2 files changed, 153 insertions(+), 47 deletions(-) rename {bsp => device}/Inc/bsp_i2c_soft.h (58%) rename {bsp => device}/Src/bsp_i2c_soft.c (64%) diff --git a/bsp/Inc/bsp_i2c_soft.h b/device/Inc/bsp_i2c_soft.h similarity index 58% rename from bsp/Inc/bsp_i2c_soft.h rename to device/Inc/bsp_i2c_soft.h index 0b95059..3a21492 100644 --- a/bsp/Inc/bsp_i2c_soft.h +++ b/device/Inc/bsp_i2c_soft.h @@ -9,6 +9,8 @@ // #define SDA_GPIO_PORT GPIOB // #define SDA_PIN GPIO_PIN_7 +#define I2C_WRITE (0x00) +#define I2C_READ (0x01) typedef enum { IIC_OK = 0x00, //IIC工作正常 @@ -17,15 +19,38 @@ typedef enum { IIC_READ_ERR = 0x04 //从slave设备读取错误 } IIC_STATUS; +typedef enum +{ + I2C_SW_Standard_Mode = 100 * 1000, + I2C_SW_Fast_Mode = 400 * 1000, + I2C_SW_Fast_Mode_Plus = 1000 * 1000, +} I2C_SW_Speed_Mode_TypeDef; //i2c速率 unit Hz + +typedef enum +{ + I2C_SW_One_Byte = 1, + I2C_SW_Two_Byte = 2, + I2C_SW_Four_Byte = 4 +} I2C_SW_Data_Width_TypeDef;//数据长度(寄存器地址或者值的数据长度) + +typedef enum +{ + I2C_SW_Slave_Address_7Bit, + I2C_SW_Slave_Address_10Bit, +} I2C_SW_Slave_Address_Width_TypeDef;//i2c slave address的位宽 + typedef struct { GPIO_TypeDef *scl_port; //定义IIC时钟使用的端口 uint16_t scl_pin; //定义IIC时钟使用的PIN脚 GPIO_TypeDef *sda_port; //定义IIC数据使用的端口 uint16_t sda_pin; //定义IIC数据使用的PIN脚 - uint8_t sda_pin_num; //定义延时,以适应不同器件对速率的不同要求,具体值要在调试中确定 - uint8_t addr; //器件地址 + uint8_t sda_pin_num; //SDA Pin ,操作IO Mode + uint16_t addr; //器件地址, 兼容16bit uint32_t delaytick; //定义延时,以适应不同器件对速率的不同要求,具体值要在调试中确定 + I2C_SW_Slave_Address_Width_TypeDef slave_address_width; + I2C_SW_Data_Width_TypeDef slave_reg_addr_width; + I2C_SW_Data_Width_TypeDef slave_reg_value_width; }IIC_SOFT_TypeDef; //IO方向设置 @@ -48,18 +73,24 @@ int IIC_SDA_Mode_Out(const IIC_SOFT_TypeDef *pSoftIIC); void IIC_Start(const IIC_SOFT_TypeDef *pSoftIIC); //发送IIC开始信号 void IIC_Stop(const IIC_SOFT_TypeDef *pSoftIIC); //发送IIC停止信号 -void IIC_Send_Byte(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t txd); //IIC发送一个字节 -// uint8_t IIC_Read_Byte(unsigned char ack);//IIC读取一个字节 -uint8_t IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC);//IIC读取一个字节 -uint8_t IIC_Wait_Ack(const IIC_SOFT_TypeDef *pSoftIIC); //IIC等待ACK信号 + +int IIC_Send_Byte(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t txd); //IIC发送一个字节 +int IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC);//IIC读取一个字节 + +int IIC_Send_Slave_Addr(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t r_w); +int IIC_Send_Reg_Addr(const IIC_SOFT_TypeDef *pSoftIIC,uint32_t reg_addr ); + + +int IIC_Wait_Ack(const IIC_SOFT_TypeDef *pSoftIIC); //IIC等待ACK信号 void IIC_Ack(const IIC_SOFT_TypeDef *pSoftIIC); //IIC发送ACK信号 void IIC_NAck(const IIC_SOFT_TypeDef *pSoftIIC); //IIC不发送ACK信号 -uint8_t IIC_Read_Test(const IIC_SOFT_TypeDef *pSoftIIC, uint8_t reg_addr, uint8_t *buf, uint8_t len); -uint8_t IIC_Write_Test(const IIC_SOFT_TypeDef *pSoftIIC , uint8_t reg_addr, uint8_t *buf, uint8_t len); +int IIC_Read_Buf(const IIC_SOFT_TypeDef *pSoftIIC, uint32_t reg_addr , uint8_t *buf, uint8_t len); +int IIC_Write_Buf(const IIC_SOFT_TypeDef *pSoftIIC , uint32_t reg_addr, uint8_t *buf, uint8_t len); - + +int IIC_Device_Check(const IIC_SOFT_TypeDef *pSoftIIC); #endif @@ -96,31 +127,30 @@ uint8_t IIC_Write_Test(const IIC_SOFT_TypeDef *pSoftIIC , uint8_t reg_addr, uint // *SDA // +十位slave 先发 高位 +0xF00 | ((slave_addr>> 8 & 0x03)<<2) | r_w - HAL_I2C_MspDeInit( &hi2c1 ); - uint8_t readout[256] = {0}; - uint8_t writein[1] = {0xFB}; +16bit 寄存器 addr ,先发 (addr>>8)&0xFF ,后发 addr&0xFF - // IIC_Init( ); - // IIC_Write_Test( 0xA0, 0, writein, 1 ); - // HAL_Delay( 200 ); - - // IIC_Read_Test( 0xA0, 0, readout, 1 ); - - // log_i("iic test %02X .... ", *readout); IIC_SOFT_TypeDef sIIC = { GPIOB, GPIO_PIN_6, GPIOB, GPIO_PIN_7, - 7,0xA0,1, + 7,0x50,1, + I2C_SW_Slave_Address_7Bit, + I2C_SW_One_Byte, + I2C_SW_One_Byte, }; IIC_Init( &sIIC ); + + if (!IIC_Device_Check(&sIIC)) + log_i( "hello i2c_address= 0x%02X (7bit) is exist\r\n", sIIC.addr); - IIC_Write_Test( &sIIC,0xA0, 0, writein, 1 ); + IIC_Write_Buf( &sIIC, 0, writein, 1 ); HAL_Delay( 200 ); - IIC_Read_Test(&sIIC, 0xA0, 0, readout, 1 ); + IIC_Read_Buf(&sIIC, 0, readout, 1 ); - log_i("iic test %02X .... ", *readout); + log_i("iic test %02X .... \r\n ", *readout); */ \ No newline at end of file diff --git a/bsp/Src/bsp_i2c_soft.c b/device/Src/bsp_i2c_soft.c similarity index 64% rename from bsp/Src/bsp_i2c_soft.c rename to device/Src/bsp_i2c_soft.c index feb9a04..d2c17cd 100644 --- a/bsp/Src/bsp_i2c_soft.c +++ b/device/Src/bsp_i2c_soft.c @@ -72,7 +72,7 @@ void IIC_Stop(const IIC_SOFT_TypeDef *pSoftIIC) //等待应答信号到来 //返回值:1,接收应答失败 // 0,接收应答成功 -uint8_t IIC_Wait_Ack(const IIC_SOFT_TypeDef *pSoftIIC) +int IIC_Wait_Ack(const IIC_SOFT_TypeDef *pSoftIIC) { uint8_t ucErrTime=0; // SDA_IN(); //SDA设置为输入 @@ -125,7 +125,7 @@ void IIC_NAck(const IIC_SOFT_TypeDef *pSoftIIC) //返回从机有无应答 //1,有应答 //0,无应答 -void IIC_Send_Byte(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t txd) +int IIC_Send_Byte(const IIC_SOFT_TypeDef *pSoftIIC, uint8_t txd) { uint8_t t; // SDA_OUT();//sda线输出 @@ -138,15 +138,16 @@ void IIC_Send_Byte(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t txd) // IIC_SDA( (txd&0x80)>>7); GPIO_WRITE_PIN(pSoftIIC->sda_port, pSoftIIC->sda_pin, (txd&0x80)>>7 ); txd<<=1; - delay_us(2); //对TEA5767这三个延时都是必须的 + delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 1); delay_us(2); GPIO_WRITE_PIN(pSoftIIC->scl_port, pSoftIIC->scl_pin, 0); delay_us(2); - } + } + return 0; } -uint8_t IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC) +int IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC) { unsigned char i,receive=0; @@ -168,17 +169,85 @@ uint8_t IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC) return receive; } - uint8_t IIC_Write_Test(const IIC_SOFT_TypeDef *pSoftIIC , uint8_t reg_addr, uint8_t *buf, uint8_t len) +// 发送Slave_Addr 带应答, 兼容7bit 10bit +int IIC_Send_Slave_Addr(const IIC_SOFT_TypeDef *pSoftIIC,uint8_t r_w) +{ + if( pSoftIIC->slave_address_width == I2C_SW_Slave_Address_7Bit ) + { + log_i("salve adrr %02X %02X",pSoftIIC->addr, (pSoftIIC->addr << 1)|r_w); + IIC_Send_Byte(pSoftIIC, (pSoftIIC->addr << 1) | r_w); + if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + } + else if( pSoftIIC->slave_address_width == I2C_SW_Slave_Address_10Bit ) + { + uint8_t h_addr = 0x0F00 | ((pSoftIIC->addr >> 8 & 0x03) << 2) | r_w; + IIC_Send_Byte(pSoftIIC, h_addr); + if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + + uint8_t l_addr = pSoftIIC->addr & 0xff; + IIC_Send_Byte(pSoftIIC, l_addr); + if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + } + return 0; +} + +// 发送reg_addr 带应答, 兼容8bit 16bit 32bit +int IIC_Send_Reg_Addr( const IIC_SOFT_TypeDef *pSoftIIC, uint32_t reg_addr ) +{ + for(int j = 0; j < pSoftIIC->slave_reg_addr_width; j++) + { + uint8_t offset = (pSoftIIC->slave_reg_addr_width - 1 - j) * 8; + uint8_t temp_reg_addr = (reg_addr >> offset) & 0xff; + + IIC_Send_Byte(pSoftIIC, temp_reg_addr); + if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + + } + return 0; +} + +int IIC_Send_One_Reg_Value( const IIC_SOFT_TypeDef *pSoftIIC, uint32_t reg_val ) +{ + for(int k = 0; k < pSoftIIC->slave_reg_value_width; k++) + { + uint8_t offset = (pSoftIIC->slave_reg_value_width - 1 - k) * 8; + + i2c_send_byte(pSoftIIC, (reg_val >> offset) & 0xff); + if(!i2c_wait_ack(pSoftIIC)) + return false; + } + return 0; +} + +int IIC_Send_Receive_One_Reg_Value( const IIC_SOFT_TypeDef *pSoftIIC, uint32_t* reg_val, uint8_t ack ) +{ + for(int k = 0; k < pSoftIIC->slave_reg_value_width; k++) + { + uint8_t offset = (pSoftIIC->slave_reg_value_width - 1 - k) * 8; + *reg_val |= (IIC_Read_Byte(pSoftIIC) << offset); + + if(ack) + i2c_ack(pSoftIIC); + else + i2c_no_ack(pSoftIIC); + } + + return 0; +} + + + int IIC_Write_Buf(const IIC_SOFT_TypeDef *pSoftIIC , uint32_t reg_addr, uint8_t *buf, uint8_t len) { IIC_Start(pSoftIIC); - IIC_Send_Byte(pSoftIIC,pSoftIIC->addr & 0xFE); - if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; - - IIC_Send_Byte(pSoftIIC,reg_addr); - if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + + IIC_Send_Slave_Addr( pSoftIIC,I2C_WRITE ); + IIC_Send_Reg_Addr( pSoftIIC, reg_addr ); - IIC_Send_Byte(pSoftIIC,*buf); - if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + for (size_t i = 0; i < len; i++) + { + IIC_Send_Byte(pSoftIIC,*buf); + if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + } IIC_Stop(pSoftIIC);//产生一个停止条件 // HAL_Delay( 200 ); @@ -187,21 +256,16 @@ uint8_t IIC_Read_Byte( const IIC_SOFT_TypeDef *pSoftIIC) } // 寄存器地址 8位置 -uint8_t IIC_Read_Test(const IIC_SOFT_TypeDef *pSoftIIC, uint8_t reg_addr, uint8_t *buf, uint8_t len) +int IIC_Read_Buf(const IIC_SOFT_TypeDef *pSoftIIC, uint32_t reg_addr, uint8_t *buf, uint8_t len) { - uint8_t temp=0; - IIC_Start(pSoftIIC); - - IIC_Send_Byte(pSoftIIC,pSoftIIC->addr & 0xFE); - if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + uint8_t temp=0; - IIC_Send_Byte(pSoftIIC,reg_addr); - if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; + IIC_Start(pSoftIIC); + IIC_Send_Slave_Addr( pSoftIIC,I2C_WRITE ); + IIC_Send_Reg_Addr( pSoftIIC, reg_addr ); IIC_Start(pSoftIIC); - IIC_Send_Byte(pSoftIIC,pSoftIIC->addr |0x01); //进入接收模式 - if(IIC_Wait_Ack(pSoftIIC)) { IIC_Stop(pSoftIIC); return -1;}; - + IIC_Send_Slave_Addr( pSoftIIC,I2C_READ ); for(int i=0; i