stm32: Add support for G0 MCUs.

This commit adds support for the STM32G0 series of MCUs.

Signed-off-by: Asensio Lorenzo Sempere <asensio.aerospace@gmail.com>
This commit is contained in:
Asensio Lorenzo Sempere 2022-02-12 14:36:58 -06:00 committed by Damien George
parent 3587d8e808
commit 010012c7c3
26 changed files with 719 additions and 110 deletions

View File

@ -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 \
)

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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++) {

View File

@ -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)

View File

@ -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;

View File

@ -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]);

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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)

View File

@ -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),

View File

@ -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

View File

@ -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;