cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 discovery board: Bootloader USART3, General Purpose timer, LED not working

AAnth.1
Senior

Hi

So here's the thing: I've been getting familiar with flashing the STM32F407 discovery board using the in-build bootloader via USART3. Boot mode is set to System memory using

Boot0 = 1 (5V)

Boot1 = 0 (GND)

I am using an USB to serial converter. Connection is:

USB_serial_TX (Green wire) <=> MCU_RX (PC11)

USB_serial_RX (White wire) <=> MCU_TX (PC10)

When using the bootloader to upload a program to control an LCD via I2C, I get the expected result. However, when trying to run a simple GP timer to control an LED, the LED does not blink.

The code itself works, because when using the on-board STLink programmer, the LED blinks. Just with the bootloader, it does not. Any ideas? Thank you.

0693W000003PgUZQA0.png

0693W000003PgUjQAK.jpg

#include "stm32f4xx.h"
 
#if !defined(__SOFT_FP__) && defined(__ARM_FP)
  #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif
 
void funcISRInit();
void funcGPIOInit();
void funcTIM4Init();
 
 
int main(void)
{
	funcISRInit();
	funcGPIOInit();
	funcTIM4Init();
	for(;;);
}
 
void funcISRInit()
{
	// Enable interrupt for TIM4
	__NVIC_EnableIRQ(TIM4_IRQn);
}
 
void funcGPIOInit()
{
	RCC->AHB1ENR |= (1<<RCC_AHB1ENR_GPIODEN_Pos);		// Enables AHB1 to communicate with GPIOD
 
	GPIOD->MODER &= ~(2<<GPIO_MODER_MODER15_Pos);	// PD15 as output	[01]
 
	GPIOD->OTYPER &= ~(1<<GPIO_OTYPER_OT15_Pos);	// Push pull
	GPIOD->OSPEEDR &= ~(3<<GPIO_OSPEEDR_OSPEED15_Pos); // Sets speed on PD12 to low
}
 
void funcTIM4Init()
{
	// Sets PD12 to TIM4
	RCC->AHB1ENR |= (1<<RCC_AHB1ENR_GPIODEN_Pos);		// Enables AHB1 to communicate with GPIOD
	GPIOD->MODER |= (2<<GPIO_MODER_MODER12_Pos);	// Sets PD12 as Alternate function
 
	GPIOD->AFR[1] |= (2<<GPIO_AFRL_AFSEL4_Pos);	// Sets PD12 to AF2 [0010]
 
	// Use PD12 to toggle LED in PWM mode. Use alternate function and TIM4
	RCC->APB1ENR |= (1<<RCC_APB1ENR_TIM4EN_Pos);	// Enables TIM4 on APB1 bus
	TIM4->CR1 |= (1<<TIM_CR1_CEN_Pos);	// CEN: Counter enabled
	TIM4->CR1 &= ~(1<<TIM_CR1_UDIS_Pos);	// UDIS: Update event enabled
	TIM4->CR1 &= ~(1<<TIM_CR1_URS_Pos);	// URS: Update request source enabled
	TIM4->CR1 &= ~(1<<TIM_CR1_OPM_Pos);	// OPM: One pulse mode disabled
	TIM4->CR1 &= ~(1<<TIM_CR1_DIR_Pos);	// DIR: Up count
	TIM4->CR1 &= ~(3<<TIM_CR1_CMS_Pos);	// CMS: Edge aligned mode enabled
	TIM4->CR1 &= ~(1<<TIM_CR1_ARPE_Pos);	// ARPE: Auto reload register not buffered
	TIM4->CR1 &= ~(3<<TIM_CR1_CKD_Pos);	// CKD: Clock division and digital filters set to tdts=tck
 
	TIM4->CR2 &= ~(1<<TIM_CR1_CKD_Pos);	// TIM4_CH1 is connected to TI1 input
 
	TIM4->DIER |= (1<<TIM_DIER_UIE_Pos);	// UIE: Update interrupt enabled
 
	TIM4->EGR |= (1<<TIM_EGR_UG_Pos);	// UG: Update generation enabled
	TIM4->SMCR |= (1<<6);	// TI1F trigger selection
 
	TIM4->CCMR1 &= ~(3<<TIM_CCMR1_CC1S_Pos);	// CC1S: CC1 set as output
	TIM4->CCMR1 |= (2<<TIM_CCMR1_OC1FE_Pos);	// Preload register enabled
	TIM4->CCMR1 |= (6<<TIM_CCMR1_OC1M_Pos);	// OC1M: PWM1 mode [6:4] 110
 
	TIM4->CCER |= (1<<TIM_CCER_CC1E_Pos);	// CC1E: Capture compare 1 output enable
	TIM4->CCER &= ~(1<<TIM_CCER_CC1P_Pos);	// CC1P: Active high
	TIM4->CCER &= ~(1<<TIM_CCER_CC1NP_Pos);	// CC1NP: Cleared because CC1 channel is set to output
 
	TIM4->PSC = 0xF9FF;		// Sets prescaler to 63999. Timer clock is now 16MHz/(63999+1)=250Hz
 
	TIM4->ARR = 0x00F9;		// Counter goes up to 249 to have a 1s timer
 
	TIM4->CCR1 = 0x007D;	// Sets compare match to half of ARR: 50% duty cycle
}
 
void TIM4_IRQHandler()
{
	TIM4->SR &= ~(1<<0);	// Clears UIF bit
	// Handles the IRQ of TIM4
 
	// Toggle LED on PD15
	static uint8_t check = 1;
	if(check)
	{
		GPIOD->BSRR |= (1<<15);
		check = 0;
	}
	else
	{
		GPIOD->BSRR |= (1<<31);
		check = 1;
	}
}

1 ACCEPTED SOLUTION

Accepted Solutions

>>Any ideas? 

Makes sure the vector table points at yours rather than the ROMs

ie SCB->VTOR = 0x08000000;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

2 REPLIES 2

>>Any ideas? 

Makes sure the vector table points at yours rather than the ROMs

ie SCB->VTOR = 0x08000000;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi clive1

You made my day. Inspecting my two projects (the GP timer where the bootloader did not work and the LCD/I2C where the bootloader works), I noticed that my GP timer project did not have the system_stm32f4xx.c file. Copying this file into my GP timer project, my timer now works like a charm via bootloader flash.

Thanks a lot for your help.

Cheers,