📄 ssp.c
字号:
**
** Using example : char *pcArg = "SSPType=0 SSPBaudRate=1000"; adcSetMode(0,pcArg,NULL);
** Notice: 设备操作失败的原因是输入不正确的设备号.
*********************************************************************************************************/
uint32 sspSetMode (uint32 uiID,
char *pcArg,
char *pRsv)
{
static uint32 uiParam[6]={-1,0,0,8,0,0};
if ((uiID >= __SSP_MAX_NUM) | (pcArg == NULL)) { /* 检查参数有效性 */
return (uint32)(OPERATE_FAIL);
}
if (__GpSSPInfoData[uiID]->ucSSPState != __SSP_IDLE) { /* 如果SSP忙,不允许进行参数设置*/
return (uint32)(OPERATE_FAIL);
}
pRsv = pRsv ; /* 为了防止编译器警告 */
ImpCmd(Tab_SSP, pcArg, uiParam); /* 解析字符串参数 */
/*
* 过滤输入字符参数
*/
if (uiParam[SSPType] > MICROWIRE) { /* 总线类型:SPI,SSI,Microwire */
return (uint32)(OPERATE_FAIL);
}
if (uiParam[MasterSlaver] > 1) { /* 主从机模式选择 从机:1 主机:0*/
return (uint32)(OPERATE_FAIL);
}
if (uiParam[SSPType] == SPI) { /* 若为SPI类型,速率<= (Fpclk/8)*/
if (uiParam[SSPBaudRate] > (Fpclk / 2)) {
return (uint32)(OPERATE_FAIL);
}
}
if ((uiParam[BitsLen] != 4 ) && /* 每帧长度:4,8,16 位 */
(uiParam[BitsLen] != 8 ) &&
(uiParam[BitsLen] != 16)) {
return (uint32)(OPERATE_FAIL);
}
if (uiParam[CPHA] > 1) { /* 输出时钟相位 */
return (uint32)(OPERATE_FAIL);
}
if (uiParam[CHOL] > 1) { /* 输出时钟极性 */
return (uint32)(OPERATE_FAIL);
}
/*
* 初始化结构体,给设备套上一层参数壳.
*/
return (__sspInit(uiID,uiParam,pRsv)); /* 调用内部初始化函数 */
}
/*********************************************************************************************************
** Function name: sspGetState
**
** Descriptions: 获取当前SSP的参数
** Input parameters: uiID 设备号,例如0表示使用SSP0
** uiState 状态宏参数,请参考SSP.h文件说明
** pRsv 保留参数,可输入为NULL.
**
** Returned value: 操作失败: OPERATE_FAIL
** 操作成功: 返回状态宏
**
** Notice : 总线类型: SPI,SSI,MicroWire
SPI : 0
SSI : 1
MICROWIRE : 2
*********************************************************************************************************/
uint32 sspGetState (uint32 uiID,
uint32 uiState,
void *pRsv)
{
__PSSP_INFO pSspInfo;
if (uiID >= __SSP_MAX_NUM) { /* 检查参数有效性 */
return (uint32)(OPERATE_FAIL);
}
pRsv = pRsv;
pSspInfo = __GpSSPInfoData[uiID]; /* 获取结构体指针 */
switch (uiState) {
case SSP_ID:
return (pSspInfo->uiSSPID); /* 设备ID */
break;
case SSP_M_S:
return (pSspInfo->ucMasterSlave); /* 主/ 从机标志 */
break;
case SSP_MODE:
return (pSspInfo->uiSSPMode); /* 总线类型: SPI,SSI,MicroWire */
break;
case SSP_BITSLEN:
return (pSspInfo->ucDataLen); /* 数据帧长度: 4, 8, 16位 */
break;
case SSP_STATE:
return (pSspInfo->ucSSPState); /* 设备状态: 空闲,正在读,正在写*/
break;
case SSP_S_INT_STATE:
return (pSspInfo->ucSendIntEn); /* 写中断使能标志 */
break;
case SSP_S_QUEUE_STATE:
return (pSspInfo->uiSQueueState); /* 接收软FIFO状态 */
break;
case SSP_R_QUEUE_STATE:
return (pSspInfo->uiRQueueState); /* 发送软FIFO状态 */
break;
case SSP_H_S_QUEUE_STATE:
return (pSspInfo->uiHardSFIFOState); /* 硬件 发 FIFO状态 */
break;
case SSP_H_R_QUEUE_STATE:
return (pSspInfo->uiHardRFIFOState); /* 硬件 收 FIFO状态 */
break;
default:
return (uint32)(OPERATE_FAIL);
}
}
/*********************************************************************************************************
** Function name: sspWrite
** Descriptions: SSP写数据操作,数据入软件FIFO.同时开启SSP.
** input parameters: uiID : 设备号,例如0表示使用SSP0
** pDataBuf : 指向待发送数据存储空间指针.类型不定.
** uiDataByteNum : 要发送的字节个数
**
** Returned value: 操作成功:OPERATE_SUCCESS;
** 操作失败:OPERATE_FAIL.
*********************************************************************************************************/
uint32 sspWrite (uint32 uiID,
void *pDataBuf,
uint32 uiDataByteNum)
{
uint32 uiOffsetBase;
volatile uint32 *puiBaseAddr;
uint8 ucDataLen; /* 帧长度 */
uint32 uiSendNByte; /* 要发送的字节数据长度值 */
uint8 ucSendData; /* 8位长度临时变量 */
uint16 usSendData; /* 16位长度临时变量 */
uint32 uiQueueErr; /* 队列操作返回状态 */
uint32 uiQueueState; /* 写缓存队列状态 */
uint8 *pucQueueBuf8; /* 字节长度临时指针变量 */
__PDATA_QUEUE SspSendQueAddr; /* 队列结构体指针 */
if ((uiID >= __SSP_MAX_NUM) | (pDataBuf == NULL)) { /* 检查参数有效性 */
return (uint32)(OPERATE_FAIL);
}
/*
* 数据帧长度处理,并缓存入软FIFO.
*/
SspSendQueAddr = __GpSSPInfoData[uiID]->SspSendQueAddr;
ucDataLen = __GpSSPInfoData[uiID]->ucDataLen;
uiQueueState = __GpSSPInfoData[uiID]->uiSQueueState;
if ((__GpSSPInfoData[uiID]->SspSendQueAddr == NULL) || /* 检查数据队列是否已创建 */
(uiQueueState == __SSP_QUEUE_FULL)) { /* 检查数据队列是否已满 */
return (uint32)(OPERATE_FAIL);
}
pucQueueBuf8 = (uint8*)pDataBuf; /* 指针类型转换 */
for (uiSendNByte = 0; uiSendNByte < uiDataByteNum; uiSendNByte++) {
ucSendData = *pucQueueBuf8++; /* 赋值同时调整指针指向下一数据*/
uiQueueErr = QueueWrite (SspSendQueAddr,ucSendData);
if (uiQueueErr != QUEUE_OK) {
uiSendNByte += (uiSendNByte == 0) ? (1) : (0);
break;
}
}
/*
* 判断是否正确入队
*/
uiQueueState = (uiQueueErr == QUEUE_FULL) ? __SSP_QUEUE_FULL : __SSP_QUEUE_NO_FULL;
if ((uiQueueErr != QUEUE_OK) && (uiQueueErr == __SSP_QUEUE_FULL)) {
return (uint32)(OPERATE_FAIL);
}
IRQDisable(); /* 关IRQ中断 */
__GpSSPInfoData[uiID]->uiSQueueState = uiQueueState; /* 保存队列状态 */
IRQEnable(); /* 开IRQ中断 */
/*
* 判断是否已开启中断,数据输出.如果已开中断,则只要将数据写入队列就返回,然后在中断处理中,队列送数就可以.
*/
if ((__GpSSPInfoData[uiID]->ucSendIntEn == __SSP_W_INT_DISABLE ) && /* 判断是否已开中断 */
(__GpSSPInfoData[uiID]->uiHardSFIFOState == __SSP_FIFO_EMPTY)) {
/* 硬件发送FIFO是否为空 */
/* 没开中断,为空,则启动数据传输*/
uiOffsetBase = __GpSSPInfoData[uiID]->uiOffsetBase;
puiBaseAddr = __GpSSPInfoData[uiID]->puiAddrBase;
/*
* 数据出队,送入SSP数据寄存器中,启动SSP发送工作.
*/
switch (ucDataLen) { /* 数据帧调整,入软FIFO缓存 */
case 4:
if (QueueRead (&ucSendData,SspSendQueAddr) == QUEUE_OK) {
usSendData = (uint16)(ucSendData & 0x0F);
}
break;
case 8:
if (QueueRead (&ucSendData,SspSendQueAddr) == QUEUE_OK) {
usSendData = (uint16)ucSendData;
}
break;
case 16:
if (QueueRead (&ucSendData,SspSendQueAddr) == QUEUE_OK) {
usSendData = ucSendData;
if (QueueRead (&ucSendData,SspSendQueAddr) == QUEUE_OK) {
usSendData = (uint16)((ucSendData << 8) | usSendData);
}
}
break;
default:
return (uint32)(OPERATE_FAIL);
}
#if SSP_CS_GPIO > 0
if (__GpSSPInfoData[uiID]->ucMasterSlave == 0) {
__SSP_CS_ENABLE(SSP_CS_Pin);
}
#endif
puiBaseAddr[__B_SSP_SSPDR << uiOffsetBase] = usSendData; /* 发送数据,入SSP寄存器 */
#if SSP_CS_GPIO > 0
if (__GpSSPInfoData[uiID]->ucMasterSlave == 0) {
__SSP_CS_DISABLE(SSP_CS_Pin);
}
#endif
puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase] |= (0x01 << 3); /* 开发送FIFO中断使能 */
}
return (uiSendNByte); /* 返回已发送的数据个数 */
}
/*********************************************************************************************************
** Function name: sspRead
** Descriptions: SSP读操作,只对软件FIFO操作.
** input parameters: uiID : 设备号,例如0表示使用SSP0
** pDataBuf : 指向保存所接收数据存储空间指针.类型不定.
** uiDataByteNum : 要接收的字节个数
**
** Returned value: 操作成功:返回正确读取字节个数
** 操作失败:OPERATE_FAIL.
*********************************************************************************************************/
uint32 sspRead (uint32 uiID,
void *pDataBuf,
uint32 uiDataByteNum)
{
uint32 uiRecvNByte;
uint8 *ucRecvData;
uint32 uiQueueErr;
if ((uiID >= __SSP_MAX_NUM) | (pDataBuf == NULL)) { /* 检查参数有效性 */
return (uint32)(OPERATE_FAIL);
}
if ((__GpSSPInfoData[uiID]->uiRQueueState == __SSP_QUEUE_EMPTY) ||
(__GpSSPInfoData[uiID]->ucSSPState != __SSP_IDLE)) { /* 收队列是否为空,SSP状态为空闲 */
return (uint32)(OPERATE_FAIL);
}
ucRecvData = (uint8*)pDataBuf; /* 数据保存指针调整 */
for (uiRecvNByte = 0; uiRecvNByte < uiDataByteNum; uiRecvNByte++) {
uiQueueErr = QueueRead (ucRecvData++,__GpSSPInfoData[uiID]->SspRecvQueAddr);
if ((uiQueueErr != QUEUE_OK) || (uiQueueErr == QUEUE_EMPTY)) {
uiRecvNByte += (uiRecvNByte == 0) ? (1) : (0);
break;
}
}
__GpSSPInfoData[uiID]->uiRQueueState = (uiQueueErr == QUEUE_EMPTY) ? \
(__SSP_QUEUE_EMPTY) : (__SSP_QUEUE_NO_FULL);
return (uiRecvNByte); /* 返回写入数据个数 */
}
/*********************************************************************************************************
** Function name: __sspWriteIsrSub
**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -