📄 i2c.c
字号:
}
}
}
/*********************************************************************************************************
** Function name: hostRecvModeEntry
** Descriptions: 进入主接收模式,改函数被__i2cISR调用
** Input parameters: Parm--I2C设备描述符结构体指针
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
static void __hostRecvModeEntry (__PI2C_INFO Parm)
{
uint32 uiOffBase;
volatile uint8 *pucAddrBase;
pucAddrBase = Parm->pucAddrBase;
uiOffBase = Parm->uiOffBase;
if(Parm->usDataNum <= 1) {
pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x2c; /* 接收字节少于等于1个 */
/* 在收到下个字节时返回非ACK */
} else {
pucAddrBase[__B_IIC_SET << uiOffBase] = 0x04; /* 当接收字节多于1个时,置位AA */
pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28; /* 在收到下个字节时返回ACK */
}
}
/*********************************************************************************************************
** Function name: ISR_I2C
** Descriptions: 中断服务函数底层调用,该中断服务函数没有完成从机模式
** Input parameters: Parm--I2C设备描述符结构体指针
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
static void __i2cISR (__PI2C_INFO Parm)
{
uint8 ucSta;
uint32 uiOffBase;
volatile uint8 *pucAddrBase;
pucAddrBase = Parm->pucAddrBase;
uiOffBase = Parm->uiOffBase;
ucSta = pucAddrBase[__B_IIC_STAT << uiOffBase]; /* 获取I2C状态码 */
switch(ucSta & 0xF8) {
case __SEND_START: /* 已发送起始条件,共用写函数 */
case __SEND_RESTART: /* 重新启动总线后,发送从机地址*/
__AddrWrite( Parm ); /* 写入器件地址 */
break;
case __SEND_SLA_W_ACK: /* 已发送SLA+W并已经接收应答 */
case __SEND_DATA_ACK: /* 发送数据,已接收应答 */
/* 这两种情况都使用下面函数 */
__subAddrWrite( Parm ); /* I2C写数据和地址在一起 */
break;
case __SEND_SLA_W_NOACK: /* 发送SLA_W,收到非应答 */
case __SEND_DATA_NOACK: /* 发送数据,收到非应答 */
case __LOSS_BUS: /* 丢失仲裁 */
case __SEND_SLA_R_NOACK: /* 发送SLA+R 接收非应答 */
/* 以上四中情况都要结束总线 */
__endBus( Parm ); /* 结束总线 */
break;
case __SEND_SLA_R_ACK: /* 发送SLA+R,收到ACK */
__hostRecvModeEntry( Parm ); /* 进入主接收模式 */
break;
case __RECV_DATA_ACK: /* 接收了数据,返回应答位 */
case __RECV_DATA_NOACK: /* 接收完数据字节,返回非应答位 */
/* 以上两种情况,都采用读函数 */
__dateRead( Parm );
break;
default: /* 其他状态 */
__endBus( Parm ); /* 结束总线 */
break;
}
}
/*********************************************************************************************************
** Function name: I2C0IRQ
** Descriptions: 库函数默认的中断服务函数,进行I2C中断处理,该函数挂接了钩子函数可处理用户任务
** Input parameters: NONE
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
void i2c0IRQ ( void )
{
__OS_ENTER_CIRCT();
__i2cISR(__GpiinfoDateTab[0]);
i2c0Hook();
VICVectAddr = 0x00; /* 清除VIC中断 */
__OS_EXIT_CIRCT();
}
/*********************************************************************************************************
** Function name: I2C1IRQ
** Descriptions: 库函数默认的中断服务函数,进行I2C中断处理,该函数挂接了钩子函数可处理用户任务
** Input parameters: NONE
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
void i2c1IRQ ( void )
{
__OS_ENTER_CIRCT();
__i2cISR(__GpiinfoDateTab[1]);
i2c1Hook();
VICVectAddr = 0x00; /* 清除VIC中断 */
__OS_EXIT_CIRCT();
}
/*********************************************************************************************************
** Function name: I2C2IRQ
** Descriptions: 库函数默认的中断服务函数,进行I2C中断处理,该函数挂接了钩子函数可处理用户任务
** Input parameters: NONE
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
void i2c2IRQ ( void )
{
__OS_ENTER_CIRCT();
__i2cISR(__GpiinfoDateTab[2]);
i2c2Hook();
VICVectAddr = 0x00; /* 清除VIC中断 */
__OS_EXIT_CIRCT();
}
/*********************************************************************************************************
** Function name: __I2CInit
** Descriptions: I2c初始化程序(非字符串型),该函数需要被封装一层的,如果设置参数的速度超过400K
** 则设置标准速度100K
** Input parameters: ID 器件子设备号
** Speed I2C通讯速度
** Rsv 保留参数
** Output parameters: NONE
** Returned value: PIN_ERR 管脚配置错误
** OPERATE_FAIL 初始化失败,ID错误
** OPERATE_SUCCESS 初始化成功
*********************************************************************************************************/
static int __i2cInit ( uint32 ID,
uint32 Speed,
void *Rsv )
{
volatile uint8 *pucAddrBase;
volatile uint32 uiOffBase;
Rsv = Rsv; /* 防止编译报警 */
/*
* 参数过滤,判断
*/
if ( ID >= __IIC_MAX_NUM ) {
return OPERATE_FAIL;
}
if ( Speed > 400000 ) {
Speed = 100000;
}
/*
* 创建信号量,操作系统部分
*/
#if __UCOSII_EN > 0
*GpposeI2cTable[ID] = OSSemCreate(1);
if(*GpposeI2cTable[ID] == (void *)NULL) { /* 如果创建信号量失败返回错误 */
return OPERATE_FAIL;
}
#endif
/*
* 初始化一些参数
*/
__GpiinfoDateTab[ID]->uiID = ID;
__GpiinfoDateTab[ID]->pucAddrBase = (uint8*)__GuiI2cBaseAddrTab[ID];
__GpiinfoDateTab[ID]->uiOffBase = 2;
__GpiinfoDateTab[ID]->ucIICflag = I2C_IDLE; /* 标识该器件现在空闲 */
__GpiinfoDateTab[ID]->ucSlave = __IIC_MASTER; /* 标识该器件为主机 */
__GpiinfoDateTab[ID]->usDataNum = 0;
pucAddrBase = __GpiinfoDateTab[ID]->pucAddrBase; /* 获取指针参数 */
uiOffBase = __GpiinfoDateTab[ID]->uiOffBase;
*(uint16*)(pucAddrBase+(__B_IIC_SCLH << uiOffBase) ) = (uint16)((Fpclk / Speed + 1) / 2);
/* 设置时钟高电平时间 */
*(uint16*)(pucAddrBase+(__B_IIC_SCLL << uiOffBase) ) = (uint16)((Fpclk / Speed) / 2);
/* 设置时钟低电平时间 */
pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x2C;
pucAddrBase[__B_IIC_SET << uiOffBase] = 0x40; /* 设置主模式 */
return OPERATE_SUCCESS;
}
/*********************************************************************************************************
** Function name: i2cInit
** Descriptions: I2c初始化程序,如果设置参数的速度超过400K则设置标准速度100K
** Input parameters: ID 器件子设备号,例如ID=0,表示初始化的是I2C0
** arg 设置参数的字符串,该函数暂时只设置I2C速度
** 例如要设置的速度为200K,则字符串为"Speed=200000"
** Rsv 保留参数
** Output parameters: NONE
** Returned value: PIN_ERR 管脚配置错误
** OPERATE_FAIL 初始化失败,ID错误
** OPERATE_SUCCESS 初始化成功
*********************************************************************************************************/
int32 i2cInit (uint32 ID,
char *arg,
void *Rsv)
{
uint32 uiParm[1]={-1};
if (ID < __IIC_MAX_NUM) {
ImpCmd(Tab_I2C, arg, uiParm); /* 解析字符串参数 */
return __i2cInit(ID, uiParm[0], Rsv); /* 初始化部件 */
}
return OPERATE_FAIL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -