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

📄 lh79524_ssp_driver.c

📁 SHARP_ARM720T_LH79524/5软件开发包_支持TFT_LCD_NAND_FLASH_ETH_USB
💻 C
📖 第 1 页 / 共 4 页
字号:
                /* Set up destination address for SSP using DMA, 
                arg = destination addr */
                /* make sure DMA clock is on */
                RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_DMA_DISABLE;
//                phys_dest = mmu_map_virtual_to_physical(arg);
                phys_dest = (arg);
                DMAC->stream0.sourcelo = ((UNS_32)&(SSP->dr)) & 0xffff;
                DMAC->stream0.sourcehi = ((UNS_32)&(SSP->dr)) >> 16;
                DMAC->stream0.destlo = (phys_dest) & 0xffff;
                DMAC->stream0.desthi = (phys_dest) >> 16;
                break;
                
            case SSP_DMA_SET_COUNT:
                /* Set up number of words for SSP operation using DMA,
                arg = number of words */
                /* make sure DMA clock is on */
                RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_DMA_DISABLE;
                DMAC->stream1.max = arg;
                DMAC->stream0.max = arg;
                break;
                
            case SSP_DMA_TX_INT_HANDLER:
                /* Default transmit interrupt handler to be called by
                SSP DMA transfer interrupt routine, no arg */
                /* disable transmit DMA */ 
                DMAC->stream1.ctrl &= ~DMAC_CTRL_ENABLE;
                /* clear any DMA interrupts signaled by the SSP */
                DMAC->clear = DMAC_EOT0 | DMAC_EOT1;
                break;              
                
            case SSP_DMA_TXRX_INT_HANDLER:
                /* Default receive and transceive interrupt handler 
                to be called by SSP DMA transfer interrupt routine, 
                no arg */
                
                /* Wait until receive time out */
                //while(((SSP->ris & SSP_RIS_RTRIS)) == 0);

                /* disable receive DMA */
                DMAC->stream0.ctrl &= ~DMAC_CTRL_ENABLE;
                /* disable transmit DMA */ 
                DMAC->stream1.ctrl &= ~DMAC_CTRL_ENABLE;
                /* clear any DMA interrupts signaled by the SSP */
                DMAC->clear = DMAC_EOT0 | DMAC_EOT1;
                phys_dest = (DMAC->stream0.decurrlo | 
                            (DMAC->stream0.decurrhi << 16) );
