/* Optimized Peripheral Source and Destination transfer width (18xx,43xx) */ static const uint8_t GPDMA_LUTPerWid[] = { ... |
// fill in the real LLI, this also calculates the correct control word Chip_GPDMA_PrepareDescriptor(LPC_GPDMA,&daclli, (uint32_t)dacfield, GPDMA_CONN_DAC, 1024, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &daclli); // create a temporary LLI for the API call, this can be discarded after the call templli.ctrl=daclli.ctrl; templli.lli=(uint32_t)&daclli; templli.src=daclli.src; templli.dst=GPDMA_CONN_DAC; // now arm the channel for transfers , the chain starts with the real LLI Chip_GPDMA_SGTransfer(LPC_GPDMA, dmaChannelNum, &templli, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA); |
This is a very interesting read indeed! I am stuck with a similar problem with linked lists, and I can't seem to get it up and running. What I am trying to accomplish is to output a frame buffer to a display through the SSP. The frame buffer size is too large to be output through one DMA transfer, which is why I am trying to accomplish it through 3 transfers linked together.
As far as I understand from your explanation of the double look up bug and from my own poking around LPCOpen, it should be necessary to create the temporary list for the first descriptor - the one actually fed to Chip_GPDMA_SGTransfer, the following descriptors should work fine, after initialization with Chip_GPDMA_PrepareDescriptor?
After I have created a temp descriptor my code no longer crashes, however, only the first transfer is completed (1/3) of the display is drawn. It seems that the subsequent lists are never executed, also the DMA Interrupt routine is never called (if I set the lli of descriptor_1 to 0, it is called).
I would be very grateful, if someone could shed some light on what it is, that I am not understanding/have goofed up! My code is as follows:
DMA_TransferDescriptor_t descriptor_1;
DMA_TransferDescriptor_t descriptor_2;
DMA_TransferDescriptor_t descriptor_3;
DMA_TransferDescriptor_t temp_descriptor_1;
Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &descriptor_1, (uint32_t)&(display_config->fb[0]), display_config->dma_connection, FB_SIZE/3, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &descriptor_1);
Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &descriptor_2, (uint32_t)&(display_config->fb[FB_SIZE/3]), display_config->dma_connection, FB_SIZE/3, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &descriptor_3);
Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &descriptor_3, (uint32_t)&(display_config->fb[FB_SIZE/3 * 2]), display_config->dma_connection, FB_SIZE/3, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, 0);temp_descriptor_1.ctrl = descriptor_1.ctrl;
temp_descriptor_1.lli = (uint32_t)&descriptor_2;
temp_descriptor_1.src = descriptor_1.src;
temp_descriptor_1.dst = display_config->dma_connection;Chip_GPDMA_SGTransfer(LPC_GPDMA, display_config->dma_channel, &temp_descriptor_1, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA);
Best regards,
Denis
This is a very, very helpful post. Please LPCXpresso support consider making a FAQ on this or even take care of this in the upcoming realese of the LPCOpen!
Many thanks to mch0 for all his posts about the LPC4370, they are helping me a lot with my thesis.
Cheers,
Andrea