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

📄 xsssp.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 3 页
字号:

        XsIcEnableIrqDeviceInt (XSIC_SSP_SGNL);
    }

    // Enable/disable receive FIFO level interrupt
    if (cfgP->RxIntEnable == SspFIFOIntDisabled)
        regsP->SSCR1 &= ~SSP_SSCR1_RIE; 
    else
        regsP->SSCR1 |= SSP_SSCR1_RIE;

    // Enable/disable transmit FIFO level interrupt
    if (cfgP->TxIntEnable == SspFIFOIntDisabled)
        regsP->SSCR1 &= ~SSP_SSCR1_TIE; 
    else
        regsP->SSCR1 |= SSP_SSCR1_TIE;

    // Enable/disable Receive and Transmit DMA
    if (cfgP->enableDMA == TRUE)
    {
        regsP->SSCR1 |= (SSP_SSCR1_RSRE | SSP_SSCR1_TSRE);
        // Enable Trailing bytes are handled by DMA
//      regsP->SSCR1 |=  SSP_SSCR1_TRAIL;
    }
    else
    {
        regsP->SSCR1 &= ~SSP_SSCR1_RSRE; 
        regsP->SSCR1 &= ~SSP_SSCR1_TSRE; 
    }

    // Set threshold level at which transmit FIFO aserts interrupt
    regsP->SSCR1 |= (((cfgP->thresholdTx - 1) << SSP_SSCR1_TFT_SHFT) & SSP_SSCR1_TFT_MASK);

    // Set threshold level at which receive FIFO aserts interrupt
    regsP->SSCR1 |= (((cfgP->thresholdRx - 1) << SSP_SSCR1_RFT_SHFT) & SSP_SSCR1_RFT_MASK);

    // Check if FIFO opertates in special function mode
    if (cfgP->enableSpecial == SspFIFOSpecialDisabled)
        regsP->SSCR1 &= ~SSP_SSCR1_EFWR; 
    else
    {
        regsP->SSCR1 |= SSP_SSCR1_EFWR;
        // Select transmit or receive FIFO
        if (cfgP->selectFIFO == SspTxFIFO)  
            regsP->SSCR1 &= ~SSP_SSCR1_STRF; 
        else
            regsP->SSCR1 |= SSP_SSCR1_STRF;
    }

    // Enable SSP
    regsP->SSCR0 |= SSP_SSCR0_SSE;

    return error;
}

/*
*******************************************************************************
*
* FUNCTION:         loopbackSsp                  
*
* DESCRIPTION:      This function is used to test SSP in polled mode operation.
*
* INPUT PARAMETERS: ctxP    is a pointer to SSP context structure. 
*                   data    is the data sent via loopback path.
*
* RETURNS:          UINT32  data (only max. 16 bit of data are significant).
*                           or zero if timeout expired and no character has been received.
*
* GLOBAL EFFECTS:   none
*
* ASSUMPTIONS:      SSP FIFO's Tx and Rx level interrupts are disabled and loopback 
*                   test mode is enabled
*
*******************************************************************************
*/

