Showing results for 
Search instead for 
Did you mean: 

I2S DMA data width question. Word vs half word.

Associate III

So I got i2s working great on a stm32f4 based on this video

which has DMA set to circular, half word. 
and we start the i2s with 
HAL_I2SEx_TransmitReceive_DMA (&hi2s2, txBuf, rxBuf, 4); 4 being the "size" or amount of 16 bit messages

We do the half callback and the complete callback and both do this

//restore signed 24 bit sample from 16-bit buffers
int lSample = (int) (rxBuf[0]<<16)|rxBuf[1];
int rSample = (int) (rxBuf[2]<<16)|rxBuf[3];


//restore to buffer
txBuf[0] = (lSample>>16)&0xFFFF;
txBuf[1] = lSample&0xFFFF;
txBuf[2] = (rSample>>16)&0xFFFF;
txBuf[3] = rSample&0xFFFF;


This all works great on f4 but the problem is when I switch to H7. 
I can only get data to be populated into the rx if I have the DMA set to "Word" instead of half word. 

So my question is do I need to change the size of the 2SEx_TransmitReceive?

Do I still need to do this to get the data? 

//restore signed 24 bit sample from 16-bit buffers

int lSample = (int) (rxBuf[0]<<16)|rxBuf[1];

int rSample = (int) (rxBuf[2]<<16)|rxBuf[3];


I'm just a little confused on what I need to do to make it work correctly. 

Principal III

You dont want to try, what i recommended , so maybe good, you read about the DMA first :

+ especially this:


And about audio processing:


If you feel a post has answered your question, please click "Accept as Solution".

I don't know what you mean by "don't want to try what you recommended"? 

In my previous post you thought I was doing too small of buffers but I don't want to do block processing, I want to process each sample in real time with as little latency as possible as this is for a audio product so doing bigger buffers does not make sense for my application? 

I've read through the DMA data sheet and I'm still not sure how to configure this properly. I can get the audio working but I'm just not sure its entirely configured right.

The DMA only works for "word" transfer so I'm trying to make sure I'm using the start function correctly and then I'm processing the incoming data correctly into a single value.  

1. About the block size: I tried to show the "usual" way when using the circular dma, with some "useful" block size.

But if you intentionally want only one sample, to get lowest possible latency - ok, that is a reason for a single-sample "block". 🙂

Just it makes the dma almost useless , to transfer 1 sample and then let it generate the INT ; you could also just use the INT from the I2S and fetch the sample from the I2S receiver with the cpu and do the processing then - more simple and clear. ( The time needed to go to the INT is same, so at first no sense to use the DMA; but there could (!) be a gain of some cpu wait states, if cpu -> I2S data access needs more cpu wait states than RAM access, because the I2S is on AHB (120MHz) bus. But this is not so easy to test, so maybe ok to use the DMA - even only moving one sample. )

2. About the data size: You transfer 24b data -> 32b word is received/stored (because this is a 32 bit cpu, not a DSP with 24 bit data paths for audio ), so just handle and store it as 32b word, not divide in two 16b parts and put these together then again; also just to do it more simple ( and faster ! ). But maybe you have also some reason to intentionally use 16b parts, you just didnt tell me (same as the "why only one sample" thing) - is there a reason ?

If you feel a post has answered your question, please click "Accept as Solution".

Lets just focus the question. 

This starts the DMA, size was set to 4 for half word transfer, should it still be 4 for word transfer. That's all I'm trying to find out and how it affects the half and complete functions. 

HAL_I2SEx_TransmitReceive_DMA (&hi2s2, txBuf, rxBuf, 4);


from the function:

@PAram Size number of data sample to be sent:

* @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S

* configuration phase, the Size parameter means the number of 16-bit data length

* in the transaction and when a 24-bit data frame or a 32-bit data frame is selected

* the Size parameter means the number of 16-bit data length.


This should mean that the DMA will trigger every 4 16-bit transfers?