📄 spi.c
字号:
** uiParmLen 要读的数据个数
** ucData 读取时MOSI填充的字节,如果为NULL,则填充OXFF
** Output parameters: NONE
** Returned value: 启动失败: OPERATE_FAIL
** 启动成功: OPERATE_SUCCESS
*********************************************************************************************************/
int32 spiReadStart (uint32 uiParmID,
uint32 uiParmLen,
uint8 ucData)
{
volatile uint32 *puiBaseAddr;
uint32 uiOffBase;
/*
* 参数过滤
*/
if (uiParmID >= __SPI_MAX_NUM) {
return OPERATE_FAIL;
}
if (uiParmLen == 0) { /* 不允许读0个字节数据 */
return OPERATE_FAIL;
}
if (__GpsiDataTab[uiParmID]->ucSpiflag != SPI_IDLE) { /* 设备不空闲就不能启动接收 */
return OPERATE_FAIL;
}
if (__GpsiDataTab[uiParmID]->ucSlave == __SPI_SLAVE) { /* 是从设备返回错误 */
return OPERATE_FAIL;
}
if (ucData == NULL) { /* 检查填充字节 */
ucData = 0xff; /* 填充默认填充字节 */
}
puiBaseAddr = __GpsiDataTab[uiParmID]->puiAddrBase; /* 获得操作的设备地址 */
uiOffBase = __GpsiDataTab[uiParmID]->uiOffBase;
__GpsiDataTab[uiParmID]->ucSpiflag = SPI_READ; /* 标识设备为读状态 */
__GpsiDataTab[uiParmID]->ucReadSend = ucData; /* 初始化填充字节 */
__GpsiDataTab[uiParmID]->uiReadLen = uiParmLen-1; /* 记录还需要读取多少个字节 */
__SPI_CS_ENABLE(__GpsiDataTab[uiParmID]->uiSpiCsPin); /* 使能片选 */
puiBaseAddr[__B_SPI_PDR << uiOffBase] = ucData; /* 发送填充字节,中断中接收数据*/
return OPERATE_SUCCESS;
}
/*********************************************************************************************************
** Function name: spiRead()
** Descriptions: SPI读函数
** Input parameters: uiParmID 设备号,例如0表示使用SPI0
** uiParmLen 要读的数据个数
** Output parameters: pucParmBuf 存储读取出来数据的缓冲区
** Returned value: 读取失败: OPERATE_FAIL
** 读取成功: >=0
*********************************************************************************************************/
int32 spiRead (uint32 uiParmID,
uint8 *pucParmBuf,
uint32 uiParmLen)
{
uint32 i;
/*
* 参数过滤
*/
if (uiParmID >= __SPI_MAX_NUM) {
return OPERATE_FAIL;
}
if (uiParmLen == 0) { /* 不允许读0个字节数据 */
return OPERATE_FAIL;
}
if (__GpsiDataTab[uiParmID]->ucSlave == __SPI_SLAVE) { /* 是从设备返回错误 */
return OPERATE_FAIL;
}
for (i = 0; i < uiParmLen; i++) {
if (QueueRead(pucParmBuf, __GpsiDataTab[uiParmID]->recvQueue) != QUEUE_OK) {
return i; /* 返回已读取到的长度 */
}
pucParmBuf++;
}
return uiParmLen; /* 读取数据完成 */
}
/*********************************************************************************************************
** Function name: spiGetflag()
** Descriptions: SPI状态获取函数
** Input parameters: uiParmID 设备号,例如0表示使用SPI0
** uiParmCmd 要读取的参数类型,具体参见Spi.h宏定义
** Output parameters: NONE
** Returned value: 获取状态失败: OPERATE_FAIL。失败的原因:参数错误;不在写状态获取写模式;
** 不在读状态获取读长度
** 获取状态成功: 根据不同命令获得的值意义不一样
** uiParmCmd = SPI_GET_STATE,返回SPI_WRITE,SPI_READ,SPI_IDLE
** uiParmCmd = SPI_GET_WRITE_MODE,返回SPI_SAVE_BACK,SPI_NOSAVE_BACK
** uiParmCmd = SPI_GET_READ_LEN,返回>=0表示还有多少字节没有读完
*********************************************************************************************************/
int32 spiGetFlag (uint32 uiParmID, uint32 uiParmCmd)
{
if (uiParmID >= __SPI_MAX_NUM) { /* 判断参数 */
return OPERATE_FAIL;
}
switch(uiParmCmd) {
case SPI_GET_STATE: /* 获取SPI当前工作状态 */
return (__GpsiDataTab[uiParmID]->ucSpiflag);
break;
case SPI_GET_WRITE_MODE: /* 获取SPI写模式 */
if(__GpsiDataTab[uiParmID]->ucSpiflag == SPI_WRITE) {
return (__GpsiDataTab[uiParmID]->ucWriteMode);
}
return OPERATE_FAIL; /* 没处在写状态则返回错误 */
break;
case SPI_GET_READ_LEN: /* 获取SPI还有多少字节没有读 */
if (__GpsiDataTab[uiParmID]->ucSpiflag == SPI_READ) {
return (__GpsiDataTab[uiParmID]->uiReadLen);
}
return OPERATE_FAIL; /* 没处在读状态则返回错误 */
break;
default:
return OPERATE_FAIL;
break;
}
}
/*********************************************************************************************************
** Function name: spiSetCs()
** Descriptions: SPI设置片选脚
** Input parameters: uiParmID 设备号,例如0表示设置SPI0
** uiPin 设备描述符指针
** Output parameters: NONE
** Returned value: OPERATE_SUCCESS:设置成功
** OPERATE_FAIL :设置失败,原因是当前不属于空闲状态,或ID错误
*********************************************************************************************************/
int32 spiSetCs (uint32 uiParmID, uint32 uiPin)
{
if (uiParmID > __SPI_MAX_NUM) { /* ID号错误 */
return OPERATE_FAIL;
}
if (__GpsiDataTab[uiParmID]->ucSpiflag == SPI_IDLE) {
__GpsiDataTab[uiParmID]->uiSpiCsPin = uiPin;
__SPI_CS_DISABLE(uiPin); /* 禁能片选信号 */
return OPERATE_SUCCESS;
}
return OPERATE_FAIL; /* 没处在读状态则返回错误 */
}
/*********************************************************************************************************
** Function name: __spiISR()
** Descriptions: SPI中断服务函数执行部分
** Input parameters: psiParm 设备描述符指针
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
static void __spiIsr (__PSPI_INFO psiParm)
{
volatile uint32 *puiBaseAddr;
uint32 uiOffBase;
uint8 ucTemp;
puiBaseAddr = psiParm->puiAddrBase; /* 获取设备基地址 */
uiOffBase = psiParm->uiOffBase;
__SPI_CS_DISABLE(psiParm->uiSpiCsPin); /* 禁能片选 */
puiBaseAddr[__B_SPI_INT << uiOffBase] = 0x01; /* 清除SPI的中断源 */
ucTemp = (uint8)puiBaseAddr[__B_SPI_PSR << uiOffBase]; /* 获取状态寄存器值 */
if ((ucTemp & 0x80) == 0) { /* 其他错误产生中断不做处理 */
return;
}
ucTemp = (uint8)puiBaseAddr[__B_SPI_PDR << uiOffBase]; /* 读取SPI数据寄存器的值 */
if (psiParm->ucSpiflag == SPI_WRITE) { /* 写状态处理 */
if (psiParm->ucWriteMode == SPI_NOSAVE_BACK) { /* 不保存写返回值 */
if (QueueRead(&ucTemp, psiParm->sendQueue) != QUEUE_OK) {
psiParm->ucSpiflag = SPI_IDLE; /* 写结束,释放设备资源 */
return;
}
__SPI_CS_ENABLE(psiParm->uiSpiCsPin); /* 使能能片选 */
puiBaseAddr[__B_SPI_PDR << uiOffBase] = ucTemp; /* 发送SPI数据 */
return;
}
/* 下面处理保存写返回值 */
QueueWrite(psiParm->recvQueue, ucTemp); /* 写返回值入队列 */
if (QueueRead(&ucTemp, psiParm->sendQueue) != QUEUE_OK) {
psiParm->ucSpiflag = SPI_IDLE; /* 写结束,释放设备资源 */
return;
}
__SPI_CS_ENABLE(psiParm->uiSpiCsPin); /* 使能能片选 */
puiBaseAddr[__B_SPI_PDR << uiOffBase] = ucTemp; /* 发送SPI数据 */
} else { /* 读状态处理 */
QueueWrite(psiParm->recvQueue, ucTemp); /* 读数据入队列,队列满就丢弃 */
/* 后面收到的字节 */
if (psiParm->uiReadLen == 0) { /* 数据读取完毕 */
psiParm->ucSpiflag = SPI_IDLE; /* 读结束,释放设备资源 */
return;
}
/* 还有数据要读取 */
__SPI_CS_ENABLE(psiParm->uiSpiCsPin); /* 使能能片选 */
psiParm->uiReadLen--; /* 发送字节数减少一个 */
puiBaseAddr[__B_SPI_PDR << uiOffBase] = psiParm->ucReadSend; /* 发送填充字节 */
}
}
/*********************************************************************************************************
** Function name: spi0ISR()
** Descriptions: SPI中断服务函数
** Input parameters: NONE
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
void spi0Isr (void)
{
__spiIsr(__GpsiDataTab[0]);
spi0Hook(); /* SPI钩子函数,执行用户代码 */
VICVectAddr = 0x00; /* 清除VIC中断 */
}
/*********************************************************************************************************
** Function name: spi1ISR()
** Descriptions: SPI中断服务函数
** Input parameters: NONE
** Output parameters: NONE
** Returned value: NONE
*********************************************************************************************************/
#if __SPI_MAX_NUM > 1
void spi1Isr (void)
{
__spiIsr(__GpsiDataTab[1]);
spi1Hook(); /* SPI钩子函数,执行用户代码 */
VICVectAddr = 0x00; /* 清除VIC中断 */
}
#endif
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -