📄 lh79524_ssp_driver.c
字号:
/* 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 + -