static
UINT32 loopbackSsp(SspContextT * ctxP, INT data)
{
    volatile SspRegT * regsP = (SspRegT *)ctxP->regsP;
    UINT start, timebase = ostCtxP->getTimebase_fnp(ostCtxP);
    UINT32 timeout =  500 * timebase;
    INT readData, statusSsp;
    BOOL exitFlag;

    // Get start time.
    start = ostCtxP->getTimer_fnp(ostCtxP);
    exitFlag = TRUE;

    // Make sure that RX FIFO is empty and there are no valid entries in
    // the FIFO. RFL = 0xF means no valid entries.
    do
    {
        // Get the status register.
        statusSsp = regsP->SSSR;

        // Check if the port is busy.
        if (!(statusSsp & SSP_SSSR_BSY))
        {
            // Check if there's anything in the RX FIFO.
            if (!(statusSsp & SSP_SSSR_RNE) &&
                 ((statusSsp & SSP_SSSR_RFL_MASK) == SSP_SSSR_RFL_MASK))
            {
                // Exit loop.
                exitFlag = FALSE;
                break;
            }

            // Drain the RX FIFO.
            readData = regsP->SSDR;
        }
    }
    while ((ostCtxP->getDelta_fnp(ostCtxP, start)) < timeout);

    // Continue only if the RX FIFO is empty.
    if (exitFlag)
    {
        // Error.
        return (-1);
    }

    // Get start time.
    start = ostCtxP->getTimer_fnp(ostCtxP);
    exitFlag = TRUE;

    // Make sure the TX FIFO isn't full.
    do
    {
        // Get the status register.
        statusSsp = regsP->SSSR;

        // Check if the port is busy.
        if (!(statusSsp & SSP_SSSR_BSY))
        {
            // Check if the TX FIFO is full.
            if (statusSsp & SSP_SSSR_TNF)
            {
                // Exit loop.
                exitFlag = FALSE;
                break;
            }

            // Wait for the TX FIFO to empty.
            DM_WaitUs(1);
        }
    }
    while ((ostCtxP->getDelta_fnp(ostCtxP, start)) < timeout);

    // Continue only if the TX FIFO isn't full.
    if (exitFlag)
    {
        // Error.
        return (-1);
    }

    // Get start time.
    start = ostCtxP->getTimer_fnp(ostCtxP);
    exitFlag = TRUE;

    // Transmit until the RX FIFO receives the data.
    do
    {
        // Get the status register.
        statusSsp = regsP->SSSR;

        // Check if the port is busy.
        if (!(statusSsp & SSP_SSSR_BSY))
        {
            // Check if the TX FIFO isn't full.
            if (statusSsp & SSP_SSSR_TNF)
            {
                // Write data
                regsP->SSDR = data;
            }

            // Get the status register.
            statusSsp = regsP->SSSR;

            // Check for data in the RX FIFO.
            if ((statusSsp & SSP_SSSR_RNE) ||
                ((statusSsp & SSP_SSSR_RFL_MASK) != SSP_SSSR_RFL_MASK))
            {
                // Transmit done.
                exitFlag = FALSE;
                break;
            }
        }
    }
    while ((ostCtxP->getDelta_fnp(ostCtxP, start)) < timeout);
            
    DM_WaitMs(10);

    // Check if we successfully transmited.
    if (exitFlag)
    {
        // Error.
        return -1;
    }

    // Get start time.
    start = ostCtxP->getTimer_fnp(ostCtxP);
    exitFlag = TRUE;

    // Read the data until the RX FIFO is empty and there are no
    // valid entries in the FIFO. RFL = 0xF means no valid entries.
    do
    {
        // Get the status register.
        statusSsp = regsP->SSSR;

        // Check if the port is busy.
        if (!(statusSsp & SSP_SSSR_BSY))
        {
            // Check for data in the RX FIFO.
            if ((statusSsp & SSP_SSSR_RNE) ||
                ((statusSsp & SSP_SSSR_RFL_MASK) != SSP_SSSR_RFL_MASK))
            {
                // Read the data.
                readData = regsP->SSDR;  
            }

            // Get the status register.
            statusSsp = regsP->SSSR;

            // Finally done.
            return (readData);
        }
    }
    while ((ostCtxP->getDelta_fnp(ostCtxP, start)) < timeout);

    // Error.
    return -1;
}

/*
*******************************************************************************
*
* FUNCTION:         writeSsp                      
*
* DESCRIPTION:      This function is used to transmit data via SSP in polled mode
*                   operation
*
* INPUT PARAMETERS: ctxP    is a pointer to UART context structure 
*                   txbufP  is a pointer to the buffer where the data is going 
*                           to be taken from
*                   len     is number of bytes to be sent
*
* RETURNS:          none.
*
* GLOBAL EFFECTS:   none.
*
* ASSUMPTIONS:      none.
*
*******************************************************************************
*/

static
void writeSsp(SspContextT * ctxP, UINT16 * txbufP, INT len)
{
    volatile SspRegT * regsP = (SspRegT *)ctxP->regsP;
  
    while (len--)
    {
        // Wait if transmit FIFO is full 
        while((regsP->SSSR & SSP_SSSR_TNF) == 0)
            {;}
        // Write data
        regsP->SSDR = *txbufP++;   
    }
}

/*
*******************************************************************************
*
* FUNCTION:         statusSsp
*
* DESCRIPTION:      This function is used to read the SSP status register.
*
* INPUT PARAMETERS: ctxP    is a pointer to SSP context structure 
*                   rxbufP  is a pointer to the buffer where received data is
*                           going to be placed
*                   len     is a specified number of bytes to read.
*
* RETURNS:          INT an actual number of bytes have been read        
*                   
* GLOBAL EFFECTS:   none.
*                  
* ASSUMPTIONS:      none.
*                  
*******************************************************************************
*/                  
static
INT statusSsp(SspContextT * ctxP)
{
    volatile SspRegT * regsP = (SspRegT *)ctxP->regsP;
    return (regsP->SSSR);
}

/*
*******************************************************************************
*
* FUNCTION:         readSsp        
*
* DESCRIPTION:      This function is used to receive data via SSP in polled mode 
*                   operation
*
* INPUT PARAMETERS: ctxP    is a pointer to SSP context structure 
*                   rxbufP  is a pointer to the buffer where received data is
*                           going to be placed
*                   len     is a specified number of bytes to read.
*
* RETURNS:          INT an actual number of bytes have been read        
*                   
* GLOBAL EFFECTS:   none.
*                  
* ASSUMPTIONS:      none.
*                  
*******************************************************************************
*/                  

static
INT readSsp(SspContextT * ctxP, UINT16 * rxbufP, INT len)
{
    volatile SspRegT * regsP = (SspRegT *)ctxP->regsP;
    INT total = len;

    while (len--)
    {
        // Wait if busy or receive FIFO is empty.
        while ((regsP->SSSR & SSP_SSSR_BSY) | !(regsP->SSSR & SSP_SSSR_RNE));
        
        // Read from FIFO
        *rxbufP++ = regsP->SSDR;
    }
    return total;
}

/*
*******************************************************************************
*
* FUNCTION:         readRawSsp
*

⌨️ 快捷键说明

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