Skip to main content
Graduate
June 18, 2024
Solved

MCU can't be flashed anymore

  • June 18, 2024
  • 2 replies
  • 1642 views

Hi everyone,

First I am sorry for the uneducated rest of this text and badly written code.

I am currently playing around with a stm32f4 chip. I am using Platform IO CMSIS and a cheap stlink v2 to program the chip. I was trying to get PWM working when the chip wouldn't connect anymore. 

I was trying to do this by using the TIM1 peripheral which didn't work and then switched to the TIM3. Unfortunately I am not sure when the chip stopped to respond. I also coded my own clock config which worked fine the first 100 flashes or so.

 

 

I have heart that bad clock config can "brick" the chip but since it worked and then didn't even tough I didn't touch the clock code anymore I am confused.

 

Here is my clock config:

#include "clock_config.h"


/**
 * Configures the stm32 to use the internal 16Mhz clock
 */
void configure_clock(){
 // Reset the flash 'Access Control Register'
 // set wait-state to 1 
 // enable prefetch buffer
 FLASH->ACR &= ~(FLASH_ACR_LATENCY_Msk | FLASH_ACR_PRFTEN_Msk);
 FLASH->ACR |= (FLASH_ACR_LATENCY | FLASH_ACR_PRFTEN);
 
 // activate the internal 16 MHz clock
 RCC->CR |= RCC_CR_HSION;

 // wait for the clock to become stable
 while (!(RCC->CR & RCC_CR_HSIRDY)){}

 // AHB and APB clocks are not configured but should be just not divided so run on 16Mhz as well

}

 

And here is the rest of my code:

uint16_t arr_from_freq(uint16_t freq){
 return F_CLK/(freq*(TIM3->PSC+1)) - 1;
}

int main(){
// Enable GPIO port A and TIM3 peripherals
 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
 RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;

 // Set the mode of GPIOA pin 6 to alternate function mode 2
 GPIOA->MODER = GPIO_MODER_MODER6_1;
 GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6;
 GPIOA->AFR[0] |= 0b0010 << (7*4);

 // Disable the timer before setting the prescaler and overflow values
 TIM3->CR1 &= ~TIM_CR1_CEN;

 // Set the prescaler and overflow values
 TIM3->PSC = 0;
 TIM3->ARR = arr_from_freq(pwm_frequency);
 TIM3->CCR1 = 0;

 // Set the PWM mode 1
 TIM3->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;
 TIM3->CCMR1 |= TIM_CCMR1_OC1PE;

 // Set the output polarity to active high
 TIM3->CCER |= TIM_CCER_CC1E;

 // Enable the main output
 TIM3->BDTR |= TIM_BDTR_MOE;

 // Enable auto reload preload
 // configures a buffer register for ARR and CCR1 so that those values
 // do not get changed while the timer is still counting
 TIM3->CR1 |= TIM_CR1_ARPE;

 // Enable the timer
 // Set the center-aligned mode
 TIM3->CR1 |= TIM_CR1_CMS_0 | TIM_CR1_CEN;

 uint16_t duty = arr_from_freq(pwm_frequency)/2;

 for (;;){
 TIM3->CCR1 = duty;
 }
 return 0;
}

 

Thanks in advance to anyone willing to help.

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    Yeah, you've not really convinced me the chip is damaged.

    Pull BOOT0 HIGH, reset or power cycle the board, try to connect and then erase your broken code.

    2 replies

    Graduate II
    June 18, 2024

    Yeah, you've not really convinced me the chip is damaged.

    Pull BOOT0 HIGH, reset or power cycle the board, try to connect and then erase your broken code.

    SmarAuthor
    Graduate
    June 19, 2024

    Thanks a lot that did work. Another question I have is if the clock_config code is at fault here or if I can make the same mistake when programming the timer?

    Graduate
    June 19, 2024

    Can you connect via Stm32CubeProgrammer? If you can then you can erase all of the flash and option bits. Hopefully you'll be able to access it via your IDE again after that.