2023-10-04 11:36 PM
Hello,
As mentioned in the title, I am trying to output a simple sinusoidal audio over I2S.
It works only the first time with DMA and IT, but not afterwards.
In blocking mode it works fine. See the code below.
Does somebody maybe know why?? (It doesn't matter how long the HAL_Delay is)
for(uint16_t i = 0; i < 3; i++){
HAL_Delay(1500);
HAL_I2S_Transmit(&hi2s2, (uint16_t*)signal1, nsamples, 150); // get a sound 3 times
//HAL_I2S_Transmit_IT(&hi2s2, (uint16_t*)signal1, nsamples); // sound only once
//HAL_I2S_Transmit_DMA(&hi2s2, (uint16_t*)signal1, nsamples); // sound only once
}
Thank you
Solved! Go to Solution.
2023-10-04 11:41 PM
That's probably caused by your DMA setup, so please show that.
You need CIRCULAR mode and the correct bit width settings (start with WORD (32bit) for all settings), then it should run "forever".
2023-10-04 11:41 PM
That's probably caused by your DMA setup, so please show that.
You need CIRCULAR mode and the correct bit width settings (start with WORD (32bit) for all settings), then it should run "forever".
2023-10-05 12:19 AM - edited 2023-10-05 01:09 AM
Ah, great! I changed the mode to CIRCULAR, and now it is continuously sending a sinusoidal sound with a short pause in between.
1) How can I stop to sending this sound now?
2) And how can I avoid this pause between?
Thank you
2023-10-05 02:12 AM
in Interrupt Mode it only works when I call Transmit two times (as code below), then I can also call later a Transmit.
But if I call Transmit only once, then, later it is not possible to do a Transmit again (I don't have a sound then).
I not understand this?
HAL_I2S_Transmit_IT(&hi2s2, (uint16_t*)signal1, nsamples);
HAL_I2S_Transmit_IT(&hi2s2, (uint16_t*)signal1, nsamples);
2023-10-05 04:20 AM - edited 2023-10-05 04:21 AM
1) How can I stop to sending this sound now?
Check the I2S HAL file, there should be a DMA stop function.
2) And how can I avoid this pause between?
Make sure that:
- this DMA has high priority
- the buffer is big enough
- the buffer is completely filled (maybe the sine values don't fill the buffer completely)
- check use of double buffering (I think HAL still cannot do this, but not sure)
2023-10-05 05:15 AM
Ok thank you for these hints, and do you have any idea about following question?:
In Interrupt Mode it only works when I call Transmit two times (as code below), then I can also call later a Transmit.
But if I call Transmit only once, then, later it is not possible to do a Transmit again (I don't have a sound then).
I not understand this?
HAL_I2S_Transmit_IT(&hi2s2, (uint16_t*)signal1, nsamples); HAL_I2S_Transmit_IT(&hi2s2, (uint16_t*)signal1, nsamples);
2023-10-05 07:41 AM
No idea. I have never used I2S with interrupts, only DMA.
Grab the ref manual and check the HAL and also the ISR functions, maybe you will find it out! Some flag not reset / set maybe?
2023-10-06 12:19 AM - edited 2023-10-06 12:19 AM
ok good, just one question, which buffer do you mean with following?
@LCE wrote:
- the buffer is completely filled (maybe the sine values don't fill the buffer completely)
2023-10-06 02:50 AM - edited 2023-10-06 02:50 AM
Example:
You have a buffer of length 1024.
You calculate one period of a sine wave with frequency fsine = 100 Hz at sampling rate fr = 100 kHz, so one sine period consists of 1000 samples
You have now 1000 samples in your buffer, the remaining buffer is still zero, but you tell the DMA that the buffer has a length of 1024, so you'll have silence for 24 of 1024 samples.
But not if you tell the DMA that the buffer length is only 1000.
2023-10-12 01:33 AM
Ok thank you for the explanation, but I cannot see where I tell different buffer lengths to the system, see screenshot below of my HAL function: