From 426de167cb71e24207d9b2fd1546cb18e74f0b79 Mon Sep 17 00:00:00 2001 From: bkleiner Date: Sat, 20 Apr 2024 00:26:09 +0200 Subject: [PATCH] make firmware compile for stm32g4 --- boards/STM32F405RG.json | 2 +- boards/STM32F411RE.json | 2 +- boards/STM32F722RE.json | 2 +- boards/STM32F745XG.json | 2 +- boards/STM32F765VI.json | 2 +- boards/STM32G473CE.json | 37 ++ boards/STM32H743VI.json | 2 +- platformio.ini | 20 +- script/device_gen.py | 3 +- src/core/target.h | 2 + src/driver/adc.h | 6 +- src/driver/at32/adc.c | 8 +- src/driver/fmc.h | 5 +- src/driver/stm32/adc.c | 37 +- src/driver/stm32/dma.c | 30 +- src/driver/stm32/dma.h | 17 + src/driver/stm32/exti.c | 2 +- src/driver/stm32/fmc.c | 14 +- src/driver/stm32/motor_dshot.c | 10 +- src/driver/stm32/motor_pwm.c | 2 +- src/driver/stm32/reset.c | 6 + src/driver/stm32/serial.c | 6 +- src/driver/stm32/spi.c | 18 +- src/driver/stm32/system.h | 33 +- src/driver/stm32/timer.c | 202 +++------- src/driver/stm32/usb.c | 24 +- src/driver/timer.h | 22 +- src/system/stm32g473/flash_layout.ld | 149 +++++++ src/system/stm32g473/gpio_pins.in | 170 ++++++++ src/system/stm32g473/gpio_pins.yaml | 566 +++++++++++++++++++++++++++ src/system/stm32g473/interrupts.c | 108 +++++ src/system/stm32g473/startup.S | 245 ++++++++++++ src/system/stm32g473/system.c | 278 +++++++++++++ 33 files changed, 1838 insertions(+), 194 deletions(-) create mode 100644 boards/STM32G473CE.json create mode 100644 src/system/stm32g473/flash_layout.ld create mode 100644 src/system/stm32g473/gpio_pins.in create mode 100644 src/system/stm32g473/gpio_pins.yaml create mode 100644 src/system/stm32g473/interrupts.c create mode 100644 src/system/stm32g473/startup.S create mode 100644 src/system/stm32g473/system.c diff --git a/boards/STM32F405RG.json b/boards/STM32F405RG.json index 5221432e7..b2216fca1 100644 --- a/boards/STM32F405RG.json +++ b/boards/STM32F405RG.json @@ -34,5 +34,5 @@ ] }, "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f405rg.html", - "vendor": "Generic" + "vendor": "ST" } \ No newline at end of file diff --git a/boards/STM32F411RE.json b/boards/STM32F411RE.json index 8e267e78a..bedfb9369 100644 --- a/boards/STM32F411RE.json +++ b/boards/STM32F411RE.json @@ -34,5 +34,5 @@ ] }, "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f411re.html", - "vendor": "Generic" + "vendor": "ST" } \ No newline at end of file diff --git a/boards/STM32F722RE.json b/boards/STM32F722RE.json index b0d402e61..9c65c1a94 100644 --- a/boards/STM32F722RE.json +++ b/boards/STM32F722RE.json @@ -30,5 +30,5 @@ ] }, "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f722re.html", - "vendor": "Generic" + "vendor": "ST" } \ No newline at end of file diff --git a/boards/STM32F745XG.json b/boards/STM32F745XG.json index c00d1276b..269a2eeec 100644 --- a/boards/STM32F745XG.json +++ b/boards/STM32F745XG.json @@ -30,5 +30,5 @@ ] }, "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f745xg.html", - "vendor": "Generic" + "vendor": "ST" } \ No newline at end of file diff --git a/boards/STM32F765VI.json b/boards/STM32F765VI.json index cba9f322f..cbcbe5eb7 100644 --- a/boards/STM32F765VI.json +++ b/boards/STM32F765VI.json @@ -30,5 +30,5 @@ ] }, "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32f765vi.html", - "vendor": "Generic" + "vendor": "ST" } \ No newline at end of file diff --git a/boards/STM32G473CE.json b/boards/STM32G473CE.json new file mode 100644 index 000000000..f3f5e5366 --- /dev/null +++ b/boards/STM32G473CE.json @@ -0,0 +1,37 @@ +{ + "build": { + "core": "stm32", + "cpu": "cortex-m4", + "extra_flags": "-DSTM32G473xx -DSTM32G473 -DSTM32G4xx -DSTM32G4 -DSTM32 -DMCU_NAME=stm32g473 -DHSE_VALUE=8000000U", + "f_cpu": "170000000L", + "mcu": "stm32g473", + "product_line": "STM32G473xx", + "variant": "Generic_G473" + }, + "debug": { + "jlink_device": "STM32G473CB", + "openocd_target": "stm32g4x", + "svd_path": "STM32G473xx.svd" + }, + "frameworks": [ + "arduino", + "cmsis", + "libopencm3", + "stm32cube" + ], + "name": "STM32G473CE (128k RAM. 512k Flash)", + "upload": { + "maximum_ram_size": 131072, + "maximum_size": 524288, + "protocol": "stlink", + "protocols": [ + "stlink", + "jlink", + "cmsis-dap", + "blackmagic", + "mbed" + ] + }, + "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32g473ce.html", + "vendor": "ST" +} \ No newline at end of file diff --git a/boards/STM32H743VI.json b/boards/STM32H743VI.json index acc67884c..8375da1f4 100644 --- a/boards/STM32H743VI.json +++ b/boards/STM32H743VI.json @@ -30,5 +30,5 @@ ] }, "url": "https://www.st.com/en/microcontrollers-microprocessors/stm32h743vi.html", - "vendor": "Generic" + "vendor": "ST" } \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 8b8e9f2c7..8348bed7b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -35,7 +35,7 @@ build_flags = [stm32] extends = common -platform = ststm32@~17.0.0 +platform = ststm32@~17.3.0 build_src_filter = ${common.build_src_filter} + framework = stm32cube board_build.stm32cube.custom_system_setup = yes @@ -133,6 +133,24 @@ build_flags = [env:stm32h743] extends = stm32h743 +[stm32g4] +extends = stm32 +system_flags = + -mfloat-abi=hard + -mfpu=fpv4-sp-d16 + +[stm32g473] +extends = stm32g4 +board = STM32G473CE +build_src_filter = ${stm32.build_src_filter} + +board_build.ldscript = $PROJECT_DIR/src/system/stm32g473/flash_layout.ld +build_flags = + ${stm32g4.build_flags} + -Isrc/system/stm32g473 + +[env:stm32g473] +extends = stm32g473 + [at32] extends = common platform = https://github.com/ArteryTek/platform-arterytekat32.git#5729d36 diff --git a/script/device_gen.py b/script/device_gen.py index 01261eaa2..28d9de8ad 100644 --- a/script/device_gen.py +++ b/script/device_gen.py @@ -33,7 +33,7 @@ def parse_all(self): ) # roughly filter to supported devices - supported = ["stm32f4", "stm32f7", "stm32h7"] + supported = ["stm32f4", "stm32g4", "stm32f7", "stm32h7"] device_file_names = [ dfn for dfn in device_file_names if any(s in dfn for s in supported) ] @@ -109,6 +109,7 @@ def __getitem__(self, item) -> modm_devices.device.Device: devices = [ "stm32f405rg", "stm32f411re", + "stm32g473ce", "stm32f722re", "stm32f745vg", "stm32f765vi", diff --git a/src/core/target.h b/src/core/target.h index 8aacbf9dd..a191d3c26 100644 --- a/src/core/target.h +++ b/src/core/target.h @@ -45,7 +45,9 @@ typedef enum { SERIAL_PORT4, SERIAL_PORT5, #endif +#ifndef STM32G4 SERIAL_PORT6, +#endif #if defined(STM32F7) || defined(STM32H7) || defined(AT32F4) SERIAL_PORT7, SERIAL_PORT8, diff --git a/src/driver/adc.h b/src/driver/adc.h index f56b2a5ef..ace908273 100644 --- a/src/driver/adc.h +++ b/src/driver/adc.h @@ -10,7 +10,11 @@ typedef enum { ADC_DEVICE2, ADC_DEVICE3, #endif - ADC_DEVICEMAX, +#ifdef STM32G473 + ADC_DEVICE4, + ADC_DEVICE5, +#endif + ADC_DEVICE_MAX, } adc_devices_t; typedef enum { diff --git a/src/driver/at32/adc.c b/src/driver/at32/adc.c index 8be05fd2f..689af521b 100644 --- a/src/driver/at32/adc.c +++ b/src/driver/at32/adc.c @@ -14,7 +14,7 @@ extern uint16_t adc_array[ADC_CHAN_MAX]; extern adc_channel_t adc_pins[ADC_CHAN_MAX]; -static adc_type *adc_devs[ADC_DEVICEMAX] = { +static adc_type *adc_devs[ADC_DEVICE_MAX] = { ADC1, ADC2, ADC3, @@ -23,7 +23,7 @@ static adc_type *adc_devs[ADC_DEVICEMAX] = { static void adc_init_pin(adc_chan_t chan, gpio_pins_t pin) { adc_array[chan] = 1; adc_pins[chan].pin = PIN_NONE; - adc_pins[chan].dev = ADC_DEVICEMAX; + adc_pins[chan].dev = ADC_DEVICE_MAX; switch (chan) { case ADC_CHAN_VREF: @@ -70,7 +70,7 @@ static void adc_init_dev() { common_init.vbat_state = FALSE; adc_common_config(&common_init); - for (uint32_t i = 0; i < ADC_DEVICEMAX; i++) { + for (uint32_t i = 0; i < ADC_DEVICE_MAX; i++) { adc_base_config_type base_init; base_init.sequence_mode = FALSE; base_init.repeat_mode = FALSE; @@ -141,7 +141,7 @@ uint16_t adc_read_raw(adc_chan_t index) { do { last_adc_chan = (last_adc_chan + 1) % ADC_CHAN_MAX; // skip through all channels without a dev - } while (adc_pins[last_adc_chan].dev == ADC_DEVICEMAX); + } while (adc_pins[last_adc_chan].dev == ADC_DEVICE_MAX); adc_start_conversion(last_adc_chan); } diff --git a/src/driver/fmc.h b/src/driver/fmc.h index aac0ec6ab..943e68b46 100644 --- a/src/driver/fmc.h +++ b/src/driver/fmc.h @@ -4,7 +4,10 @@ #include "util/util.h" -#if defined(STM32H7) +#if defined(STM32G4) +#define FLASH_WORD_SIZE 8 +typedef uint64_t flash_word_t; +#elif defined(STM32H7) #define FLASH_WORD_SIZE 32 typedef uint64_t flash_word_t; #else diff --git a/src/driver/stm32/adc.c b/src/driver/stm32/adc.c index 6220ab227..8fcd1c70c 100644 --- a/src/driver/stm32/adc.c +++ b/src/driver/stm32/adc.c @@ -5,12 +5,25 @@ typedef struct { ADC_Common_TypeDef *common; } adc_dev_t; -#ifdef STM32H7 +#if defined(STM32G4) +#define ADC_INTERNAL_CHANNEL ADC_DEVICE1 +#define LL_ADC_CHANNEL_TEMPSENSOR LL_ADC_CHANNEL_TEMPSENSOR_ADC1 +#define ADC_SAMPLINGTIME LL_ADC_SAMPLINGTIME_247CYCLES_5 +#define READY_TO_CONVERT(dev) LL_ADC_IsActiveFlag_EOC(dev) + +static const adc_dev_t adc_dev[ADC_DEVICE_MAX] = { + {.adc = ADC1, .common = ADC12_COMMON}, + {.adc = ADC2, .common = ADC12_COMMON}, + {.adc = ADC3, .common = ADC345_COMMON}, + {.adc = ADC4, .common = ADC345_COMMON}, + {.adc = ADC5, .common = ADC345_COMMON}, +}; +#elif defined(STM32H7) #define ADC_INTERNAL_CHANNEL ADC_DEVICE3 #define ADC_SAMPLINGTIME LL_ADC_SAMPLINGTIME_387CYCLES_5 #define READY_TO_CONVERT(dev) LL_ADC_IsActiveFlag_EOC(dev) -static const adc_dev_t adc_dev[ADC_DEVICEMAX] = { +static const adc_dev_t adc_dev[ADC_DEVICE_MAX] = { {.adc = ADC1, .common = ADC12_COMMON}, {.adc = ADC2, .common = ADC12_COMMON}, {.adc = ADC3, .common = ADC3_COMMON}, @@ -20,7 +33,7 @@ static const adc_dev_t adc_dev[ADC_DEVICEMAX] = { #define ADC_SAMPLINGTIME LL_ADC_SAMPLINGTIME_480CYCLES #define READY_TO_CONVERT(dev) LL_ADC_IsActiveFlag_EOCS(dev) -static const adc_dev_t adc_dev[ADC_DEVICEMAX] = { +static const adc_dev_t adc_dev[ADC_DEVICE_MAX] = { {.adc = ADC1, .common = ADC}, }; #endif @@ -56,7 +69,7 @@ static const uint32_t channel_map[] = { static void adc_init_pin(adc_chan_t chan, gpio_pins_t pin) { adc_array[chan] = 1; adc_pins[chan].pin = PIN_NONE; - adc_pins[chan].dev = ADC_DEVICEMAX; + adc_pins[chan].dev = ADC_DEVICE_MAX; switch (chan) { case ADC_CHAN_VREF: @@ -117,7 +130,10 @@ static void adc_init_dev(adc_devices_t index) { LL_ADC_InitTypeDef adc_init; adc_init.Resolution = LL_ADC_RESOLUTION_12B; -#ifdef STM32H7 +#if defined(STM32G4) + adc_init.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + adc_init.LowPowerMode = LL_ADC_LP_MODE_NONE; +#elif defined(STM32H7) adc_init.LeftBitShift = LL_ADC_LEFT_BIT_SHIFT_NONE; adc_init.LowPowerMode = LL_ADC_LP_MODE_NONE; #else @@ -165,7 +181,7 @@ static void adc_start_conversion(adc_chan_t index) { LL_ADC_SetChannelSamplingTime(dev->adc, chan->channel, ADC_SAMPLINGTIME); LL_ADC_REG_SetSequencerRanks(dev->adc, LL_ADC_REG_RANK_1, chan->channel); -#ifdef STM32H7 +#if defined(STM32H7) || defined(STM32G4) LL_ADC_REG_StartConversion(dev->adc); #else LL_ADC_REG_StartConversionSWStart(dev->adc); @@ -173,7 +189,10 @@ static void adc_start_conversion(adc_chan_t index) { } void adc_init() { -#ifdef STM32H7 +#if defined(STM32G4) + rcc_enable(RCC_AHB2_GRP1(ADC12)); + rcc_enable(RCC_AHB2_GRP1(ADC345)); +#elif defined(STM32H7) rcc_enable(RCC_AHB1_GRP1(ADC12)); rcc_enable(RCC_AHB4_GRP1(ADC3)); #else @@ -192,7 +211,7 @@ void adc_init() { adc_init_pin(ADC_CHAN_IBAT, target.ibat); } - for (uint32_t i = 0; i < ADC_DEVICEMAX; i++) { + for (uint32_t i = 0; i < ADC_DEVICE_MAX; i++) { adc_init_dev(i); } @@ -211,7 +230,7 @@ uint16_t adc_read_raw(adc_chan_t index) { do { last_adc_chan = (last_adc_chan + 1) % ADC_CHAN_MAX; // skip through all channels without a dev - } while (adc_pins[last_adc_chan].dev == ADC_DEVICEMAX); + } while (adc_pins[last_adc_chan].dev == ADC_DEVICE_MAX); adc_start_conversion(last_adc_chan); } diff --git a/src/driver/stm32/dma.c b/src/driver/stm32/dma.c index 2797a6198..dfe16fc06 100644 --- a/src/driver/stm32/dma.c +++ b/src/driver/stm32/dma.c @@ -20,6 +20,20 @@ // DMA2 Stream6 TIM1_CH3 // DMA2 Stream7 +#if defined(STM32G4) +#define DMA_STREAMS \ + DMA_STREAM(2, 0, 3, SPI1_RX) \ + DMA_STREAM(2, 0, 6, SPI1_TX) \ + DMA_STREAM(1, 0, 4, SPI2_RX) \ + DMA_STREAM(1, 0, 5, SPI2_TX) \ + DMA_STREAM(1, 0, 1, SPI3_RX) \ + DMA_STREAM(1, 0, 8, SPI3_TX) \ + DMA_STREAM(2, 0, 1, SPI4_RX) \ + DMA_STREAM(2, 0, 2, SPI4_TX) \ + DMA_STREAM(2, 0, 4, TIM1_CH1) \ + DMA_STREAM(2, 0, 7, TIM1_CH3) \ + DMA_STREAM(2, 0, 5, TIM1_CH4) +#else #define DMA_STREAMS \ DMA_STREAM(2, 3, 2, SPI1_RX) \ DMA_STREAM(2, 3, 5, SPI1_TX) \ @@ -32,8 +46,22 @@ DMA_STREAM(2, 6, 3, TIM1_CH1) \ DMA_STREAM(2, 6, 6, TIM1_CH3) \ DMA_STREAM(2, 6, 4, TIM1_CH4) +#endif -#ifdef STM32H7 +#if defined(STM32G4) +#define DMA_STREAM(_port, _chan, _stream, _dev) \ + [DMA_DEVICE_##_dev] = { \ + .device = DMA_DEVICE_##_dev, \ + .port = DMA##_port, \ + .port_index = _port, \ + .channel = -1, \ + .channel_index = -1, \ + .request = LL_DMAMUX_REQ_##_dev, \ + .stream = DMA##_port##_Channel##_stream, \ + .stream_index = LL_DMA_CHANNEL_##_stream, \ + .irq = DMA##_port##_Channel##_stream##_IRQn, \ + }, +#elif defined(STM32H7) #define DMA_STREAM(_port, _chan, _stream, _dev) \ [DMA_DEVICE_##_dev] = { \ .device = DMA_DEVICE_##_dev, \ diff --git a/src/driver/stm32/dma.h b/src/driver/stm32/dma.h index b47d6011c..4f6269627 100644 --- a/src/driver/stm32/dma.h +++ b/src/driver/stm32/dma.h @@ -1,5 +1,20 @@ #pragma once +#ifdef STM32G4 +#define DMA_FLAG_TE (0x1 << 3) +#define DMA_FLAG_HT (0x1 << 2) +#define DMA_FLAG_TC (0x1 << 1) +#define DMA_FLAG_GI (0x1 << 0) + +#define dma_flag_for_channel(dev, flags) ((flags) << (dev->stream_index * 4)) +#define dma_is_flag_active_tc(dev) READ_BIT(dev->port->ISR, dma_flag_for_channel(dev, DMA_FLAG_TC)) +#define dma_clear_flag_tc(dev) WRITE_REG(dev->port->IFCR, dma_flag_for_channel(dev, DMA_FLAG_TC | DMA_FLAG_TE | DMA_FLAG_HT | DMA_FLAG_GI)); + +#define LL_DMA_EnableStream LL_DMA_EnableChannel +#define LL_DMA_DisableStream LL_DMA_DisableChannel +#define LL_DMA_IsEnabledStream LL_DMA_IsEnabledChannel + +#else #define DMA_FLAG_TC (0x1 << 5) #define DMA_FLAG_HT (0x1 << 4) #define DMA_FLAG_TE (0x1 << 3) @@ -19,3 +34,5 @@ static const uint32_t _dma_flag_shift[] = {0, 6, 16, 22, 0, 6, 16, 22}; else \ WRITE_REG(dev->port->HIFCR, dma_flag_for_channel(dev, DMA_FLAG_TC | DMA_FLAG_TE | DMA_FLAG_HT | DMA_FLAG_FE)); \ } + +#endif \ No newline at end of file diff --git a/src/driver/stm32/exti.c b/src/driver/stm32/exti.c index 6beb94945..e0f2e84cf 100644 --- a/src/driver/stm32/exti.c +++ b/src/driver/stm32/exti.c @@ -172,7 +172,7 @@ void EXTI15_10_IRQHandler() { handle_exit_isr(); } -#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) +#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7) || defined(STM32G4) #define EXTI5_IRQn EXTI9_5_IRQn #define EXTI6_IRQn EXTI9_5_IRQn diff --git a/src/driver/stm32/fmc.c b/src/driver/stm32/fmc.c index 0c65b4fd7..2be8c385d 100644 --- a/src/driver/stm32/fmc.c +++ b/src/driver/stm32/fmc.c @@ -13,7 +13,9 @@ #define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGSERR) #endif -#ifdef STM32H7 +#if defined(STM32G4) +#define PROGRAM_TYPE FLASH_TYPEPROGRAM_DOUBLEWORD +#elif defined(STM32H7) #define PROGRAM_TYPE FLASH_TYPEPROGRAM_FLASHWORD #else #define PROGRAM_TYPE FLASH_TYPEPROGRAM_WORD @@ -34,7 +36,15 @@ void fmc_unlock() { void fmc_erase() { // clear error status __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); -#ifdef STM32H7 +#if defined(STM32G4) + uint32_t page_error; + FLASH_EraseInitTypeDef erase_init; + erase_init.TypeErase = FLASH_TYPEERASE_PAGES; + erase_init.Banks = FLASH_BANK_1; + erase_init.Page = 24; + erase_init.NbPages = 8; + HAL_FLASHEx_Erase(&erase_init, &page_error); +#elif defined(STM32H7) FLASH_Erase_Sector(FLASH_SECTOR_1, FLASH_BANK_BOTH, FLASH_VOLTAGE_RANGE_3); #else FLASH_Erase_Sector(FLASH_SECTOR_3, FLASH_VOLTAGE_RANGE_3); diff --git a/src/driver/stm32/motor_dshot.c b/src/driver/stm32/motor_dshot.c index e3fb601b7..f6468c1b8 100644 --- a/src/driver/stm32/motor_dshot.c +++ b/src/driver/stm32/motor_dshot.c @@ -112,7 +112,7 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { LL_DMA_InitTypeDef DMA_InitStructure; LL_DMA_StructInit(&DMA_InitStructure); -#ifdef STM32H7 +#if defined(STM32H7) || defined(STM32G4) DMA_InitStructure.PeriphRequest = dma->request; #else DMA_InitStructure.Channel = dma->channel; @@ -127,9 +127,11 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL; DMA_InitStructure.Priority = LL_DMA_PRIORITY_VERYHIGH; +#ifndef STM32G4 DMA_InitStructure.FIFOMode = LL_DMA_FIFOMODE_DISABLE; DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; DMA_InitStructure.PeriphBurst = LL_DMA_PBURST_SINGLE; +#endif LL_DMA_Init(dma->port, dma->stream_index, &DMA_InitStructure); interrupt_enable(dma->irq, DMA_PRIORITY); @@ -210,9 +212,9 @@ static void dshot_dma_setup_port(uint32_t index) { dma_clear_flag_tc(dma); - dma->stream->PAR = (uint32_t)&port->gpio->BSRR; - dma->stream->M0AR = (uint32_t)&port_dma_buffer[index][0]; - dma->stream->NDTR = DSHOT_DMA_BUFFER_SIZE; + LL_DMA_SetPeriphAddress(dma->port, dma->stream_index, (uint32_t)&port->gpio->BSRR); + LL_DMA_SetMemoryAddress(dma->port, dma->stream_index, (uint32_t)&port_dma_buffer[index][0]); + LL_DMA_SetDataLength(dma->port, dma->stream_index, DSHOT_DMA_BUFFER_SIZE); LL_DMA_EnableStream(dma->port, dma->stream_index); dshot_enable_dma_request(port->timer_channel); diff --git a/src/driver/stm32/motor_pwm.c b/src/driver/stm32/motor_pwm.c index 28a50956e..1b26ea667 100644 --- a/src/driver/stm32/motor_pwm.c +++ b/src/driver/stm32/motor_pwm.c @@ -48,7 +48,7 @@ void motor_pwm_init() { timer_up_init(tim, PWM_DIVIDER, PWM_TOP); LL_TIM_OC_Init(timer_defs[tim].instance, timer_channel_val(ch), &tim_oc_init); LL_TIM_EnableCounter(timer_defs[tim].instance); -#ifndef STM32F411 +#if defined(TIMER14) if (tim != TIMER14) { LL_TIM_EnableAllOutputs(timer_defs[tim].instance); } diff --git a/src/driver/stm32/reset.c b/src/driver/stm32/reset.c index 827ac0ae2..089dfc2b8 100644 --- a/src/driver/stm32/reset.c +++ b/src/driver/stm32/reset.c @@ -8,6 +8,12 @@ #define BOOTLOADER_OFFSET 0x1FFF0000 #endif +#ifdef STM32G4 +#define BOOTLOADER_OFFSET 0x1FFF0000 +#define LL_RTC_BAK_SetRegister LL_RTC_BKP_SetRegister +#define LL_RTC_BAK_GetRegister LL_RTC_BKP_GetRegister +#endif + #ifdef STM32F7 #define BOOTLOADER_OFFSET 0x1FF00000 #endif diff --git a/src/driver/stm32/serial.c b/src/driver/stm32/serial.c index 50905c22b..855531eed 100644 --- a/src/driver/stm32/serial.c +++ b/src/driver/stm32/serial.c @@ -36,12 +36,14 @@ const usart_port_def_t usart_port_defs[SERIAL_PORT_MAX] = { .rcc = RCC_APB1_GRP1(UART5), }, #endif +#ifndef STM32G4 { .channel_index = 6, .channel = USART6, .irq = USART6_IRQn, .rcc = RCC_APB2_GRP1(USART6), }, +#endif #if defined(STM32F7) || defined(STM32H7) { .channel_index = 7, @@ -137,7 +139,7 @@ void serial_hard_init(serial_port_t *serial, serial_port_config_t config, bool s } #endif -#if !defined(STM32F7) && !defined(STM32H7) +#if !defined(STM32F7) && !defined(STM32H7) && !defined(STM32G4) LL_USART_ClearFlag_RXNE(USART.channel); #endif LL_USART_ClearFlag_TC(USART.channel); @@ -268,7 +270,9 @@ USART_IRQ_HANDLER(3) USART_IRQ_HANDLER(4) USART_IRQ_HANDLER(5) #endif +#ifndef STM32G4 USART_IRQ_HANDLER(6) +#endif #if defined(STM32F7) || defined(STM32H7) USART_IRQ_HANDLER(7) USART_IRQ_HANDLER(8) diff --git a/src/driver/stm32/spi.c b/src/driver/stm32/spi.c index defc716f8..01bc4224b 100644 --- a/src/driver/stm32/spi.c +++ b/src/driver/stm32/spi.c @@ -110,11 +110,14 @@ static void spi_dma_init_rx(spi_ports_t port) { LL_DMA_DeInit(dma->port, dma->stream_index); LL_DMA_InitTypeDef DMA_InitStructure; -#ifdef STM32H7 +#if defined(STM32H7) || defined(STM32G4) DMA_InitStructure.PeriphRequest = dma->request; - DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&PORT.channel->RXDR; #else DMA_InitStructure.Channel = dma->channel; +#endif +#if defined(STM32H7) + DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&PORT.channel->RXDR; +#else DMA_InitStructure.PeriphOrM2MSrcAddress = LL_SPI_DMA_GetRegAddr(PORT.channel); #endif DMA_InitStructure.MemoryOrM2MDstAddress = 0; @@ -126,9 +129,11 @@ static void spi_dma_init_rx(spi_ports_t port) { DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL; DMA_InitStructure.Priority = LL_DMA_PRIORITY_HIGH; +#ifndef STM32G4 DMA_InitStructure.FIFOMode = LL_DMA_FIFOMODE_DISABLE; DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; DMA_InitStructure.PeriphBurst = LL_DMA_PBURST_SINGLE; +#endif LL_DMA_Init(dma->port, dma->stream_index, &DMA_InitStructure); } @@ -138,11 +143,14 @@ static void spi_dma_init_tx(spi_ports_t port) { LL_DMA_DeInit(dma->port, dma->stream_index); LL_DMA_InitTypeDef DMA_InitStructure; -#ifdef STM32H7 +#if defined(STM32H7) || defined(STM32G4) DMA_InitStructure.PeriphRequest = dma->request; - DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&PORT.channel->TXDR; #else DMA_InitStructure.Channel = dma->channel; +#endif +#if defined(STM32H7) + DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&PORT.channel->TXDR; +#else DMA_InitStructure.PeriphOrM2MSrcAddress = LL_SPI_DMA_GetRegAddr(PORT.channel); #endif DMA_InitStructure.MemoryOrM2MDstAddress = 0; @@ -154,9 +162,11 @@ static void spi_dma_init_tx(spi_ports_t port) { DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL; DMA_InitStructure.Priority = LL_DMA_PRIORITY_VERYHIGH; +#ifndef STM32G4 DMA_InitStructure.FIFOMode = LL_DMA_FIFOMODE_DISABLE; DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; DMA_InitStructure.PeriphBurst = LL_DMA_PBURST_SINGLE; +#endif LL_DMA_Init(dma->port, dma->stream_index, &DMA_InitStructure); } diff --git a/src/driver/stm32/system.h b/src/driver/stm32/system.h index d15d1cabe..e232604bd 100644 --- a/src/driver/stm32/system.h +++ b/src/driver/stm32/system.h @@ -16,6 +16,23 @@ #include #endif +#ifdef STM32G4 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + #ifdef STM32F7 #include #include @@ -50,12 +67,20 @@ #ifdef STM32F411 #define SYS_CLOCK_FREQ_HZ 108000000 -#define PWM_CLOCK_FREQ_HZ 108000000 +#define PWM_CLOCK_FREQ_HZ SYS_CLOCK_FREQ_HZ #define SPI_CLOCK_FREQ_HZ (SYS_CLOCK_FREQ_HZ / 2) #define LOOPTIME_MAX 250 #endif +#ifdef STM32G473 +#define SYS_CLOCK_FREQ_HZ 160000000 +#define PWM_CLOCK_FREQ_HZ SYS_CLOCK_FREQ_HZ +#define SPI_CLOCK_FREQ_HZ SYS_CLOCK_FREQ_HZ + +#define LOOPTIME_MAX 125 +#endif + #ifdef STM32F405 #define SYS_CLOCK_FREQ_HZ 168000000 #define PWM_CLOCK_FREQ_HZ 84000000 @@ -66,7 +91,7 @@ #ifdef STM32F7 #define SYS_CLOCK_FREQ_HZ 216000000 -#define PWM_CLOCK_FREQ_HZ 216000000 +#define PWM_CLOCK_FREQ_HZ SYS_CLOCK_FREQ_HZ #define SPI_CLOCK_FREQ_HZ (SYS_CLOCK_FREQ_HZ / 4) #define LOOPTIME_MAX 125 @@ -102,7 +127,11 @@ typedef struct { uint32_t request; +#ifdef STM32G4 + DMA_Channel_TypeDef *stream; +#else DMA_Stream_TypeDef *stream; +#endif uint8_t stream_index; IRQn_Type irq; diff --git a/src/driver/stm32/timer.c b/src/driver/stm32/timer.c index db8984347..5827fde3e 100644 --- a/src/driver/stm32/timer.c +++ b/src/driver/stm32/timer.c @@ -6,98 +6,45 @@ const timer_def_t timer_defs[TIMER_MAX] = { [TIMER_INVALID] = {}, - [TIMER1] = { - .rcc = RCC_APB2_GRP1(TIM1), - .irq = TIM1_UP_TIM10_IRQn, - .instance = TIM1, - }, - [TIMER2] = { - .rcc = RCC_APB1_GRP1(TIM2), - .irq = TIM2_IRQn, - .instance = TIM2, - }, - [TIMER3] = { - .rcc = RCC_APB1_GRP1(TIM3), - .irq = TIM3_IRQn, - .instance = TIM3, - }, - [TIMER4] = { - .rcc = RCC_APB1_GRP1(TIM4), - .irq = TIM4_IRQn, - .instance = TIM4, - }, - [TIMER5] = { - .rcc = RCC_APB1_GRP1(TIM5), - .irq = TIM5_IRQn, - .instance = TIM5, - }, +#if defined(STM32G4) + [TIMER1] = {.rcc = RCC_APB2_GRP1(TIM1), .irq = TIM1_UP_TIM16_IRQn, .instance = TIM1}, + [TIMER2] = {.rcc = RCC_APB1_GRP1(TIM2), .irq = TIM2_IRQn, .instance = TIM2}, + [TIMER3] = {.rcc = RCC_APB1_GRP1(TIM3), .irq = TIM3_IRQn, .instance = TIM3}, + [TIMER4] = {.rcc = RCC_APB1_GRP1(TIM4), .irq = TIM4_IRQn, .instance = TIM4}, + [TIMER5] = {.rcc = RCC_APB1_GRP1(TIM5), .irq = TIM5_IRQn, .instance = TIM5}, + [TIMER6] = {.rcc = RCC_APB1_GRP1(TIM6), .irq = TIM6_DAC_IRQn, .instance = TIM6}, + [TIMER7] = {.rcc = RCC_APB1_GRP1(TIM7), .irq = TIM7_DAC_IRQn, .instance = TIM7}, + [TIMER8] = {.rcc = RCC_APB2_GRP1(TIM8), .irq = TIM8_UP_IRQn, .instance = TIM8}, + [TIMER15] = {.rcc = RCC_APB2_GRP1(TIM15), .irq = TIM1_BRK_TIM15_IRQn, .instance = TIM15}, + [TIMER16] = {.rcc = RCC_APB2_GRP1(TIM16), .irq = TIM1_UP_TIM16_IRQn, .instance = TIM16}, + [TIMER17] = {.rcc = RCC_APB2_GRP1(TIM17), .irq = TIM1_TRG_COM_TIM17_IRQn, .instance = TIM17}, + [TIMER20] = {.rcc = RCC_APB2_GRP1(TIM20), .irq = TIM20_UP_IRQn, .instance = TIM20}, +#else + [TIMER1] = {.rcc = RCC_APB2_GRP1(TIM1), .irq = TIM1_UP_TIM10_IRQn, .instance = TIM1}, + [TIMER2] = {.rcc = RCC_APB1_GRP1(TIM2), .irq = TIM2_IRQn, .instance = TIM2}, + [TIMER3] = {.rcc = RCC_APB1_GRP1(TIM3), .irq = TIM3_IRQn, .instance = TIM3}, + [TIMER4] = {.rcc = RCC_APB1_GRP1(TIM4), .irq = TIM4_IRQn, .instance = TIM4}, + [TIMER5] = {.rcc = RCC_APB1_GRP1(TIM5), .irq = TIM5_IRQn, .instance = TIM5}, #ifndef STM32F411 - [TIMER6] = { - .rcc = RCC_APB1_GRP1(TIM6), - .irq = TIM6_DAC_IRQn, - .instance = TIM6, - }, - [TIMER7] = { - .rcc = RCC_APB1_GRP1(TIM7), - .irq = TIM7_IRQn, - .instance = TIM7, - }, - [TIMER8] = { - .rcc = RCC_APB2_GRP1(TIM8), - .irq = TIM8_UP_TIM13_IRQn, - .instance = TIM8, - }, + [TIMER6] = {.rcc = RCC_APB1_GRP1(TIM6), .irq = TIM6_DAC_IRQn, .instance = TIM6}, + [TIMER7] = {.rcc = RCC_APB1_GRP1(TIM7), .irq = TIM7_IRQn, .instance = TIM7}, + [TIMER8] = {.rcc = RCC_APB2_GRP1(TIM8), .irq = TIM8_UP_TIM13_IRQn, .instance = TIM8}, #endif #ifndef STM32H7 - [TIMER9] = { - .rcc = RCC_APB2_GRP1(TIM9), - .irq = TIM1_BRK_TIM9_IRQn, - .instance = TIM9, - }, - [TIMER10] = { - .rcc = RCC_APB2_GRP1(TIM10), - .irq = TIM1_UP_TIM10_IRQn, - .instance = TIM10, - }, - [TIMER11] = { - .rcc = RCC_APB2_GRP1(TIM11), - .irq = TIM1_TRG_COM_TIM11_IRQn, - .instance = TIM11, - }, + [TIMER9] = {.rcc = RCC_APB2_GRP1(TIM9), .irq = TIM1_BRK_TIM9_IRQn, .instance = TIM9}, + [TIMER10] = {.rcc = RCC_APB2_GRP1(TIM10), .irq = TIM1_UP_TIM10_IRQn, .instance = TIM10}, + [TIMER11] = {.rcc = RCC_APB2_GRP1(TIM11), .irq = TIM1_TRG_COM_TIM11_IRQn, .instance = TIM11}, #endif #ifndef STM32F411 - [TIMER12] = { - .rcc = RCC_APB1_GRP1(TIM12), - .irq = TIM8_BRK_TIM12_IRQn, - .instance = TIM12, - }, - [TIMER13] = { - .rcc = RCC_APB1_GRP1(TIM13), - .irq = TIM8_UP_TIM13_IRQn, - .instance = TIM13, - }, - [TIMER14] = { - .rcc = RCC_APB1_GRP1(TIM14), - .irq = TIM8_TRG_COM_TIM14_IRQn, - .instance = TIM14, - }, + [TIMER12] = {.rcc = RCC_APB1_GRP1(TIM12), .irq = TIM8_BRK_TIM12_IRQn, .instance = TIM12}, + [TIMER13] = {.rcc = RCC_APB1_GRP1(TIM13), .irq = TIM8_UP_TIM13_IRQn, .instance = TIM13}, + [TIMER14] = {.rcc = RCC_APB1_GRP1(TIM14), .irq = TIM8_TRG_COM_TIM14_IRQn, .instance = TIM14}, #endif #ifdef STM32H743 - [TIMER15] = { - .rcc = RCC_APB2_GRP1(TIM15), - .irq = TIM15_IRQn, - .instance = TIM15, - }, - [TIMER16] = { - .rcc = RCC_APB2_GRP1(TIM16), - .irq = TIM16_IRQn, - .instance = TIM16, - }, - [TIMER17] = { - .rcc = RCC_APB2_GRP1(TIM17), - .irq = TIM17_IRQn, - .instance = TIM17, - }, + [TIMER15] = {.rcc = RCC_APB2_GRP1(TIM15), .irq = TIM15_IRQn, .instance = TIM15}, + [TIMER16] = {.rcc = RCC_APB2_GRP1(TIM16), .irq = TIM16_IRQn, .instance = TIM16}, + [TIMER17] = {.rcc = RCC_APB2_GRP1(TIM17), .irq = TIM17_IRQn, .instance = TIM17}, +#endif #endif }; @@ -149,63 +96,28 @@ static void timer_irq_handler() { #undef TIM1_TRG_COM_TIM11_IRQHandler #endif -void TIM15_IRQHandler() { - timer_irq_handler(); -} -void TIM16_IRQHandler() { - timer_irq_handler(); -} -void TIM17_IRQHandler() { - timer_irq_handler(); -} -void TIM1_BRK_IRQHandler() { - timer_irq_handler(); -} -void TIM1_BRK_TIM9_IRQHandler() { - timer_irq_handler(); -} -void TIM1_CC_IRQHandler() { - timer_irq_handler(); -} -void TIM1_TRG_COM_IRQHandler() { - timer_irq_handler(); -} -void TIM1_TRG_COM_TIM11_IRQHandler() { - timer_irq_handler(); -} -void TIM1_UP_IRQHandler() { - timer_irq_handler(); -} -void TIM1_UP_TIM10_IRQHandler() { - timer_irq_handler(); -} -void TIM2_IRQHandler() { - timer_irq_handler(); -} -void TIM3_IRQHandler() { - timer_irq_handler(); -} -void TIM4_IRQHandler() { - timer_irq_handler(); -} -void TIM5_IRQHandler() { - timer_irq_handler(); -} -void TIM6_DAC_IRQHandler() { - timer_irq_handler(); -} -void TIM7_IRQHandler() { - timer_irq_handler(); -} -void TIM8_BRK_TIM12_IRQHandler() { - timer_irq_handler(); -} -void TIM8_CC_IRQHandler() { - timer_irq_handler(); -} -void TIM8_TRG_COM_TIM14_IRQHandler() { - timer_irq_handler(); -} -void TIM8_UP_TIM13_IRQHandler() { - timer_irq_handler(); -} +void TIM1_BRK_IRQHandler() { timer_irq_handler(); } +void TIM1_BRK_TIM15_IRQHandler() { timer_irq_handler(); } +void TIM1_BRK_TIM9_IRQHandler() { timer_irq_handler(); } +void TIM1_CC_IRQHandler() { timer_irq_handler(); } +void TIM1_TRG_COM_IRQHandler() { timer_irq_handler(); } +void TIM1_TRG_COM_TIM11_IRQHandler() { timer_irq_handler(); } +void TIM1_TRG_COM_TIM17_IRQHandler() { timer_irq_handler(); } +void TIM1_UP_IRQHandler() { timer_irq_handler(); } +void TIM1_UP_TIM10_IRQHandler() { timer_irq_handler(); } +void TIM1_UP_TIM16_IRQHandler() { timer_irq_handler(); } +void TIM15_IRQHandler() { timer_irq_handler(); } +void TIM16_IRQHandler() { timer_irq_handler(); } +void TIM17_IRQHandler() { timer_irq_handler(); } +void TIM2_IRQHandler() { timer_irq_handler(); } +void TIM20_UP_IRQHandler() { timer_irq_handler(); } +void TIM3_IRQHandler() { timer_irq_handler(); } +void TIM4_IRQHandler() { timer_irq_handler(); } +void TIM5_IRQHandler() { timer_irq_handler(); } +void TIM6_DAC_IRQHandler() { timer_irq_handler(); } +void TIM7_DAC_IRQHandler() { timer_irq_handler(); } +void TIM7_IRQHandler() { timer_irq_handler(); } +void TIM8_BRK_TIM12_IRQHandler() { timer_irq_handler(); } +void TIM8_TRG_COM_TIM14_IRQHandler() { timer_irq_handler(); } +void TIM8_UP_IRQHandler() { timer_irq_handler(); } +void TIM8_UP_TIM13_IRQHandler() { timer_irq_handler(); } \ No newline at end of file diff --git a/src/driver/stm32/usb.c b/src/driver/stm32/usb.c index 0d16df287..a415dfab6 100644 --- a/src/driver/stm32/usb.c +++ b/src/driver/stm32/usb.c @@ -19,6 +19,14 @@ #define CDC_PROTOCOL USB_PROTO_NONE +#ifdef STM32G4 +#define USB_IRQ USB_LP_IRQn +#define USB_IRQ_HANDLER USB_LP_IRQHandler +#else +#define USB_IRQ OTG_FS_IRQn +#define USB_IRQ_HANDLER OTG_FS_IRQHandler +#endif + struct cdc_config { struct usb_config_descriptor config; struct usb_iad_descriptor comm_iad; @@ -222,7 +230,7 @@ static usbd_respond cdc_control(usbd_device *dev, usbd_ctlreq *req, usbd_rqc_cal static void cdc_rxonly(usbd_device *dev, uint8_t event, uint8_t ep) { if (ring_buffer_free(&usb_rx_buffer) <= CDC_DATA_SZ) { - interrupt_disable(OTG_FS_IRQn); + interrupt_disable(USB_IRQ); rx_stalled = true; return; } @@ -241,9 +249,9 @@ static void cdc_kickoff_rx() { return; } - interrupt_disable(OTG_FS_IRQn); + interrupt_disable(USB_IRQ); cdc_rxonly(&udev, 0, CDC_RXD_EP); - interrupt_enable(OTG_FS_IRQn, USB_PRIORITY); + interrupt_enable(USB_IRQ, USB_PRIORITY); } static void cdc_txonly(usbd_device *dev, uint8_t event, uint8_t ep) { @@ -278,9 +286,9 @@ static void cdc_kickoff_tx() { return; } - interrupt_disable(OTG_FS_IRQn); + interrupt_disable(USB_IRQ); cdc_txonly(&udev, 0, CDC_TXD_EP); - interrupt_enable(OTG_FS_IRQn, USB_PRIORITY); + interrupt_enable(USB_IRQ, USB_PRIORITY); } static usbd_respond cdc_setconf(usbd_device *dev, uint8_t cfg) { @@ -311,7 +319,7 @@ static usbd_respond cdc_setconf(usbd_device *dev, uint8_t cfg) { } } -void OTG_FS_IRQHandler() { +void USB_IRQ_HANDLER() { usbd_poll(&udev); } @@ -325,12 +333,14 @@ void usb_drv_init() { #ifdef STM32H7 gpio_pin_init_af(PIN_A11, gpio_init, GPIO_AF10_OTG1_FS); gpio_pin_init_af(PIN_A12, gpio_init, GPIO_AF10_OTG1_FS); +#elif defined(STM32G4) + // TODO #else gpio_pin_init_af(PIN_A11, gpio_init, GPIO_AF10_OTG_FS); gpio_pin_init_af(PIN_A12, gpio_init, GPIO_AF10_OTG_FS); #endif - interrupt_enable(OTG_FS_IRQn, USB_PRIORITY); + interrupt_enable(USB_IRQ, USB_PRIORITY); usbd_init(&udev, &usbd_hw, CDC_EP0_SIZE, ubuf, sizeof(ubuf)); usbd_reg_config(&udev, cdc_setconf); diff --git a/src/driver/timer.h b/src/driver/timer.h index 9a704c8ef..843ba6d55 100644 --- a/src/driver/timer.h +++ b/src/driver/timer.h @@ -6,6 +6,20 @@ typedef enum { TIMER_INVALID, +#if defined(STM32G4) + TIMER1, + TIMER2, + TIMER3, + TIMER4, + TIMER5, + TIMER6, + TIMER7, + TIMER8, + TIMER15, + TIMER16, + TIMER17, + TIMER20, +#else TIMER1, TIMER2, TIMER3, @@ -19,18 +33,19 @@ typedef enum { TIMER9, TIMER10, TIMER11, -#ifndef STM32F411 +#if !defined(STM32F411) && !defined(STM32G473) TIMER12, TIMER13, TIMER14, #endif -#ifdef STM32H743 +#if defined(STM32H743) || defined(STM32G473) TIMER15, TIMER16, TIMER17, #endif -#ifdef AT32F4 +#if defined(AT32F4) || defined(STM32G473) TIMER20, +#endif #endif TIMER_MAX, } timer_index_t; @@ -44,6 +59,7 @@ typedef enum { TIMER_CH3 = (0x1 << 4), TIMER_CH3N = (0x1 << 5), TIMER_CH4 = (0x1 << 6), + TIMER_CH4N = (0x1 << 7), TIMER_CH_ALL = 0xff, } timer_channel_t; diff --git a/src/system/stm32g473/flash_layout.ld b/src/system/stm32g473/flash_layout.ld new file mode 100644 index 000000000..db22da8ae --- /dev/null +++ b/src/system/stm32g473/flash_layout.ld @@ -0,0 +1,149 @@ +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of 128K RAM */ + +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0; /* required amount of heap */ +_Min_Stack_Size = 0x4000; /* required amount of stack */ + +/* Specify the memory areas */ +/* +Flash Layout: +0x08000000 - 0x0800C000: isr, rodata, data (Section 0 - Section 2) +0x0800C000 - 0x08010000: configuration, profile (Section 3) +0x08010000 - 0x080FFFFF: code (Section 4 - Section 11) +*/ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 48K + FLASH_CONFIG (r) : ORIGIN = 0x0800C000, LENGTH = 16K + FLASH_CODE (rx) : ORIGIN = 0x08010000, LENGTH = 448K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Define output sections */ +SECTIONS +{ + .config_flash : + { + _config_flash_start = .; + KEEP(*(.config_flash)) + _config_flash_end = .; + } >FLASH_CONFIG + + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH_CODE + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(4); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(4); + } >RAM + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/src/system/stm32g473/gpio_pins.in b/src/system/stm32g473/gpio_pins.in new file mode 100644 index 000000000..c2abe55f1 --- /dev/null +++ b/src/system/stm32g473/gpio_pins.in @@ -0,0 +1,170 @@ +GPIO_PIN(A, 0) +GPIO_AF(PIN_A0, -1, ADC_TAG(ADC_DEVICE1, 1)) +GPIO_AF(PIN_A0, -1, ADC_TAG(ADC_DEVICE2, 1)) +GPIO_AF(PIN_A0, 1, TIMER_TAG(TIMER2, TIMER_CH1)) +GPIO_AF(PIN_A0, 2, TIMER_TAG(TIMER5, TIMER_CH1)) +GPIO_PIN(A, 1) +GPIO_AF(PIN_A1, -1, ADC_TAG(ADC_DEVICE1, 2)) +GPIO_AF(PIN_A1, -1, ADC_TAG(ADC_DEVICE2, 2)) +GPIO_AF(PIN_A1, 1, TIMER_TAG(TIMER2, TIMER_CH2)) +GPIO_AF(PIN_A1, 2, TIMER_TAG(TIMER5, TIMER_CH2)) +GPIO_AF(PIN_A1, 9, TIMER_TAG(TIMER15, TIMER_CH1N)) +GPIO_PIN(A, 2) +GPIO_AF(PIN_A2, -1, ADC_TAG(ADC_DEVICE1, 3)) +GPIO_AF(PIN_A2, 1, TIMER_TAG(TIMER2, TIMER_CH3)) +GPIO_AF(PIN_A2, 2, TIMER_TAG(TIMER5, TIMER_CH3)) +GPIO_AF(PIN_A2, 7, SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX)) +GPIO_AF(PIN_A2, 9, TIMER_TAG(TIMER15, TIMER_CH1)) +GPIO_PIN(A, 3) +GPIO_AF(PIN_A3, -1, ADC_TAG(ADC_DEVICE1, 4)) +GPIO_AF(PIN_A3, 1, TIMER_TAG(TIMER2, TIMER_CH4)) +GPIO_AF(PIN_A3, 2, TIMER_TAG(TIMER5, TIMER_CH4)) +GPIO_AF(PIN_A3, 7, SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX)) +GPIO_AF(PIN_A3, 9, TIMER_TAG(TIMER15, TIMER_CH2)) +GPIO_PIN(A, 4) +GPIO_AF(PIN_A4, -1, ADC_TAG(ADC_DEVICE2, 17)) +GPIO_AF(PIN_A4, 2, TIMER_TAG(TIMER3, TIMER_CH2)) +GPIO_PIN(A, 5) +GPIO_AF(PIN_A5, -1, ADC_TAG(ADC_DEVICE2, 13)) +GPIO_AF(PIN_A5, 1, TIMER_TAG(TIMER2, TIMER_CH1)) +GPIO_AF(PIN_A5, 5, SPI_TAG(SPI_PORT1, RES_SPI_SCK)) +GPIO_PIN(A, 6) +GPIO_AF(PIN_A6, -1, ADC_TAG(ADC_DEVICE2, 3)) +GPIO_AF(PIN_A6, 1, TIMER_TAG(TIMER16, TIMER_CH1)) +GPIO_AF(PIN_A6, 2, TIMER_TAG(TIMER3, TIMER_CH1)) +GPIO_AF(PIN_A6, 5, SPI_TAG(SPI_PORT1, RES_SPI_MISO)) +GPIO_PIN(A, 7) +GPIO_AF(PIN_A7, -1, ADC_TAG(ADC_DEVICE2, 4)) +GPIO_AF(PIN_A7, 1, TIMER_TAG(TIMER17, TIMER_CH1)) +GPIO_AF(PIN_A7, 2, TIMER_TAG(TIMER3, TIMER_CH2)) +GPIO_AF(PIN_A7, 4, TIMER_TAG(TIMER8, TIMER_CH1N)) +GPIO_AF(PIN_A7, 5, SPI_TAG(SPI_PORT1, RES_SPI_MOSI)) +GPIO_AF(PIN_A7, 6, TIMER_TAG(TIMER1, TIMER_CH1N)) +GPIO_PIN(A, 8) +GPIO_AF(PIN_A8, -1, ADC_TAG(ADC_DEVICE5, 1)) +GPIO_AF(PIN_A8, 6, TIMER_TAG(TIMER1, TIMER_CH1)) +GPIO_PIN(A, 9) +GPIO_AF(PIN_A9, -1, ADC_TAG(ADC_DEVICE5, 2)) +GPIO_AF(PIN_A9, 6, TIMER_TAG(TIMER1, TIMER_CH2)) +GPIO_AF(PIN_A9, 7, SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX)) +GPIO_AF(PIN_A9, 10, TIMER_TAG(TIMER2, TIMER_CH3)) +GPIO_PIN(A, 10) +GPIO_AF(PIN_A10, 5, SPI_TAG(SPI_PORT2, RES_SPI_MISO)) +GPIO_AF(PIN_A10, 6, TIMER_TAG(TIMER1, TIMER_CH3)) +GPIO_AF(PIN_A10, 7, SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX)) +GPIO_AF(PIN_A10, 10, TIMER_TAG(TIMER2, TIMER_CH4)) +GPIO_PIN(A, 11) +GPIO_AF(PIN_A11, 5, SPI_TAG(SPI_PORT2, RES_SPI_MOSI)) +GPIO_AF(PIN_A11, 6, TIMER_TAG(TIMER1, TIMER_CH1N)) +GPIO_AF(PIN_A11, 10, TIMER_TAG(TIMER4, TIMER_CH1)) +GPIO_AF(PIN_A11, 11, TIMER_TAG(TIMER1, TIMER_CH4)) +GPIO_PIN(A, 12) +GPIO_AF(PIN_A12, 1, TIMER_TAG(TIMER16, TIMER_CH1)) +GPIO_AF(PIN_A12, 6, TIMER_TAG(TIMER1, TIMER_CH2N)) +GPIO_AF(PIN_A12, 10, TIMER_TAG(TIMER4, TIMER_CH2)) +GPIO_PIN(A, 13) +GPIO_AF(PIN_A13, 1, TIMER_TAG(TIMER16, TIMER_CH1N)) +GPIO_AF(PIN_A13, 10, TIMER_TAG(TIMER4, TIMER_CH3)) +GPIO_PIN(A, 14) +GPIO_AF(PIN_A14, 5, TIMER_TAG(TIMER8, TIMER_CH2)) +GPIO_AF(PIN_A14, 7, SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX)) +GPIO_PIN(A, 15) +GPIO_AF(PIN_A15, 1, TIMER_TAG(TIMER2, TIMER_CH1)) +GPIO_AF(PIN_A15, 2, TIMER_TAG(TIMER8, TIMER_CH1)) +GPIO_AF(PIN_A15, 7, SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX)) +GPIO_PIN(B, 0) +GPIO_AF(PIN_B0, -1, ADC_TAG(ADC_DEVICE1, 15)) +GPIO_AF(PIN_B0, -1, ADC_TAG(ADC_DEVICE3, 12)) +GPIO_AF(PIN_B0, 2, TIMER_TAG(TIMER3, TIMER_CH3)) +GPIO_AF(PIN_B0, 4, TIMER_TAG(TIMER8, TIMER_CH2N)) +GPIO_AF(PIN_B0, 6, TIMER_TAG(TIMER1, TIMER_CH2N)) +GPIO_PIN(B, 1) +GPIO_AF(PIN_B1, -1, ADC_TAG(ADC_DEVICE1, 12)) +GPIO_AF(PIN_B1, -1, ADC_TAG(ADC_DEVICE3, 1)) +GPIO_AF(PIN_B1, 2, TIMER_TAG(TIMER3, TIMER_CH4)) +GPIO_AF(PIN_B1, 4, TIMER_TAG(TIMER8, TIMER_CH3N)) +GPIO_AF(PIN_B1, 6, TIMER_TAG(TIMER1, TIMER_CH3N)) +GPIO_PIN(B, 2) +GPIO_AF(PIN_B2, -1, ADC_TAG(ADC_DEVICE2, 12)) +GPIO_AF(PIN_B2, 2, TIMER_TAG(TIMER5, TIMER_CH1)) +GPIO_AF(PIN_B2, 3, TIMER_TAG(TIMER20, TIMER_CH1)) +GPIO_PIN(B, 3) +GPIO_AF(PIN_B3, 1, TIMER_TAG(TIMER2, TIMER_CH2)) +GPIO_AF(PIN_B3, 4, TIMER_TAG(TIMER8, TIMER_CH1N)) +GPIO_AF(PIN_B3, 5, SPI_TAG(SPI_PORT1, RES_SPI_SCK)) +GPIO_AF(PIN_B3, 6, SPI_TAG(SPI_PORT3, RES_SPI_SCK)) +GPIO_AF(PIN_B3, 7, SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX)) +GPIO_PIN(B, 4) +GPIO_AF(PIN_B4, 1, TIMER_TAG(TIMER16, TIMER_CH1)) +GPIO_AF(PIN_B4, 2, TIMER_TAG(TIMER3, TIMER_CH1)) +GPIO_AF(PIN_B4, 4, TIMER_TAG(TIMER8, TIMER_CH2N)) +GPIO_AF(PIN_B4, 5, SPI_TAG(SPI_PORT1, RES_SPI_MISO)) +GPIO_AF(PIN_B4, 6, SPI_TAG(SPI_PORT3, RES_SPI_MISO)) +GPIO_AF(PIN_B4, 7, SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX)) +GPIO_PIN(B, 5) +GPIO_AF(PIN_B5, 2, TIMER_TAG(TIMER3, TIMER_CH2)) +GPIO_AF(PIN_B5, 3, TIMER_TAG(TIMER8, TIMER_CH3N)) +GPIO_AF(PIN_B5, 5, SPI_TAG(SPI_PORT1, RES_SPI_MOSI)) +GPIO_AF(PIN_B5, 6, SPI_TAG(SPI_PORT3, RES_SPI_MOSI)) +GPIO_AF(PIN_B5, 10, TIMER_TAG(TIMER17, TIMER_CH1)) +GPIO_PIN(B, 6) +GPIO_AF(PIN_B6, 1, TIMER_TAG(TIMER16, TIMER_CH1N)) +GPIO_AF(PIN_B6, 2, TIMER_TAG(TIMER4, TIMER_CH1)) +GPIO_AF(PIN_B6, 5, TIMER_TAG(TIMER8, TIMER_CH1)) +GPIO_AF(PIN_B6, 7, SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX)) +GPIO_PIN(B, 7) +GPIO_AF(PIN_B7, 1, TIMER_TAG(TIMER17, TIMER_CH1N)) +GPIO_AF(PIN_B7, 2, TIMER_TAG(TIMER4, TIMER_CH2)) +GPIO_AF(PIN_B7, 7, SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX)) +GPIO_AF(PIN_B7, 10, TIMER_TAG(TIMER3, TIMER_CH4)) +GPIO_PIN(B, 8) +GPIO_AF(PIN_B8, 1, TIMER_TAG(TIMER16, TIMER_CH1)) +GPIO_AF(PIN_B8, 2, TIMER_TAG(TIMER4, TIMER_CH3)) +GPIO_AF(PIN_B8, 7, SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX)) +GPIO_AF(PIN_B8, 10, TIMER_TAG(TIMER8, TIMER_CH2)) +GPIO_PIN(B, 9) +GPIO_AF(PIN_B9, 1, TIMER_TAG(TIMER17, TIMER_CH1)) +GPIO_AF(PIN_B9, 2, TIMER_TAG(TIMER4, TIMER_CH4)) +GPIO_AF(PIN_B9, 7, SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX)) +GPIO_AF(PIN_B9, 10, TIMER_TAG(TIMER8, TIMER_CH3)) +GPIO_AF(PIN_B9, 12, TIMER_TAG(TIMER1, TIMER_CH3N)) +GPIO_PIN(B, 10) +GPIO_AF(PIN_B10, 1, TIMER_TAG(TIMER2, TIMER_CH3)) +GPIO_AF(PIN_B10, 7, SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX)) +GPIO_PIN(B, 11) +GPIO_AF(PIN_B11, -1, ADC_TAG(ADC_DEVICE1, 14)) +GPIO_AF(PIN_B11, -1, ADC_TAG(ADC_DEVICE2, 14)) +GPIO_AF(PIN_B11, 1, TIMER_TAG(TIMER2, TIMER_CH4)) +GPIO_AF(PIN_B11, 7, SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX)) +GPIO_PIN(B, 12) +GPIO_AF(PIN_B12, -1, ADC_TAG(ADC_DEVICE1, 11)) +GPIO_AF(PIN_B12, -1, ADC_TAG(ADC_DEVICE4, 3)) +GPIO_PIN(B, 13) +GPIO_AF(PIN_B13, -1, ADC_TAG(ADC_DEVICE3, 5)) +GPIO_AF(PIN_B13, 5, SPI_TAG(SPI_PORT2, RES_SPI_SCK)) +GPIO_AF(PIN_B13, 6, TIMER_TAG(TIMER1, TIMER_CH1N)) +GPIO_PIN(B, 14) +GPIO_AF(PIN_B14, -1, ADC_TAG(ADC_DEVICE1, 5)) +GPIO_AF(PIN_B14, -1, ADC_TAG(ADC_DEVICE4, 4)) +GPIO_AF(PIN_B14, 1, TIMER_TAG(TIMER15, TIMER_CH1)) +GPIO_AF(PIN_B14, 5, SPI_TAG(SPI_PORT2, RES_SPI_MISO)) +GPIO_AF(PIN_B14, 6, TIMER_TAG(TIMER1, TIMER_CH2N)) +GPIO_PIN(B, 15) +GPIO_AF(PIN_B15, -1, ADC_TAG(ADC_DEVICE2, 15)) +GPIO_AF(PIN_B15, -1, ADC_TAG(ADC_DEVICE4, 5)) +GPIO_AF(PIN_B15, 1, TIMER_TAG(TIMER15, TIMER_CH2)) +GPIO_AF(PIN_B15, 2, TIMER_TAG(TIMER15, TIMER_CH1N)) +GPIO_AF(PIN_B15, 4, TIMER_TAG(TIMER1, TIMER_CH3N)) +GPIO_AF(PIN_B15, 5, SPI_TAG(SPI_PORT2, RES_SPI_MOSI)) +GPIO_PIN(C, 13) +GPIO_AF(PIN_C13, 4, TIMER_TAG(TIMER1, TIMER_CH1N)) +GPIO_AF(PIN_C13, 6, TIMER_TAG(TIMER8, TIMER_CH4N)) +GPIO_PIN(C, 14) +GPIO_PIN(C, 15) +GPIO_PIN(F, 0) +GPIO_AF(PIN_F0, -1, ADC_TAG(ADC_DEVICE1, 10)) +GPIO_AF(PIN_F0, 6, TIMER_TAG(TIMER1, TIMER_CH3N)) +GPIO_PIN(F, 1) +GPIO_AF(PIN_F1, -1, ADC_TAG(ADC_DEVICE2, 10)) +GPIO_AF(PIN_F1, 5, SPI_TAG(SPI_PORT2, RES_SPI_SCK)) +GPIO_PIN(G, 10) diff --git a/src/system/stm32g473/gpio_pins.yaml b/src/system/stm32g473/gpio_pins.yaml new file mode 100644 index 000000000..d0f272a90 --- /dev/null +++ b/src/system/stm32g473/gpio_pins.yaml @@ -0,0 +1,566 @@ +PA0: +- func: adc + af: -1 + instance: 1 + name: '1' +- func: adc + af: -1 + instance: 2 + name: '1' +- func: timer + af: 1 + instance: 2 + name: ch1 +- func: timer + af: 2 + instance: 5 + name: ch1 +PA1: +- func: adc + af: -1 + instance: 1 + name: '2' +- func: adc + af: -1 + instance: 2 + name: '2' +- func: timer + af: 1 + instance: 2 + name: ch2 +- func: timer + af: 2 + instance: 5 + name: ch2 +- func: timer + af: 9 + instance: 15 + name: ch1n +PA2: +- func: adc + af: -1 + instance: 1 + name: '3' +- func: timer + af: 1 + instance: 2 + name: ch3 +- func: timer + af: 2 + instance: 5 + name: ch3 +- func: serial + af: 7 + instance: 2 + name: tx +- func: timer + af: 9 + instance: 15 + name: ch1 +PA3: +- func: adc + af: -1 + instance: 1 + name: '4' +- func: timer + af: 1 + instance: 2 + name: ch4 +- func: timer + af: 2 + instance: 5 + name: ch4 +- func: serial + af: 7 + instance: 2 + name: rx +- func: timer + af: 9 + instance: 15 + name: ch2 +PA4: +- func: adc + af: -1 + instance: 2 + name: '17' +- func: timer + af: 2 + instance: 3 + name: ch2 +PA5: +- func: adc + af: -1 + instance: 2 + name: '13' +- func: timer + af: 1 + instance: 2 + name: ch1 +- func: spi + af: 5 + instance: 1 + name: sck +PA6: +- func: adc + af: -1 + instance: 2 + name: '3' +- func: timer + af: 1 + instance: 16 + name: ch1 +- func: timer + af: 2 + instance: 3 + name: ch1 +- func: spi + af: 5 + instance: 1 + name: miso +PA7: +- func: adc + af: -1 + instance: 2 + name: '4' +- func: timer + af: 1 + instance: 17 + name: ch1 +- func: timer + af: 2 + instance: 3 + name: ch2 +- func: timer + af: 4 + instance: 8 + name: ch1n +- func: spi + af: 5 + instance: 1 + name: mosi +- func: timer + af: 6 + instance: 1 + name: ch1n +PA8: +- func: adc + af: -1 + instance: 5 + name: '1' +- func: timer + af: 6 + instance: 1 + name: ch1 +PA9: +- func: adc + af: -1 + instance: 5 + name: '2' +- func: timer + af: 6 + instance: 1 + name: ch2 +- func: serial + af: 7 + instance: 1 + name: tx +- func: timer + af: 10 + instance: 2 + name: ch3 +PA10: +- func: spi + af: 5 + instance: 2 + name: miso +- func: timer + af: 6 + instance: 1 + name: ch3 +- func: serial + af: 7 + instance: 1 + name: rx +- func: timer + af: 10 + instance: 2 + name: ch4 +PA11: +- func: spi + af: 5 + instance: 2 + name: mosi +- func: timer + af: 6 + instance: 1 + name: ch1n +- func: timer + af: 10 + instance: 4 + name: ch1 +- func: timer + af: 11 + instance: 1 + name: ch4 +PA12: +- func: timer + af: 1 + instance: 16 + name: ch1 +- func: timer + af: 6 + instance: 1 + name: ch2n +- func: timer + af: 10 + instance: 4 + name: ch2 +PA13: +- func: timer + af: 1 + instance: 16 + name: ch1n +- func: timer + af: 10 + instance: 4 + name: ch3 +PA14: +- func: timer + af: 5 + instance: 8 + name: ch2 +- func: serial + af: 7 + instance: 2 + name: tx +PA15: +- func: timer + af: 1 + instance: 2 + name: ch1 +- func: timer + af: 2 + instance: 8 + name: ch1 +- func: serial + af: 7 + instance: 2 + name: rx +PB0: +- func: adc + af: -1 + instance: 1 + name: '15' +- func: adc + af: -1 + instance: 3 + name: '12' +- func: timer + af: 2 + instance: 3 + name: ch3 +- func: timer + af: 4 + instance: 8 + name: ch2n +- func: timer + af: 6 + instance: 1 + name: ch2n +PB1: +- func: adc + af: -1 + instance: 1 + name: '12' +- func: adc + af: -1 + instance: 3 + name: '1' +- func: timer + af: 2 + instance: 3 + name: ch4 +- func: timer + af: 4 + instance: 8 + name: ch3n +- func: timer + af: 6 + instance: 1 + name: ch3n +PB2: +- func: adc + af: -1 + instance: 2 + name: '12' +- func: timer + af: 2 + instance: 5 + name: ch1 +- func: timer + af: 3 + instance: 20 + name: ch1 +PB3: +- func: timer + af: 1 + instance: 2 + name: ch2 +- func: timer + af: 4 + instance: 8 + name: ch1n +- func: spi + af: 5 + instance: 1 + name: sck +- func: spi + af: 6 + instance: 3 + name: sck +- func: serial + af: 7 + instance: 2 + name: tx +PB4: +- func: timer + af: 1 + instance: 16 + name: ch1 +- func: timer + af: 2 + instance: 3 + name: ch1 +- func: timer + af: 4 + instance: 8 + name: ch2n +- func: spi + af: 5 + instance: 1 + name: miso +- func: spi + af: 6 + instance: 3 + name: miso +- func: serial + af: 7 + instance: 2 + name: rx +PB5: +- func: timer + af: 2 + instance: 3 + name: ch2 +- func: timer + af: 3 + instance: 8 + name: ch3n +- func: spi + af: 5 + instance: 1 + name: mosi +- func: spi + af: 6 + instance: 3 + name: mosi +- func: timer + af: 10 + instance: 17 + name: ch1 +PB6: +- func: timer + af: 1 + instance: 16 + name: ch1n +- func: timer + af: 2 + instance: 4 + name: ch1 +- func: timer + af: 5 + instance: 8 + name: ch1 +- func: serial + af: 7 + instance: 1 + name: tx +PB7: +- func: timer + af: 1 + instance: 17 + name: ch1n +- func: timer + af: 2 + instance: 4 + name: ch2 +- func: serial + af: 7 + instance: 1 + name: rx +- func: timer + af: 10 + instance: 3 + name: ch4 +PB8: +- func: timer + af: 1 + instance: 16 + name: ch1 +- func: timer + af: 2 + instance: 4 + name: ch3 +- func: serial + af: 7 + instance: 3 + name: rx +- func: timer + af: 10 + instance: 8 + name: ch2 +PB9: +- func: timer + af: 1 + instance: 17 + name: ch1 +- func: timer + af: 2 + instance: 4 + name: ch4 +- func: serial + af: 7 + instance: 3 + name: tx +- func: timer + af: 10 + instance: 8 + name: ch3 +- func: timer + af: 12 + instance: 1 + name: ch3n +PB10: +- func: timer + af: 1 + instance: 2 + name: ch3 +- func: serial + af: 7 + instance: 3 + name: tx +PB11: +- func: adc + af: -1 + instance: 1 + name: '14' +- func: adc + af: -1 + instance: 2 + name: '14' +- func: timer + af: 1 + instance: 2 + name: ch4 +- func: serial + af: 7 + instance: 3 + name: rx +PB12: +- func: adc + af: -1 + instance: 1 + name: '11' +- func: adc + af: -1 + instance: 4 + name: '3' +PB13: +- func: adc + af: -1 + instance: 3 + name: '5' +- func: spi + af: 5 + instance: 2 + name: sck +- func: timer + af: 6 + instance: 1 + name: ch1n +PB14: +- func: adc + af: -1 + instance: 1 + name: '5' +- func: adc + af: -1 + instance: 4 + name: '4' +- func: timer + af: 1 + instance: 15 + name: ch1 +- func: spi + af: 5 + instance: 2 + name: miso +- func: timer + af: 6 + instance: 1 + name: ch2n +PB15: +- func: adc + af: -1 + instance: 2 + name: '15' +- func: adc + af: -1 + instance: 4 + name: '5' +- func: timer + af: 1 + instance: 15 + name: ch2 +- func: timer + af: 2 + instance: 15 + name: ch1n +- func: timer + af: 4 + instance: 1 + name: ch3n +- func: spi + af: 5 + instance: 2 + name: mosi +PC13: +- func: timer + af: 4 + instance: 1 + name: ch1n +- func: timer + af: 6 + instance: 8 + name: ch4n +PC14: [] +PC15: [] +PF0: +- func: adc + af: -1 + instance: 1 + name: '10' +- func: timer + af: 6 + instance: 1 + name: ch3n +PF1: +- func: adc + af: -1 + instance: 2 + name: '10' +- func: spi + af: 5 + instance: 2 + name: sck +PG10: [] diff --git a/src/system/stm32g473/interrupts.c b/src/system/stm32g473/interrupts.c new file mode 100644 index 000000000..ad6023284 --- /dev/null +++ b/src/system/stm32g473/interrupts.c @@ -0,0 +1,108 @@ +__attribute__((weak)) void Default_Handler(); + +__attribute__((used)) void Default_Handler_Proxy() { + Default_Handler(); +} + +__attribute__((weak, alias("Default_Handler_Proxy"))) void NMI_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void HardFault_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void MemManage_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void BusFault_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void UsageFault_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void SVC_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DebugMon_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void PendSV_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void SysTick_Handler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void WWDG_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void PVD_PVM_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void RTC_TAMP_LSECSS_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void RTC_WKUP_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FLASH_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void RCC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void EXTI0_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void EXTI1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void EXTI2_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void EXTI3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void EXTI4_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel2_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel4_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel5_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel6_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel7_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void ADC1_2_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void USB_HP_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void USB_LP_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FDCAN1_IT0_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FDCAN1_IT1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void EXTI9_5_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM1_BRK_TIM15_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM1_UP_TIM16_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM1_TRG_COM_TIM17_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM1_CC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM2_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM4_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C1_EV_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C1_ER_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C2_EV_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C2_ER_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void SPI1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void SPI2_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void USART1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void USART2_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void USART3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void EXTI15_10_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void RTC_Alarm_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void USBWakeUp_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM8_BRK_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM8_UP_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM8_TRG_COM_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM8_CC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void ADC3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FMC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void LPTIM1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM5_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void SPI3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void UART4_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void UART5_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM6_DAC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM7_DAC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel2_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel4_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel5_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void ADC4_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void ADC5_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void UCPD1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void COMP1_2_3_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void COMP4_5_6_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void COMP7_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void CRS_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void SAI1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM20_BRK_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM20_UP_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM20_TRG_COM_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void TIM20_CC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FPU_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C4_EV_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C4_ER_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void SPI4_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FDCAN2_IT0_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FDCAN2_IT1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FDCAN3_IT0_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FDCAN3_IT1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void RNG_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void LPUART1_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C3_EV_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void I2C3_ER_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMAMUX_OVR_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void QUADSPI_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA1_Channel8_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel6_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel7_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void DMA2_Channel8_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void CORDIC_IRQHandler(); +__attribute__((weak, alias("Default_Handler_Proxy"))) void FMAC_IRQHandler(); \ No newline at end of file diff --git a/src/system/stm32g473/startup.S b/src/system/stm32g473/startup.S new file mode 100644 index 000000000..187c7889d --- /dev/null +++ b/src/system/stm32g473/startup.S @@ -0,0 +1,245 @@ +/** + ****************************************************************************** + * @file startup_stm32g473xx.s + * @author MCD Application Team + * @brief STM32G473xx devices vector table GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address, + * - Configure the clock system + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF1E0F85F +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr r0, =_estack + mov sp, r0 /* set stack pointer */ + +/* Call the clock system initialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + ldr r1, =_edata + ldr r2, =_sidata + movs r3, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + ldr r4, =_ebss + movs r3, #0 + b LoopFillZerobss + +FillZerobss: + str r3, [r2] + adds r2, r2, #4 + +LoopFillZerobss: + cmp r2, r4 + bcc FillZerobss + + bl system_check_for_bootloader +/* Call the clock system initialization function.*/ + bl SystemInit +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl memory_section_init + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/****************************************************************************** +* +* The minimal vector table for a Cortex-M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_PVM_IRQHandler + .word RTC_TAMP_LSECSS_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_2_IRQHandler + .word USB_HP_IRQHandler + .word USB_LP_IRQHandler + .word FDCAN1_IT0_IRQHandler + .word FDCAN1_IT1_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_TIM15_IRQHandler + .word TIM1_UP_TIM16_IRQHandler + .word TIM1_TRG_COM_TIM17_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word TIM3_IRQHandler + .word TIM4_IRQHandler + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word USBWakeUp_IRQHandler + .word TIM8_BRK_IRQHandler + .word TIM8_UP_IRQHandler + .word TIM8_TRG_COM_IRQHandler + .word TIM8_CC_IRQHandler + .word ADC3_IRQHandler + .word FMC_IRQHandler + .word LPTIM1_IRQHandler + .word TIM5_IRQHandler + .word SPI3_IRQHandler + .word UART4_IRQHandler + .word UART5_IRQHandler + .word TIM6_DAC_IRQHandler + .word TIM7_DAC_IRQHandler + .word DMA2_Channel1_IRQHandler + .word DMA2_Channel2_IRQHandler + .word DMA2_Channel3_IRQHandler + .word DMA2_Channel4_IRQHandler + .word DMA2_Channel5_IRQHandler + .word ADC4_IRQHandler + .word ADC5_IRQHandler + .word UCPD1_IRQHandler + .word COMP1_2_3_IRQHandler + .word COMP4_5_6_IRQHandler + .word COMP7_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word CRS_IRQHandler + .word SAI1_IRQHandler + .word TIM20_BRK_IRQHandler + .word TIM20_UP_IRQHandler + .word TIM20_TRG_COM_IRQHandler + .word TIM20_CC_IRQHandler + .word FPU_IRQHandler + .word I2C4_EV_IRQHandler + .word I2C4_ER_IRQHandler + .word SPI4_IRQHandler + .word 0 + .word FDCAN2_IT0_IRQHandler + .word FDCAN2_IT1_IRQHandler + .word FDCAN3_IT0_IRQHandler + .word FDCAN3_IT1_IRQHandler + .word RNG_IRQHandler + .word LPUART1_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word DMAMUX_OVR_IRQHandler + .word QUADSPI_IRQHandler + .word DMA1_Channel8_IRQHandler + .word DMA2_Channel6_IRQHandler + .word DMA2_Channel7_IRQHandler + .word DMA2_Channel8_IRQHandler + .word CORDIC_IRQHandler + .word FMAC_IRQHandler + + .size g_pfnVectors, .-g_pfnVectors + diff --git a/src/system/stm32g473/system.c b/src/system/stm32g473/system.c new file mode 100644 index 000000000..1bdd82ec4 --- /dev/null +++ b/src/system/stm32g473/system.c @@ -0,0 +1,278 @@ +/** + ****************************************************************************** + * @file system_stm32g4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32g4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the HSI (16 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32g4xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 16 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * Require 48MHz for RNG | Disabled + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32g4xx_system + * @{ + */ + +/** @addtogroup STM32G4xx_System_Private_Includes + * @{ + */ + +#include "stm32g4xx.h" + +#if !defined(HSE_VALUE) +#define HSE_VALUE 24000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSI_VALUE) +#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate the vector table + anywhere in Flash or Sram, else the vector table is kept at the automatic + remap of boot address selected */ +/* #define USER_VECT_TAB_ADDRESS */ + +#if defined(USER_VECT_TAB_ADDRESS) +/*!< Uncomment the following line if you need to relocate your vector Table + in Sram else user remap will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#endif /* VECT_TAB_SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ + /******************************************************************************/ + /** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Variables + * @{ + */ +/* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. +*/ +uint32_t SystemCoreClock = HSI_VALUE; + +const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; +const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) { +/* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << (10 * 2)) | (3UL << (11 * 2))); /* set CP10 and CP11 Full Access */ +#endif + + /* Configure the Vector Table location add offset address ------------------*/ +#if defined(USER_VECT_TAB_ADDRESS) + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (**) HSI_VALUE is a constant defined in stm32g4xx_hal.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32g4xx_hal.h file (default value + * 24 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) { + uint32_t tmp, pllvco, pllr, pllsource, pllm; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) { + case 0x04: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4) + 1U; + if (pllsource == 0x02UL) /* HSI used as PLL clock source */ + { + pllvco = (HSI_VALUE / pllm); + } else /* HSE used as PLL clock source */ + { + pllvco = (HSE_VALUE / pllm); + } + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * 2U; + SystemCoreClock = pllvco / pllr; + break; + + default: + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */