Using DMA for Bit-Banging Pulse Pattern on GPIO

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

Moderators: RoccoMarco, barthess

joewa
Posts: 22
Joined: Tue May 13, 2014 10:40 pm

Using DMA for Bit-Banging Pulse Pattern on GPIO

Postby joewa » Wed Jan 04, 2017 1:33 am

Hi,
I want to use DMA to generate some custom pulse pattern. Now, I'd like to modify my WS2812-LED-Driver for STM32F4 for that purpose.
Here is how it works so far:

Code: Select all

    dmaStreamAllocate(WS2812_DMA_STREAM, 10, NULL, NULL);
    dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(WS2812_PWMD.tim->CCR[WS2812_TIM_CH]));  // Set duty cycle
    dmaStreamSetMemory0(WS2812_DMA_STREAM, ws2812_frame_buffer);
    dmaStreamSetTransactionSize(WS2812_DMA_STREAM, WS2812_BIT_N);
    dmaStreamSetMode(WS2812_DMA_STREAM,
          STM32_DMA_CR_CHSEL(3) | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD |
         STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC | STM32_DMA_CR_PL(3));
     //CHSEL(3): Select DMA-channel 3 (TIM2_UP); M2P: Memory 2 Periph; Circular mode; PL: Priority Level
    // Start DMA
    dmaStreamEnable(WS2812_DMA_STREAM);
    pwmStart(&WS2812_PWMD, &ws2812_pwm_config);
    pwmEnableChannel(&WS2812_PWMD, WS2812_TIM_CH, 0);

See (or clone 8-) ) the full driver here: https://github.com/joewa/WS2812-LED-Dri ... r/ws2812.c

Now, my idea is to use DMA to set and reset some pins on GPIOA through GPIOA->BSRR.W.
The ws2812_frame_buffer is now filled with zeros. One bit set and reset word is provided:

Code: Select all

    ws2812_frame_buffer[4] = GPIO_BSRR_BS_10;
    ws2812_frame_buffer[WS2812_COLOR_BIT_N-1] = GPIO_BSRR_BR_10;

And I changed the DMA peripheral adress to GPIOA-BSRR:

Code: Select all

dmaStreamSetPeripheral(WS2812_DMA_STREAM, &(GPIOA->BSRR.W));

I was expecting this should do the job... but PA10 remains low...

I assume that the GPIO is correctly configured, because setting and resetting the pin via software works:

Code: Select all

GPIOA->BSRR.W = GPIO_BSRR_BS_10; // set
GPIOA->BSRR.W = GPIO_BSRR_BR_10; // reset


I would be happy about any ideas!

Jörg

joewa
Posts: 22
Joined: Tue May 13, 2014 10:40 pm

Re: Using DMA for Bit-Banging Pulse Pattern on GPIO

Postby joewa » Wed Jan 04, 2017 7:14 pm

Yay! I solved this: Apparently, DMA1 cannot access the GPIO registers. DMA2 works!
"Figure 33. System implementation of the two DMA controllers" provides the hint:
"The DMA1 controller AHB peripheral port is not connected to the bus matrix like DMA2 controller. As a result, only DMA2 streams are able to perform memory-to-memory transfers."

However, I didn't find out from the manual yet, which registers can be accessed through which DMA...

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Using DMA for Bit-Banging Pulse Pattern on GPIO

Postby Giovanni » Wed Jan 04, 2017 7:23 pm

Hi,

Glad you solved.

This is not a support forum, moving this thread in the appropriate one.

Giovanni


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 6 guests