//                destination = (UNS_16 *)mmu_map_physical_to_virtual(phys_dest);
                destination = (UNS_16 *)(phys_dest);
                
                for (tmp = 0; tmp < DMAC->stream0.tcnt; tmp++)
                {
                    /* receive the the remaining words */
                    *destination++ = SSP->dr;
                }
                /* clear the receiver timeout interrupt 
                and prevent further timeouts */
                //SSP->rxto = 0;
                break;              
                
            case SSP_DMA_TX_START:
                /* Start DMA transfer from memory to SSP, SSP_DMA_TX_INIT
                must be called before this, no arg */
                DMAC->stream1.ctrl |= DMAC_CTRL_ENABLE;
                break;
                
            case SSP_DMA_RX_START:
                /* Start DMA transfer from SSP to memory, SSP_DMA_RX_INIT
                must be called before this, no arg */
                /* If there are not enough words to transfer to trigger at least
                *  one SSP receive interrupt, then do the transfer using non-DMA
                *  operations.
                *  Otherwise, set the stream0 control register enable bit to arm
                *  SSP receive DMA.
                *  Set the stream1 control register enable bit to start the DMA
                *  transfer out of the SSP. */
                if (DMAC->stream1.max <= 5)
                {
                    /* DMA won't time out. do the transfer manually */
                    UNS_16 i, * destination;
      
//                    destination = (UNS_16 *)mmu_map_physical_to_virtual
//                        (DMAC->stream0.destlo | (DMAC->stream0.desthi << 16 ));
                    destination = (UNS_16 *)(DMAC->stream0.destlo | (DMAC->stream0.desthi << 16 ));
                        
                    for (i = 0; i< DMAC->stream1.max; i++)
                    {
                        SSP->dr = 0;
                        destination[i] = SSP->dr;
                    }
                }
                else
                {
                    /* enable receive DMA */
                    DMAC->stream0.ctrl |= DMAC_CTRL_ENABLE;
                    /* enable transmit DMA (send zero; transfer starts 
                    immediately) */ 
                    DMAC->stream1.ctrl |= DMAC_CTRL_ENABLE;
                }
                break;
                
            case SSP_DMA_TX_RX_START:
                /*  Start DMA transfer from SSP to memory, SSP_DMA_TX_RX_INIT
                must be called before this, no arg */
                /* If there are not enough words to transfer to trigger at least
                *  one SSP receive interrupt, then do the transfer using non-DMA
                *  operations.
                *  Otherwise, set the stream0 control register enable bit to arm
                *  SSP receive DMA.
                *  Set the stream1 control register enable bit to start the DMA
                *  transfer out of the SSP. */
                tmp = DMAC->stream1.max;
                if (DMAC->stream1.max <= 5)
                {
                    /* DMA won't time out. do the transfer manually */
//                    source = (UNS_16 *)mmu_map_physical_to_virtual
//                        (DMAC->stream1.sourcelo | (DMAC->stream1.sourcehi << 16 ));
                    source = (UNS_16 *)(DMAC->stream1.sourcelo | (DMAC->stream1.sourcehi << 16 ));
//                    destination = (UNS_16 *)mmu_map_physical_to_virtual
//                        (DMAC->stream0.destlo | (DMAC->stream0.desthi << 16 ));
                    destination = (UNS_16 *)(DMAC->stream0.destlo | (DMAC->stream0.desthi << 16 ));
                    
                    while(tmp--)
                    {
                        SSP->dr = *source++;
                        *destination++ = SSP->dr;
                    }
                }
                else
                {
                    /* enable receive DMA */
                    DMAC->stream0.ctrl |= DMAC_CTRL_ENABLE;
                    /* enable transmit DMA (transfer starts immediately) */ 
                    DMAC->stream1.ctrl |= DMAC_CTRL_ENABLE;
                }
                break;
                
            case SSP_GET_STATUS:
                switch (arg)
                {
                    case SSP_GET_SPEED:
                        status = ssp_get_speed();
                        break;
                        
                    case SSP_GET_INT_STATUS:
                        /* Returns SSP interrupt status */
                        tmp = SSP->mis;
                        if ((tmp & SSP_MIS_RORMIS) != 0)
                        {
                            status = SSP_RECEIVE_FIFO_OVERRUN_INT;
                        }
                        else if ((tmp & SSP_MIS_TXMIS) != 0)
                        {
                            status = SSP_TRANSMIT_FIFO_INT;
                        }
                        else if ((tmp & SSP_MIS_RXMIS) != 0)
                        {
                            status = SSP_RECEIVE_FIFO_INT;
                        }
                        else if ((tmp & SSP_ICR_RTIC) != 0)
                        {
                            status = SSP_RECEIVE_TIMEOUT_INT;
                        }
                        else
                        {
                            status = _ERROR;
                        }
                        break;

                    case SSP_GET_BUSY:
                        /* Returns 1 if SSP is busy, 0 for not busy */
                        if ((SSP->sr & SSP_SR_BSY) != 0)
                        {
                            status = 1;
                        }
                        else
                        {
                            status = 0;
                        }
                        break;
                        
                    case SSP_GET_RX_FIFO_FULL:
                        /* Returns 1 if SSP receive fifo is full, 
                        0 for not full */
                        if ((SSP->sr & SSP_SR_RFF) != 0)
                        {
                            status = 1;
                        }
                        else
                        {
                            status = 0;
                        }
                        break;
                        
                    case SSP_GET_RX_FIFO_NOT_EMPTY:
                        /* Returns 1 if SSP receive fifo is not empty, 
                        0 for empty */
                        if ((SSP->sr & SSP_SR_RNE) != 0)
                        {
                            status = 1;
                        }
                        else
                        {
                            status = 0;
                        }
                        break;
                        
                    case SSP_GET_TX_FIFO_NOT_FULL:
                        /* Returns 1 if SSP transmit fifo is not full, 
                        0 for full */
                        if ((SSP->sr & SSP_SR_TNF) != 0)
                        {
                            status = 1;
                        }
                        else
                        {
                            status = 0;
                        }
                        break;
                        
                    case SSP_GET_TX_FIFO_EMPTY:
                        /* Returns 1 if SSP transmit fifo is empty, 
                        0 for not empty */
                        if ((SSP->sr & SSP_SR_TFE) != 0)
                        {
                            status = 1;
                        }
                        else
                        {
                            status = 0;
                        }
                        break;
                        
                    default:
                        /* Unsupported parameter */
                        status = _ERROR;
                        break;
                }
                break;

            default:
                /* Unsupported parameter */
                status = _ERROR;
        }
    }

    return status;
}

/***********************************************************************
 *
 * Function: ssp_read
 *
 * Purpose: SSP read function (stub only)
 *
 * Processing:
 *     Return 0 to the caller.
 *
 * Parameters:
 *     devid:     Pointer to SSP config structure
 *     buffer:    Pointer to data buffer to copy to
 *     max_bytes: Number of bytes to read
 *
 * Outputs: None
 *
 * Returns: Number of bytes actually read (always 0)
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 ssp_read(INT_32 devid,
                void *buffer,
                INT_32 max_bytes)
{
    return 0;
}

/***********************************************************************
 *
 * Function: ssp_write
 *
 * Purpose: SSP write function (stub only)
 *
 * Processing:
 *     Return 0 to the caller.
 *
 * Parameters:
 *     devid: Pointer to SSP config structure
 *     buffer:  Pointer to data buffer to copy from
 *     n_bytes: Number of bytes to write
 *
 * Outputs: None
 *
 * Returns: Number of bytes actually written (always 0)
 *
 * Notes: None
 *
 **********************************************************************/
INT_32 ssp_write(INT_32 devid,
                 void *buffer,
                 INT_32 n_bytes)
{
    return 0;
}

⌨️ 快捷键说明

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