I2S DMA not running on SAME51 when TXCTRL.bit.DMA = 1 - Page 1
Forum section: electronics / general

author: Chicopy
author_rank: Newbie
timestamp: October 31, 2024, 07:27:06 pm
content: Hi,I have troubles with ATSAME51 I2S (not) running DMA transfers.I was able to configure I2S & DMA to transmit data to stereo Codec corectly when was TXCTRL.bit.DMA = 0;i.e. single DMA channel is used to transmit data of both audio channels, organized samp_Left, samp_Right, samp_Left, samp_Right,...Problem starts since I wanted to set TXCTRL.bit.DMA = 1; // DMA=1: even-numbered and odd-numbered slots use separate DMA channelsI have configuredDMA channel to make 256 transfers of data from Left-audio-channel-buffer to I2S->TXDATA.reg, andDMA channel to make 256 transfers of data from Right-audio-channel-buffer to I2S->TXDATA.reg.According to datasheet DS60001507E / page 1900, 51.6.8.1 DMA Operation, there must be used 2 triggers for Transmitter,one for "even" and second for "odd" slot.// Table 51-3. I2C DMA Request Generation// SERCTRLm.DMA Mode Slot Parity DMA Request Trigger// -------------------------------------------------------------------// 0 Receiver all I2S_DMAC_ID_RX_m// Transmitter all I2S_DMAC_ID_TX_m// ------------------------------------------------------------------- we have SERCTRLm.DMA=1// 1 Receiver even I2S_DMAC_ID_RX_m// odd I2S_DMAC_ID_TX_m// Transmitter even I2S_DMAC_ID_TX_m <0x4E=> I2S Tx 0 Trigger// odd I2S_DMAC_ID_RX_m <0x4C=> I2S Rx 0 Trigger// -------------------------------------------------------------------I used DMA channel with trigger <0x4E=> I2S Tx 0 Trigger, and channel with trigger <0x4C=> I2S Rx 0 Trigger.As it didn't make any transfers (constantly 0000... on SDO line) I also tried to swap them, and also many other combinations of triggers:// <0x4C=> I2S Rx 0 Trigger// <0x4D=> I2S Rx 1 Trigger// <0x4E=> I2S Tx 0 Trigger// <0x4F=> I2S Tx 1 TriggerIs there anybody who managed to use 2 separate DMA channels, each for one slot (audio-channel) ?(i.e. that uses TXCTRL.bit.DMA = 1)Example of source code that works would help me a lot.Mainly would help me to know:- which 2 triggers are supposed to be used- whether both TXCTRL.bit.DMA = 1; and also RXCTRL.bit.DMA = 1; must be set- whether also RX-Serializer must be enabled (because is needed trigger I2S_DMAC_ID_RX_m)- whether for RX-Serializer must be used Clock Unit 1I think I have already spent few weeks on it and tried everything (all 4 lines above, all combinations of triggers), but nothing works.Thanks for any tips or code.

author: ataradov
author_rank: Super Contributor
timestamp: October 31, 2024, 09:43:07 pm
content: I have not used and have not seen anyone use DMA=1. It is possible that there is some hardware issue or configuration trickery.I don't even know how it is supposed to work. Those requests make no sense unless in separate channel mode you can only do RX or TX, but not both.In any case, I would double check if it is DMA is not being triggered or something goes wrong after that. Does DMA generate any transfer complete interrupts? Any changes to the programmed counts?

