kopia lustrzana https://github.com/skuep/AIOC
254 wiersze
6.0 KiB
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();
|
|
}
|
|
|