cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F072 USART becomes unresponsive after jump from custom bootloader to application code

ajay
Associate
Posted on October 17, 2016 at 12:37

Hi, I wrote a custom bootloader which downloads new firmware using GSM module and starts application firmware. Bootloader is able to start application firmware and application firmware is able to configure vector table, systick and different I/O pins. But is unable to communicate on any USART interface.

Below is code to jump to application firmware from bootloader:

__disable_irq();

// Jump to user application

JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);

Jump_To_Application = (pFunction) JumpAddress;

// Initialize user application's Stack Pointer

__set_MSP(*(__IO uint32_t*) ApplicationAddress);

//Remap_Table();

Jump_To_Application();

Below is start of main() in application firmware:

void

Remap_Table(

void

)

{

// Copy interrupt vector table to the RAM.

volatile

uint32_t *VectorTable = (

volatile

uint32_t *)0x20000000;

uint32_t ui32_VectorIndex = 0;

for

(ui32_VectorIndex = 0; ui32_VectorIndex < 48; ui32_VectorIndex++)

{

VectorTable[ui32_VectorIndex] = *(__IO uint32_t*)((uint32_t)FIRMWARE_START_ADDR + (ui32_VectorIndex << 2));

}

RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);

// Remap RAM into 0x0000 0000

SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);

}

int

main(

void

)

{

Remap_Table();

//SystemInit();

__enable_irq();

SysTick_Config(SystemCoreClock / 1000);

configurePins();

//NVIC_SetPriority(SysTick_IRQn, 0x0);

configureImu();

//configures I2C Interface

REST_COUNTER = 0;

configureDebugger();

//configures USART4

configureLidar();

//configure I2C

configureGps();

//configure USART3

.....

}

Device is able to configure interfaces but when trying to access USART to write data it keeps on looping at :

while

(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);

Transmit Data Register of USART is not getting set.

Can anyone please tell me what I am missing or doing wrong?

#usart #stm32 #bootloader #arm-cortex-m0-stm32-multiply

3 REPLIES 3
Posted on October 17, 2016 at 15:10

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Clock Not RESET

Use a debugger, inspect the system for the vector table content, and the peripheral and clock settings. Step through the transition and into you main() code, and the code outputting to the USART

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ajay
Associate
Posted on October 18, 2016 at 12:46

I tried debugging and found out that USART_Init call makes call toRCC_GetClocksFreq which computes clock frequency values. In the RCC_GetClocksFreq function following line is used to calculate the prescaler

tmp = RCC->CFGR & RCC_CFGR_HPRE;
tmp = tmp >> 4;
presc = APBAHBPrescTable[tmp];
......
//Value of APBAHBPrescTable
static
__I uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};

Value of tmp evaluates to 0 but

APBAHBPrescTable[0] evaluates to 0x05,

APBAHBPrescTable

evaluates to address 0x200000B4 which contains value0x0800C Because of thisHCLK clock frequency is getting devided by 5 and furthurePCLK clock frequency evaluates to HCLK clock frequency devided by 5 again. While value of RCC->CFGR register is 0x00.
Posted on October 18, 2016 at 16:11

Use static const not static volatile, prior to main() running the statics may not have been initialized (copied to RAM), certainly in the Keil SystemInit() case.

static
const uint8_t APBAHBPrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};

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