2013-01-04 04:51 PM
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.
2013-01-04 05:43 PM
This looks wrong
GPIOD->AFR[2] = 0x20000000;
// PD15 to AF2
Should be, although I'd probably mask it on
GPIOD->AFR[1] = 0x20000000;
// PD15 to AF2
2013-01-04 08:11 PM
Ah, that did it. I swear I tried both [1] and [2] though, since the datasheet doesn't mention which one is the top half of the register. I guess there were other problems too when I tried [1]. Thanks.
2013-01-04 08:53 PM
[0] is the bottom half 0 .. 7
[1] is the top half 8 .. 15 [2] exceeds the bounds of the array2013-01-04 09:05 PM
Wow, I think this might be the first time in my life that I've been thrown off by a zero indexed array.