2
\$\begingroup\$

I have been doing some experiments with the STM32F405 and audio and discovered an interesting issue and wonder if anyone else has encountered the following?

I have a stereo codec CS4344 running at 96k using the 12S interface and code similar to audio examples from STM32F4Discovery.

I am also using ADC2 with DMA2 stream2 to sample control voltages from potentiometers etc. I have a running average on the ADC data inside the IRQ generated by the stream transfer complete IRQ and I started seeing glitches in my audio (popping sound) when switching from 48k to 96k.

The audio signal generation code is very short (just a sine wave with LUT) so there is no issue with overhead.

I then experimented by moving the ADC averaging calculations outside the ADC IRQ and just setting a flag and glitches disappeared.

The crux of this is it seems is that just enabling the IRQ for the stream like this:

            NVIC_EnableIRQ(DMA2_Stream2_IRQn);

alone does not set a priority for the interrupt that allows it to be nested. What seems to be happening is when ADC IRQ is being serviced the audio I2S HT and TC IRQs are not able to interrupt the ADC IRQ. Setting the ADC interrupt with priority in the more conventional way seems to fix it.

    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

The DMA priority of High,Medium, Low that is set as part of the DMA config alone does not seem to be enough to permit nested interrupts if using the stream interrupt alone.

My question is how do the priorities of the DMA as set in the DMA_InitStructure interact with the IRQ channel Preemption Priority? What is the significance of the DMA priority of High,Medium, Low ?

\$\endgroup\$
3
\$\begingroup\$

You are confusing DMA priorities with IRQ priorities. The priorities you set with the DMA_InitStructure only deal with setting the priorities inside the DMA controller, i.e. which of two (or more) simultaneous DMA(!) requests gets serviced first. This is completely independent of the interrupts that get triggered at the middle and/or end of a DMA transfer, which get prioritized by the NVIC (along with the other interrupt sources). As you said, you need to set higher (i.e. lower number) IRQ priorities for the DMA interrupts than for the ADC interrupts to make sure that the I2S related DMA interrupts are serviced immediately.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the clarification. I am getting a handle on it now. I am still getting some glitches though even with the ADC IRQ priority set to a lower (2) value than the I2S (0) if I average the samples inside the ADC IRQ. I don't understand this as it should be running as a nested interrupt now. I read that STM32F4 doesn't work well with more than 2 concurrent DMA streams but that seems ludicrous with all the DMA possibilities. \$\endgroup\$ – Bruce Duncan Dec 4 '13 at 22:33
  • \$\begingroup\$ I can only imagine that if the different buffers and variables are located in the same block of SRAM (see page 52 of the Reference Manual), there could be contention for access to that memory block, and that this is handled differently depending on whether the access comes from an ISR, the DMA controller or normal operation. \$\endgroup\$ – fm_andreas Dec 5 '13 at 7:40
3
\$\begingroup\$

Problem solved. I was using config code from the net and it had an interrupt configured for the same SPI port as the I2S which seemed to conflict with the DMA stream interrupt. So lesson I learned is if I2S is enabled on SPI then only the DMA interrupt is needed.

\$\endgroup\$
  • \$\begingroup\$ You can mark your own answer as "accepted", so this question won't appear as an open issue. \$\endgroup\$ – Bence Kaulics Nov 30 '15 at 22:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.