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

📄 ssp.c

📁 philips arm7 lpc2103的常用功能的库函数第二部分
💻 C
📖 第 1 页 / 共 3 页
字号:
** Descriptions:			SSP发送中断调用子函数,内部使用.将软FIFO中的数据写入SSP硬件FIFO中.
** input parameters:		psspInfo: 指向SSP设备信息结构体指针.
**
** Returned value:			无返回值.
** Notice:                  每次最多发送8个帧.         
*********************************************************************************************************/ 
static void  __sspWriteIsrSub (__PSSP_INFO psspInfo)
 
{
	         uint8   ucSendData;
             uint16  usSendData; 
    volatile uint16  usQueueByteNum;
    const    uint16  usSspFrameLen = psspInfo->usSspFrameNum;           /*  限制变量参数不可修改,只读   */
             uint16  usSendByteNum;
             uint32  uiOffsetBase;
    volatile uint32 *puiBaseAddr;
      __PDATA_QUEUE  SspSendQueAddr;
            
    if (psspInfo == NULL) {
        puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase] &= (~(0x01 << 3)); /*  关TxFIFO至少半空中断,防重入 */
        return;
    }
	IRQDisable();                                                       /*  关IRQ中断                   */
    psspInfo->ucSendIntEn = __SSP_W_INT_ENABLE;                         /*  标志当前已进入写中断        */
    psspInfo->ucSSPState  = __SSP_SEND;                  
    
    uiOffsetBase   = psspInfo->uiOffsetBase;
    puiBaseAddr    = psspInfo->puiAddrBase;
    SspSendQueAddr = psspInfo->SspSendQueAddr;
    IRQEnable();                                                        /*  开IRQ中断                   */
    
    /*
     *  状态判断
     */
   if (psspInfo->uiSQueueState == __SSP_QUEUE_EMPTY) {                 /*  判断发送队列是否为空        */
        if ((puiBaseAddr[__B_SSP_SSPSR << uiOffsetBase] & (0x01 << 0)) == 1) {
        psspInfo->ucSendIntEn   = __SSP_W_INT_DISABLE;                  /*  标志硬写FIFO为空,可软件启动 */
        puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase] &= (~(0x01 << 3)); /*  关TxFIFO至少半空中断,防重入 */
	    }
	    return;    
    }
    
    /*
     *  数据写中断处理.
     */
    if (SspSendQueAddr->NData == 0) {
       puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase] &= (~(0x01 << 3));  /*  关TxFIFO至少半空中断,防重入 */
       return;
    }
    usQueueByteNum = SspSendQueAddr->NData;
    usSendByteNum  = (uint16)((usQueueByteNum > (usSspFrameLen)) ?  \
                              ((usSspFrameLen) - 1) : (usQueueByteNum - 1));
    if (usSendByteNum == 0) {
        usSendByteNum = 1;
    }                          
    do {
        switch (psspInfo->ucDataLen) {                                  /*  根据要发送的数据帧调整数据  */
        case 4:
            if (QueueRead(&ucSendData,psspInfo->SspSendQueAddr) == QUEUE_OK) {
                usSendData = (uint16)(ucSendData & 0xF0);               /*  先发高4位 (当帧格式为4位)   */
            }
            break;
        case 8:
            if (QueueRead(&ucSendData,psspInfo->SspSendQueAddr) == QUEUE_OK) {
                usSendData = (uint16)(ucSendData & 0xFF);
            }   
            break;
        case 16:
            if (QueueRead(&ucSendData,psspInfo->SspSendQueAddr) == QUEUE_OK) {
                usSendData = (uint16)(ucSendData << 8);
                if (QueueRead(&ucSendData,psspInfo->SspSendQueAddr) == QUEUE_OK) {
                    usSendData = (uint16)(ucSendData | usSendData); 
                }
            }  
            break;                                                      
        default:
            break;                                                      /*  队列写入错误,退出循环       */
        }
        #if SSP_CS_GPIO > 0
        if (psspInfo->ucMasterSlave == 0) {
            __SSP_CS_ENABLE(SSP_CS_Pin);    
        }      
        #endif
        puiBaseAddr[__B_SSP_SSPDR << uiOffsetBase] = usSendData; 
        #if SSP_CS_GPIO > 0
        if (psspInfo->ucMasterSlave == 0) {
            __SSP_CS_DISABLE(SSP_CS_Pin);    
        }   
        #endif 
        
        if (psspInfo->ucDataLen == 4) {
            usSendData = (uint16)(ucSendData & 0x0F);                   /*  再发低4位  (当帧格式为4位)  */
            #if SSP_CS_GPIO > 0
            if (psspInfo->ucMasterSlave == 0) {
                __SSP_CS_ENABLE(SSP_CS_Pin);    
            }      
            #endif
            puiBaseAddr[__B_SSP_SSPDR << uiOffsetBase] = usSendData; 
            #if SSP_CS_GPIO > 0
            if (psspInfo->ucMasterSlave == 0) {
                __SSP_CS_DISABLE(SSP_CS_Pin);    
            }   
            #endif 
        } 
    } while (--usSendByteNum != 0);                                     /*  当发送未完                  */
    
    /*
     *  状态标志处理.
     */
	IRQDisable();                                                       /*  关IRQ中断                   */
	if ((puiBaseAddr[__B_SSP_SSPSR << uiOffsetBase] & (0x01 << 0)) == 1) {
        psspInfo->ucSendIntEn   = __SSP_W_INT_DISABLE;                  /*  标志硬写FIFO为空,可软件启动 */
        if ((SspSendQueAddr->NData - usSendByteNum) == 0) {
            puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase] &= (~(0x01 << 3));
                                                                        /*  关TxFIFO至少半空中断,防重入 */
        }
	}
    psspInfo->ucSSPState    = __SSP_IDLE;    
    psspInfo->uiSQueueState = (SspSendQueAddr->NData == 0) ? (__SSP_QUEUE_EMPTY) : (__SSP_QUEUE_NO_FULL);
    psspInfo->uiHardSFIFOState = ((puiBaseAddr[__B_SSP_SSPSR << uiOffsetBase] & (0x01 << 1)) == 0) ?    \
                                (__SSP_FIFO_FULL) : (__SSP_FIFO_NO_FULL);
    IRQEnable();                                                        /*  开IRQ中断                   */
}

