summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/Makefile24
-rw-r--r--ports/stm32/adc.c34
-rw-r--r--ports/stm32/adc.h2
-rw-r--r--ports/stm32/boards/stm32g0xx_hal_conf_base.h106
-rw-r--r--ports/stm32/dac.c6
-rw-r--r--ports/stm32/dma.c115
-rw-r--r--ports/stm32/dma.h2
-rw-r--r--ports/stm32/extint.c41
-rw-r--r--ports/stm32/extint.h3
-rw-r--r--ports/stm32/flash.c24
-rw-r--r--ports/stm32/machine_adc.c18
-rw-r--r--ports/stm32/machine_uart.c24
-rw-r--r--ports/stm32/modmachine.c12
-rw-r--r--ports/stm32/mpconfigboard_common.h12
-rw-r--r--ports/stm32/mphalport.c3
-rw-r--r--ports/stm32/mphalport.h4
-rw-r--r--ports/stm32/powerctrl.c27
-rw-r--r--ports/stm32/powerctrlboot.c71
-rw-r--r--ports/stm32/pyb_i2c.c12
-rw-r--r--ports/stm32/rtc.c18
-rw-r--r--ports/stm32/spi.c18
-rw-r--r--ports/stm32/stm32.mk3
-rw-r--r--ports/stm32/stm32_it.c113
-rw-r--r--ports/stm32/timer.c34
-rw-r--r--ports/stm32/uart.c98
-rw-r--r--ports/stm32/uart.h5
26 files changed, 719 insertions, 110 deletions
diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile
index 34d586674..10e4e15d9 100644
--- a/ports/stm32/Makefile
+++ b/ports/stm32/Makefile
@@ -324,14 +324,12 @@ SRC_CXX += \
SRC_O += \
$(STARTUP_FILE) \
$(SYSTEM_FILE)
-
-ifeq ($(MCU_SERIES),f0)
-SRC_O += \
- resethandler_m0.o \
- shared/runtime/gchelper_m0.o
-else
+
ifeq ($(MCU_SERIES),l0)
CSUPEROPT = -Os # save some code space
+endif
+
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 g0 l0))
SRC_O += \
resethandler_m0.o \
shared/runtime/gchelper_m0.o
@@ -341,7 +339,6 @@ SRC_O += \
resethandler.o \
shared/runtime/gchelper_m3.o
endif
-endif
HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
hal.c \
@@ -366,7 +363,7 @@ HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
ll_utils.c \
)
-ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g4 h7 l0 l4 wb))
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h7 l0 l4 wb))
HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
hal_pcd.c \
hal_pcd_ex.c \
@@ -386,7 +383,6 @@ ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7))
HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
hal_mmc.c \
hal_sdram.c \
- hal_dma_ex.c \
hal_dcmi.c \
)
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4))
@@ -396,7 +392,13 @@ $(BUILD)/$(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_hal_mmc.o: CFLAGS += -Wno
endif
endif
-ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),g4))
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 g0 g4 h7))
+HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
+ hal_dma_ex.c \
+ )
+endif
+
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),g0 g4))
HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_, hal_fdcan.c)
endif
@@ -413,7 +415,7 @@ endif
endif
endif
-ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 f4 f7 l0))
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 f4 f7 g0 l0))
HAL_SRC_C += $(addprefix $(STM32LIB_HAL_BASE)/Src/stm32$(MCU_SERIES)xx_,\
hal_i2s.c \
)
diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c
index c5ca6306e..3b5a8b364 100644
--- a/ports/stm32/adc.c
+++ b/ports/stm32/adc.c
@@ -102,13 +102,13 @@
#define ADC_CAL2 ((uint16_t *)(ADC_CAL_ADDRESS + 4))
#define ADC_CAL_BITS (12)
-#elif defined(STM32G4)
+#elif defined(STM32G0) || defined(STM32G4)
#define ADC_SCALE_V (((float)VREFINT_CAL_VREF) / 1000.0f)
#define ADC_CAL_ADDRESS VREFINT_CAL_ADDR
#define ADC_CAL1 TEMPSENSOR_CAL1_ADDR
#define ADC_CAL2 TEMPSENSOR_CAL2_ADDR
-#define ADC_CAL_BITS (12) // UM2570, __HAL_ADC_CALC_TEMPERATURE: 'corresponds to a resolution of 12 bits'
+#define ADC_CAL_BITS (12) // UM2319/UM2570, __HAL_ADC_CALC_TEMPERATURE: 'corresponds to a resolution of 12 bits'
#elif defined(STM32H7)
@@ -150,7 +150,7 @@
defined(STM32F746xx) || defined(STM32F765xx) || \
defined(STM32F767xx) || defined(STM32F769xx)
#define VBAT_DIV (4)
-#elif defined(STM32G4)
+#elif defined(STM32G0) || defined(STM32G4)
#define VBAT_DIV (3)
#elif defined(STM32H743xx) || defined(STM32H747xx) || \
defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \
@@ -210,7 +210,7 @@ STATIC bool is_adcx_channel(int channel) {
return IS_ADC_CHANNEL(channel) || channel == ADC_CHANNEL_TEMPSENSOR;
#elif defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
return IS_ADC_CHANNEL(channel);
- #elif defined(STM32H7)
+ #elif defined(STM32G0) || defined(STM32H7)
return __HAL_ADC_IS_CHANNEL_INTERNAL(channel)
|| IS_ADC_CHANNEL(__HAL_ADC_DECIMAL_NB_TO_CHANNEL(channel));
#elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
@@ -227,7 +227,7 @@ STATIC void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t ti
uint32_t tickstart = HAL_GetTick();
#if defined(STM32F4) || defined(STM32F7)
while ((adcHandle->Instance->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
- #elif defined(STM32F0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
while (READ_BIT(adcHandle->Instance->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {
#else
#error Unsupported processor
@@ -244,6 +244,8 @@ STATIC void adcx_clock_enable(ADC_HandleTypeDef *adch) {
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
__HAL_RCC_ADC12_CLK_ENABLE();
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);
+ #elif defined(STM32G0)
+ __HAL_RCC_ADC_CLK_ENABLE();
#elif defined(STM32G4)
__HAL_RCC_ADC12_CLK_ENABLE();
#elif defined(STM32H7)
@@ -269,8 +271,10 @@ STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
adch->Init.Resolution = resolution;
adch->Init.ContinuousConvMode = DISABLE;
adch->Init.DiscontinuousConvMode = DISABLE;
- #if !defined(STM32F0)
+ #if !defined(STM32F0) && !defined(STM32G0)
adch->Init.NbrOfDiscConversion = 0;
+ #endif
+ #if !defined(STM32F0)
adch->Init.NbrOfConversion = 1;
#endif
adch->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
@@ -295,7 +299,7 @@ STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
adch->Init.OversamplingMode = DISABLE;
adch->Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
adch->Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
- #elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
adch->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
adch->Init.ScanConvMode = ADC_SCAN_DISABLE;
adch->Init.LowPowerAutoWait = DISABLE;
@@ -312,7 +316,9 @@ STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
#if defined(STM32H7)
HAL_ADCEx_Calibration_Start(adch, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
#endif
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G0)
+ HAL_ADCEx_Calibration_Start(adch);
+ #elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
HAL_ADCEx_Calibration_Start(adch, ADC_SINGLE_ENDED);
#endif
}
@@ -333,7 +339,7 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel) {
ADC_ChannelConfTypeDef sConfig;
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
sConfig.Rank = ADC_REGULAR_RANK_1;
if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel) == 0) {
channel = __HAL_ADC_DECIMAL_NB_TO_CHANNEL(channel);
@@ -361,6 +367,12 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.OffsetRightShift = DISABLE;
sConfig.OffsetSignedSaturation = DISABLE;
+ #elif defined(STM32G0)
+ if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) {
+ sConfig.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
+ } else {
+ sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
+ }
#elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) {
sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;
@@ -545,7 +557,7 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
// for subsequent samples we can just set the "start sample" bit
#if defined(STM32F4) || defined(STM32F7)
self->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
- #elif defined(STM32F0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
SET_BIT(self->handle.Instance->CR, ADC_CR_ADSTART);
#else
#error Unsupported processor
@@ -655,7 +667,7 @@ STATIC mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i
// ADC is started: set the "start sample" bit
#if defined(STM32F4) || defined(STM32F7)
adc->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
- #elif defined(STM32F0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
SET_BIT(adc->handle.Instance->CR, ADC_CR_ADSTART);
#else
#error Unsupported processor
diff --git a/ports/stm32/adc.h b/ports/stm32/adc.h
index 3b79dc01f..c61bad459 100644
--- a/ports/stm32/adc.h
+++ b/ports/stm32/adc.h
@@ -42,7 +42,7 @@ static inline void adc_deselect_vbat(ADC_TypeDef *adc, uint32_t channel) {
if (channel == ADC_CHANNEL_VBAT) {
ADC_Common_TypeDef *adc_common;
- #if defined(STM32F0) || defined(STM32WB)
+ #if defined(STM32F0) || defined(STM32G0) || defined(STM32WB)
adc_common = ADC1_COMMON;
#elif defined(STM32F4)
adc_common = ADC_COMMON_REGISTER(0);
diff --git a/ports/stm32/boards/stm32g0xx_hal_conf_base.h b/ports/stm32/boards/stm32g0xx_hal_conf_base.h
new file mode 100644
index 000000000..fc49ca945
--- /dev/null
+++ b/ports/stm32/boards/stm32g0xx_hal_conf_base.h
@@ -0,0 +1,106 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_STM32G0XX_HAL_CONF_BASE_H
+#define MICROPY_INCLUDED_STM32G0XX_HAL_CONF_BASE_H
+
+// Oscillator values in Hz
+// These must come before the HAL headers because stm32g0xx_ll_rcc.h will define HSI_VALUE unless already defined
+#define HSI_VALUE (16000000)
+#define LSI_VALUE (32000)
+#if defined(STM32G0C1xx) || defined(STM32G0B1xx) || defined(STM32G0B0xx)
+#define HSI48_VALUE 48000000
+#endif
+
+// Include various HAL modules for convenience
+
+#include "stm32g0xx_hal_rcc.h"
+#include "stm32g0xx_hal_gpio.h"
+#include "stm32g0xx_hal_dma.h"
+#include "stm32g0xx_hal_cortex.h"
+#include "stm32g0xx_hal_adc.h"
+#include "stm32g0xx_hal_adc_ex.h"
+#include "stm32g0xx_hal_cec.h"
+#include "stm32g0xx_hal_comp.h"
+#include "stm32g0xx_hal_crc.h"
+#include "stm32g0xx_hal_cryp.h"
+#include "stm32g0xx_hal_dac.h"
+#include "stm32g0xx_hal_exti.h"
+#include "stm32g0xx_hal_fdcan.h"
+#include "stm32g0xx_hal_flash.h"
+#include "stm32g0xx_hal_i2c.h"
+#include "stm32g0xx_hal_i2s.h"
+#include "stm32g0xx_hal_irda.h"
+#include "stm32g0xx_hal_iwdg.h"
+#include "stm32g0xx_hal_lptim.h"
+#include "stm32g0xx_hal_pcd.h"
+#include "stm32g0xx_hal_hcd.h"
+#include "stm32g0xx_hal_pwr.h"
+#include "stm32g0xx_hal_rng.h"
+#include "stm32g0xx_hal_rtc.h"
+#include "stm32g0xx_hal_smartcard.h"
+#include "stm32g0xx_hal_smbus.h"
+#include "stm32g0xx_hal_spi.h"
+#include "stm32g0xx_hal_tim.h"
+#include "stm32g0xx_hal_uart.h"
+#include "stm32g0xx_hal_usart.h"
+#include "stm32g0xx_hal_wwdg.h"
+
+#include "stm32g0xx_ll_lpuart.h"
+#include "stm32g0xx_ll_rtc.h"
+#include "stm32g0xx_ll_usart.h"
+
+// Enable various HAL modules
+#define HAL_MODULE_ENABLED
+#define HAL_ADC_MODULE_ENABLED
+#define HAL_CORTEX_MODULE_ENABLED
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
+#define HAL_PWR_MODULE_ENABLED
+#define HAL_RCC_MODULE_ENABLED
+#define HAL_RTC_MODULE_ENABLED
+#define HAL_SPI_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
+#define HAL_UART_MODULE_ENABLED
+#define HAL_USART_MODULE_ENABLED
+
+// SysTick has the highest priority
+#define TICK_INT_PRIORITY (0x00)
+
+// Miscellaneous HAL settings
+#define USE_RTOS 0
+#define PREFETCH_ENABLE 1
+#define INSTRUCTION_CACHE_ENABLE 1
+#define USE_SPI_CRC 1
+#define USE_HAL_CRYP_SUSPEND_RESUME 1
+
+// HAL parameter assertions are disabled
+#define assert_param(expr) ((void)0)
+
+#endif // MICROPY_INCLUDED_STM32G0XX_HAL_CONF_BASE_H
diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c
index b7fb0cbd7..c41bf858a 100644
--- a/ports/stm32/dac.c
+++ b/ports/stm32/dac.c
@@ -124,7 +124,7 @@ STATIC uint32_t TIMx_Config(mp_obj_t timer) {
STATIC void dac_deinit(uint32_t dac_channel) {
DAC->CR &= ~(DAC_CR_EN1 << dac_channel);
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4)
DAC->MCR = (DAC->MCR & ~(DAC_MCR_MODE1_Msk << dac_channel)) | (DAC_OUTPUTBUFFER_DISABLE << dac_channel);
#else
DAC->CR |= DAC_CR_BOFF1 << dac_channel;
@@ -142,7 +142,7 @@ STATIC void dac_config_channel(uint32_t dac_channel, uint32_t trig, uint32_t out
DAC->CR &= ~(DAC_CR_EN1 << dac_channel);
uint32_t cr_off = DAC_CR_DMAEN1 | DAC_CR_MAMP1 | DAC_CR_WAVE1 | DAC_CR_TSEL1 | DAC_CR_TEN1;
uint32_t cr_on = trig;
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4)
DAC->MCR = (DAC->MCR & ~(DAC_MCR_MODE1_Msk << dac_channel)) | (outbuf << dac_channel);
#else
cr_off |= DAC_CR_BOFF1;
@@ -259,7 +259,7 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp
__DAC_CLK_ENABLE();
#elif defined(STM32H7)
__HAL_RCC_DAC12_CLK_ENABLE();
- #elif defined(STM32F0) || defined(STM32G4) || defined(STM32L4)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L4)
__HAL_RCC_DAC1_CLK_ENABLE();
#else
#error Unsupported Processor
diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c
index cb8e555df..2dc6e8e8b 100644
--- a/ports/stm32/dma.c
+++ b/ports/stm32/dma.c
@@ -80,7 +80,7 @@ typedef union {
struct _dma_descr_t {
#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
DMA_Stream_TypeDef *instance;
- #elif defined(STM32F0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
DMA_Channel_TypeDef *instance;
#else
#error "Unsupported Processor"
@@ -95,7 +95,7 @@ struct _dma_descr_t {
static const DMA_InitTypeDef dma_init_struct_spi_i2c = {
#if defined(STM32F4) || defined(STM32F7)
.Channel = 0,
- #elif defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
.Request = 0,
#endif
.Direction = 0,
@@ -119,7 +119,7 @@ static const DMA_InitTypeDef dma_init_struct_spi_i2c = {
static const DMA_InitTypeDef dma_init_struct_i2s = {
#if defined(STM32F4) || defined(STM32F7)
.Channel = 0,
- #elif defined(STM32H7) || defined(STM32L0) || defined(STM32L4)
+ #elif defined(STM32G0) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4)
.Request = 0,
#endif
.Direction = DMA_MEMORY_TO_PERIPH,
@@ -143,7 +143,7 @@ static const DMA_InitTypeDef dma_init_struct_i2s = {
static const DMA_InitTypeDef dma_init_struct_sdio = {
#if defined(STM32F4) || defined(STM32F7)
.Channel = 0,
- #elif defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
.Request = 0,
#endif
.Direction = 0,
@@ -153,7 +153,7 @@ static const DMA_InitTypeDef dma_init_struct_sdio = {
.MemDataAlignment = DMA_MDATAALIGN_WORD,
#if defined(STM32F4) || defined(STM32F7)
.Mode = DMA_PFCTRL,
- #elif defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
.Mode = DMA_NORMAL,
#endif
.Priority = DMA_PRIORITY_VERY_HIGH,
@@ -171,7 +171,7 @@ static const DMA_InitTypeDef dma_init_struct_sdio = {
static const DMA_InitTypeDef dma_init_struct_dac = {
#if defined(STM32F4) || defined(STM32F7)
.Channel = 0,
- #elif defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
.Request = 0,
#endif
.Direction = 0,
@@ -507,6 +507,46 @@ static const uint8_t dma_irqn[NSTREAM] = {
DMA2_Channel7_IRQn,
};
+#elif defined(STM32G0)
+
+#define NCONTROLLERS (2)
+#define NSTREAMS_PER_CONTROLLER (7)
+#define NSTREAM (NCONTROLLERS * NSTREAMS_PER_CONTROLLER)
+
+#define DMA_SUB_INSTANCE_AS_UINT8(dma_request) (dma_request)
+
+#define DMA1_ENABLE_MASK (0x007f) // Bits in dma_enable_mask corresponding to DMA1 (7 channels)
+#define DMA2_ENABLE_MASK (0x0f80) // Bits in dma_enable_mask corresponding to DMA2 (only 5 channels)
+
+// DMA1 streams
+#if MICROPY_HW_ENABLE_DAC
+const dma_descr_t dma_DAC_1_TX = { DMA1_Channel3, DMA_REQUEST_DAC1_CH1, dma_id_2, &dma_init_struct_dac };
+const dma_descr_t dma_DAC_2_TX = { DMA1_Channel4, DMA_REQUEST_DAC1_CH2, dma_id_3, &dma_init_struct_dac };
+#endif
+const dma_descr_t dma_SPI_3_TX = { DMA1_Channel7, DMA_REQUEST_SPI3_TX, dma_id_6, &dma_init_struct_spi_i2c};
+const dma_descr_t dma_SPI_3_RX = { DMA2_Channel1, DMA_REQUEST_SPI3_RX, dma_id_7, &dma_init_struct_spi_i2c};
+const dma_descr_t dma_SPI_2_TX = { DMA1_Channel5, DMA_REQUEST_SPI2_TX, dma_id_4, &dma_init_struct_spi_i2c};
+const dma_descr_t dma_SPI_2_RX = { DMA1_Channel6, DMA_REQUEST_SPI2_RX, dma_id_5, &dma_init_struct_spi_i2c};
+const dma_descr_t dma_SPI_1_RX = { DMA2_Channel3, DMA_REQUEST_SPI1_RX, dma_id_9, &dma_init_struct_spi_i2c};
+const dma_descr_t dma_SPI_1_TX = { DMA2_Channel4, DMA_REQUEST_SPI1_TX, dma_id_10, &dma_init_struct_spi_i2c};
+
+static const uint8_t dma_irqn[NSTREAM] = {
+ DMA1_Channel1_IRQn,
+ DMA1_Channel2_3_IRQn,
+ DMA1_Channel2_3_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn,
+ 0,
+ 0,
+};
+
#elif defined(STM32G4)
#define NCONTROLLERS (2)
@@ -665,7 +705,7 @@ volatile dma_idle_count_t dma_idle;
#define DMA_INVALID_CHANNEL 0xff // Value stored in dma_last_channel which means invalid
-#if defined(STM32F0) || defined(STM32L0)
+#if defined(STM32F0) || defined(STM32G0) || defined(STM32L0)
#define DMA1_IS_CLK_ENABLED() ((RCC->AHBENR & RCC_AHBENR_DMA1EN) != 0)
#if defined(DMA2)
#define DMA2_IS_CLK_ENABLED() ((RCC->AHBENR & RCC_AHBENR_DMA2EN) != 0)
@@ -830,6 +870,59 @@ void DMA2_Stream7_IRQHandler(void) {
IRQ_EXIT(DMA2_Stream7_IRQn);
}
+#elif defined(STM32G0)
+
+void DMA1_Channel1_IRQHandler(void) {
+ IRQ_ENTER(DMA1_Channel1_IRQn);
+ if (dma_handle[dma_id_0] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_0]);
+ }
+ IRQ_EXIT(DMA1_Channel1_IRQn);
+}
+
+void DMA1_Channel2_3_IRQHandler(void) {
+ IRQ_ENTER(DMA1_Channel2_3_IRQn);
+ if (dma_handle[dma_id_1] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_1]);
+ }
+ if (dma_handle[dma_id_2] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_2]);
+ }
+ IRQ_EXIT(DMA1_Channel2_3_IRQn);
+}
+
+void DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQHandler(void) {
+ IRQ_ENTER(DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn);
+ if (dma_handle[dma_id_3] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_3]);
+ }
+ if (dma_handle[dma_id_4] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_4]);
+ }
+ if (dma_handle[dma_id_5] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_5]);
+ }
+ if (dma_handle[dma_id_6] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_6]);
+ }
+ if (dma_handle[dma_id_7] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_7]);
+ }
+ if (dma_handle[dma_id_8] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_8]);
+ }
+ if (dma_handle[dma_id_9] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_9]);
+ }
+ if (dma_handle[dma_id_10] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_10]);
+ }
+ if (dma_handle[dma_id_11] != NULL) {
+ HAL_DMA_IRQHandler(dma_handle[dma_id_11]);
+ }
+ IRQ_EXIT(DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn);
+}
+
#elif defined(STM32G4)
void DMA1_Channel1_IRQHandler(void) {
@@ -1164,7 +1257,7 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint3
dma->Instance = dma_descr->instance;
dma->Init = *dma_descr->init;
dma->Init.Direction = dir;
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
dma->Init.Request = dma_descr->sub_instance;
#else
#if !defined(STM32F0)
@@ -1191,8 +1284,8 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, uint32_t dir
dma_enable_clock(dma_id);
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
- // Always reset and configure the H7 and L0/L4 DMA peripheral
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ // Always reset and configure the H7 and G0/G4/H7/L0/L4/WB/WL DMA peripheral
// (dma->State is set to HAL_DMA_STATE_RESET by memset above)
// TODO: understand how L0/L4 DMA works so this is not needed
HAL_DMA_DeInit(dma);
@@ -1367,7 +1460,7 @@ void dma_nohal_start(const dma_descr_t *descr, uint32_t src_addr, uint32_t dst_a
dma->CCR |= DMA_CCR_EN;
}
-#elif defined(STM32WB) || defined(STM32WL)
+#elif defined(STM32G0) || defined(STM32WB) || defined(STM32WL)
// These functions are currently not implemented or needed for this MCU.
diff --git a/ports/stm32/dma.h b/ports/stm32/dma.h
index 9b0b4c77a..70c7e6a00 100644
--- a/ports/stm32/dma.h
+++ b/ports/stm32/dma.h
@@ -28,7 +28,7 @@
typedef struct _dma_descr_t dma_descr_t;
-#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
+#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32H7)
extern const dma_descr_t dma_I2C_1_RX;
extern const dma_descr_t dma_SPI_3_RX;
diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c
index 55c9095f1..2fc68e195 100644
--- a/ports/stm32/extint.c
+++ b/ports/stm32/extint.c
@@ -91,7 +91,7 @@
#define EXTI_SWIER_BB(line) (*(__IO uint32_t *)(PERIPH_BB_BASE + ((EXTI_OFFSET + offsetof(EXTI_TypeDef, SWIER)) * 32) + ((line) * 4)))
#endif
-#if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+#if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
// The L4 MCU supports 40 Events/IRQs lines of the type configurable and direct.
// Here we only support configurable line types. Details, see page 330 of RM0351, Rev 1.
// The USB_FS_WAKUP event is a direct type and there is no support for it.
@@ -143,7 +143,7 @@ STATIC mp_obj_t pyb_extint_callback_arg[EXTI_NUM_VECTORS];
#endif
STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
- #if defined(STM32F0) || defined(STM32L0)
+ #if defined(STM32F0) || defined(STM32L0) || defined(STM32G0)
EXTI0_1_IRQn, EXTI0_1_IRQn, EXTI2_3_IRQn, EXTI2_3_IRQn,
EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn,
@@ -154,12 +154,20 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
#else
PVD_VDDIO2_IRQn,
#endif
+ #if defined(STM32G0)
+ ADC1_COMP_IRQn,
+ ADC1_COMP_IRQn,
+ RTC_TAMP_IRQn,
+ 0, // COMP3
+ RTC_TAMP_IRQn,// 21
+ #else
RTC_IRQn,
0, // internal USB wakeup event
RTC_IRQn,
RTC_IRQn,
ADC1_COMP_IRQn,
ADC1_COMP_IRQn,
+ #endif
#else
@@ -317,9 +325,15 @@ void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_
#if !defined(STM32WB) && !defined(STM32WL)
__HAL_RCC_SYSCFG_CLK_ENABLE();
#endif
+ #if defined(STM32G0)
+ EXTI->EXTICR[line >> 2] =
+ (EXTI->EXTICR[line >> 2] & ~(0x0f << (4 * (line & 0x03))))
+ | ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (4 * (line & 0x03)));
+ #else
SYSCFG->EXTICR[line >> 2] =
(SYSCFG->EXTICR[line >> 2] & ~(0x0f << (4 * (line & 0x03))))
| ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (4 * (line & 0x03)));
+ #endif
extint_trigger_mode(line, mode);
@@ -354,9 +368,15 @@ void extint_set(const pin_obj_t *pin, uint32_t mode) {
#if !defined(STM32WB) && !defined(STM32WL)
__HAL_RCC_SYSCFG_CLK_ENABLE();
#endif
+ #if defined(STM32G0)
+ EXTI->EXTICR[line >> 2] =
+ (EXTI->EXTICR[line >> 2] & ~(0x0f << (4 * (line & 0x03))))
+ | ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (4 * (line & 0x03)));
+ #else
SYSCFG->EXTICR[line >> 2] =
(SYSCFG->EXTICR[line >> 2] & ~(0x0f << (4 * (line & 0x03))))
| ((uint32_t)(GPIO_GET_INDEX(pin->gpio)) << (4 * (line & 0x03)));
+ #endif
// Enable or disable the rising detector
if ((mode & GPIO_MODE_IT_RISING) == GPIO_MODE_IT_RISING) {
@@ -391,7 +411,7 @@ void extint_enable(uint line) {
if (pyb_extint_mode[line] == EXTI_Mode_Interrupt) {
#if defined(STM32H7)
EXTI_D1->IMR1 |= (1 << line);
- #elif defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 |= (1 << line);
#else
EXTI->IMR |= (1 << line);
@@ -399,7 +419,7 @@ void extint_enable(uint line) {
} else {
#if defined(STM32H7)
EXTI_D1->EMR1 |= (1 << line);
- #elif defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
EXTI->EMR1 |= (1 << line);
#else
EXTI->EMR |= (1 << line);
@@ -425,7 +445,7 @@ void extint_disable(uint line) {
#if defined(STM32H7)
EXTI_D1->IMR1 &= ~(1 << line);
EXTI_D1->EMR1 &= ~(1 << line);
- #elif defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 &= ~(1 << line);
EXTI->EMR1 &= ~(1 << line);
#else
@@ -447,7 +467,7 @@ void extint_swint(uint line) {
return;
}
// we need 0 to 1 transition to trigger the interrupt
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
EXTI->SWIER1 &= ~(1 << line);
EXTI->SWIER1 |= (1 << line);
#else
@@ -525,7 +545,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_swint_obj, extint_obj_swint);
/// \classmethod regs()
/// Dump the values of the EXTI registers.
STATIC mp_obj_t extint_regs(void) {
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
printf("EXTI_IMR1 %08x\n", (unsigned int)EXTI->IMR1);
printf("EXTI_IMR2 %08x\n", (unsigned int)EXTI->IMR2);
printf("EXTI_EMR1 %08x\n", (unsigned int)EXTI->EMR1);
@@ -536,8 +556,15 @@ STATIC mp_obj_t extint_regs(void) {
printf("EXTI_FTSR2 %08x\n", (unsigned int)EXTI->FTSR2);
printf("EXTI_SWIER1 %08x\n", (unsigned int)EXTI->SWIER1);
printf("EXTI_SWIER2 %08x\n", (unsigned int)EXTI->SWIER2);
+ #if defined(STM32G0)
+ printf("EXTI_RPR1 %08x\n", (unsigned int)EXTI->RPR1);
+ printf("EXTI_FPR1 %08x\n", (unsigned int)EXTI->FPR1);
+ printf("EXTI_RPR2 %08x\n", (unsigned int)EXTI->RPR2);
+ printf("EXTI_FPR2 %08x\n", (unsigned int)EXTI->FPR2);
+ #else
printf("EXTI_PR1 %08x\n", (unsigned int)EXTI->PR1);
printf("EXTI_PR2 %08x\n", (unsigned int)EXTI->PR2);
+ #endif
#elif defined(STM32H7)
printf("EXTI_IMR1 %08x\n", (unsigned int)EXTI_D1->IMR1);
printf("EXTI_IMR2 %08x\n", (unsigned int)EXTI_D1->IMR2);
diff --git a/ports/stm32/extint.h b/ports/stm32/extint.h
index 247852fa1..95e29c97f 100644
--- a/ports/stm32/extint.h
+++ b/ports/stm32/extint.h
@@ -49,6 +49,9 @@
#elif defined(STM32H7) || defined(STM32WB)
#define EXTI_RTC_TIMESTAMP (18)
#define EXTI_RTC_WAKEUP (19)
+#elif defined(STM32G0)
+#define EXTI_RTC_WAKEUP (19)
+#define EXTI_RTC_TIMESTAMP (21)
#else
#define EXTI_RTC_TIMESTAMP (21)
#define EXTI_RTC_WAKEUP (22)
diff --git a/ports/stm32/flash.c b/ports/stm32/flash.c
index 0c4d2cf5b..2644e0f58 100644
--- a/ports/stm32/flash.c
+++ b/ports/stm32/flash.c
@@ -29,6 +29,20 @@
#include "py/mphal.h"
#include "flash.h"
+#if defined(STM32G0)
+// These are not defined on the CMSIS header
+#define FLASH_FLAG_SR_ERRORS (FLASH_FLAG_OPERR | FLASH_FLAG_PROGERR | FLASH_FLAG_WRPERR | \
+ FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | FLASH_FLAG_PGSERR | \
+ FLASH_FLAG_MISERR | FLASH_FLAG_FASTERR | FLASH_FLAG_RDERR | \
+ FLASH_FLAG_OPTVERR)
+#if defined(FLASH_OPTR_DBANK)
+#define FLASH_FLAG_ECCR_ERRORS (FLASH_FLAG_ECCC | FLASH_FLAG_ECCD | FLASH_FLAG_ECCC2 | FLASH_FLAG_ECCD2)
+#else
+#define FLASH_FLAG_ECCR_ERRORS (FLASH_FLAG_ECCC | FLASH_FLAG_ECCD)
+#endif
+#define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_SR_ERRORS | FLASH_FLAG_ECCR_ERRORS)
+#endif
+
#if MICROPY_HW_STM32WB_FLASH_SYNCRONISATION
// See WB55 specific documentation in AN5289 Rev 3, and in particular, Figure 10.
@@ -97,7 +111,7 @@ static const flash_layout_t flash_layout[] = {
};
#endif
-#elif defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+#elif defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
static const flash_layout_t flash_layout[] = {
{ (uint32_t)FLASH_BASE, (uint32_t)FLASH_PAGE_SIZE, 512 },
@@ -165,7 +179,7 @@ static uint32_t get_page(uint32_t addr) {
return (addr - FLASH_BASE) / FLASH_PAGE_SIZE;
}
-#elif defined(STM32G4)
+#elif defined(STM32G0) || defined(STM32G4)
static uint32_t get_page(uint32_t addr) {
return (addr - FLASH_BASE) / FLASH_PAGE_SIZE;
@@ -252,7 +266,7 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = flash_dest;
EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
- #elif defined(STM32G4)
+ #elif defined(STM32G0) || defined(STM32G4)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = get_page(flash_dest);
@@ -291,7 +305,7 @@ int flash_erase(uint32_t flash_dest, uint32_t num_word32) {
#else
EraseInitStruct.VoltageRange = 0; // unused parameter on STM32H7A3/B3
#endif
- #if defined(STM32G4) || defined(STM32H7)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7)
EraseInitStruct.Banks = get_bank(flash_dest);
#endif
EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL);
@@ -370,7 +384,7 @@ int flash_write(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
HAL_StatusTypeDef status = HAL_OK;
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
// program the flash uint64 by uint64
for (int i = 0; i < num_word32 / 2; i++) {
diff --git a/ports/stm32/machine_adc.c b/ports/stm32/machine_adc.c
index 819fd3414..ca40acf0d 100644
--- a/ports/stm32/machine_adc.c
+++ b/ports/stm32/machine_adc.c
@@ -28,7 +28,7 @@
#include "py/mphal.h"
#include "adc.h"
-#if defined(STM32F0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+#if defined(STM32F0) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
#define ADC_V2 (1)
#else
#define ADC_V2 (0)
@@ -42,7 +42,7 @@
#define ADCx_COMMON __LL_ADC_COMMON_INSTANCE(0)
#endif
-#if defined(STM32F0) || defined(STM32L0) || defined(STM32WL)
+#if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32WL)
#define ADC_STAB_DELAY_US (1)
#define ADC_TEMPSENSOR_DELAY_US (10)
#elif defined(STM32G4)
@@ -65,7 +65,7 @@
#elif defined(STM32H7)
#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_8CYCLES_5
#define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_387CYCLES_5
-#elif defined(STM32L0) || defined(STM32WL)
+#elif defined(STM32G0) || defined(STM32L0) || defined(STM32WL)
#define ADC_SAMPLETIME_DEFAULT ADC_SAMPLETIME_12CYCLES_5
#define ADC_SAMPLETIME_DEFAULT_INT ADC_SAMPLETIME_160CYCLES_5
#elif defined(STM32L4) || defined(STM32WB)
@@ -105,7 +105,7 @@ STATIC const uint8_t adc_cr_to_bits_table[] = {12, 10, 8, 6};
void adc_config(ADC_TypeDef *adc, uint32_t bits) {
// Configure ADC clock source and enable ADC clock
- #if defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);
__HAL_RCC_ADC_CLK_ENABLE();
#else
@@ -174,7 +174,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {
#if ADC_V2
if (!(adc->CR & ADC_CR_ADEN)) {
// ADC isn't enabled so calibrate it now
- #if defined(STM32F0) || defined(STM32L0) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32WL)
LL_ADC_StartCalibration(adc);
#elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
LL_ADC_StartCalibration(adc, LL_ADC_SINGLE_ENDED);
@@ -237,7 +237,7 @@ void adc_config(ADC_TypeDef *adc, uint32_t bits) {
}
STATIC int adc_get_bits(ADC_TypeDef *adc) {
- #if defined(STM32F0) || defined(STM32L0) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0) || defined(STM32WL)
uint32_t res = (adc->CFGR1 & ADC_CFGR1_RES) >> ADC_CFGR1_RES_Pos;
#elif defined(STM32F4) || defined(STM32F7)
uint32_t res = (adc->CR1 & ADC_CR1_RES) >> ADC_CR1_RES_Pos;
@@ -267,7 +267,7 @@ STATIC void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp
}
#endif
- #if defined(STM32F0) || defined(STM32L0)
+ #if defined(STM32F0) || defined(STM32G0) || defined(STM32L0)
if (channel == ADC_CHANNEL_VREFINT) {
ADC1_COMMON->CCR |= ADC_CCR_VREFEN;
@@ -279,7 +279,11 @@ STATIC void adc_config_channel(ADC_TypeDef *adc, uint32_t channel, uint32_t samp
ADC1_COMMON->CCR |= ADC_CCR_VBATEN;
#endif
}
+ #if defined(STM32G0)
+ adc->SMPR = sample_time << ADC_SMPR_SMP1_Pos; // select sample time from SMP1 (default)
+ #else
adc->SMPR = sample_time << ADC_SMPR_SMP_Pos; // select sample time
+ #endif
adc->CHSELR = 1 << channel; // select channel for conversion
#elif defined(STM32F4) || defined(STM32F7)
diff --git a/ports/stm32/machine_uart.c b/ports/stm32/machine_uart.c
index 681939094..bf7bcfb9c 100644
--- a/ports/stm32/machine_uart.c
+++ b/ports/stm32/machine_uart.c
@@ -76,10 +76,14 @@
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (!self->is_enabled) {
- #ifdef LPUART1
+ #if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
mp_printf(print, "UART('LP1')");
} else
+ #elif defined(LPUART2)
+ if (self->uart_id == PYB_LPUART_2) {
+ mp_printf(print, "UART('LP2')");
+ } else
#endif
{
mp_printf(print, "UART(%u)", self->uart_id);
@@ -105,12 +109,18 @@ STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
if (cr1 & USART_CR1_PCE) {
bits -= 1;
}
- #ifdef LPUART1
+ #if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
mp_printf(print, "UART('LP1', baudrate=%u, bits=%u, parity=",
uart_get_baudrate(self), bits);
} else
#endif
+ #if defined(LPUART2)
+ if (self->uart_id == PYB_LPUART_2) {
+ mp_printf(print, "UART('LP2', baudrate=%u, bits=%u, parity=",
+ uart_get_baudrate(self), bits);
+ } else
+ #endif
{
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=",
self->uart_id, uart_get_baudrate(self), bits);
@@ -354,10 +364,18 @@ STATIC mp_obj_t pyb_uart_make_new(const mp_obj_type_t *type, size_t n_args, size
} else if (strcmp(port, MICROPY_HW_LPUART1_NAME) == 0) {
uart_id = PYB_LPUART_1;
#endif
+ #ifdef MICROPY_HW_LPUART2_NAME
+ } else if (strcmp(port, MICROPY_HW_LPUART2_NAME) == 0) {
+ uart_id = PYB_LPUART_2;
+ #endif
#ifdef LPUART1
} else if (strcmp(port, "LP1") == 0 && uart_exists(PYB_LPUART_1)) {
uart_id = PYB_LPUART_1;
#endif
+ #ifdef LPUART2
+ } else if (strcmp(port, "LP2") == 0 && uart_exists(PYB_LPUART_2)) {
+ uart_id = PYB_LPUART_2;
+ #endif
} else {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("UART(%s) doesn't exist"), port);
}
@@ -459,7 +477,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_readchar_obj, pyb_uart_readchar);
// uart.sendbreak()
STATIC mp_obj_t pyb_uart_sendbreak(mp_obj_t self_in) {
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
self->uartx->RQR = USART_RQR_SBKRQ; // write-only register
#else
self->uartx->CR1 |= USART_CR1_SBK;
diff --git a/ports/stm32/modmachine.c b/ports/stm32/modmachine.c
index 0239ea64c..3a24e08f4 100644
--- a/ports/stm32/modmachine.c
+++ b/ports/stm32/modmachine.c
@@ -68,6 +68,12 @@
#define RCC_CSR_PORRSTF RCC_CSR_BORRSTF
#endif
+#if defined(STM32G0)
+// G0 has BOR and POR combined
+#define RCC_CSR_BORRSTF RCC_CSR_PWRRSTF
+#define RCC_CSR_PORRSTF RCC_CSR_PWRRSTF
+#endif
+
#if defined(STM32H7)
#define RCC_SR RSR
#define RCC_SR_IWDGRSTF RCC_RSR_IWDG1RSTF
@@ -167,7 +173,7 @@ STATIC mp_obj_t machine_info(size_t n_args, const mp_obj_t *args) {
// get and print clock speeds
// SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz
{
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
printf("S=%u\nH=%u\nP1=%u\n",
(unsigned int)HAL_RCC_GetSysClockFreq(),
(unsigned int)HAL_RCC_GetHCLKFreq(),
@@ -310,14 +316,14 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
mp_obj_new_int(HAL_RCC_GetSysClockFreq()),
mp_obj_new_int(HAL_RCC_GetHCLKFreq()),
mp_obj_new_int(HAL_RCC_GetPCLK1Freq()),
- #if !defined(STM32F0)
+ #if !defined(STM32F0) && !defined(STM32G0)
mp_obj_new_int(HAL_RCC_GetPCLK2Freq()),
#endif
};
return mp_obj_new_tuple(MP_ARRAY_SIZE(tuple), tuple);
} else {
// set
- #if defined(STM32F0) || defined(STM32L0) || defined(STM32L4)
+ #if defined(STM32F0) || defined(STM32L0) || defined(STM32L4) || defined(STM32G0)
mp_raise_NotImplementedError(MP_ERROR_TEXT("machine.freq set not supported yet"));
#else
mp_int_t sysclk = mp_obj_get_int(args[0]);
diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h
index 7c8662318..51bad18dd 100644
--- a/ports/stm32/mpconfigboard_common.h
+++ b/ports/stm32/mpconfigboard_common.h
@@ -319,6 +319,16 @@
#define MICROPY_HW_MAX_UART (8)
#define MICROPY_HW_MAX_LPUART (0)
+// Configuration for STM32G0 series
+#elif defined(STM32G0)
+
+#define MP_HAL_UNIQUE_ID_ADDRESS (UID_BASE)
+#define PYB_EXTI_NUM_VECTORS (22) // previously 23
+#define MICROPY_HW_MAX_I2C (3)
+#define MICROPY_HW_MAX_TIMER (17)
+#define MICROPY_HW_MAX_UART (6)
+#define MICROPY_HW_MAX_LPUART (2)
+
// Configuration for STM32G4 series
#elif defined(STM32G4)
@@ -505,7 +515,7 @@
// Enable CAN if there are any peripherals defined
#if defined(MICROPY_HW_CAN1_TX) || defined(MICROPY_HW_CAN2_TX) || defined(MICROPY_HW_CAN3_TX)
#define MICROPY_HW_ENABLE_CAN (1)
-#if defined(STM32G4) || defined(STM32H7)
+#if defined(STM32G0) || defined(STM32G4) || defined(STM32H7)
#define MICROPY_HW_ENABLE_FDCAN (1) // define for MCUs with FDCAN
#endif
#else
diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c
index 9961c3d99..477192330 100644
--- a/ports/stm32/mphalport.c
+++ b/ports/stm32/mphalport.c
@@ -99,6 +99,9 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {
#elif defined(STM32L0)
#define AHBxENR IOPENR
#define AHBxENR_GPIOAEN_Pos RCC_IOPENR_IOPAEN_Pos
+ #elif defined(STM32G0)
+ #define AHBxENR IOPENR
+ #define AHBxENR_GPIOAEN_Pos RCC_IOPENR_GPIOAEN_Pos
#elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
#define AHBxENR AHB2ENR
#define AHBxENR_GPIOAEN_Pos RCC_AHB2ENR_GPIOAEN_Pos
diff --git a/ports/stm32/mphalport.h b/ports/stm32/mphalport.h
index 6cfa9b927..47bb1f8c8 100644
--- a/ports/stm32/mphalport.h
+++ b/ports/stm32/mphalport.h
@@ -2,13 +2,15 @@
#include STM32_HAL_H
#include "pin.h"
-// F0-1.9.0+F4-1.16.0+F7-1.7.0+G4-1.3.0+H7-1.6.0+L0-1.11.2+L4-1.17.0+WB-1.10.0+WL-1.1.0
+// F0-1.9.0+F4-1.16.0+F7-1.7.0+G0-1.5.1+G4-1.3.0+H7-1.6.0+L0-1.11.2+L4-1.17.0+WB-1.10.0+WL-1.1.0
#if defined(STM32F0)
#define MICROPY_PLATFORM_VERSION "HAL1.9.0"
#elif defined(STM32F4)
#define MICROPY_PLATFORM_VERSION "HAL1.16.0"
#elif defined(STM32F7)
#define MICROPY_PLATFORM_VERSION "HAL1.7.0"
+#elif defined(STM32G0)
+#define MICROPY_PLATFORM_VERSION "HAL1.5.1"
#elif defined(STM32G4)
#define MICROPY_PLATFORM_VERSION "HAL1.3.0"
#elif defined(STM32H7)
diff --git a/ports/stm32/powerctrl.c b/ports/stm32/powerctrl.c
index a2e3b5c71..cf06f3e18 100644
--- a/ports/stm32/powerctrl.c
+++ b/ports/stm32/powerctrl.c
@@ -143,7 +143,7 @@ void powerctrl_check_enter_bootloader(void) {
if (BL_STATE_GET_KEY(bl_state) == BL_STATE_KEY && (RCC->RCC_SR & RCC_SR_SFTRSTF)) {
// Reset by NVIC_SystemReset with bootloader data set -> branch to bootloader
RCC->RCC_SR = RCC_SR_RMVF;
- #if defined(STM32F0) || defined(STM32F4) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32F0) || defined(STM32F4) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB)
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
#endif
branch_to_bootloader(BL_STATE_GET_REG(bl_state), BL_STATE_GET_ADDR(bl_state));
@@ -286,7 +286,7 @@ int powerctrl_rcc_clock_config_pll(RCC_ClkInitTypeDef *rcc_init, uint32_t sysclk
#endif
-#if !defined(STM32F0) && !defined(STM32L0) && !defined(STM32L4)
+#if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32L0) && !defined(STM32L4)
STATIC uint32_t calc_ahb_div(uint32_t wanted_div) {
#if defined(STM32H7)
@@ -378,14 +378,17 @@ STATIC uint32_t calc_apb2_div(uint32_t wanted_div) {
#endif
}
-#if defined(STM32F4) || defined(STM32F7) || defined(STM32G4) || defined(STM32H7)
+#if defined(STM32F4) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7)
int powerctrl_set_sysclk(uint32_t sysclk, uint32_t ahb, uint32_t apb1, uint32_t apb2) {
// Return straightaway if the clocks are already at the desired frequency
if (sysclk == HAL_RCC_GetSysClockFreq()
&& ahb == HAL_RCC_GetHCLKFreq()
&& apb1 == HAL_RCC_GetPCLK1Freq()
- && apb2 == HAL_RCC_GetPCLK2Freq()) {
+ #if !defined(STM32G0)
+ && apb2 == HAL_RCC_GetPCLK2Freq()
+ #endif
+ ) {
return 0;
}
@@ -428,7 +431,11 @@ set_clk:
// Desired system clock source is in sysclk_source
RCC_ClkInitTypeDef RCC_ClkInitStruct;
+ #if defined(STM32G0) || defined(STM32G4)
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_ALL;
+ #else
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
+ #endif
if (sysclk_source == RCC_SYSCLKSOURCE_PLLCLK) {
// Set HSE as system clock source to allow modification of the PLL configuration
// We then change to PLL after re-configuring PLL
@@ -449,7 +456,9 @@ set_clk:
ahb = sysclk >> AHBPrescTable[RCC_ClkInitStruct.AHBCLKDivider >> RCC_CFGR_HPRE_Pos];
#endif
RCC_ClkInitStruct.APB1CLKDivider = calc_apb1_div(ahb / apb1);
+ #if !defined(STM32G0)
RCC_ClkInitStruct.APB2CLKDivider = calc_apb2_div(ahb / apb2);
+ #endif
#if defined(STM32H7)
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB3CLKDivider = MICROPY_HW_CLK_APB3_DIV;
@@ -692,7 +701,7 @@ void powerctrl_enter_stop_mode(void) {
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
#endif
- #if !defined(STM32F0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB) && !defined(STM32WL)
+ #if !defined(STM32F0) && !defined(STM32G0) && !defined(STM32G4) && !defined(STM32L0) && !defined(STM32L4) && !defined(STM32WB) && !defined(STM32WL)
// takes longer to wake but reduces stop current
HAL_PWREx_EnableFlashPowerDown();
#endif
@@ -771,7 +780,7 @@ void powerctrl_enter_stop_mode(void) {
#if defined(STM32H7)
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL1) {
}
- #elif defined(STM32WB) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32WB) || defined(STM32WL)
while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) {
}
#else
@@ -867,7 +876,7 @@ void powerctrl_enter_standby_mode(void) {
#if defined(STM32F0) || defined(STM32L0)
#define CR_BITS (RTC_CR_ALRAIE | RTC_CR_WUTIE | RTC_CR_TSIE)
#define ISR_BITS (RTC_ISR_ALRAF | RTC_ISR_WUTF | RTC_ISR_TSF)
- #elif defined(STM32G4) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32WL)
#define CR_BITS (RTC_CR_ALRAIE | RTC_CR_ALRBIE | RTC_CR_WUTIE | RTC_CR_TSIE)
#define ISR_BITS (RTC_MISR_ALRAMF | RTC_MISR_ALRBMF | RTC_MISR_WUTMF | RTC_MISR_TSMF)
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
@@ -891,7 +900,7 @@ void powerctrl_enter_standby_mode(void) {
// clear RTC wake-up flags
#if defined(SR_BITS)
RTC->SR &= ~SR_BITS;
- #elif defined(STM32G4) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32WL)
RTC->MISR &= ~ISR_BITS;
#else
RTC->ISR &= ~ISR_BITS;
@@ -909,7 +918,7 @@ void powerctrl_enter_standby_mode(void) {
#elif defined(STM32H7)
EXTI_D1->PR1 = 0x3fffff;
PWR->WKUPCR |= PWR_WAKEUP_FLAG1 | PWR_WAKEUP_FLAG2 | PWR_WAKEUP_FLAG3 | PWR_WAKEUP_FLAG4 | PWR_WAKEUP_FLAG5 | PWR_WAKEUP_FLAG6;
- #elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB)
// clear all wake-up flags
PWR->SCR |= PWR_SCR_CWUF5 | PWR_SCR_CWUF4 | PWR_SCR_CWUF3 | PWR_SCR_CWUF2 | PWR_SCR_CWUF1;
// TODO
diff --git a/ports/stm32/powerctrlboot.c b/ports/stm32/powerctrlboot.c
index 4ecd83e2c..555457c58 100644
--- a/ports/stm32/powerctrlboot.c
+++ b/ports/stm32/powerctrlboot.c
@@ -104,6 +104,77 @@ void SystemClock_Config(void) {
powerctrl_config_systick();
}
+#elif defined(STM32G0)
+
+void SystemClock_Config(void) {
+ // Enable power control peripheral
+ __HAL_RCC_PWR_CLK_ENABLE();
+
+ // Set flash latency to 2 because SYSCLK > 48MHz
+ FLASH->ACR = (FLASH->ACR & ~0x7) | 0x2;
+
+ #if MICROPY_HW_CLK_USE_HSI
+ // Enable the 16MHz internal oscillator and the PLL to get a 64MHz SYSCLK
+ RCC->CR |= RCC_CR_HSION;
+ while ((RCC->CR & RCC_CR_HSIRDY) == 0) {
+ // Wait for HSI to be ready
+ }
+
+ // Use the PLL to get a 64MHz SYSCLK
+ #define PLLM (HSI_VALUE / 16000000) // input is 8MHz
+ #define PLLN (8) // 8*16MHz = 128MHz
+ #define PLLP (2) // f_P = 64MHz
+ #define PLLQ (2) // f_Q = 64MHz
+ #define PLLR (2) // f_R = 64MHz
+ RCC->PLLCFGR =
+ (PLLP - 1) << RCC_PLLCFGR_PLLP_Pos | RCC_PLLCFGR_PLLPEN
+ | (PLLQ - 1) << RCC_PLLCFGR_PLLQ_Pos | RCC_PLLCFGR_PLLQEN
+ | (PLLR - 1) << RCC_PLLCFGR_PLLR_Pos | RCC_PLLCFGR_PLLREN
+ | PLLN << RCC_PLLCFGR_PLLN_Pos
+ | (PLLM - 1) << RCC_PLLCFGR_PLLM_Pos
+ | RCC_PLLCFGR_PLLSRC_HSI;
+
+ #else
+ #error System clock not specified
+ #endif
+
+ RCC->CR |= RCC_CR_PLLON; // Turn PLL on
+ while ((RCC->CR & RCC_CR_PLLRDY) == 0) {
+ // Wait for PLL to lock
+ }
+ const uint32_t sysclk_src = 2; // 2 = PLLRCLK
+
+ // Select SYSCLK source
+ RCC->CFGR |= sysclk_src << RCC_CFGR_SW_Pos;
+ while (((RCC->CFGR >> RCC_CFGR_SWS_Pos) & 0x7) != sysclk_src) {
+ // Wait for SYSCLK source to change
+ }
+
+ SystemCoreClockUpdate();
+ powerctrl_config_systick();
+
+ #if MICROPY_HW_ENABLE_RNG || MICROPY_HW_ENABLE_USB
+ // Enable the 48MHz internal oscillator
+ RCC->CRRCR |= RCC_CRRCR_HSI48ON;
+ RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
+ SYSCFG->CFGR3 |= SYSCFG_CFGR3_ENREF_HSI48;
+ while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY)) {
+ // Wait for HSI48 to be ready
+ }
+
+ // Select RC48 as HSI48 for USB and RNG
+ RCC->CCIPR |= RCC_CCIPR_HSI48SEL;
+
+ #if MICROPY_HW_ENABLE_USB
+ // Synchronise HSI48 with 1kHz USB SoF
+ __HAL_RCC_CRS_CLK_ENABLE();
+ CRS->CR = 0x20 << CRS_CR_TRIM_Pos;
+ CRS->CFGR = 2 << CRS_CFGR_SYNCSRC_Pos | 0x22 << CRS_CFGR_FELIM_Pos
+ | __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000, 1000) << CRS_CFGR_RELOAD_Pos;
+ #endif
+ #endif
+}
+
#elif defined(STM32L0)
void SystemClock_Config(void) {
diff --git a/ports/stm32/pyb_i2c.c b/ports/stm32/pyb_i2c.c
index 5cd7c0c8b..9dfa27656 100644
--- a/ports/stm32/pyb_i2c.c
+++ b/ports/stm32/pyb_i2c.c
@@ -130,7 +130,7 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = {
#endif
};
-#if defined(STM32F7) || defined(STM32G4) || defined(STM32L4) || defined(STM32H7)
+#if defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4)
// The STM32F0, F3, F7, H7 and L4 use a TIMINGR register rather than ClockSpeed and
// DutyCycle.
@@ -163,6 +163,16 @@ const pyb_i2c_obj_t pyb_i2c_obj[] = {
#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_FULL)
#define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_FAST)
+#elif defined(STM32G0)
+// generated using CubeMX
+#define MICROPY_HW_I2C_BAUDRATE_TIMING { \
+ {PYB_I2C_SPEED_STANDARD, 0x10707DBC}, \
+ {PYB_I2C_SPEED_FULL, 0x00602173}, \
+ {PYB_I2C_SPEED_FAST, 0x00300B29}, \
+}
+#define MICROPY_HW_I2C_BAUDRATE_DEFAULT (PYB_I2C_SPEED_FULL)
+#define MICROPY_HW_I2C_BAUDRATE_MAX (PYB_I2C_SPEED_FAST)
+
#elif defined(STM32G4)
// timing input depends on PLL
// for now: 170MHz sysclock, PCLK 10.625 MHz
diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c
index e776f67bb..55977791b 100644
--- a/ports/stm32/rtc.c
+++ b/ports/stm32/rtc.c
@@ -225,7 +225,9 @@ void rtc_init_finalise() {
// fresh reset; configure RTC Calendar
RTC_CalendarConfig();
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0)
+ if (__HAL_RCC_GET_FLAG(RCC_FLAG_PWRRST) != RESET) {
+ #elif defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST) != RESET) {
#else
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET) {
@@ -266,7 +268,7 @@ STATIC HAL_StatusTypeDef PYB_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct
HAL_PWR_EnableBkUpAccess();
uint32_t tickstart = HAL_GetTick();
- #if defined(STM32F7) || defined(STM32G4) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
// __HAL_RCC_PWR_CLK_ENABLE();
// Enable write access to Backup domain
// PWR->CR1 |= PWR_CR1_DBP;
@@ -354,7 +356,7 @@ STATIC HAL_StatusTypeDef PYB_RTC_Init(RTC_HandleTypeDef *hrtc) {
#elif defined(STM32F7)
hrtc->Instance->OR &= (uint32_t) ~RTC_OR_ALARMTYPE;
hrtc->Instance->OR |= (uint32_t)(hrtc->Init.OutPutType);
- #elif defined(STM32G4) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32G4) || defined(STM32WL)
hrtc->Instance->CR &= (uint32_t) ~RTC_CR_TAMPALRM_TYPE_Msk;
hrtc->Instance->CR |= (uint32_t)(hrtc->Init.OutPutType);
#else
@@ -622,6 +624,8 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime
#if defined(STM32F0) || defined(STM32L0)
#define RTC_WKUP_IRQn RTC_IRQn
+#elif defined(STM32G0)
+#define RTC_WKUP_IRQn RTC_TAMP_IRQn
#endif
// wakeup(None)
@@ -719,7 +723,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
RTC->WPR = 0xff;
// enable external interrupts on line EXTI_RTC_WAKEUP
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 |= 1 << EXTI_RTC_WAKEUP;
EXTI->RTSR1 |= 1 << EXTI_RTC_WAKEUP;
#elif defined(STM32H7)
@@ -731,7 +735,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
#endif
// clear interrupt flags
- #if defined(STM32G4) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32WL)
RTC->ICSR &= ~RTC_ICSR_WUTWF;
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
RTC->SR &= ~RTC_SR_WUTF;
@@ -742,6 +746,8 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
EXTI->PR1 = 1 << EXTI_RTC_WAKEUP;
#elif defined(STM32H7)
EXTI_D1->PR1 = 1 << EXTI_RTC_WAKEUP;
+ #elif defined(STM32G0)
+ // Do nothing
#else
EXTI->PR = 1 << EXTI_RTC_WAKEUP;
#endif
@@ -758,7 +764,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
RTC->WPR = 0xff;
// disable external interrupts on line EXTI_RTC_WAKEUP
- #if defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
EXTI->IMR1 &= ~(1 << EXTI_RTC_WAKEUP);
#elif defined(STM32H7)
EXTI_D1->IMR1 |= 1 << EXTI_RTC_WAKEUP;
diff --git a/ports/stm32/spi.c b/ports/stm32/spi.c
index 0ce6b5abc..188376ec0 100644
--- a/ports/stm32/spi.c
+++ b/ports/stm32/spi.c
@@ -216,7 +216,7 @@ int spi_find_index(mp_obj_t id) {
}
STATIC uint32_t spi_get_source_freq(SPI_HandleTypeDef *spi) {
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
return HAL_RCC_GetPCLK1Freq();
#elif defined(STM32H7)
if (spi->Instance == SPI1 || spi->Instance == SPI2 || spi->Instance == SPI3) {
@@ -317,7 +317,11 @@ void spi_init(const spi_t *self, bool enable_nss_pin) {
#endif
#if defined(MICROPY_HW_SPI2_SCK)
} else if (spi->Instance == SPI2) {
+ #if defined(STM32G0)
+ irqn = SPI2_3_IRQn;
+ #else
irqn = SPI2_IRQn;
+ #endif
#if defined(MICROPY_HW_SPI2_NSS)
pins[0] = MICROPY_HW_SPI2_NSS;
#endif
@@ -331,7 +335,11 @@ void spi_init(const spi_t *self, bool enable_nss_pin) {
#endif
#if defined(MICROPY_HW_SPI3_SCK)
} else if (spi->Instance == SPI3) {
+ #if defined(STM32G0)
+ irqn = SPI2_3_IRQn;
+ #else
irqn = SPI3_IRQn;
+ #endif
#if defined(MICROPY_HW_SPI3_NSS)
pins[0] = MICROPY_HW_SPI3_NSS;
#endif
@@ -439,14 +447,22 @@ void spi_deinit(const spi_t *spi_obj) {
__HAL_RCC_SPI2_FORCE_RESET();
__HAL_RCC_SPI2_RELEASE_RESET();
__HAL_RCC_SPI2_CLK_DISABLE();
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(SPI2_3_IRQn);
+ #else
HAL_NVIC_DisableIRQ(SPI2_IRQn);
+ #endif
#endif
#if defined(MICROPY_HW_SPI3_SCK)
} else if (spi->Instance == SPI3) {
__HAL_RCC_SPI3_FORCE_RESET();
__HAL_RCC_SPI3_RELEASE_RESET();
__HAL_RCC_SPI3_CLK_DISABLE();
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(SPI2_3_IRQn);
+ #else
HAL_NVIC_DisableIRQ(SPI3_IRQn);
+ #endif
#endif
#if defined(MICROPY_HW_SPI4_SCK)
} else if (spi->Instance == SPI4) {
diff --git a/ports/stm32/stm32.mk b/ports/stm32/stm32.mk
index ed3298824..c55b243fe 100644
--- a/ports/stm32/stm32.mk
+++ b/ports/stm32/stm32.mk
@@ -48,7 +48,7 @@ CFLAGS_CORTEX_M += -mfpu=fpv5-d16 -mfloat-abi=hard
SUPPORTS_HARDWARE_FP_SINGLE = 1
SUPPORTS_HARDWARE_FP_DOUBLE = 1
else
-ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 l0 wl))
+ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f0 g0 l0 wl))
CFLAGS_CORTEX_M += -msoft-float
else
CFLAGS_CORTEX_M += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
@@ -61,6 +61,7 @@ endif
CFLAGS_MCU_f0 = $(CFLAGS_CORTEX_M) -mtune=cortex-m0 -mcpu=cortex-m0
CFLAGS_MCU_f4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
CFLAGS_MCU_f7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7
+CFLAGS_MCU_g0 = $(CFLAGS_CORTEX_M) -mtune=cortex-m0plus -mcpu=cortex-m0plus
CFLAGS_MCU_g4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
CFLAGS_MCU_l0 = $(CFLAGS_CORTEX_M) -mtune=cortex-m0plus -mcpu=cortex-m0plus
CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
diff --git a/ports/stm32/stm32_it.c b/ports/stm32/stm32_it.c
index 39229a143..55c772efb 100644
--- a/ports/stm32/stm32_it.c
+++ b/ports/stm32/stm32_it.c
@@ -529,7 +529,7 @@ void TAMP_STAMP_IRQHandler(void) {
void RTC_WKUP_IRQHandler(void) {
IRQ_ENTER(RTC_WKUP_IRQn);
- #if defined(STM32G4) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32WL)
RTC->MISR &= ~RTC_MISR_WUTMF; // clear wakeup interrupt flag
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
RTC->SR &= ~RTC_SR_WUTF; // clear wakeup interrupt flag
@@ -540,8 +540,17 @@ void RTC_WKUP_IRQHandler(void) {
IRQ_EXIT(RTC_WKUP_IRQn);
}
-#if defined(STM32F0) || defined(STM32L0)
+#if defined(STM32F0) || defined(STM32G0) || defined(STM32L0)
+#if defined(STM32G0)
+void RTC_TAMP_IRQHandler(void) {
+ IRQ_ENTER(RTC_TAMP_IRQn);
+ RTC->MISR &= ~RTC_MISR_WUTMF; // clear wakeup interrupt flag
+ Handle_EXTI_Irq(EXTI_RTC_WAKEUP); // clear EXTI flag and execute optional callback
+ Handle_EXTI_Irq(EXTI_RTC_TIMESTAMP); // clear EXTI flag and execute optional callback
+ IRQ_EXIT(RTC_TAMP_IRQn);
+}
+#else
void RTC_IRQHandler(void) {
IRQ_ENTER(RTC_IRQn);
if (RTC->ISR & RTC_ISR_WUTF) {
@@ -558,6 +567,7 @@ void RTC_IRQHandler(void) {
}
IRQ_EXIT(RTC_IRQn);
}
+#endif
void EXTI0_1_IRQHandler(void) {
IRQ_ENTER(EXTI0_1_IRQn);
@@ -653,6 +663,15 @@ void TIM2_IRQHandler(void) {
IRQ_EXIT(TIM2_IRQn);
}
+#if defined(STM32G0)
+void TIM3_TIM4_IRQHandler(void) {
+ IRQ_ENTER(TIM3_TIM4_IRQn);
+ timer_irq_handler(3);
+ timer_irq_handler(4);
+ IRQ_EXIT(TIM3_TIM4_IRQn);
+}
+
+#else
void TIM3_IRQHandler(void) {
IRQ_ENTER(TIM3_IRQn);
timer_irq_handler(3);
@@ -664,6 +683,7 @@ void TIM4_IRQHandler(void) {
timer_irq_handler(4);
IRQ_EXIT(TIM4_IRQn);
}
+#endif
void TIM5_IRQHandler(void) {
IRQ_ENTER(TIM5_IRQn);
@@ -673,15 +693,29 @@ void TIM5_IRQHandler(void) {
}
#if defined(TIM6) // STM32F401 doesn't have TIM6
+#if defined(STM32G0)
+void TIM6_DAC_LPTIM1_IRQHandler(void) {
+ IRQ_ENTER(TIM6_DAC_LPTIM1_IRQn);
+ timer_irq_handler(6);
+ IRQ_EXIT(TIM6_DAC_LPTIM1_IRQn);
+}
+#else
void TIM6_DAC_IRQHandler(void) {
IRQ_ENTER(TIM6_DAC_IRQn);
timer_irq_handler(6);
IRQ_EXIT(TIM6_DAC_IRQn);
}
#endif
+#endif
#if defined(TIM7) // STM32F401 doesn't have TIM7
-#if defined(STM32G4)
+#if defined(STM32G0)
+void TIM7_LPTIM2_IRQHandler(void) {
+ IRQ_ENTER(TIM7_LPTIM2_IRQn);
+ timer_irq_handler(7);
+ IRQ_EXIT(TIM7_LPTIM2_IRQn);
+}
+#elif defined(STM32G4)
void TIM7_DAC_IRQHandler(void) {
IRQ_ENTER(TIM7_DAC_IRQn);
timer_irq_handler(7);
@@ -731,6 +765,32 @@ void TIM8_TRG_COM_TIM14_IRQHandler(void) {
}
#endif
+#if defined(STM32G0)
+void TIM14_IRQHandler(void) {
+ IRQ_ENTER(TIM14_IRQn);
+ timer_irq_handler(14);
+ IRQ_EXIT(TIM14_IRQn);
+}
+
+void TIM15_IRQHandler(void) {
+ IRQ_ENTER(TIM15_IRQn);
+ timer_irq_handler(15);
+ IRQ_EXIT(TIM15_IRQn);
+}
+
+void TIM16_FDCAN_IT0_IRQHandler(void) {
+ IRQ_ENTER(TIM16_FDCAN_IT0_IRQn);
+ timer_irq_handler(16);
+ IRQ_EXIT(TIM16_FDCAN_IT0_IRQn);
+}
+
+void TIM17_FDCAN_IT1_IRQHandler(void) {
+ IRQ_ENTER(TIM17_FDCAN_IT1_IRQn);
+ timer_irq_handler(17);
+ IRQ_EXIT(TIM17_FDCAN_IT1_IRQn);
+}
+#endif
+
#if defined(STM32H7)
void TIM15_IRQHandler(void) {
IRQ_ENTER(TIM15_IRQn);
@@ -779,6 +839,29 @@ void USART3_8_IRQHandler(void) {
IRQ_EXIT(USART3_8_IRQn);
}
+#elif defined(STM32G0)
+
+#if defined(STM32G0B1xx) || defined(STM32G0C1xx)
+void USART2_LPUART2_IRQHandler(void) {
+ IRQ_ENTER(USART2_LPUART2_IRQn);
+ uart_irq_handler(2);
+ uart_irq_handler(PYB_LPUART_2);
+ IRQ_EXIT(USART2_LPUART2_IRQn);
+}
+
+void USART3_4_5_6_LPUART1_IRQHandler(void) {
+ IRQ_ENTER(USART3_4_5_6_LPUART1_IRQn);
+ uart_irq_handler(3);
+ uart_irq_handler(4);
+ uart_irq_handler(5);
+ uart_irq_handler(6);
+ uart_irq_handler(PYB_LPUART_1);
+ IRQ_EXIT(USART3_4_5_6_LPUART1_IRQn);
+}
+#else
+#error Unsupported processor
+#endif
+
#elif defined(STM32L0)
void USART4_5_IRQHandler(void) {
@@ -798,6 +881,14 @@ void USART3_IRQHandler(void) {
}
#endif
+#if defined(USART4)
+void USART4_IRQHandler(void) {
+ IRQ_ENTER(USART4_IRQn);
+ uart_irq_handler(4);
+ IRQ_EXIT(USART4_IRQn);
+}
+#endif
+
#if defined(UART4)
void UART4_IRQHandler(void) {
IRQ_ENTER(UART4_IRQn);
@@ -806,6 +897,14 @@ void UART4_IRQHandler(void) {
}
#endif
+#if defined(USART5)
+void USART5_IRQHandler(void) {
+ IRQ_ENTER(USART5_IRQn);
+ uart_irq_handler(5);
+ IRQ_EXIT(USART5_IRQn);
+}
+#endif
+
#if defined(UART5)
void UART5_IRQHandler(void) {
IRQ_ENTER(UART5_IRQn);
@@ -864,6 +963,14 @@ void LPUART1_IRQHandler(void) {
}
#endif
+#if defined(LPUART2)
+void LPUART2_IRQHandler(void) {
+ IRQ_ENTER(LPUART2_IRQn);
+ uart_irq_handler(PYB_LPUART_2);
+ IRQ_EXIT(LPUART2_IRQn);
+}
+#endif
+
#if MICROPY_PY_PYB_LEGACY
#if defined(MICROPY_HW_I2C1_SCL)
diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c
index 12f0515d4..8181885e2 100644
--- a/ports/stm32/timer.c
+++ b/ports/stm32/timer.c
@@ -236,7 +236,7 @@ uint32_t timer_get_source_freq(uint32_t tim_id) {
uint32_t source, clk_div;
if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) {
// TIM{1,8,9,10,11} are on APB2
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
source = HAL_RCC_GetPCLK1Freq();
clk_div = RCC->CFGR & RCC_CFGR_PPRE;
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
@@ -252,7 +252,7 @@ uint32_t timer_get_source_freq(uint32_t tim_id) {
} else {
// TIM{2,3,4,5,6,7,12,13,14} are on APB1
source = HAL_RCC_GetPCLK1Freq();
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
clk_div = RCC->CFGR & RCC_CFGR_PPRE;
#elif defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
clk_div = RCC->CDCFGR1 & RCC_CDCFGR2_CDPPRE1;
@@ -482,7 +482,7 @@ STATIC void config_deadtime(pyb_timer_obj_t *self, mp_int_t ticks, mp_int_t brk)
deadTimeConfig.DeadTime = compute_dtg_from_ticks(ticks);
deadTimeConfig.BreakState = brk == BRK_OFF ? TIM_BREAK_DISABLE : TIM_BREAK_ENABLE;
deadTimeConfig.BreakPolarity = brk == BRK_LOW ? TIM_BREAKPOLARITY_LOW : TIM_BREAKPOLARITY_HIGH;
- #if defined(STM32F7) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
+ #if defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
deadTimeConfig.BreakFilter = 0;
deadTimeConfig.Break2State = TIM_BREAK_DISABLE;
deadTimeConfig.Break2Polarity = TIM_BREAKPOLARITY_LOW;
@@ -804,7 +804,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
#define TIM_ENTRY(id, irq) [id - 1] = (uint32_t)TIM##id | irq
STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {
#if defined(TIM1)
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
TIM_ENTRY(1, TIM1_BRK_UP_TRG_COM_IRQn),
#elif defined(STM32F4) || defined(STM32F7)
TIM_ENTRY(1, TIM1_UP_TIM10_IRQn),
@@ -816,23 +816,35 @@ STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {
#endif
TIM_ENTRY(2, TIM2_IRQn),
#if defined(TIM3)
+ #if defined(STM32G0B1xx) || defined(STM32G0C1xx)
+ TIM_ENTRY(3, TIM3_TIM4_IRQn),
+ #else
TIM_ENTRY(3, TIM3_IRQn),
#endif
+ #endif
#if defined(TIM4)
+ #if defined(STM32G0B1xx) || defined(STM32G0C1xx)
+ TIM_ENTRY(3, TIM3_TIM4_IRQn),
+ #else
TIM_ENTRY(4, TIM4_IRQn),
#endif
+ #endif
#if defined(TIM5)
TIM_ENTRY(5, TIM5_IRQn),
#endif
#if defined(TIM6)
#if defined(STM32F412Zx)
TIM_ENTRY(6, TIM6_IRQn),
+ #elif defined(STM32G0)
+ TIM_ENTRY(6, TIM6_DAC_LPTIM1_IRQn),
#else
TIM_ENTRY(6, TIM6_DAC_IRQn),
#endif
#endif
#if defined(TIM7)
- #if defined(STM32G4)
+ #if defined(STM32G0)
+ TIM_ENTRY(7, TIM7_LPTIM2_IRQn),
+ #elif defined(STM32G4)
TIM_ENTRY(7, TIM7_DAC_IRQn),
#else
TIM_ENTRY(7, TIM7_IRQn),
@@ -860,27 +872,31 @@ STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {
#if defined(TIM13)
TIM_ENTRY(13, TIM8_UP_TIM13_IRQn),
#endif
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
TIM_ENTRY(14, TIM14_IRQn),
#elif defined(TIM14)
TIM_ENTRY(14, TIM8_TRG_COM_TIM14_IRQn),
#endif
#if defined(TIM15)
- #if defined(STM32F0) || defined(STM32H7)
+ #if defined(STM32F0) || defined(STM32G0) || defined(STM32H7)
TIM_ENTRY(15, TIM15_IRQn),
#else
TIM_ENTRY(15, TIM1_BRK_TIM15_IRQn),
#endif
#endif
#if defined(TIM16)
- #if defined(STM32F0) || defined(STM32H7) || defined(STM32WL)
+ #if defined(STM32G0B1xx) || defined(STM32G0C1xx)
+ TIM_ENTRY(16, TIM16_FDCAN_IT0_IRQn),
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32H7) || defined(STM32WL)
TIM_ENTRY(16, TIM16_IRQn),
#else
TIM_ENTRY(16, TIM1_UP_TIM16_IRQn),
#endif
#endif
#if defined(TIM17)
- #if defined(STM32F0) || defined(STM32H7) || defined(STM32WL)
+ #if defined(STM32G0B1xx) || defined(STM32G0C1xx)
+ TIM_ENTRY(17, TIM17_FDCAN_IT1_IRQn),
+ #elif defined(STM32F0) || defined(STM32G0) || defined(STM32H7) || defined(STM32WL)
TIM_ENTRY(17, TIM17_IRQn),
#else
TIM_ENTRY(17, TIM1_TRG_COM_TIM17_IRQn),
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index 13e1667d2..adcbe8836 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -41,13 +41,13 @@
#if defined(STM32F4)
#define UART_RXNE_IS_SET(uart) ((uart)->SR & USART_SR_RXNE)
#else
-#if defined(STM32H7) || defined(STM32WL)
+#if defined(STM32G0) || defined(STM32H7) || defined(STM32WL)
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#endif
#define UART_RXNE_IS_SET(uart) ((uart)->ISR & USART_ISR_RXNE)
#endif
-#if defined(STM32WL)
+#if defined(STM32G0) || defined(STM32WL)
#define UART_RXNE_IT_EN(uart) do { (uart)->CR1 |= USART_CR1_RXNEIE_RXFNEIE; } while (0)
#define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE_RXFNEIE; } while (0)
#else
@@ -55,7 +55,7 @@
#define UART_RXNE_IT_DIS(uart) do { (uart)->CR1 &= ~USART_CR1_RXNEIE; } while (0)
#endif
-#if defined(STM32WL)
+#if defined(STM32G0) || defined(STM32WL)
#define USART_CR1_IE_BASE (USART_CR1_PEIE | USART_CR1_TXEIE_TXFNFIE | USART_CR1_TCIE | USART_CR1_RXNEIE_RXFNEIE | USART_CR1_IDLEIE)
#else
#define USART_CR1_IE_BASE (USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE | USART_CR1_RXNEIE | USART_CR1_IDLEIE)
@@ -82,7 +82,7 @@
#define USART_CR3_IE_ALL (USART_CR3_IE_BASE)
#endif
-#elif defined(STM32G4)
+#elif defined(STM32G0) || defined(STM32G4)
#define USART_CR1_IE_ALL (USART_CR1_IE_BASE | USART_CR1_EOBIE | USART_CR1_RTOIE | USART_CR1_CMIE)
#define USART_CR2_IE_ALL (USART_CR2_IE_BASE)
#if defined(USART_CR3_TCBGTIE)
@@ -122,13 +122,13 @@ typedef struct _pyb_uart_irq_map_t {
STATIC const pyb_uart_irq_map_t mp_uart_irq_map[] = {
{ USART_CR1_IDLEIE, UART_FLAG_IDLE}, // RX idle
{ USART_CR1_PEIE, UART_FLAG_PE}, // parity error
- #if defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32WL)
{ USART_CR1_TXEIE_TXFNFIE, UART_FLAG_TXE}, // TX register empty
#else
{ USART_CR1_TXEIE, UART_FLAG_TXE}, // TX register empty
#endif
{ USART_CR1_TCIE, UART_FLAG_TC}, // TX complete
- #if defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32WL)
{ USART_CR1_RXNEIE_RXFNEIE, UART_FLAG_RXNE}, // RX register not empty
#else
{ USART_CR1_RXNEIE, UART_FLAG_RXNE}, // RX register not empty
@@ -229,6 +229,11 @@ bool uart_exists(int uart_id) {
return true;
#endif
+ #if defined(MICROPY_HW_LPUART2_TX) && defined(MICROPY_HW_LPUART2_RX)
+ case PYB_LPUART_2:
+ return true;
+ #endif
+
default:
return false;
}
@@ -270,7 +275,11 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
case PYB_UART_2:
uart_unit = 2;
UARTx = USART2;
+ #if defined(STM32G0)
+ irqn = USART2_LPUART2_IRQn;
+ #else
irqn = USART2_IRQn;
+ #endif
pins[0] = MICROPY_HW_UART2_TX;
pins[1] = MICROPY_HW_UART2_RX;
#if defined(MICROPY_HW_UART2_RTS)
@@ -293,6 +302,8 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART3;
#if defined(STM32F0)
irqn = USART3_8_IRQn;
+ #elif defined(STM32G0)
+ irqn = USART3_4_5_6_LPUART1_IRQn;
#else
irqn = USART3_IRQn;
#endif
@@ -323,6 +334,10 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART4;
irqn = USART4_5_IRQn;
__HAL_RCC_USART4_CLK_ENABLE();
+ #elif defined(STM32G0)
+ UARTx = USART4;
+ irqn = USART3_4_5_6_LPUART1_IRQn;
+ __HAL_RCC_USART4_CLK_ENABLE();
#else
UARTx = UART4;
irqn = UART4_IRQn;
@@ -354,6 +369,10 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART5;
irqn = USART4_5_IRQn;
__HAL_RCC_USART5_CLK_ENABLE();
+ #elif defined(STM32G0)
+ UARTx = USART5;
+ irqn = USART3_4_5_6_LPUART1_IRQn;
+ __HAL_RCC_USART5_CLK_ENABLE();
#else
UARTx = UART5;
irqn = UART5_IRQn;
@@ -380,6 +399,8 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
UARTx = USART6;
#if defined(STM32F0)
irqn = USART3_8_IRQn;
+ #elif defined(STM32G0)
+ irqn = USART3_4_5_6_LPUART1_IRQn;
#else
irqn = USART6_IRQn;
#endif
@@ -480,7 +501,11 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
uart_fn = AF_FN_LPUART;
uart_unit = 1;
UARTx = LPUART1;
+ #if defined(STM32G0)
+ irqn = USART3_4_5_6_LPUART1_IRQn;
+ #else
irqn = LPUART1_IRQn;
+ #endif
pins[0] = MICROPY_HW_LPUART1_TX;
pins[1] = MICROPY_HW_LPUART1_RX;
#if defined(MICROPY_HW_LPUART1_RTS)
@@ -497,6 +522,30 @@ bool uart_init(pyb_uart_obj_t *uart_obj,
break;
#endif
+ #if defined(MICROPY_HW_LPUART2_TX) && defined(MICROPY_HW_LPUART2_RX)
+ case PYB_LPUART_2:
+ uart_fn = AF_FN_LPUART;
+ uart_unit = 2;
+ UARTx = LPUART2;
+ #if defined(STM32G0)
+ irqn = USART2_LPUART2_IRQn;
+ #endif
+ pins[0] = MICROPY_HW_LPUART2_TX;
+ pins[1] = MICROPY_HW_LPUART2_RX;
+ #if defined(MICROPY_HW_LPUART2_RTS)
+ if (flow & UART_HWCONTROL_RTS) {
+ pins[2] = MICROPY_HW_LPUART2_RTS;
+ }
+ #endif
+ #if defined(MICROPY_HW_LPUART2_CTS)
+ if (flow & UART_HWCONTROL_CTS) {
+ pins[3] = MICROPY_HW_LPUART2_CTS;
+ }
+ #endif
+ __HAL_RCC_LPUART2_CLK_ENABLE();
+ break;
+ #endif
+
default:
// UART does not exist or is not configured for this board
return false;
@@ -626,14 +675,20 @@ void uart_deinit(pyb_uart_obj_t *self) {
__HAL_RCC_USART1_CLK_DISABLE();
#if defined(USART2)
} else if (self->uart_id == 2) {
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART2_LPUART2_IRQn);
+ #else
HAL_NVIC_DisableIRQ(USART2_IRQn);
+ #endif
__HAL_RCC_USART2_FORCE_RESET();
__HAL_RCC_USART2_RELEASE_RESET();
__HAL_RCC_USART2_CLK_DISABLE();
#endif
#if defined(USART3)
} else if (self->uart_id == 3) {
- #if !defined(STM32F0)
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART3_4_5_6_LPUART1_IRQn);
+ #elif !defined(STM32F0)
HAL_NVIC_DisableIRQ(USART3_IRQn);
#endif
__HAL_RCC_USART3_FORCE_RESET();
@@ -715,11 +770,26 @@ void uart_deinit(pyb_uart_obj_t *self) {
#endif
#if defined(LPUART1)
} else if (self->uart_id == PYB_LPUART_1) {
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART3_4_5_6_LPUART1_IRQn);
+ #else
HAL_NVIC_DisableIRQ(LPUART1_IRQn);
+ #endif
__HAL_RCC_LPUART1_FORCE_RESET();
__HAL_RCC_LPUART1_RELEASE_RESET();
__HAL_RCC_LPUART1_CLK_DISABLE();
#endif
+ #if defined(LPUART2)
+ } else if (self->uart_id == PYB_LPUART_2) {
+ #if defined(STM32G0)
+ HAL_NVIC_DisableIRQ(USART2_LPUART2_IRQn);
+ #else
+ HAL_NVIC_DisableIRQ(LPUART2_IRQn);
+ #endif
+ __HAL_RCC_LPUART2_FORCE_RESET();
+ __HAL_RCC_LPUART2_RELEASE_RESET();
+ __HAL_RCC_LPUART2_CLK_DISABLE();
+ #endif
}
}
@@ -730,7 +800,7 @@ void uart_attach_to_repl(pyb_uart_obj_t *self, bool attached) {
uint32_t uart_get_source_freq(pyb_uart_obj_t *self) {
uint32_t uart_clk = 0;
- #if defined(STM32F0)
+ #if defined(STM32F0) || defined(STM32G0)
uart_clk = HAL_RCC_GetPCLK1Freq();
#elif defined(STM32F7)
switch ((RCC->DCKCFGR2 >> ((self->uart_id - 1) * 2)) & 3) {
@@ -830,14 +900,14 @@ uint32_t uart_get_baudrate(pyb_uart_obj_t *self) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
return LL_LPUART_GetBaudRate(self->uartx, uart_get_source_freq(self)
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
, self->uartx->PRESC
#endif
);
}
#endif
return LL_USART_GetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
self->uartx->PRESC,
#endif
LL_USART_OVERSAMPLING_16);
@@ -847,7 +917,7 @@ void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
#if defined(LPUART1)
if (self->uart_id == PYB_LPUART_1) {
LL_LPUART_SetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
LL_LPUART_PRESCALER_DIV1,
#endif
baudrate);
@@ -855,7 +925,7 @@ void uart_set_baudrate(pyb_uart_obj_t *self, uint32_t baudrate) {
}
#endif
LL_USART_SetBaudRate(self->uartx, uart_get_source_freq(self),
- #if defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
LL_USART_PRESCALER_DIV1,
#endif
LL_USART_OVERSAMPLING_16, baudrate);
@@ -906,7 +976,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
return data;
} else {
// no buffering
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
int data = self->uartx->RDR & self->char_mask;
self->uartx->ICR = USART_ICR_ORECF; // clear ORE if it was set
return data;
@@ -1056,7 +1126,7 @@ void uart_irq_handler(mp_uint_t uart_id) {
uint16_t next_head = (self->read_buf_head + 1) % self->read_buf_len;
if (next_head != self->read_buf_tail) {
// only read data if room in buf
- #if defined(STM32F0) || defined(STM32F7) || defined(STM32G4) || defined(STM32L0) || defined(STM32L4) || defined(STM32H7) || defined(STM32WB) || defined(STM32WL)
+ #if defined(STM32F0) || defined(STM32F7) || defined(STM32G0) || defined(STM32G4) || defined(STM32H7) || defined(STM32L0) || defined(STM32L4) || defined(STM32WB) || defined(STM32WL)
int data = self->uartx->RDR; // clears UART_FLAG_RXNE
#else
self->mp_irq_flags = self->uartx->SR; // resample to get any new flags since next read of DR will clear SR
diff --git a/ports/stm32/uart.h b/ports/stm32/uart.h
index 5fee841f8..ec8a27591 100644
--- a/ports/stm32/uart.h
+++ b/ports/stm32/uart.h
@@ -43,6 +43,9 @@ typedef enum {
#ifdef LPUART1
PYB_LPUART_1 = MICROPY_HW_MAX_UART + 1,
#endif
+ #ifdef LPUART2
+ PYB_LPUART_2 = MICROPY_HW_MAX_UART + 2,
+ #endif
} pyb_uart_t;
#define CHAR_WIDTH_8BIT (0)
@@ -102,7 +105,7 @@ void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len);
static inline bool uart_tx_avail(pyb_uart_obj_t *self) {
#if defined(STM32F4)
return self->uartx->SR & USART_SR_TXE;
- #elif defined(STM32H7) || defined(STM32WL)
+ #elif defined(STM32G0) || defined(STM32H7) || defined(STM32WL)
return self->uartx->ISR & USART_ISR_TXE_TXFNF;
#else
return self->uartx->ISR & USART_ISR_TXE;