#include "stm32f3xx_hal.h" #include "aioc.h" #include "settings.h" #include "led.h" #include "ptt.h" #include "usb.h" #include #include // from ST application note AN2606 // Table 171: Bootloader device-dependent parameters #if defined(STM32F302xB) || defined(STM32F302xC) || \ defined(STM32F303xB) || defined(STM32F303xC) || \ defined(STM32F373xC) #define SYSTEM_MEMORY_BASE 0x1FFFD800 #else #warning Live DFU reboot not supported on this MCU #endif #define USB_RESET_DELAY 100 /* ms */ static void SystemClock_Config(void) { HAL_StatusTypeDef status; /* Enable external oscillator and configure PLL: 8 MHz (HSE) / 1 * 9 = 72 MHz */ RCC_OscInitTypeDef OscConfig = { .OscillatorType = RCC_OSCILLATORTYPE_HSE, .HSEState = RCC_HSE_ON, .HSEPredivValue = RCC_HSE_PREDIV_DIV1, .PLL = { .PLLState = RCC_PLL_ON, .PLLSource = RCC_CFGR_PLLSRC_HSE_PREDIV, .PLLMUL = RCC_PLL_MUL9 } }; status = HAL_RCC_OscConfig(&OscConfig); assert(status == HAL_OK); /* Set correct peripheral clocks. 72 MHz (PLL) / 1.5 = 48 MHz */ RCC_PeriphCLKInitTypeDef PeriphClk = { .PeriphClockSelection = RCC_PERIPHCLK_USB, .USBClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5 }; status = HAL_RCCEx_PeriphCLKConfig(&PeriphClk); assert(status == HAL_OK); /* Set up divider for maximum speeds and switch clock */ RCC_ClkInitTypeDef ClkConfig = { .ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2, .SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK, .AHBCLKDivider = RCC_SYSCLK_DIV1, .APB1CLKDivider = RCC_HCLK_DIV2, .APB2CLKDivider = RCC_HCLK_DIV1 }; status = HAL_RCC_ClockConfig(&ClkConfig, FLASH_LATENCY_2); assert(status == HAL_OK); NVIC_SetPriority(SysTick_IRQn, AIOC_IRQ_PRIO_SYSTICK); /* Enable MCO Pin to PLL/2 output */ __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GpioInit = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF0_MCO }; HAL_GPIO_Init(GPIOA, &GpioInit); HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLLCLK_DIV2, RCC_MCODIV_1); } static void SystemReset(void) { uint32_t resetFlags = RCC->CSR; /* Clear reset flags */ RCC->CSR |= RCC_CSR_RMVF; /* Reset USB if necessary */ if (!(resetFlags & RCC_CSR_PORRSTF)) { /* Since the USB Pullup is hardwired to the supply voltage, * the host (re-)enumerates our USB device only during Power-On-Reset. * For all other reset causes, do a manual USB reset. */ USB_Reset(); #if 1 /* Use SysTick to delay before continuing */ SysTick->LOAD = ((uint32_t) USB_RESET_DELAY * (HAL_RCC_GetHCLKFreq() / 1000)) - 1; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; while (! (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) ) /* Wait for timer expiration */; SysTick->CTRL = 0x00000000; /* Reset SysTick */ #endif } if (resetFlags & RCC_CSR_IWDGRSTF) { #if defined(SYSTEM_MEMORY_BASE) /* Reset cause was watchdog, which is used for rebooting into the bootloader. Set stack pointer to *SYSTEM_MEMORY_BASE and jump to *(SYSTEM_MEMORY_BASE + 4) https://stackoverflow.com/a/42031657 */ asm volatile ( " msr msp, %[sp] \n" " bx %[pc] \n" :: [sp] "r" (*( (uint32_t*)(SYSTEM_MEMORY_BASE) )), [pc] "r" (*( (uint32_t*)(SYSTEM_MEMORY_BASE + 4) )) ); #else while(1) ; #endif } /* Initialize HAL */ HAL_Init(); /* Enable Clock to SYSCFG */ __HAL_RCC_SYSCFG_CLK_ENABLE(); /* Enable SWO debug output */ __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitTypeDef GpioSWOInit = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = GPIO_AF0_TRACE }; HAL_GPIO_Init(GPIOB, &GpioSWOInit); } int _write(int file, char *ptr, int len) { for (uint32_t i=0; i