2013-03-10 12:42 AM
Hi all, I am very new to ARM chips, lots to learn. I have some code from a ST example that initialises the gpio/tim2/DAC2/DMA all in one funtion it works fine. If I split it onto 4 functions for clarity etc, it stops working. Unless I place a long delay loop after the TIM2 init function. Where should I be looking to learn more about waiting for last operations on the timer registers?
Thank you for your asstance. Cheers. Pete L.2013-03-10 06:06 AM
Well there are issues about how, and in what order, peripheral initialization should occur.
For timers, settings can be applied somewhat latently. The setting of ARR (period) normally occurs at the Update point of the prior value, unless it has been set to be applied immediately. Does the delay relate to the periodicity of the timer, or alter if you change the timer settings? Your examples may be more illustrative.2013-03-11 02:47 PM
Hi Clive, and thanks for the reply.
Code below. The confusing thing to me is that it works without delay as inline code, but once put in a function needs the delay. I see the TIM_TimeBaseInit function does; TIMx->EGR = TIM_PSCReloadMode_Immediate; so there should be no waiting for the timer to load. I do call this function (setupTIM2ForDAC2) later in the code to change the period (ARR) and it works fine.I'm not worried to get this working, but I do want to understand why. Thanks for your assistance. Pete L. The setup function I created is; void setupTIM2ForDAC2(u32 per) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* TIM2 Periph clock enable */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = per;//0x19; TIM_TimeBaseStructure.TIM_Prescaler = 0x6; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); } called in the funtion; static void DAC_initFromSample(void) { int x; setupGPIOForDAC2(); setupTIM2ForDAC2(0x19); /* wait here for some reason! */ for(x=0;x<200000;x++){} setupDAC2(); setupDMAForDAC2(); DMA_Cmd(DMA2_Channel4, ENABLE); DAC_Cmd(DAC_Channel_2, ENABLE); DAC_DMACmd(DAC_Channel_2, ENABLE); TIM_Cmd(TIM2, ENABLE); }2013-03-11 04:09 PM
Looks like you might be using a F10x series XL part.
I might have chosen a up count. I would probably enable the TIM, DMA and DAC clocks first. The delay seems to be for the benefit of the DMA and DAC setup that come after the code presented. This example should be easy enough to modify, STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\DAC\OneChannelDMA_Escalator\main.c2013-03-11 04:49 PM
Hi Clive,
yes the 103VE. Interesting/confusing about the up/down count. I would have expected it to have a major effect on the timing, as counting up to 0xffff from a small number would be much longer than counting down from that number. But I saw no difference. Must check that again... So I should enable clocks well before using the module? I will go looking for the sample you suggest, and modify my existing code as well. Cheers. Pete L.2013-03-11 06:41 PM
Hi again,
just made a change to enable all the clocks at the top of the calling function, as below. Took out the delay and it works. Traps for young players... The up/down count is still a mystery though. Thanks for your help. Cheers. Pete L. static void DAC_initFromSample(void) { int x; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); setupGPIOForDAC2(); setupTIM2ForDAC2(0x19); /* wait here for some reason! */ // for(x=0;x<200000;x++){} setupDAC2(); setupDMAForDAC2(); DMA_Cmd(DMA2_Channel4, ENABLE); DAC_Cmd(DAC_Channel_2, ENABLE); DAC_DMACmd(DAC_Channel_2, ENABLE); TIM_Cmd(TIM2, ENABLE); }