/*********************************************************************************************************
** Function name:			__sspReadIsrSub
**
** Descriptions:			SSP接收中断调用子函数,内部使用.
** input parameters:		psspInfo: 指向SSP设备信息结构体指针.
**
** Returned value:			无返回值.
** Notice:                  无论是4, 8, 16位 / 帧,都作为一次8位入队处理.读取SSP硬件FIFO数据,缓存入软FIFO中.
*********************************************************************************************************/ 
static void  __sspReadIsrSub (__PSSP_INFO psspInfo)
{
              uint8  ucRecvData;
             uint16  usRecvData;
             uint16  usReadByteNum;
    const    uint16  usSspFrameLen = (uint32)psspInfo->usSspFrameNum;   /*  限制变量参数不可修改,只读   */
             uint32  uiOffsetBase;
    volatile uint32 *puiBaseAddr;
      __PDATA_QUEUE  SspRecvQueAddr;
    
    if (psspInfo == NULL) {
        return;
    }
	IRQDisable(); 
	psspInfo->ucSSPState  = __SSP_RECIEVE;                  
    if (psspInfo->uiRQueueState == __SSP_QUEUE_FULL) {                  /*  判断是否收队列为满          */
       return;    
    }
    IRQEnable();                                                        /*  开IRQ中断                   */
    
    uiOffsetBase   = psspInfo->uiOffsetBase;
    puiBaseAddr    = psspInfo->puiAddrBase;
    SspRecvQueAddr = psspInfo->SspRecvQueAddr;
    
    usReadByteNum  = usSspFrameLen;
    do {
        #if SSP_CS_GPIO > 0
        if (psspInfo->ucMasterSlave == 0) {
            __SSP_CS_ENABLE(SSP_CS_Pin);    
        }      
        #endif
        
        usRecvData = (uint16)puiBaseAddr[__B_SSP_SSPDR << uiOffsetBase];
        
        #if SSP_CS_GPIO > 0
        if (psspInfo->ucMasterSlave == 0) {
            __SSP_CS_DISABLE(SSP_CS_Pin);    
        }   
        #endif
         
        if (psspInfo->ucDataLen == 16) {
            ucRecvData = (uint8)(usRecvData >> 8);                      /*  高8位入队                   */
            if (QueueWrite(SspRecvQueAddr,ucRecvData) != QUEUE_OK) {
                break;
            }
        }
        ucRecvData = (uint8)(usRecvData & 0xFF);                        /*  低8位入队                   */
        if (QueueWrite(SspRecvQueAddr,ucRecvData) != QUEUE_OK) {
            break; 
        }
    }while (((puiBaseAddr[__B_SSP_SSPSR << uiOffsetBase] & 0x01 << 2) != 0) &&
            (--usReadByteNum != 0));                                    /*  当硬FIFO未空,未发完8帧,继续 */
    
    /*
     *  状态标志处理.
     */
    IRQDisable();                                                       /*  关IRQ中断                   */
    psspInfo->ucSSPState       = __SSP_IDLE;                  
    psspInfo->uiHardRFIFOState = ((puiBaseAddr[__B_SSP_SSPSR << uiOffsetBase] & 0x01 << 3) == 1) ?     \
                                (__SSP_FIFO_FULL) : (__SSP_FIFO_NO_FULL);
    if ((SspRecvQueAddr->NData) >= (SspRecvQueAddr->MaxData)) {         /*  软FIFO已满                  */
        psspInfo->uiRQueueState = __SSP_QUEUE_FULL;
    } else {
        psspInfo->uiRQueueState = __SSP_QUEUE_NO_FULL;
    }
    IRQEnable();                                                        /*  开IRQ中断                   */
}

