Hi Vojtech,
You forgot the screen shot....
Let me tell you what I'm trying to do.
I have 8 channels of audio, let's say each sample is an int_32. They are organize in memory to make signal processing easy:
#define AUDIO_CHANPEROUT 4 ///< i4s format
#define AUDIO_NOUTS 2 ///< 2 TX outputs per SAI
#define AUDIO_NOUTPUTCHANNELS AUDIO_CHANPEROUT * AUDIO_NOUTS
#define AUDIO_OUTPUTBUFSIZE 16 ///< samples per channel for audio output buffer
int32_t audioBuf[AUDIO_NOUTPUTCHANNELS][2][AUDIO_OUTPUTBUFSIZE];
I'm setting each of the two TX outputs to i4s format (2 channels per stream). Tx0 outputs channel 1-4, Tx1 outputs channel 5-8.
Once the program starts, the audio *must* run continuously. This is the usual case with audio (except the case of low power sleeping, we'll ignore that for now).
So the indices for the buffer are, in order:
- output channel 0-7
- pingpong = 0 or 1
- sample number 0-16
So when I have a DSP loop, I process 16 samples of one channel, then go to the next. Most efficient way to do it in general. That would happen in the "halfway there" DMA interrupt, which would also increment (mod 2) the pingpong index.
I let the DMA controller do the hard work. I set the FIFO request in the SSI to 4. So then the DMA will get 4 words in 1 minor loop, which is the 4 channels of one sample for one output. So the minor loop has to skip by 32 samples each time to get to the next channel. Then, it has to skip 4 whole channels to get to the next sample, as those channels are handled by the other Tx output. So that's the adjustment after the minor loop. Then, after the major loop, do another adjustment to reset the address back to the beginning, and chain the DMA to itself. Then the processor never has to get involved once it starts.
So in this case, I believe the DMA settings I want are thus:
DMA0:
Source:
start address: &audioBuf[0][0][0]
transaction size: 32-bits
address adjustment: 128
Destination:
start address: (LDD_DMA_TAddress)(I2S_PDD_GetTxDataChannelRegAddress(I2S0_BASE_PTR,0U))
transaction size: 32-bits
address adjustment: 0
Transfer Settings:
transactions count: 4
request count: 32
After request complete actions:
source address adjustment: -508 (skip back to beginning but one sample ahead 512-4)
After transfer complete actions:
channel linking: enabled, DMA0 (same channel)
source address adjustment: -636 (skip back to beginning 512+128-4)
DMA1:
Source:
start address: &audioBuf[4][0][0]
transaction size: 32-bits
address adjustment: 128
Destination:
start address: (LDD_DMA_TAddress)(I2S_PDD_GetTxDataChannelRegAddress(I2S0_BASE_PTR,1U))
transaction size: 32-bits
address adjustment: 0
Transfer Settings:
transactions count: 4
request count: 32
After request complete actions:
source address adjustment: -508
After transfer complete actions:
channel linking: enabled, DMA1 (same channel)
source address adjustment: -636
... if this makes sense, then you can see why I want to access those greyed out fields.
NOTE: I edited this with updated values thanks to source code in Earl Goodrich's post here: Re: is there any demo code for using I2S?
I implemented this and tested it by:
1. created SSI_LDD and enabled DMA
2. generated PE code
3. disabled generating PE code for the audio SSI_LDD module
4. once disabled, then disable DMA in the SSI_LDD interface and save (to avoid conflicts with below)
5. deleted the DMA source files
6. created two DMAChannel_LDD components (outside of SSI_LDD)
7. renamed them the same name as the deleted DMA components
8. made sure I generate the needed methods
9. generate the PE code of these
10. disable generating the PE code after generating once
11. delete the extra events in Events.c (since the ones I want are in Audio0.c)
12. added the 'halfway' interrupt flag and other bug fixes noted in other of my recent posts
Its running and seems to be working fine. Setting the bus throttle-back to 8 cycles in the two DMA engines seems to have a positive effect overall.
In sum, this setup should be allowed in the component, as it's usual way to do audio.
Best,
Marc