AIOC/stm32/aioc-fw/Src/main.c

254 wiersze
6.0 KiB
C

#include "stm32f3xx_hal.h"
#include "aioc.h"
#include "settings.h"
#include "led.h"
#include "ptt.h"
#include "usb.h"
#include <assert.h>
#include <stdio.h>
// 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<len; i++) {
ITM_SendChar(*ptr++);
}
return len;
}
void _close(void)
{
}
void _lseek(void)
{
}
void _read(void)
{
}
void _fstat(void)
{
}
void _getpid(void)
{
}
void _isatty(void)
{
}
void _kill(void)
{
}
int main(void)
{
SystemReset();
SystemClock_Config();
Settings_Init();
LED_Init();
LED_MODE(0, LED_MODE_SLOWPULSE2X);
LED_MODE(1, LED_MODE_SLOWPULSE2X);
PTT_Init();
USB_Init();
uint32_t i = 0;
while (1) {
USB_Task();
if ( (i++ & 0x7FFF) == 0) {
usb_audio_fbstats_t fb;
USB_AudioGetSpeakerFeedbackStats(&fb);
usb_audio_bufstats_t buf;
USB_AudioGetSpeakerBufferStats(&buf);
#if 0
printf("buf: (%d/%d/%d) fb: (%06lX/%06lX/%06lX)\n",
buf.bufLevelMin, buf.bufLevelMax, buf.bufLevelAvg,
fb.feedbackMin, fb.feedbackMax, fb.feedbackAvg);
#endif
}
}
return 0;
}
void NMI_Handler(void) {
}
void HardFault_Handler(void) {
/* Go to infinite loop when Hard Fault exception occurs */
while (1) {
}
}
void MemManage_Handler(void) {
/* Go to infinite loop when Memory Manage exception occurs */
while (1) {
}
}
void BusFault_Handler(void) {
/* Go to infinite loop when Bus Fault exception occurs */
while (1) {
}
}
void UsageFault_Handler(void) {
/* Go to infinite loop when Usage Fault exception occurs */
while (1) {
}
}
void SVC_Handler(void) {
}
void DebugMon_Handler(void) {
}
void PendSV_Handler(void) {
}
void SysTick_Handler(void) {
HAL_IncTick();
}