bsp_i2c_soft update

develop
esea_info 2 years ago
parent a7079b7124
commit 7ce92a9ae6
  1. 76
      device/Inc/bsp_i2c_soft.h
  2. 124
      device/Src/bsp_i2c_soft.c

@ -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);
*/

@ -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<len-1; i++)
{
*buf=IIC_Read_Byte(pSoftIIC);
@ -216,3 +280,15 @@ uint8_t IIC_Read_Test(const IIC_SOFT_TypeDef *pSoftIIC, uint8_t reg_addr, uint8_
return 0;
}
int IIC_Device_Check(const IIC_SOFT_TypeDef *pSoftIIC)
{
uint8_t ret = 0;
IIC_Start(pSoftIIC);
ret = IIC_Send_Slave_Addr( pSoftIIC,I2C_WRITE );
IIC_Stop(pSoftIIC);
return ret;
}
Loading…
Cancel
Save