#include "yuyy_hard_iic.h"
#include "cw32f030_gpio.h"
#include "cw32f030_rcc.h"
#include "cw32f030_i2c.h"
#define YUYY_HARD_IIC(x) x==2?CW_I2C2:CW_I2C1
void yuyy_hard_iic_init(void)
{
__RCC_GPIOB_CLK_ENABLE();
__RCC_I2C1_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStructure;
PB10_AFx_I2C1SCL();
PB11_AFx_I2C1SDA();
GPIO_InitStructure.Pins = GPIO_PIN_10 | GPIO_PIN_11;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; //
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
I2C_InitTypeDef I2C_InitStruct;
I2C_InitStruct.I2C_BaudEn = ENABLE;
I2C_InitStruct.I2C_Baud = 9; //100K=(8000000/(8*(1+9))
I2C_InitStruct.I2C_FLT = ENABLE;
I2C_InitStruct.I2C_AA = DISABLE;
I2C1_DeInit();
I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模块
I2C_Cmd(CW_I2C1,ENABLE); //模块使能
}
uint8_t yuyy_hard_iic_sendregaddr(uint8_t iicx,uint8_t devaddr,uint16_t regaddr,uint8_t regaddrlen)
{
uint8_t err = 0,u8State,retry = 0,sendlen = 0;
I2C_GenerateSTART(YUYY_HARD_IIC(iicx), ENABLE);
while(1)
{
while(0 == I2C_GetIrq(YUYY_HARD_IIC(iicx)));
u8State = I2C_GetState(YUYY_HARD_IIC(iicx));
switch(u8State)
{
case 0x08: //发送完START信号
case 0x10: //发送完重复起始信号
I2C_GenerateSTART(YUYY_HARD_IIC(iicx), DISABLE);
I2C_Send7bitAddress(YUYY_HARD_IIC(iicx), (devaddr<<1),I2C_Direction_Transmitter); //发送从机地址
break;
case 0x18: //发送完SLA+W信号
case 0x28: //发送完1字节数据:发送EEPROM中memory地址也会产生,发送后面的数据也会产生
if(sendlen < regaddrlen)
{
if(sendlen == 0 && regaddrlen == 2)
I2C_SendData(YUYY_HARD_IIC(iicx),(regaddr>>8)&0xFF);
else
I2C_SendData(YUYY_HARD_IIC(iicx),regaddr&0xFF);
}
sendlen++;
break;
case 0x20: //发送完SLA+W后从机返回NACK
case 0x38: //主机在发送 SLA+W 阶段或者发送数据阶段丢失仲裁 或者 主机在发送 SLA+R 阶段或者回应 NACK 阶段丢失仲裁
if(retry < 3)
{
sendlen = 0;
I2C_GenerateSTART(YUYY_HARD_IIC(iicx), ENABLE);
}
else
err = 1;
retry++;
break;
case 0x30: //发送完一个数据字节后从机返回NACK
err = 1;
break;
default:
err = 1;
break;
}
if(err > 0 || sendlen == regaddrlen)
{
if(err > 0)
{
I2C_GenerateSTOP(YUYY_HARD_IIC(iicx), ENABLE);
}
I2C_ClearIrq(YUYY_HARD_IIC(iicx));
break;
}
I2C_ClearIrq(YUYY_HARD_IIC(iicx));
}
return err;
}
uint8_t yuyy_hard_iic_senddatas(uint8_t iicx,uint8_t devaddr,uint16_t regaddr,uint8_t regaddrlen,uint8_t *datas,uint8_t datalen)
{
uint8_t err = 0,u8State = 0,sendlen = 0;
err = yuyy_hard_iic_sendregaddr(iicx,devaddr,regaddr,regaddrlen);
if(err == 0)
{
while(1)
{
while(0 == I2C_GetIrq(YUYY_HARD_IIC(iicx)));
u8State = I2C_GetState(YUYY_HARD_IIC(iicx));
switch(u8State)
{
case 0x18: //发送完SLA+W信号
case 0x28: //发送完1字节数据:发送EEPROM中memory地址也会产生,发送后面的数据也会产生
if(sendlen < datalen)
{
I2C_SendData(YUYY_HARD_IIC(iicx),datas[sendlen]);
}
sendlen++;
break;
case 0x20: //发送完SLA+W后从机返回NACK
case 0x38: //主机在发送 SLA+W 阶段或者发送数据阶段丢失仲裁 或者 主机在发送 SLA+R 阶段或者回应 NACK 阶段丢失仲裁
err = 1;
break;
case 0x30: //发送完一个数据字节后从机返回NACK
err = 1;
break;
default:
err = 1;
break;
}
if(err > 0 || sendlen > datalen)
{
I2C_GenerateSTOP(YUYY_HARD_IIC(iicx), ENABLE);
I2C_ClearIrq(YUYY_HARD_IIC(iicx));
break;
}
I2C_ClearIrq(YUYY_HARD_IIC(iicx));
}
}
return err;
}
uint8_t yuyy_hard_iic_readdatas(uint8_t iicx,uint8_t devaddr,uint16_t regaddr,uint8_t regaddrlen,uint8_t *datas,uint8_t datalen)
{
uint8_t err = 0,u8State = 0,retry = 0,i = 0;
if(regaddrlen > 0)
{
err = yuyy_hard_iic_sendregaddr(iicx,devaddr,regaddr,regaddrlen);
while(0 == I2C_GetIrq(YUYY_HARD_IIC(iicx)));
I2C_GenerateSTOP(YUYY_HARD_IIC(iicx), ENABLE);
I2C_ClearIrq(YUYY_HARD_IIC(iicx));
}
if(err == 0)
{
I2C_GenerateSTART(YUYY_HARD_IIC(iicx), ENABLE);
while(1)
{
while(0 == I2C_GetIrq(YUYY_HARD_IIC(iicx)));
u8State = I2C_GetState(YUYY_HARD_IIC(iicx));
switch(u8State)
{
case 0x28:
I2C_GenerateSTART(YUYY_HARD_IIC(iicx), ENABLE);
break;
case 0x08: //发送完START信号
case 0x10: //发送完重复起始信号
I2C_GenerateSTART(YUYY_HARD_IIC(iicx), DISABLE);
I2C_Send7bitAddress(YUYY_HARD_IIC(iicx), (devaddr<<1),I2C_Direction_Receiver); //发送从机地址+R字节
case 0x40: //发送完SLA+R信号,开始接收数据
if(datalen>1)
I2C_AcknowledgeConfig(YUYY_HARD_IIC(iicx),ENABLE);
break;
case 0x50: //接收完一字节数据,在接收最后1字节数据之前设置AA=0;
datas[i++] = I2C_ReceiveData(YUYY_HARD_IIC(iicx));
if(i==datalen-1)
I2C_AcknowledgeConfig(YUYY_HARD_IIC(iicx),DISABLE);
break;
case 0x58: //接收到一个数据字节,且NACK已回复
datas[i++] = I2C_ReceiveData(YUYY_HARD_IIC(iicx));
break;
case 0x38: //主机在发送 SLA+W 阶段或者发送数据阶段丢失仲裁 或者 主机在发送 SLA+R 阶段或者回应 NACK 阶段丢失仲裁
//I2C_GenerateSTART(YUYY_HARD_IIC(iicx), ENABLE);
err = 1;
break;
case 0x48: //发送完SLA+R后从机返回NACK
if(retry < 3)
{
I2C_GenerateSTART(YUYY_HARD_IIC(iicx), ENABLE);
}
else
err = 2;
retry++;
break;
default:
err = u8State;
break;
}
if(i==datalen || err > 0)
{
I2C_GenerateSTOP(YUYY_HARD_IIC(iicx), ENABLE);
I2C_ClearIrq(YUYY_HARD_IIC(iicx));
break;
}
I2C_ClearIrq(YUYY_HARD_IIC(iicx));
}
}
return err;
}