2021-08-16 05:27 AM
Hi to all,
I hope this is the right place where asking to.
Anyway in my custom board I use four timers: SysTick, RTC, TIM6 (DAC) and TIM3 (PWM).
I wnted to add a new timer (I tryed TIM7 and TIM2), but it wouldn't work and I discovered that neither TIM3 and TIM6 work, but them where working time ago.
What can check and do?
Hereafter I add TIM6 (once working) and TIM7 configuration:
// TIM6
DAC->CR &= ~(DAC_CR_DMAEN1 | DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1 | DAC_CR_BOFF1 | DAC_CR_EN1); //Clear channel 1 CR register ->timer6 enabled
DAC->CR |= DAC_CR_DMAEN1 | DAC_CR_TEN1 | DAC_CR_EN1; //SW trigger
if(!(RCC->APB1ENR & RCC_APB1ENR_TIM6EN)) RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; // Enable TIM6 clock
TIM6->CR1 = 0x0000; // Reset CR1 (Edge mode | Up counter | Continous mode)
TIM6->CR2 = 0x0000; // Reset CR2
TIM6->CR2 |= TIM_CR2_MMS_1; // The update event is selected as a trigger output (TRGO).
TIM6->DIER |= TIM_DIER_UIE | TIM_DIER_UDE; //Enable interrupt | Enable DMA request
TIM6->EGR = TIM_EGR_UG; // Re-initializes the timer counter and generates an update of the registers
TIM6->PSC = 35; // Prescaler
TIM6->ARR = 1000; // Auto reload register (frequency)
TIM6->CNT = 0; // Counter (freq = SYSCLOCK/PSC/CNT)
TIM6->SMCR &= ~7;
TIM6->CR1 |= TIM_CR1_CEN; // Enable TIM6
if(!(RCC->AHBENR & RCC_AHBENR_DMA2EN)) RCC->AHBENR |= RCC_AHBENR_DMA2EN; // Enable DMA2 clock
DMA2_Channel3->CCR = 0x00000000; // Reset register
// DMA2_Channel3->CCR |= DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_DIR; // size 16 bit both mem and periph | mem increment | circular | up
DMA2_Channel3->CCR |= DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_MINC | DMA_CCR_CIRC | DMA_CCR_DIR | DMA_CCR_TCIE; // size 16 bit both mem and periph | mem increment | circular | up | Transfer compl int
DMA2_Channel3->CNDTR = 70; // Data to be transfered
DMA2_Channel3->CPAR = (uint32_t) &(DAC->DHR12R1); // Peripheral address
DMA2_Channel3->CMAR = (uint32_t) &sen[0]; // Memory address
DMA2_Channel3->CCR |= DMA_CCR_EN; // Enable
//TIM7
if(!(RCC->APB1ENR & RCC_APB1ENR_TIM7EN)) RCC->APB1ENR |= RCC_APB1ENR_TIM7EN; // Enable TIM7 clock
TIM7->CR1 = 0x0000; // Reset CR1 (Edge mode | Up counter | Continous mode)
TIM7->CR2 = 0x0000; // Reset CR2
TIM7->DIER |= TIM_DIER_UIE; //Enable interrupt
TIM7->EGR |= TIM_EGR_UG; // Re-initializes the timer counter and generates an update of the registers
// TIM7->EGR &= ~TIM_EGR_UG; // Re-initializes the timer counter and generates an update of the registers
TIM7->PSC = 72; // Prescaler
TIM7->ARR = 100; // Auto reload register (frequency)
TIM7->CNT = 10; // (freq = SYSCLOCK/PSC/CNT)
TIM7->CR1 |= TIM_CR1_CEN; // Enable TIM7
Thank you
Freya
2021-08-16 05:41 AM
View the register values and ensure they're what you expect. What does "it wouldn't work" mean exactly?
> TIM7->CNT = 10; // (freq = SYSCLOCK/PSC/CNT)
Not sure what this means, but the update interval is (timer clock) / (PSC + 1) / (ARR + 1). The timer tick interval is (timer clock) / (PSC + 1).
2021-08-16 06:20 AM
"it woudn't work" means that when I coded PWM and DAC routines they worked well. Then I coded other parts of the project so I didn't check if PWM and DAC continued to work.
Now I decided toset a timer and interrupt routine to launch acquiredata() function to set a more precise timing. When I "cut and paste" timer initialization, I discovered it wouldn't work and so did the others (only SysTick and RTC continue working).
2021-08-16 11:59 AM
Read out the timer registers in the working state and compare them to the not working state.
If it's the same code in both cases, it's unlikely the code is the issue here.
2021-08-16 12:41 PM
Watch for the Hazard of enabling the clock and immediately touching the peripheral registers.
Enable all the clocks you want EARLY, or put in a while() loop rather than the if () you're using.
2021-08-17 12:48 AM
Indeed I did not think there could be such a problem.
Anyway I put all clock enable in an ClockInit() function at very initialization beginning and now it seems to work properly.
Thank you
Freya