AnsweredAssumed Answered

Low level PWM problems

Question asked by chichkine.ivan on Jan 5, 2013
Latest reply on Jan 5, 2013 by chichkine.ivan
I'm trying to implement PWM on TIM4_CH4 with output on PD15 using only low level register writes as I don't much care for all the high level functions provided. However, I tried to convert the functions to their basics at around 2 AM, and unsurprisingly it doesn't work. This is the code I low level'ified (https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32Discovery/DispForm.aspx?ID=1816&Source=/public/STe2ecommunities/Tags.aspx?tags=stm32f4). I got rid of all the extra channels and this is what I was left with:

uint16_t BKPWM = 50;
 
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN; // GPIOD and E enable
RCC->APB1ENR |= RCC_APB1Periph_TIM4; // timer 4 enable
 
GPIOE->MODER = 0x55555555; // portE all outputs
GPIOD->MODER = 0x91110000; // 8, 10, 12, 14 outputs. 15 alternate function (timer 4)
GPIOD->OSPEEDR = 0xFFFFFFFF;
GPIOE->OSPEEDR = 0xFFFFFFFF;
GPIOD->AFR[2] = 0x20000000; // PD15 to AF2
 
PrescalerValue = (uint16_t) ((168000000 /2) / 28000000) - 1;
 
TIM4->CR1 &= (uint16_t)~0x70;
TIM4->CR1 &= (uint16_t)(~TIM_CR1_CKD);
 
TIM4->ARR = 255;
 
TIM4->PSC = PrescalerValue;
 
TIM4->EGR = TIM_PSCReloadMode_Immediate;
 
 
TIM4->CCER &= (uint16_t)~TIM_CCER_CC4E;
 
TIM4->CCMR2 &= (uint16_t)~TIM_CCMR2_OC4M;
TIM4->CCMR2 &= (uint16_t)~TIM_CCMR2_CC4S;
TIM4->CCMR2 |= (uint16_t)(TIM_OCMode_PWM1 << 8);
 
TIM4->CCER &= (uint16_t)~TIM_CCER_CC4P;
TIM4->CCER |= (uint16_t)(TIM_OCPolarity_High << 12);
TIM4->CCER |= (uint16_t)(TIM_OutputState_Enable << 12);
 
TIM4->CCR4 = BKPWM;// 200 / 255
 
 
TIM4->CCMR2 &= (uint16_t)(~TIM_CCMR2_OC4PE);
TIM4->CCMR2 |= (uint16_t)(TIM_OCPreload_Enable << 8);
 
TIM4->CR1 |= TIM_CR1_ARPE;
 
TIM4->CR1 |= TIM_CR1_CEN;

I'm sure it's just a simple mistake of accidentally deleting something while converting the code but I can't find it.

Outcomes