/*********************************************************************************************************
** Function name:			__sspIsrNone
**
** Descriptions:			SSP中断空处理调用子函数,内部使用.
** input parameters:		psspInfo: 指向SSP设备信息结构体指针.
**
** Returned value:			无返回值.
*********************************************************************************************************/ 
static void  __sspIsrNone (__PSSP_INFO psspInfo)
{
             uint32  uiOffsetBase;
    volatile uint32 *puiBaseAddr;
    volatile uint32  uiTmp = 0;
    
    psspInfo = psspInfo;
    
    uiOffsetBase = __GpSSPInfoData[__SSP0]->uiOffsetBase;             
    puiBaseAddr  = __GpSSPInfoData[__SSP0]->puiAddrBase;
    
    /*
     * 清空所有的中断
     */
    puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase] &= (~(0x01 << 3));     /*  关TxFIFO至少半空中断,防重入 */
    uiTmp = puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase];               /*  清读一半中断                */
    puiBaseAddr[__B_SSP_SSPIMSC << uiOffsetBase] = uiTmp;               /*  清写一半中断                */
    puiBaseAddr[__B_SSP_SSPICR << uiOffsetBase]  |= 0x03;               /*  清除接收中断标志            */
    return;
}

/*********************************************************************************************************
** Defination:    函数指针数组来调用各个中断状态处理函数.
**
** Descriptions:  安装SSP中断调用子函数,内部使用.
** Notice:        只对至少一半空/满状态进行读写中断处理.
**********************************************************************************************************/
static void (* const    __sspIsrFun[16]) (__PSSP_INFO psspInfo) = {
    __sspIsrNone,       __sspIsrNone,   __sspReadIsrSub,    __sspIsrNone,  
    __sspReadIsrSub,    __sspIsrNone,   __sspReadIsrSub,    __sspIsrNone,  
    __sspWriteIsrSub,   __sspIsrNone,   __sspReadIsrSub,    __sspIsrNone, 
    __sspReadIsrSub,    __sspIsrNone,   __sspReadIsrSub,    __sspIsrNone     
};
  
/*********************************************************************************************************
** Function name:			ssp0Isr
** Descriptions:			SSP0中断服务函数
** Transfer Functions:      __sspIsrFunInstall(); 中断处理函数指针安装函数. 
**                          ssp0Hook();           钩子函数,存放用户处理中断代码.
** input parameters:		无
** Returned value:			无 
*********************************************************************************************************/ 
void ssp0Isr (void)

{
             uint32  uiOffsetBase;
    volatile uint32 *puiBaseAddr;
             uint32  uiStateNum;
             uint32  uiSspIntState;

    uiOffsetBase = __GpSSPInfoData[__SSP0]->uiOffsetBase;             
    puiBaseAddr  = __GpSSPInfoData[__SSP0]->puiAddrBase;   
    
    uiSspIntState = puiBaseAddr[__B_SSP_SSPMIS << uiOffsetBase];        /*  获取中断状态号              */
    uiStateNum    = uiSspIntState & 0x0F;

    puiBaseAddr[__B_SSP_SSPICR << uiOffsetBase] |= 0x03;                /*  清除接收中断标志            */
    (*__sspIsrFun[uiStateNum ])(__GpSSPInfoData[__SSP0]);               /*  调用对应状态中断处理函数    */

    ssp0Hook();	                                                        /*  调用钩子函数                */
    VICVectAddr = 0x00;	                                                /*  清除内核中断逻辑            */
} 
 

 
#endif                                                                  /*  SSP_FUN_LIB                 */ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -