Anyone familiar with the STM32 advanced-control timer? - Page 1
Forum section: electronics / general

author: Dago
author_rank: Frequent Contributor
timestamp: June 30, 2014, 10:08:00 am
content: Hey guys! I started my foray in to ARM-land with an STM32F303CCT6 Cortex-M4 microcontroller. I'm not currently using the headers from ST. I have the MCU working fine and all the GPIO etc. stuff seems to work great.I've been trying to get the advanced-control timer working (I need to drive a H-bridge) so center-aligned PWM would be great. I *think* I've understood how to configure the timer-module based on the ST appnote AN4013 (http://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/DM00042534.pdfchapter 2.5) and the MCU reference manual (http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00043574.pdf) but I'm unable to get a peep out of the timer module. Pins stay at GND level, no change at any point. What I *do* know is that the counter is running and I have configured the output pins as outputs with push-pull and have selected alternate function 6 for all of them which maps TIM1_CHx outputs to the pins (specified in MCU specific datasheet page 41:http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00058181.pdf). I have also enabled the "automatic output enable" which seems to be working because it enabled the "master output enable" bit. TIM1_CH1 is connected to PA8, CH2 to PA9, CH1N to PB13 and CH2N to PB0.Here is the related code where you can see in which order I do things (based on the appnote):http://paste.dy.fi/m2HHere are all the related register states from the debugger after configuration:Code:GPIOA_MODER: 0x48000000: 0xa9550000GPIOA_OTYPER: 0x48000004: 0x00000000GPIOA_OSPEEDR: 0x48000008: 0x0c000000GPIOA_PUPDR: 0x4800000c: 0x65500000TimerTIM1_CR1: 0x40012c00: 0x000000b1TIM1_CR2: 0x40012c04: 0x00000000TIM1_SMCR: 0x40012c08: 0x00000000TIM1_DIER: 0x40012c0c: 0x00000000TIM1_SR: 0x40012c10: 0x00000007TIM1_EGR: 0x40012c14: 0x00000000TIM1_CCMR1: 0x40012c18: 0x00006868TIM1_CCMR2: 0x40012c1c: 0x00000000TIM1_CCER: 0x40012c20: 0x00000055TIM1_CNT: 0x40012c24: 0x00000a57TIM1_PSC: 0x40012c28: 0x00000000TIM1_ARR: 0x40012c2c: 0x00000fffTIM1_RCR: 0x40012c30: 0x00000000TIM1_CCR1: 0x40012c34: 0x000000f0TIM1_CCR2: 0x40012c38: 0x000000ffTIM1_CCR3: 0x40012c3c: 0x00000000TIM1_CCR4: 0x40012c40: 0x00000000TIM1_BDTR: 0x40012c44: 0x0000c000TIM1_DCR: 0x40012c48: 0x00000000TIM1_DMAR: 0x40012c4c: 0x000000b1TIM1_CCMR3: 0x40012c54: 0x00000000TIM1_CCR5: 0x40012c58: 0x00000000TIM1_CCR6: 0x40012c5c: 0x00000000TIM1_OR: 0x40012c60: 0x00000000I have gone through them several times now and verified that my defines seem to be correct. So I think I'm missing some part or I'm doing something in the wrong order. Too bad I can't see the OCxREF signal states with the debugger, that would tell me if the output compares are working or not... Any ideas what I'm doing wrong (or what I'm not doing what I'm supposed to)?Edit: I have also enabled the clock for the related GPIO ports (A & B) and for the timer module.

author: dannyf
author_rank: Super Contributor
timestamp: June 30, 2014, 10:28:45 am
content: I would suggest that you follow the library (three routines, TIM_TimeBaseInit(), TIM_OC1Init(), and TIM_CtrlPWMOutputs()) to see which registers they touch and how they touch those registers.Alternatively, you can monitor TIM1 counter value during debug to make sure that it is running and the OCx registers are set correctly.It is difficult to start with registers as it takes sometime to get used to different parts of the register set needed to set up a functionality.

author: Dago
author_rank: Frequent Contributor
timestamp: June 30, 2014, 11:34:22 am
content: Quote from: dannyf on June 30, 2014, 10:28:45 amI copied the way they set the registers in those functions (if those are enough to get something out):Code:uint32_t temp_cr = tim->CR1;SET_REG_MASK(temp_cr, AC_TIM_CR1_CMS_bm, AC_TIM_CR1_CMS_EDGE_gc);SET_REG_MASK(temp_cr, AC_TIM_CR1_CEN_bm, AC_TIM_CR1_CEN_EN_gc);tim->CR1 = temp_cr;tim->ARR = 0x0FFF;SET_REG_MASK(tim->EGR, AC_TIM_EGR_UG_bm, AC_TIM_EGR_UG_REINIT_gc);uint32_t temp_ccer = tim->CCER;tim->CCER &= ~AC_TIM_CCER_CC1E_bm;uint32_t temp_ccmr = tim->CCMR1;SET_REG_MASK(temp_ccmr, AC_TIM_CCMR1_OC1M_bm, AC_TIM_CCMR1_OC1M_PWMM1_gc);SET_REG_MASK(temp_ccmr, AC_TIM_CCMR1_CC1S_bm, AC_TIM_CCMR1_CC1S_OUT_gc);SET_REG_MASK(temp_ccer, AC_TIM_CCER_CC1E_bm, AC_TIM_CCER_CC1E_EN_gc);SET_REG_MASK(temp_ccer, AC_TIM_CCER_CC1NE_bm, AC_TIM_CCER_CC1NE_EN_gc);SET_REG_MASK(tim->CR2, AC_TIM_CR2_OIS1N_bm, AC_TIM_CR2_OIS1N_1_gc);tim->CCMR1 = temp_ccmr;tim->CCR1 = 0xFF;tim->CCER = temp_ccer;SET_REG_MASK(tim->BDTR, AC_TIM_BDTR_MOE_bm, AC_TIM_BDTR_MOE_EN_gc);But it doesn't work either. Following those library routines is kinda difficult though because they are not too verbose (which is a reason why I decided to rewrite them in the first place). For example in the TIM_TimeBaseInit() they never set the counter enable bit (CEN) so I guess it's included in some define they use...

author: Dago
author_rank: Frequent Contributor
timestamp: June 30, 2014, 11:55:31 am
content: I got it working.I misread a note in the datasheet: "In STM32F303xB/xC and STM32F358x devices, bits 10 and 11 of GPIOF_MODER, arereserved and must be kept at reset state." Didn't notice it said GPIOFand thought it applied to all GPIO ports so I wasn't configuring them as alternate function but just as regular outputs.Thanks for the help!

author: dannyf
author_rank: Super Contributor
timestamp: June 30, 2014, 12:11:51 pm
content: Cen is set in TIMx-CMD.