I'm using a S32K344 EVB and trying to setup the DMA to transfer from the LPSPI RX buffer, but not using the PIT-based trigger. I am sending 1 command word to a sensor and receiving back at least 2 words of data, and I want to have these automatically transferred to memory whenever the transaction takes place (not periodically).
My understanding on how to enable DMA transfers from reading the Reference Manual:
I'm assuming the LPSPI Status Register, (RDF bit) is the peripheral trigger to the DMAMUX, and that routes the request to the eDMA Engine, and this is what kicks off the data transfer. Is that correct? Is there any software intervention required, like an ISR needed to clear any flags? Or does it transfer everytime the RDF flag is pulsed?
I verified the SPI is working as expected with a logic analyzer and am able to see the RDR register has data in it from my sensor and the RDF flag set, but I don't see any data in the destination memory location.
I have attached my code, for reference. Please help to point out what I might have missed.
-Alex
解決済! 解決策の投稿を見る。
Hi,
your understanding is correct. the Receive Data Flag (SR[RDF]) is set when the number of words in the receive FIFO is greater than RXWATER. For default RXWATER=0 and your 48bit frame size there should be 2 words in RXFIFO so you should set DMA to read single word per DMA request, there should be 2 DMA requests from LPSPI. You should modify TCD little bit
IP_TCD->TCD0_DLAST_SGA = -8;
// Last destination address adjustment after a major loop
IP_TCD->NBYTES0.TCD0_NBYTES_MLOFFNO = 4;
// 12 bytes per a minor loop
IP_TCD->CITER0.TCD0_CITER_ELINKNO = 2;
IP_TCD->BITER0.TCD0_BITER_ELINKNO = 2;
// 1 major/2 minor loop
You can check within debugger if setting of TCD is really a desired one, then after transfer check if channel interrupt flag is set and DONE bit as well.
Also cache enabled could be a reason you see no data in destination buffer, put buffer in noncacheable area
__attribute__(( aligned(32) )) uint32 RxMasterBuffer[20] __attribute__ ((section (".mcal_bss_no_cacheable")));
BR, Petr
Hi Petr,
Thanks again for the help. I found the issue and I have the DMA working as expected, but I am hoping you can help me understand a little better. Here is the change I made that enabled the DMA to work:
changed IP_DMAMUX_0->CHCFG[0] = 0xAE to IP_DMAMUX_0->CHCFG[3] = 0xAE
I noticed in the "Watch registers" tab that CHCFG0 address is 0x40280003 while CHCFG3 address is 0x40280000. After I noticed this and made the change, I also read in the datasheet the register address offset is the same as reflected above, so this was my fault for not noticing.
So then my questions is why is the address offset not lined up as CHCFG0 = 0, CHCFG1 = 1, etc.; and why is the S32K344_DMAMUX.h also not reflecting this same offset convention?
Thanks, -Alex
Hi,
well, I overlooked that too, but it is stated within the RM, as you wrote. Answer can be simple... It is implemented this way.
A S32K344_DMAMUX.h should follow this. If not, user need to be care in using right register.
BR, Petr
Thanks for the reply, Petr. I will try your suggestions and reply again with the results.
Hi,
your understanding is correct. the Receive Data Flag (SR[RDF]) is set when the number of words in the receive FIFO is greater than RXWATER. For default RXWATER=0 and your 48bit frame size there should be 2 words in RXFIFO so you should set DMA to read single word per DMA request, there should be 2 DMA requests from LPSPI. You should modify TCD little bit
IP_TCD->TCD0_DLAST_SGA = -8;
// Last destination address adjustment after a major loop
IP_TCD->NBYTES0.TCD0_NBYTES_MLOFFNO = 4;
// 12 bytes per a minor loop
IP_TCD->CITER0.TCD0_CITER_ELINKNO = 2;
IP_TCD->BITER0.TCD0_BITER_ELINKNO = 2;
// 1 major/2 minor loop
You can check within debugger if setting of TCD is really a desired one, then after transfer check if channel interrupt flag is set and DONE bit as well.
Also cache enabled could be a reason you see no data in destination buffer, put buffer in noncacheable area
__attribute__(( aligned(32) )) uint32 RxMasterBuffer[20] __attribute__ ((section (".mcal_bss_no_cacheable")));
BR, Petr