author: Chicopy
author_rank: Newbie
timestamp: November 01, 2024, 07:41:38 am
content: I am actually porting to E51 my older project that successfully used DMA=1 from D21.On D21 the DMA=1 thing worked as described in datasheet;Only TX-serializer was enabled, 2 DMA channels used, channel sending data for Left-channel, and channel sending 0 to Right-channel (not used).Now on the E51 I am watching I2S bus with logic analyzer, for DMA channel is enabled interrupt TCMPL,interrupt handler contains counter of "transfer complete" interrupts (still 0, even after 1s running).Transmissions are (not) started viaI2S->CTRLA.reg = 0x3E; // RXEN=1, TXEN=1, CKEN1=1, CKEN0=1, ENABLE=1i.e. both serializers should be running;1s after start I print most of I2S and DMA registers and wb_descriptors:DMA diff 1s = 0 // this is the counter of DMA channel "transfer complete"I2S Registers:CTRLA 3ECLKCTRL0 030F4087CLKCTRL1 030F4087INTENSET 0000INTFLAG 2211SYNCBUSY 0000TXCTRL 02FC0080RXCTRL 00FC00A0TXDATA 00000000RXDATA 00000000DMA Registers:CTRL 0F02CRCCTRL 0000CRCDATAIN 00000000CRCCHKSUM 00000000CRCSTATUS 00DBGCTRL 00SWTRIGCTRL 00000000PRICTRL0 40404040INTPEND 0000INTSTATUS 00000000BUSYCH 00000000PENDCH 00000000ACTIVE 00FD0100BASEADDR 200000F0WRBADDR 200002F0.CHCTRLA 00204C02.CHCTRLB 00.CHPRILVL 00.CHEVCTRL 00.CHINTENCLR 02.CHINTENSET 02.CHINTFLAG 00.CHSTATUS 00.CHCTRLA 00204E02.CHCTRLB 00.CHPRILVL 00.CHEVCTRL 00.CHINTENCLR 00.CHINTENSET 00.CHINTFLAG 00.CHSTATUS 00wb_descriptor BTCTRL_1609 BTCNT_0100SRCADDR_20002344 DSTADDR_43002830 DESCADDR_200004F0wb_descriptor BTCTRL_1201 BTCNT_0100SRCADDR_20000524 DSTADDR_43002830 DESCADDR_20000100I found that if a 10x reading of I2S->RXDATA.reg (+delays 10ms) is added after the 1s testing, then it generates transmissions of 10 words from buffer.Now I think that might be necessary to configure & enable 2 more DMA channels to read from I2S->RXDATA.reg ,using the same triggers like 2 existing DMA channels that make writes to I2S->TXDATA.reg .I.e. maybe is not possible to do only transmissions to stereo Codec without runnig also dummy reception side. I will try.

author: Chicopy
author_rank: Newbie
timestamp: November 03, 2024, 09:38:59 am
content: talking to myself, hoping somebody could join..attached is code (not very clean, sorry) that uses bit DMA=1, only in TXCTRL, not in RXCTRL;used are 4 DMA channels, {0} and  for TX side,  and  for RX side.The channels  have to run, despite I didn't want to implement reading from Codec;but it seems to have to run, probably because trigger <0x4C=> I2S Rx 0 Trigger is needed.Currently the DMA transfers are running and content of one buffer is transmitted to odd slot, and content of second buffer is transmitted to even slot.Unfortunately it doesn't run correctly.- data from DMA channel  are correct (data in buffer are 32b, some flags in 16 MSBs + counter in 16 LSBs, samples are incremented +1, correct)- data from DMA channel {0} are NOT correct (samples are incremented +2 !)- I don't check channels , am not interested on RX side yetDMA channels {0} and  are configured the same way, no idea why {0} skips every second sample while  runs correctly:...descriptor.BTCTRL.bit.BLOCKACT = 0x1; // No action at last block, channel disable + block interruptdescriptor.BTCTRL.bit.BEATSIZE = 0x2; // 2 = 32-bit bus transfer, needed for I2S !descriptor.BTCTRL.bit.SRCINC = 0x1; // Source increment is enableddescriptor.BTCTRL.bit.DSTINC = 0x0; // Destination increment disableddescriptor.BTCTRL.bit.STEPSEL = 0x1; // Step applies to Sourcedescriptor.BTCTRL.bit.STEPSIZE = 0x0; // Step size is X1Any tips ?