2016-10-17 03:37 AM
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. volatileuint32_t *VectorTable = (
volatileuint32_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); } intmain(
void)
{ Remap_Table(); //SystemInit(); __enable_irq(); SysTick_Config(SystemCoreClock / 1000); configurePins(); //NVIC_SetPriority(SysTick_IRQn, 0x0); configureImu(); //configures I2C InterfaceREST_COUNTER = 0;
configureDebugger(); //configures USART4configureLidar();
//configure I2CconfigureGps();
//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-multiply2016-10-17 06:10 AM
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 USART2016-10-18 03:46 AM
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.2016-10-18 07:11 AM
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};