📄 lh79524_ssp_driver.c
字号:
else
{
status = _ERROR;
}
break;
case SSP_TX_WORD:
/* transmit one word using polling mode. arg = word to be
transfered */
/* wait untile transmit fifo is not full */
while((SSP->sr & SSP_SR_TNF) == 0);
SSP->dr = (UNS_16)arg;
break;
case SSP_RX_WORD:
/* SSP receive one word using polling mode. no arg */
/* wait until receive fifo is not empty */
while((SSP->sr & SSP_SR_RNE) == 0);
status = SSP->dr;
break;
case SSP_TX_RX_WORD:
/* SSP transceive one word using polling mode. arg =
word to be trasmitted. Returns the word received. */
/* wait untile transmit fifo is not full */
while((SSP->sr & SSP_SR_TNF) == 0);
SSP->dr = (UNS_16)arg;
/* wait until receive fifo is not empty */
while((SSP->sr & SSP_SR_RNE) == 0);
status = SSP->dr;
break;
case SSP_LOOP_BACK_ENABLE:
/* Enable SSP loop back mode. arg = 1, enable. arg = 0,
disable */
if (arg == 1)
{
/* Enable loop back mode */
SSP->ctrl1 |= SSP_CR1_LBM;
}
else if (arg == 0)
{
/* Disable loop back mode */
SSP->ctrl1 &= ~SSP_CR1_LBM;
}
else
{
status = _ERROR;
}
break;
case SSP_INT_ENABLE:
/* Enable SSP interruption generation, arg =
* SSP_RECEIVE_FIFO_OVERRUN_INT : enable receive fifo overrun int
* SSP_RECEIVE_TIMEOUT ; enable receive time out int
* SSP_TRANSMIT_FIFO_INT : enable transmit fifo interruption
* SSP_RECEIVE_FIFO_INT : enable receive fifo interruption
*/
if (arg == SSP_RECEIVE_FIFO_OVERRUN_INT)
{
SSP->imsc |= SSP_IMSC_RORIM;
}
else if (arg == SSP_RECEIVE_TIMEOUT_INT)
{
SSP->imsc |= SSP_IMSC_RTIM;
}
else if (arg == SSP_TRANSMIT_FIFO_INT)
{
SSP->imsc |= SSP_IMSC_TXIM;
}
else if (arg == SSP_RECEIVE_FIFO_INT)
{
SSP->imsc |= SSP_IMSC_RXIM;
}
else
{
status = _ERROR;
}
break;
case SSP_INT_DISABLE:
/* Disable SSP interruption generation, arg =
* SSP_RECEIVE_FIFO_OVERRUN_INT : disable receive fifo overrun int
* SSP_RECEIVE_TIMEOUT ; disable receive time out
* SSP_TRANSMIT_FIFO_INT : disable transmit fifo interruption
* SSP_RECEIVE_FIFO_INT : disable receive fifo interruption
*/
if (arg == SSP_RECEIVE_FIFO_OVERRUN_INT)
{
SSP->imsc &= ~SSP_IMSC_RORIM;
}
else if (arg == SSP_RECEIVE_TIMEOUT_INT)
{
SSP->imsc &= ~SSP_IMSC_RTIM;
}
else if (arg == SSP_TRANSMIT_FIFO_INT)
{
SSP->imsc &= ~SSP_IMSC_TXIM;
}
else if (arg == SSP_RECEIVE_FIFO_INT)
{
SSP->imsc &= ~SSP_IMSC_RXIM;
}
else
{
status = _ERROR;
}
break;
case SSP_INT_CLEAR:
/* only ssp receive fifo overrun interrupt can be cleared,
no arg */
/* clear SSP receive fifo overrun interrupt */
SSP->icr |= SSP_ICR_RORIC | SSP_ICR_RTIC;
break;
case SSP_DMA_TX_INIT:
/* Set up initial value for SSP transmit using DMA, no arg */
/* make sure DMA clock is on */
RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_DMA_DISABLE;
DMAC->stream1.ctrl = DMAC_CTRL_SOINC | DMAC_CTRL_SOSIZE_2BYTE |
DMAC_CTRL_DESIZE_2BYTE | DMAC_CTRL_ADDR_MODE_WRAP |
DMAC_CTRL_PERIPH_DEST | DMAC_CTRL_SOBURST_4INC;
/* clear any previous SSP DMA complete interrupts */
DMAC->clear = DMAC_EOT0 | DMAC_EOT1;
/* Enable transmit interrupt */
DMAC->mask |= DMAC_EOT1;
/* must generate transmit interrupt request signals to
request DMA */
//ssp_set_enable(SSP_TRANSMIT_FIFO_INT);
SSP->imsc |= SSP_IMSC_TXIM;
/* disable the receiver interrupts */
//ssp_set_disable(SSP_RECEIVE_FIFO_OVERRUN_INT);
SSP->imsc &= ~SSP_IMSC_RORIM;
//ssp_set_disable(SSP_RECEIVE_FIFO_INT);
SSP->imsc &= ~SSP_IMSC_RTIM;
SSP->imsc &= ~SSP_IMSC_RXIM;
/* don't let the receiver or transmitter signal
an interrupt to the VIC */
VIC->intenclear |= _SBF(VIC_SSPI2S, 1);
/* Only allow DMA interrupt */
/* Enable int on end of transfer */
DMAC->mask = DMAC_EOT1;
/* Enable SSP TX working in DMA mode */
SSP->dmacr |= SSP_DMACR_TXDMAE;
break;
case SSP_DMA_RX_INIT:
/* Set up initial value for SSP receive using DMA, no arg */
/* make sure DMA clock is on */
RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_DMA_DISABLE;
DMAC->stream1.ctrl = DMAC_CTRL_SOSIZE_2BYTE |
DMAC_CTRL_DESIZE_2BYTE | DMAC_CTRL_ADDR_MODE_WRAP |
DMAC_CTRL_PERIPH_DEST | DMAC_CTRL_SOBURST_4INC;
DMAC->stream0.ctrl = DMAC_CTRL_DEINC | DMAC_CTRL_SOSIZE_2BYTE |
DMAC_CTRL_DESIZE_2BYTE | DMAC_CTRL_ADDR_MODE_WRAP |
DMAC_CTRL_PERIPH_SOURCE | DMAC_CTRL_SOBURST_4INC;
/*
Chip issue work-around (see errata sheet)
enable receive DMA amd then disable it to prevent
bad initial DMA transfer from receive FIFO.
*/
DMAC->stream0.ctrl |= DMAC_CTRL_ENABLE;
DMAC->stream0.ctrl = DMAC_CTRL_DEINC | DMAC_CTRL_SOSIZE_2BYTE |
DMAC_CTRL_DESIZE_2BYTE | DMAC_CTRL_ADDR_MODE_WRAP |
DMAC_CTRL_PERIPH_SOURCE | DMAC_CTRL_SOBURST_4INC;
/* clear any previous SSP DMA complete interrupts */
DMAC->clear = DMAC_EOT0 | DMAC_EOT1;
/* Enable receive interrupt */
DMAC->mask |= DMAC_EOT0 ;
/* must generate interrupt request signals to request DMA */
//ssp_set_enable(SSP_TRANSMIT_FIFO_INT);
SSP->imsc |= SSP_IMSC_TXIM;
//ssp_set_enable(SSP_RECEIVE_FIFO_INT);
SSP->imsc |= SSP_IMSC_RXIM;
/* disable the receiver overflow interrupt
(it shouldn't happen) */
//ssp_set_disable(SSP_RECEIVE_FIFO_OVERRUN_INT);
SSP->imsc &= ~SSP_IMSC_RTIM;
SSP->imsc &= ~SSP_IMSC_RORIM;
/* set up the SSP DMA receiver timeout */
//bps = ssp_get_speed();
//if (bps == 0)
//{
//status = _ERROR;
//break; /* ssp was not initialized properly */
//}
//bpf = ssp_get_speed();
//if ( (SSP->ctrl0 & SSP_CR0_FRF_NS) == SSP_CR0_FRF_NS)
//bpf += 8; /* the control word is sent first */
/*
timeout in microseconds for a frame at the watermark
is (5 frames in FIFO * 1000000 us/s * bpf bits/frame)
/ (bps bits/s) */
//ssp_set_dma_receive_timeout( (5 * 1000000 * bpf) / bps );
/* don't let the receiver or transmitter signal an
interrupt to the VIC */
//int_command(VIC_SSPRX, SOURCE_INT_DISABLE);
//int_command(VIC_SSPTX, SOURCE_INT_DISABLE);
//int_command(VIC_SSPROR,SOURCE_INT_DISABLE);
//int_command(VIC_SSPINT,SOURCE_INT_DISABLE);
VIC->intenclear |= _SBF(VIC_SSPI2S, 1);
/* don't let the DMA controller signal an interrupt to the VIC */
//int_command(VIC_DMA,SOURCE_INT_DISABLE);
VIC->intenclear |= _SBF(VIC_DMA0, 1);
/* Enable SSP RX working in DMA mode */
SSP->dmacr |= SSP_DMACR_RXDMAE;
break;
case SSP_DMA_TX_RX_INIT:
/* Set up initial value for SSP transceive using DMA, no arg */
/* make sure DMA clock is on */
RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_DMA_DISABLE;
DMAC->stream1.ctrl = DMAC_CTRL_SOINC | DMAC_CTRL_SOSIZE_2BYTE |
DMAC_CTRL_DESIZE_2BYTE | DMAC_CTRL_ADDR_MODE_WRAP |
DMAC_CTRL_PERIPH_DEST | DMAC_CTRL_SOBURST_4INC;
DMAC->stream0.ctrl = DMAC_CTRL_DEINC | DMAC_CTRL_SOSIZE_2BYTE |
DMAC_CTRL_DESIZE_2BYTE | DMAC_CTRL_ADDR_MODE_WRAP |
DMAC_CTRL_PERIPH_SOURCE | DMAC_CTRL_SOBURST_4INC;
/* clear any previous SSP DMA complete interrupts */
DMAC->clear = DMAC_EOT0 | DMAC_EOT1;
/* Enable receive and transmit interrupt */
DMAC->mask |= DMAC_EOT0 | DMAC_EOT1;
/* must generate interrupt request signals to request DMA */
//ssp_set_enable(SSP_TRANSMIT_FIFO_INT);
SSP->imsc |= SSP_IMSC_TXIM;
//ssp_set_enable(SSP_RECEIVE_FIFO_INT);
SSP->imsc |= SSP_IMSC_RXIM;
/* disable the receiver overflow interrupt
(it shouldn't happen) */
//ssp_set_disable(SSP_RECEIVE_FIFO_OVERRUN_INT);
SSP->imsc &= ~SSP_IMSC_RORIM;
SSP->imsc &= ~SSP_IMSC_RTIM;
/* set up the SSP DMA receiver timeout */
//bps = ssp_get_speed();
//if (bps == 0)
//{
//status = _ERROR;
//break; /* ssp was not initialized properly */
//}
//bpf = ssp_get_speed();
//if ( (SSP->ctrl0 & SSP_CR0_FRF_NS) == SSP_CR0_FRF_NS)
//bpf += 8; /* the control word is sent first */
/*
timeout in microseconds for a frame at the watermark
is (5 frames in FIFO * 1000000 us/s * bpf bits/frame)
/ (bps bits/s) */
//ssp_set_dma_receive_timeout( (5 * 1000000 * bpf) / bps );
/* don't let the receiver or transmitter signal an
interrupt to the VIC */
//int_command(VIC_SSPRX, SOURCE_INT_DISABLE);
//int_command(VIC_SSPTX, SOURCE_INT_DISABLE);
//int_command(VIC_SSPROR,SOURCE_INT_DISABLE);
//int_command(VIC_SSPINT,SOURCE_INT_DISABLE);
VIC->intenclear |= _SBF(VIC_SSPI2S, 1);
/* don't let the DMA controller signal an interrupt to the VIC */
//int_command(VIC_DMA,SOURCE_INT_DISABLE);
VIC->intenclear |= _SBF(VIC_DMA1, 1);
VIC->intenclear |= _SBF(VIC_DMA0, 1);
/* Enable SSP RX and TX working in DMA mode */
SSP->dmacr |= SSP_DMACR_TXDMAE;
SSP->dmacr |= SSP_DMACR_RXDMAE;
break;
case SSP_DMA_SET_SOURCE:
/* Set up source address for SSP using DMA, arg = source addr */
/* make sure DMA clock is on */
RCPC->ahbclkctrl &= ~RCPC_AHBCLKCTRL_DMA_DISABLE;
// phys_source = mmu_map_virtual_to_physical(arg);
phys_source = (arg);
DMAC->stream1.sourcelo = (phys_source) & 0xffff;
DMAC->stream1.sourcehi = (phys_source) >> 16;
DMAC->stream1.destlo = ((UNS_32)&(SSP->dr)) & 0xffff;
DMAC->stream1.desthi = ((UNS_32)&(SSP->dr)) >> 16;
break;
case SSP_DMA_SET_DEST:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -