Example for SSP1/GPDMA transfer at Cortex-M3 (LPC1787)
-
23-12-2019 - |
Question
I try to utilize the GPDMA controller to access the SSP1 channel. Using the CMSIS library this should be comprehensive. But I can't see anything at the SSP1 output.
As a first example I want to send one byte.
uint8_t buffer[20] = { 0x9F };
int main(void)
{
// ... using PINSEL_ConfigPin to configure the SSP1 pins...
// configure SSP
SSP_CFG_Type ssp_config;
ssp_config.Databit = SSP_DATABIT_8;
ssp_config.CPHA = SSP_CPHA_SECOND;
ssp_config.CPOL = SSP_CPOL_LO;
ssp_config.Mode = SSP_MASTER_MODE;
ssp_config.FrameFormat = SSP_FRAME_SPI;
ssp_config.ClockRate = 4500000;
SSP_Init(LPC_SSP1, &ssp_config);
SSP_Cmd(LPC_SSP1, ENABLE);
// configure GPDMA
GPDMA_Channel_CFG_Type dma_config;
dma_config.ChannelNum = GPDMA_CONN_SSP1_Tx;
dma_config.TransferSize = 1; // <-- (A)
dma_config.TransferWidth = 0; // M2M only
dma_config.SrcMemAddr = (uint32_t)&buffer[0];
dma_config.DstMemAddr = 0;
dma_config.TransferType = GPDMA_TRANSFERTYPE_M2P;
dma_config.SrcConn = 0;
dma_config.DstConn = GPDMA_CONN_SSP1_Tx;
dma_config.DMALLI = 0;
Status status = GPDMA_Setup(&dma_config);
// (B) this was just a try
LPC_SC->DMAREQSEL |= (1 << dma_config.DstConn);
// now start DMA
GPDMA_ChannelCmd(4, ENABLE);
}
Annotations: (A) I varied the size: 0, 1, 20, several value nothing changes (B) The CMSIS implementation always resets the bits in the DMAREQSEL register. Since I think the must be set, I added this line. But the result doesn't change.
When I use the SSP polling function that directly reads/writes the LPC_SSP1 registers I can see the transfer at the logic analyzer. But nothing happens when the GPDMA is used. What's wrong with the approach?
Is there a working example out there?
Solution
The setup was incomplete. While the DMA is ready to transfer the SSP interface must enable the DMA access.
This line before the end of the function makes it work:
SSP_DMACmd(LPC_SSP1, SSP_DMA_TX, ENABLE);