cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 TIM causing FLASH PGPERR

patrick23
Associate II
Posted on January 30, 2015 at 13:09

Hey Everyone,

I'm using an STM32F405 on a custom board with the STM32CubeF4 library. Whenever I enable the TIM4 peripheral, the TIM4->DMAR register automatically changes from 0 to 1. This is causing the FLASH flags PGPERR and PGSERR to be set. If I manually set TIM4->DMAR = 0 and clear the FLASH flags, the flags go away. If I leave the TIM4->DMAR register alone and clear the FLASH flags, the flags come back seemingly instantaneously. Anyone have an idea what might be causing the issue? Or do I have to keep using the band-aid I came up with? Here's the code:

TIM_HandleTypeDef h_tim4;
__TIM4_CLK_ENABLE();
/*
* APB1 Input clock is 84Mhz
* prescaler is set to 84 
* Updated rate is 100 Hz
* 1 ticks = 10ms
*/
h_tim4.Instance = TIM4;
h_tim4.Init.Period = (10 * 1000) - 1;
h_tim4.Init.Prescaler = 84 - 1;
h_tim4.Init.ClockDivision = 0;
h_tim4.Init.CounterMode = TIM_COUNTERMODE_UP;
h_tim4.Init.RepetitionCounter = 0;
// Initialize TIM4 Peripheral
HAL_TIM_Base_Init(&h_tim4);
// Setup TIM4 interrupt
HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM4_IRQn);
HAL_TIM_Base_Start_IT(&h_tim4);
/* For some reason, TIM4->DMAR = 1 ???
* This is causing FLASH flags PGPERR and PGSERR to be set.
* Manually set TIM4->DMAR = 0
*/
TIM4->DMAR = 0;
// Clear pending FLASH flags
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR |
FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR |
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);

3 REPLIES 3
Posted on January 30, 2015 at 17:35

Anyone have an idea what might be causing the issue? Or do I have to keep using the band-aid I came up with?

A DMA action against FLASH? Mapped at Zero. You'd need to look at the bigger context of what your other code is doing, and if something/structure is being initialized completely/properly.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 02, 2015 at 09:17

TIMx_DIER is an alias register to allow DMA indirect access to other TIMx registers. You shouldn't be touching it and shouldn't be bothered by its content unless you *exactly* know what are you doing, which doesn't appear to be the case.

Similarly, as Clive said, acting on timer can't change FLASH registers except indirectly, thus any relationship lies in your other code.

JW
patrick23
Associate II
Posted on February 03, 2015 at 04:54

Are you talking about TIMx_DMAR? I never manually change TIMx_DIER, although that register is changed indirectly through the HAL_TIM_Base_Start_IT() function.

You're right, I don't understand the TIMx_DMAR register. I don't intend to use it. I'm only using this timer simply for the update interrupt at the interval that I choose. However, whenever I enable the timer (through TIMx_CR1 CEN bit), the TIMx_DMAR value changes from 0 to 1, which is exactly when the FLASH flags are raised. If I try to clear the FLASH flags, they're immediately raised again. When I manually change the value TIMx_DMAR value back to 0 and clear the FLASH flags, the flags remain cleared.

My problem is that I'm thinking the FLASH flag problem is related to the TIMx_DMAR register because I never directly (or indirectly to my knowledge) set the TIMx_DMAR register. After reading the reference manual more carefully, is the TIMx_DMAR register simply reflecting the TIMx_CR1 register because the TIMx_DCR register is set to 0?