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 ) 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