stm32: Reorganize code in stm32f1.c

Reorganize stm32f1.c into major code blocks.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2021-12-18 19:35:15 -05:00
parent 2ee1f48895
commit d29f97cd99
1 changed files with 84 additions and 49 deletions

View File

@ -1,6 +1,6 @@
// Code to setup clocks and gpio on stm32f1 // Code to setup clocks and gpio on stm32f1
// //
// Copyright (C) 2019 Kevin O'Connor <kevin@koconnor.net> // Copyright (C) 2019-2021 Kevin O'Connor <kevin@koconnor.net>
// //
// This file may be distributed under the terms of the GNU GPLv3 license. // This file may be distributed under the terms of the GNU GPLv3 license.
@ -11,6 +11,11 @@
#include "internal.h" // enable_pclock #include "internal.h" // enable_pclock
#include "sched.h" // sched_main #include "sched.h" // sched_main
/****************************************************************
* Clock setup
****************************************************************/
#define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 2) #define FREQ_PERIPH (CONFIG_CLOCK_FREQ / 2)
// Enable a peripheral clock // Enable a peripheral clock
@ -68,7 +73,52 @@ gpio_clock_enable(GPIO_TypeDef *regs)
RCC->APB2ENR; RCC->APB2ENR;
} }
static void stm32f1_alternative_remap(uint32_t mapr_mask, uint32_t mapr_value) // Main clock setup called at chip startup
static void
clock_setup(void)
{
// Configure and enable PLL
uint32_t cfgr;
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) {
// Configure 72Mhz PLL from external crystal (HSE)
RCC->CR |= RCC_CR_HSEON;
uint32_t div = CONFIG_CLOCK_FREQ / (CONFIG_CLOCK_REF_FREQ / 2);
cfgr = 1 << RCC_CFGR_PLLSRC_Pos;
if ((div & 1) && div <= 16)
cfgr |= RCC_CFGR_PLLXTPRE_HSE_DIV2;
else
div /= 2;
cfgr |= (div - 2) << RCC_CFGR_PLLMULL_Pos;
} else {
// Configure 72Mhz PLL from internal 8Mhz oscillator (HSI)
uint32_t div2 = (CONFIG_CLOCK_FREQ / 8000000) * 2;
cfgr = ((0 << RCC_CFGR_PLLSRC_Pos)
| ((div2 - 2) << RCC_CFGR_PLLMULL_Pos));
}
cfgr |= RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_ADCPRE_DIV8;
RCC->CFGR = cfgr;
RCC->CR |= RCC_CR_PLLON;
// Set flash latency
FLASH->ACR = (2 << FLASH_ACR_LATENCY_Pos) | FLASH_ACR_PRFTBE;
// Wait for PLL lock
while (!(RCC->CR & RCC_CR_PLLRDY))
;
// Switch system clock to PLL
RCC->CFGR = cfgr | RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL)
;
}
/****************************************************************
* GPIO setup
****************************************************************/
static void
stm32f1_alternative_remap(uint32_t mapr_mask, uint32_t mapr_value)
{ {
// The MAPR register is a mix of write only and r/w bits // The MAPR register is a mix of write only and r/w bits
// We have to save the written values in a global variable // We have to save the written values in a global variable
@ -180,65 +230,50 @@ gpio_peripheral(uint32_t gpio, uint32_t mode, int pullup)
} }
} }
// Handle USB reboot requests
void /****************************************************************
usb_request_bootloader(void) * USB bootloader
****************************************************************/
// Reboot into USB "HID" bootloader
static void
usb_hid_bootloader(void)
{ {
if (!(CONFIG_STM32_FLASH_START_2000 || CONFIG_STM32_FLASH_START_800))
return;
// Enter "stm32duino" or HID bootloader
irq_disable(); irq_disable();
RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN; RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
PWR->CR |= PWR_CR_DBP; PWR->CR |= PWR_CR_DBP;
if (CONFIG_STM32_FLASH_START_800) BKP->DR4 = 0x424C; // HID Bootloader magic key
// HID Bootloader magic key
BKP->DR4 = 0x424C;
else
// stm32duino bootloader magic key
BKP->DR10 = 0x01;
PWR->CR &=~ PWR_CR_DBP; PWR->CR &=~ PWR_CR_DBP;
NVIC_SystemReset(); NVIC_SystemReset();
} }
// Main clock setup called at chip startup // Reboot into USB "stm32duino" bootloader
static void static void
clock_setup(void) usb_stm32duino_bootloader(void)
{ {
// Configure and enable PLL irq_disable();
uint32_t cfgr; RCC->APB1ENR |= RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN;
if (!CONFIG_STM32_CLOCK_REF_INTERNAL) { PWR->CR |= PWR_CR_DBP;
// Configure 72Mhz PLL from external crystal (HSE) BKP->DR10 = 0x01; // stm32duino bootloader magic key
RCC->CR |= RCC_CR_HSEON; PWR->CR &=~ PWR_CR_DBP;
uint32_t div = CONFIG_CLOCK_FREQ / (CONFIG_CLOCK_REF_FREQ / 2); NVIC_SystemReset();
cfgr = 1 << RCC_CFGR_PLLSRC_Pos;
if ((div & 1) && div <= 16)
cfgr |= RCC_CFGR_PLLXTPRE_HSE_DIV2;
else
div /= 2;
cfgr |= (div - 2) << RCC_CFGR_PLLMULL_Pos;
} else {
// Configure 72Mhz PLL from internal 8Mhz oscillator (HSI)
uint32_t div2 = (CONFIG_CLOCK_FREQ / 8000000) * 2;
cfgr = ((0 << RCC_CFGR_PLLSRC_Pos)
| ((div2 - 2) << RCC_CFGR_PLLMULL_Pos));
}
cfgr |= RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_ADCPRE_DIV8;
RCC->CFGR = cfgr;
RCC->CR |= RCC_CR_PLLON;
// Set flash latency
FLASH->ACR = (2 << FLASH_ACR_LATENCY_Pos) | FLASH_ACR_PRFTBE;
// Wait for PLL lock
while (!(RCC->CR & RCC_CR_PLLRDY))
;
// Switch system clock to PLL
RCC->CFGR = cfgr | RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL)
;
} }
// Handle USB reboot requests
void
usb_request_bootloader(void)
{
if (CONFIG_STM32_FLASH_START_800)
usb_hid_bootloader();
else if (CONFIG_STM32_FLASH_START_2000)
usb_stm32duino_bootloader();
}
/****************************************************************
* Startup
****************************************************************/
// Main entry point - called from armcm_boot.c:ResetHandler() // Main entry point - called from armcm_boot.c:ResetHandler()
void void
armcm_main(void) armcm_main(void)