PWM + DMA not changing the color of WS2812B LED strip
I have the following code trying to turn 5 pixels of the LED strip to red. The setup I have is the LED strip is connected to PC6.
#include <stdint.h>
// STM32F103C8 is a medium density device, hence we use the xB header
#include <stm32f103xb.h>
#if !defined(__SOFT_FP__) && defined(__ARM_FP)
#warning \
"FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif
void enable_clock() {
RCC->CR |= RCC_CR_HSION;
while ((RCC->CR & RCC_CR_HSIRDY) == 0);
}
// @formatter:off
#define HI 6
#define LO 3
uint32_t buffer[] = {
LO, LO, LO, LO, LO, LO, LO, LO,
HI, HI, HI, HI, HI, HI, HI, HI,
LO, LO, LO, LO, LO, LO, LO, LO,
LO, LO, LO, LO, LO, LO, LO, LO,
HI, HI, HI, HI, HI, HI, HI, HI,
LO, LO, LO, LO, LO, LO, LO, LO,
LO, LO, LO, LO, LO, LO, LO, LO,
HI, HI, HI, HI, HI, HI, HI, HI,
LO, LO, LO, LO, LO, LO, LO, LO,
LO, LO, LO, LO, LO, LO, LO, LO,
HI, HI, HI, HI, HI, HI, HI, HI,
LO, LO, LO, LO, LO, LO, LO, LO,
LO, LO, LO, LO, LO, LO, LO, LO,
HI, HI, HI, HI, HI, HI, HI, HI,
LO, LO, LO, LO, LO, LO, LO, LO,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
// @formatter:on
void blink_dma_to_gpio() {
enable_clock();
// GPIO C configuration
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Enable IO port C
GPIOC->CRL &= ~(GPIO_CRL_CNF6 | GPIO_CRL_MODE6); // GPIO C: Clear pin 6 configuration
GPIOC->CRL |= GPIO_CRL_CNF6 | GPIO_CRL_MODE6; // GPIO C: Set pin 6 to alternate function push-pull 50MHz output
// TIM3 configuration
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // Enable TIM3
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; // Enable alternate function
AFIO->MAPR |= AFIO_MAPR_TIM3_REMAP; // Full remap TIM3
TIM3->PSC = 1 - 1;
TIM3->ARR = 10 - 1;
TIM3->BDTR |= TIM_BDTR_MOE;
TIM3->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // PWM mode 1
TIM3->CCER |= TIM_CCER_CC1E; // Enable capture compare 1
TIM3->CCMR2 |= TIM_CCMR2_OC3M_0; // Active on match
TIM3->CCER |= TIM_CCER_CC3E; // Enable capture compare 3
TIM3->DIER |= TIM_DIER_CC3DE; // Enable DMA1 request
// DMA1 configuration
RCC->AHBENR |= RCC_AHBENR_DMA1EN; // Enable DMA1
DMA1_Channel2->CPAR = (uint32_t) &TIM3->CCR1;
DMA1_Channel2->CMAR = (uint32_t) &buffer;
DMA1_Channel2->CNDTR = 168;
DMA1_Channel2->CCR = DMA_CCR_MSIZE_1 // 32 bit memory
| DMA_CCR_PSIZE_1 // 32 bit peripheral
| DMA_CCR_MINC // Increment memory
| DMA_CCR_CIRC // Circular memory
| DMA_CCR_DIR // Memory to peripheral
| DMA_CCR_HTIE // Half transfer interrupt
| DMA_CCR_TCIE // Transfer complete interrupt
;
// Enable peripherals
DMA1_Channel2->CCR |= DMA_CCR_EN;
TIM3->CR1 |= TIM_CR1_CEN;
}
int main() {
blink_dma_to_gpio();
for (;;);
}I already had the output hooked up to an oscilloscope and the output waves look correct. However, when I run this code, nothing changes on the LED strip. I just want to ask if there is something wrong with my code here, or could there be any potential hardware issues I did not think of.
