⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi.c

📁 philips arm7 lpc2103的常用功能的库函数第二部分
💻 C
📖 第 1 页 / 共 2 页
字号:
**                          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 + -