LPC, configured as master, is communicating using DMA and SPI to a peripheral.
Master passes a command to the slave and the slave returns some data.
I use linked list descriptors for the whole communication.
If i want to send a second command from the master, the peripheral requires a SSEL signal.
Using DMA (with linked list) and setting the peripheral registers for a new SSEL signal seems to not work
(Remark: Using DMA (with linked list) and setting the peripheral registers for "end of transfer" bit does work)
Are there any restrictions regarding controlling the SSEL signal via linked list in a DMA transfer.
Are there any other solutions to control the SSEL signal?
Hi Praveenth Pra,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hey jeremyzhou,
Thanks for the quick response.
These are the relevant part for the SPI and DMA
LPC_SPI1->TXCTRL=(((SPIM_XFER_OPTION_SIZE(8) |SPIM_XFER_OPTION_EOT) <<
16) | SPI_TXDATCTL_DEASSERT_ALL) & ~SPI_TXDATCTL_EOT;
Chip_SPIM_AssertSSEL(LPC_SPI1, 0);
//Linked List
//Command for the slave
DMA_CHDESC_T dmaSPISTxDescArray[3] __attribute__ ((aligned(16)));
DMA_CHDESC_T dmaSPISRxDescArray[3] __attribute__ ((aligned(16)));
uint8_t command[4]={0x03,0x03,0x03,0x03};
dmaSPISTxDescArray[0].source = DMA_ADDR(command) + 4-1;
dmaSPISTxDescArray[0].dest = DMA_ADDR(&LPC_SPI1->TXDAT);
dmaSPISTxDescArray[0].next = DMA_ADDR(&dmaSPISTxDescArray[1]);
dmaSPISTxDescArray[0].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG |
DMA_XFERCFG_RELOAD|
DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 |
DMA_XFERCFG_DSTINC_0 | DMA_XFERCFG_XFERCOUNT(4);
dmaSPISRxDescArray[0].source = DMA_ADDR(&LPC_SPI1->RXDAT);
dmaSPISRxDescArray[0].dest = DMA_ADDR(command) + 4-1;
dmaSPISRxDescArray[0].next = DMA_ADDR(&dmaSPISRxDescArray[1]);
dmaSPISRxDescArray[0].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG |
DMA_XFERCFG_RELOAD|
DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_DSTINC_1 |
DMA_XFERCFG_SRCINC_0 | DMA_XFERCFG_XFERCOUNT(4);
uint32_t deassertSSel = LPC_SPI1->TXCTRL | SPI_TXDATCTL_DEASSERTNUM_SSEL(0);
dmaSPISTxDescArray[1].source = DMA_ADDR(&deassertSSel);
dmaSPISTxDescArray[1].dest = DMA_ADDR(&LPC_SPI1->TXDATCTL);
dmaSPISTxDescArray[1].next = DMA_ADDR(&dmaSPISTxDescArray[2]);
dmaSPISTxDescArray[1].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG |
DMA_XFERCFG_RELOAD|
DMA_XFERCFG_WIDTH_32 | DMA_XFERCFG_SRCINC_0 |
DMA_XFERCFG_DSTINC_0 |
DMA_XFERCFG_XFERCOUNT(1);
dmaSPISRxDescArray[1].source = DMA_ADDR(&LPC_SPI1->TXDATCTL);
dmaSPISRxDescArray[1].dest = DMA_ADDR(&deassertSSel);
dmaSPISRxDescArray[1].next = DMA_ADDR(&dmaSPISRxDescArray[2]);
dmaSPISRxDescArray[1].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG | //DMA_XFERCFG_SETINTA |
DMA_XFERCFG_RELOAD|
DMA_XFERCFG_WIDTH_32| DMA_XFERCFG_DSTINC_0 |
DMA_XFERCFG_SRCINC_0 |
DMA_XFERCFG_XFERCOUNT(1);
uint32_t assertSSEL = (((SPIM_XFER_OPTION_SIZE(8) |SPIM_XFER_OPTION_EOT) <<
16) | SPI_TXDATCTL_DEASSERT_ALL) & ~SPI_TXDATCTL_EOT;
assertSSEL = assertSSEL & (SPI_TXDATCTL_CTRLMASK & ~SPI_TXDATCTL_DEASSERTNUM_SSEL(0));
dmaSPISTxDescArray[2].source = DMA_ADDR(&assertSSEL);
dmaSPISTxDescArray[2].dest = DMA_ADDR(&LPC_SPI1->TXCTRL);
dmaSPISTxDescArray[2].next = DMA_ADDR(&dmaSPISTxDescArray[3]);
dmaSPISTxDescArray[2].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG |
DMA_XFERCFG_RELOAD|
DMA_XFERCFG_WIDTH_32 | DMA_XFERCFG_SRCINC_0 |
DMA_XFERCFG_DSTINC_0 |
DMA_XFERCFG_XFERCOUNT(1);
dmaSPISRxDescArray[2].source = DMA_ADDR(&LPC_SPI1->TXCTRL);
dmaSPISRxDescArray[2].dest = DMA_ADDR(&assertSSEL);
dmaSPISRxDescArray[2].next = DMA_ADDR(&dmaSPISRxDescArray[3]);
dmaSPISRxDescArray[2].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG |
DMA_XFERCFG_RELOAD|
DMA_XFERCFG_WIDTH_32| DMA_XFERCFG_DSTINC_0 |
DMA_XFERCFG_SRCINC_0 |
DMA_XFERCFG_XFERCOUNT(1);
dmaSPISTxDescArray[3].source = DMA_ADDR(command) + 4-1;
dmaSPISTxDescArray[3].dest = DMA_ADDR(&LPC_SPI1->TXDAT);
dmaSPISTxDescArray[3].next = 0;
dmaSPISTxDescArray[3].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG |
DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_SRCINC_1 |
DMA_XFERCFG_DSTINC_0 | DMA_XFERCFG_XFERCOUNT(4);
dmaSPISRxDescArray[countOfDescriptors+1].source = DMA_ADDR(&LPC_SPI1->RXDAT);
dmaSPISRxDescArray[countOfDescriptors+1].dest = DMA_ADDR(command) + 4-1;
dmaSPISRxDescArray[countOfDescriptors+1].next = 0;
dmaSPISRxDescArray[countOfDescriptors+1].xfercfg = DMA_XFERCFG_CFGVALID |
DMA_XFERCFG_SWTRIG | DMA_XFERCFG_SETINTA |
DMA_XFERCFG_WIDTH_8 | DMA_XFERCFG_DSTINC_1 |
DMA_XFERCFG_SRCINC_0 | DMA_XFERCFG_XFERCOUNT(4);
dmaClearChannel(APP_SPI_DMA_TXCH);
dmaClearChannel(APP_SPI_DMA_RXCH);
Chip_SPI_FlushFifos(LPC_SPI1);
/* DMA interrupt */
NVIC_EnableIRQ(DMA_IRQn);
while (!Chip_DMA_SetupTranChannel(LPC_DMA, APP_SPI_DMA_RXCH, &dmaSPISRxDescArray[0]));
Chip_DMA_SetupChannelTransfer(LPC_DMA, APP_SPI_DMA_RXCH, dmaSPISRxDescArray[0].xfercfg);
Chip_DMA_EnableChannel(LPC_DMA, APP_SPI_DMA_RXCH);
Chip_DMA_SetValidChannel(LPC_DMA, APP_SPI_DMA_RXCH);
while (!Chip_DMA_SetupTranChannel(LPC_DMA, APP_SPI_DMA_TXCH, &dmaSPISTxDescArray[0]));
Chip_DMA_SetupChannelTransfer(LPC_DMA, APP_SPI_DMA_TXCH, dmaSPISTxDescArray[0].xfercfg);
Chip_DMA_EnableChannel(LPC_DMA, APP_SPI_DMA_TXCH);
Chip_DMA_SetValidChannel(LPC_DMA, APP_SPI_DMA_TXCH);
I saw that modifiying the registers for asserting the chip select does not have an impact, unless the SPI is disabled and enabled again, but this "destroys" the connection to the DMA
Thanks for your reply.
I still have one point that need you to clarify.
In my opinion, the SSEL will keep active automatically before the end-of-transfer.
I also didn't find the kind of operation to set the SSEL signal active in the periph_spis_dma demo in the LPCOpen libarary.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------