STM32F4 DMA Peripheral-to-Memory: Memory Corruption

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

Moderators: barthess, RoccoMarco

User avatar
Posts: 60
Joined: Fri Apr 17, 2015 5:10 pm
Has thanked: 4 times
Been thanked: 3 times

Re: STM32F4 DMA Peripheral-to-Memory: Memory Corruption

Postby Skadi » Tue Jan 29, 2019 2:45 pm

Hi Bob,

thank you for your reply.

FXCoder wrote:Hi,
To use the timer purely as a DMA trigger there is no need to involve Slave Mode.
You don't care about the timer value in such a use case. Just the trigger event.
So just leave SMCR reset.
Capture Input mode will produce a CC event at the edge transition(s) of the timer trigger input (according to how the edge mode is set of course).
Your existing TIM1 settings look OK apart from setting SMCR.

According to your suggestion I commented the corresponding line out:

Code: Select all

 //TIM1->SMCR |= 0x0064;

BTW to have ChibiOS enable the DMA for you (in the case there is no other peripheral set that uses DMA) add -DSTM32_DMA_REQUIRED to the UDEFS section of your makefile.

I alos added the appropriate line in the makefile.

Code: Select all


Probably good to add some error checking in the code.
e.g. check the result of dmaStreamAllocate()

I also ckecked the DMA allocation by

Code: Select all

 alloc_err = dmaStreamAllocate(STM32_DMA2_STREAM2, 0, NULL, NULL);

     if (alloc_err == true) {
       palTogglePad(GPIOB, 10); // LED toggled if error occures

Everything looks fine so far, no allocation problems occure.

The only statement I'm not sure about is
The define of STM32_DMA2_STREAM2 isn't shown in the code snippets but I assume it is...
#define STM32_DMA2_STREAM2 STM32_DMA_STREAM_ID(2, 2)

IMHO the STM32_DMA2_STREAM2 is already defined in the stm32_dma.h file:

Code: Select all

 * @name    DMA streams identifiers
 * @{
 * @brief   Returns a pointer to a stm32_dma_stream_t structure.
 * @param[in] id        the stream numeric identifier
 * @return              A pointer to the stm32_dma_stream_t constant structure
 *                      associated to the DMA stream.
#define STM32_DMA_STREAM(id)        (&_stm32_dma_streams[id])

#define STM32_DMA1_STREAM0          STM32_DMA_STREAM(0)
#define STM32_DMA1_STREAM1          STM32_DMA_STREAM(1)
#define STM32_DMA1_STREAM2          STM32_DMA_STREAM(2)
#define STM32_DMA1_STREAM3          STM32_DMA_STREAM(3)
#define STM32_DMA1_STREAM4          STM32_DMA_STREAM(4)
#define STM32_DMA1_STREAM5          STM32_DMA_STREAM(5)
#define STM32_DMA1_STREAM6          STM32_DMA_STREAM(6)
#define STM32_DMA1_STREAM7          STM32_DMA_STREAM(7)
#define STM32_DMA2_STREAM0          STM32_DMA_STREAM(8)
#define STM32_DMA2_STREAM1          STM32_DMA_STREAM(9)
#define STM32_DMA2_STREAM2          STM32_DMA_STREAM(10)
#define STM32_DMA2_STREAM3          STM32_DMA_STREAM(11)
#define STM32_DMA2_STREAM4          STM32_DMA_STREAM(12)
#define STM32_DMA2_STREAM5          STM32_DMA_STREAM(13)
#define STM32_DMA2_STREAM6          STM32_DMA_STREAM(14)
#define STM32_DMA2_STREAM7          STM32_DMA_STREAM(15)
/** @} */

I have implemented everything (expect the last mentioned point), but I still get the wrong result, by means of an arbitrary data fetch in.

I think i now realized the problem. By having a look on the attached picture, it is obvious

Image Link

The triggering is correct. As indicated at the clock signal (CLK) the data is fetched in at a falling edge, the problem is I do not know which ADC channel is currently fetched out (CH1 or CH2). At my previous design there was an additional word clock WCK signal. This clock would be easy to create by a frequency divider f_WCK = f_CLK/2.

I will try to do this by an additional IC, as the frequency is not too high (f_CLK = 1.5 MHz). What would be the best / most reliable way to start the DMA by this additional input signal.


User avatar
Posts: 257
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 104 times
Been thanked: 80 times

Re: STM32F4 DMA Peripheral-to-Memory: Memory Corruption

Postby FXCoder » Tue Jan 29, 2019 11:18 pm

Your DMA reference is good.
My mistake.
The full macro I was thinking of should have been...

Regarding a way to sync DMA start...
One way would be to use a pal callback (e.g. on leading edge) from the word sync pulse on a GPIO line.
That call back would enable the DMA and start the timer for capture.

Roughly like this...

Code: Select all

    /* Setup the DMA controller. */
    /* Setup word sync GPIO. */
    palSetLineMode(word_sync_gpio_line, PAL_MODE_INPUT_PULLDOWN);
    palSetLineCallback(word_sync_gpio_line, (palcallback_t)start_capture, NULL);

    /* Set callback for sync detection. */
    palEnableLineEvent(word_sync_gpio_line, PAL_EVENT_MODE_RISING_EDGE);
    /* Wait for capture (or timeout). */

Then in the callback...

Code: Select all

void start_capture(void *arg) {
  /* Disable event now capture has started. */
  /* Enable the DMA controller. */
  /* Setup the timer and enable it. */

As an alternative it would be possible to have the code reconfigure the existing GPIO and avoid the extra word pulse circuitry.
e.g. use the one GPIO with a pal event to find the leading edge and then reconfigure GPIO for TIM trigger, etc. in the callback.

For good information on driver implementations look at the peripheral drivers in os/hal/ports/STM32/LLD/...

User avatar
Posts: 60
Joined: Fri Apr 17, 2015 5:10 pm
Has thanked: 4 times
Been thanked: 3 times

Re: STM32F4 DMA Peripheral-to-Memory: Memory Corruption

Postby Skadi » Thu Jan 31, 2019 1:47 pm

Hi Bob,

thank you for your support!

The pal callback approach with the extra GPIO pin looks good to me. I will try that one asap as I added the extra circuitry.


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 4 guests