Kevin O'Connor 700e35c6ac armcm_timer: Unify udelay() implementation
Move the udelay() code from various arm board directories into the
src/generic/armcm_timer.c code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2019-06-09 20:27:57 -04:00

193 lines
5.5 KiB
C

/*
* Main starting point for STM32F042 boards.
*
* Copyright (C) 2019 Eug Krashtan <eug.krashtan@gmail.com>
* This file may be distributed under the terms of the GNU GPLv3 license.
*
*/
#include "stm32f0xx_hal.h"
#include "autoconf.h"
#include "command.h" // DECL_CONSTANT
#include "board/misc.h" // timer_read_time
#include "sched.h" // sched_main
#include "internal.h"
#include "can.h"
#include "log.h"
DECL_CONSTANT_STR("MCU","stm32f042");
static IWDG_HandleTypeDef hiwdg;
/****************************************************************
* dynamic memory pool
****************************************************************/
static char dynmem_pool[3 * 1024];
// Return the start of memory available for dynamic allocations
void *
dynmem_start(void)
{
return dynmem_pool;
}
// Return the end of memory available for dynamic allocations
void *
dynmem_end(void)
{
return &dynmem_pool[sizeof(dynmem_pool)];
}
/****************************************************************
* misc functions
****************************************************************/
void
command_reset(uint32_t *args)
{
NVIC_SystemReset();
}
DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset");
void clock_config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI
|RCC_OSCILLATORTYPE_HSI14|RCC_OSCILLATORTYPE_HSI48
|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.HSI14State = RCC_HSI14_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.HSI14CalibrationValue = 16;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_RTC;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
}
void
watchdog_reset(void)
{
HAL_IWDG_Refresh(&hiwdg);
}
DECL_TASK(watchdog_reset);
void
watchdog_init(void)
{
hiwdg.Instance = IWDG;
hiwdg.Init.Prescaler = IWDG_PRESCALER_16;
hiwdg.Init.Window = 4095;
hiwdg.Init.Reload = 4095;
//HAL_IWDG_Init(&hiwdg); ToDo enable after debug
}
DECL_INIT(watchdog_init);
// Main entry point
int
main(void)
{
HAL_Init();
clock_config();
gpio_init();
#if (CONFIG_DEBUG_OUT)
LogInit();
#endif
sched_main();
return 0;
}
void __attribute__((weak)) lprint(char *msg) {}
void __attribute__((weak)) lnprint(char *msg, size_t len) {}
/*
* MSP init functions ( __weak replacement )
*/
/*
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_RCC_WWDG_CLK_ENABLE();
}
/****************************************************************
* Debug helper (taken from https://community.arm.com/)
* In case of Hard Fault it helps to find fault reason
* on Cortex-M0 chips
****************************************************************/
void hard_fault_handler_c(unsigned long *hardfault_args){
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
volatile unsigned long stacked_r0 ;
volatile unsigned long stacked_r1 ;
volatile unsigned long stacked_r2 ;
volatile unsigned long stacked_r3 ;
volatile unsigned long stacked_r12 ;
volatile unsigned long stacked_lr ;
volatile unsigned long stacked_pc ;
volatile unsigned long stacked_psr ;
volatile unsigned long _CFSR ;
volatile unsigned long _HFSR ;
volatile unsigned long _DFSR ;
volatile unsigned long _AFSR ;
volatile unsigned long _BFAR ;
volatile unsigned long _MMAR ;
stacked_r0 = ((unsigned long)hardfault_args[0]) ;
stacked_r1 = ((unsigned long)hardfault_args[1]) ;
stacked_r2 = ((unsigned long)hardfault_args[2]) ;
stacked_r3 = ((unsigned long)hardfault_args[3]) ;
stacked_r12 = ((unsigned long)hardfault_args[4]) ;
stacked_lr = ((unsigned long)hardfault_args[5]) ;
stacked_pc = ((unsigned long)hardfault_args[6]) ;
stacked_psr = ((unsigned long)hardfault_args[7]) ;
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
_CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;
// Hard Fault Status Register
_HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;
// Debug Fault Status Register
_DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;
// Auxiliary Fault Status Register
_AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
_MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
// Bus Fault Address Register
_BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;
__asm("BKPT #0\n") ; // Break into the debugger
#pragma GCC diagnostic pop
}