Potential DMA IRQ problem.

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
Anubirux
Posts: 39
Joined: Sat Apr 21, 2012 2:28 pm

Potential DMA IRQ problem.

Post by Anubirux »

I've run into something disturbing in DMA driver. STM32F1 XL and HD devices have shared DMA2 4th and 5th channel. At dmaStreamRelease there is no check whether when disabling 4th channel, 5th is allocated, or opposite.

Here you have fix proposal (2.6.x):

Code: Select all

void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {

  chDbgCheck(dmastp != NULL, "dmaStreamRelease");

  /* Check if the streams is not taken.*/
  chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
              "dmaStreamRelease(), #1", "not allocated");


  /* Marks the stream as not allocated.*/
  dma_streams_mask &= ~(1 << dmastp->selfindex);

  /* Disables the associated IRQ vector.*/
#if !(STM32_HAS_DMA2 && !defined(STM32F10X_CL)) || defined(__DOXYGEN__)
  nvicDisableVector(dmastp->vector);
#else
  /* Check unless it is 10 or 11 stream. If yes, make additional check before
     disabling IRQ.*/
  if (dmastp->selfindex < 10) {
    nvicDisableVector(dmastp->vector);
  }
  else {
    if (dma_streams_mask & (3 << 10) == 0)
      nvicDisableVector(dmastp->vector);
  }
#endif/* STM32_HAS_DMA2 && !STM32F10X_CL */

  /* Shutting down clocks that are no more required, if any.*/
  if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
    rccDisableDMA1(FALSE);
#if STM32_HAS_DMA2
  if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
    rccDisableDMA2(FALSE);
#endif
}
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Potential DMA IRQ problem.

Post by Giovanni »

Hi,

Thanks, fixed as bug #510.

Giovanni
Anubirux
Posts: 39
Joined: Sat Apr 21, 2012 2:28 pm

Re: Potential DMA IRQ problem.

Post by Anubirux »

Hello,

small misunderstanding ;)

This line:

Code: Select all

 /* Marks the stream as not allocated.*/
dma_streams_mask &= ~(1 << dmastp->selfindex);

has to be before disabling IRQ. Its because check whether 4th and 5th channel is free will always return false:

Code: Select all

    if (dma_streams_mask & (3 << 10) == 0)
      nvicDisableVector(dmastp->vector);
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Potential DMA IRQ problem.

Post by Giovanni »

Oops, missed that, fixed now.

Giovanni
Post Reply