stm32: Add support for STM32F0 MCUs.
This commit is contained in:
parent
4a7d157a5b
commit
ea7e747979
@ -57,10 +57,15 @@ CFLAGS_CORTEX_M = -mthumb
|
||||
ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32F767xx STM32F769xx STM32H743xx))
|
||||
CFLAGS_CORTEX_M += -mfpu=fpv5-d16 -mfloat-abi=hard
|
||||
else
|
||||
ifeq ($(MCU_SERIES),f0)
|
||||
CFLAGS_CORTEX_M += -msoft-float
|
||||
else
|
||||
CFLAGS_CORTEX_M += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
|
||||
endif
|
||||
endif
|
||||
|
||||
# Options for particular MCU series
|
||||
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_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4
|
||||
@ -155,7 +160,6 @@ SRC_LIBM = $(addprefix lib/libm_dbl/,\
|
||||
else
|
||||
SRC_LIBM = $(addprefix lib/libm/,\
|
||||
math.c \
|
||||
thumb_vfp_sqrtf.c \
|
||||
acoshf.c \
|
||||
asinfacosf.c \
|
||||
asinhf.c \
|
||||
@ -181,6 +185,11 @@ SRC_LIBM = $(addprefix lib/libm/,\
|
||||
wf_lgamma.c \
|
||||
wf_tgamma.c \
|
||||
)
|
||||
ifeq ($(MCU_SERIES),f0)
|
||||
SRC_LIBM += lib/libm/ef_sqrt.c
|
||||
else
|
||||
SRC_LIBM += lib/libm/thumb_vfp_sqrtf.c
|
||||
endif
|
||||
endif
|
||||
|
||||
EXTMOD_SRC_C = $(addprefix extmod/,\
|
||||
@ -197,7 +206,6 @@ DRIVERS_SRC_C = $(addprefix drivers/,\
|
||||
|
||||
SRC_C = \
|
||||
main.c \
|
||||
system_stm32.c \
|
||||
stm32_it.c \
|
||||
usbd_conf.c \
|
||||
usbd_desc.c \
|
||||
@ -252,10 +260,19 @@ SRC_C = \
|
||||
adc.c \
|
||||
$(wildcard boards/$(BOARD)/*.c)
|
||||
|
||||
ifeq ($(MCU_SERIES),f0)
|
||||
SRC_O = \
|
||||
$(STARTUP_FILE) \
|
||||
system_stm32f0.o \
|
||||
resethandler_m0.o \
|
||||
gchelper_m0.o
|
||||
else
|
||||
SRC_O = \
|
||||
$(STARTUP_FILE) \
|
||||
system_stm32.o \
|
||||
resethandler.o \
|
||||
gchelper.o \
|
||||
gchelper.o
|
||||
endif
|
||||
|
||||
SRC_HAL = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
|
||||
hal.c \
|
||||
@ -277,14 +294,19 @@ SRC_HAL = $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
|
||||
hal_rcc_ex.c \
|
||||
hal_rtc.c \
|
||||
hal_rtc_ex.c \
|
||||
hal_sd.c \
|
||||
hal_spi.c \
|
||||
hal_tim.c \
|
||||
hal_tim_ex.c \
|
||||
hal_uart.c \
|
||||
)
|
||||
|
||||
ifeq ($(MCU_SERIES),$(filter $(MCU_SERIES),f4 f7 h7 l4))
|
||||
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_,\
|
||||
hal_sd.c \
|
||||
ll_sdmmc.c \
|
||||
ll_usb.c \
|
||||
)
|
||||
endif
|
||||
|
||||
ifeq ($(CMSIS_MCU),$(filter $(CMSIS_MCU),STM32H743xx))
|
||||
SRC_HAL += $(addprefix $(HAL_DIR)/Src/stm32$(MCU_SERIES)xx_, hal_fdcan.c)
|
||||
|
@ -59,7 +59,15 @@
|
||||
#define ADCx_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE
|
||||
#define ADC_NUM_CHANNELS (19)
|
||||
|
||||
#if defined(STM32F4)
|
||||
#if defined(STM32F0)
|
||||
|
||||
#define ADC_FIRST_GPIO_CHANNEL (0)
|
||||
#define ADC_LAST_GPIO_CHANNEL (15)
|
||||
#define ADC_CAL_ADDRESS (0x1ffff7ba)
|
||||
#define ADC_CAL1 ((uint16_t*)0x1ffff7b8)
|
||||
#define ADC_CAL2 ((uint16_t*)0x1ffff7c2)
|
||||
|
||||
#elif defined(STM32F4)
|
||||
|
||||
#define ADC_FIRST_GPIO_CHANNEL (0)
|
||||
#define ADC_LAST_GPIO_CHANNEL (15)
|
||||
@ -104,7 +112,9 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(STM32F405xx) || defined(STM32F415xx) || \
|
||||
#if defined(STM32F091xC)
|
||||
#define VBAT_DIV (2)
|
||||
#elif defined(STM32F405xx) || defined(STM32F415xx) || \
|
||||
defined(STM32F407xx) || defined(STM32F417xx) || \
|
||||
defined(STM32F401xC) || defined(STM32F401xE) || \
|
||||
defined(STM32F411xE)
|
||||
@ -159,7 +169,7 @@ STATIC bool is_adcx_channel(int channel) {
|
||||
#if defined(STM32F411xE)
|
||||
// The HAL has an incorrect IS_ADC_CHANNEL macro for the F411 so we check for temp
|
||||
return IS_ADC_CHANNEL(channel) || channel == ADC_CHANNEL_TEMPSENSOR;
|
||||
#elif defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
|
||||
#elif defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
|
||||
return IS_ADC_CHANNEL(channel);
|
||||
#elif defined(STM32L4)
|
||||
ADC_HandleTypeDef handle;
|
||||
@ -174,7 +184,7 @@ STATIC void adc_wait_for_eoc_or_timeout(int32_t timeout) {
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
while ((ADCx->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
|
||||
#elif defined(STM32H7) || defined(STM32L4)
|
||||
#elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4)
|
||||
while (READ_BIT(ADCx->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {
|
||||
#else
|
||||
#error Unsupported processor
|
||||
@ -186,7 +196,7 @@ STATIC void adc_wait_for_eoc_or_timeout(int32_t timeout) {
|
||||
}
|
||||
|
||||
STATIC void adcx_clock_enable(void) {
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
|
||||
ADCx_CLK_ENABLE();
|
||||
#elif defined(STM32H7)
|
||||
__HAL_RCC_ADC3_CLK_ENABLE();
|
||||
@ -205,12 +215,14 @@ 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)
|
||||
adch->Init.NbrOfDiscConversion = 0;
|
||||
adch->Init.NbrOfConversion = 1;
|
||||
#endif
|
||||
adch->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
|
||||
adch->Init.ExternalTrigConv = ADC_SOFTWARE_START;
|
||||
adch->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
|
||||
adch->Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
|
||||
adch->Init.ScanConvMode = DISABLE;
|
||||
adch->Init.DataAlign = ADC_DATAALIGN_RIGHT;
|
||||
@ -271,7 +283,9 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
|
||||
|
||||
sConfig.Channel = channel;
|
||||
sConfig.Rank = 1;
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F0)
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES_5;
|
||||
#elif defined(STM32F4) || defined(STM32F7)
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
|
||||
#elif defined(STM32H7)
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_8CYCLES_5;
|
||||
@ -283,10 +297,10 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
|
||||
sConfig.SamplingTime = ADC_SAMPLETIME_12CYCLES_5;
|
||||
sConfig.SingleDiff = ADC_SINGLE_ENDED;
|
||||
sConfig.OffsetNumber = ADC_OFFSET_NONE;
|
||||
sConfig.Offset = 0;
|
||||
#else
|
||||
#error Unsupported processor
|
||||
#endif
|
||||
sConfig.Offset = 0;
|
||||
|
||||
HAL_ADC_ConfigChannel(adc_handle, &sConfig);
|
||||
}
|
||||
@ -443,7 +457,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)
|
||||
ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
|
||||
#elif defined(STM32H7) || defined(STM32L4)
|
||||
#elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4)
|
||||
SET_BIT(ADCx->CR, ADC_CR_ADSTART);
|
||||
#else
|
||||
#error Unsupported processor
|
||||
@ -553,7 +567,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)
|
||||
ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
|
||||
#elif defined(STM32H7) || defined(STM32L4)
|
||||
#elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4)
|
||||
SET_BIT(ADCx->CR, ADC_CR_ADSTART);
|
||||
#else
|
||||
#error Unsupported processor
|
||||
|
@ -177,7 +177,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(STM32L4)
|
||||
#elif defined(STM32F0) || defined(STM32L4)
|
||||
__HAL_RCC_DAC1_CLK_ENABLE();
|
||||
#else
|
||||
#error Unsupported Processor
|
||||
|
@ -55,7 +55,7 @@ typedef enum {
|
||||
struct _dma_descr_t {
|
||||
#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
|
||||
DMA_Stream_TypeDef *instance;
|
||||
#elif defined(STM32L4)
|
||||
#elif defined(STM32F0) || defined(STM32L4)
|
||||
DMA_Channel_TypeDef *instance;
|
||||
#else
|
||||
#error "Unsupported Processor"
|
||||
@ -141,7 +141,46 @@ static const DMA_InitTypeDef dma_init_struct_dac = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F0)
|
||||
|
||||
#define NCONTROLLERS (2)
|
||||
#define NSTREAMS_PER_CONTROLLER (7)
|
||||
#define NSTREAM (NCONTROLLERS * NSTREAMS_PER_CONTROLLER)
|
||||
|
||||
#define DMA_SUB_INSTANCE_AS_UINT8(dma_channel) (dma_channel)
|
||||
|
||||
#define DMA1_ENABLE_MASK (0x007f) // Bits in dma_enable_mask corresponfing 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, HAL_DMA1_CH3_DAC_CH1, DMA_MEMORY_TO_PERIPH, dma_id_3, &dma_init_struct_dac };
|
||||
const dma_descr_t dma_DAC_2_TX = { DMA1_Channel4, HAL_DMA1_CH4_DAC_CH2, DMA_MEMORY_TO_PERIPH, dma_id_4, &dma_init_struct_dac };
|
||||
#endif
|
||||
const dma_descr_t dma_SPI_2_TX = { DMA1_Channel5, HAL_DMA1_CH5_SPI2_TX, DMA_MEMORY_TO_PERIPH, dma_id_5, &dma_init_struct_spi_i2c};
|
||||
const dma_descr_t dma_SPI_2_RX = { DMA1_Channel6, HAL_DMA1_CH6_SPI2_RX, DMA_PERIPH_TO_MEMORY, dma_id_6, &dma_init_struct_spi_i2c};
|
||||
const dma_descr_t dma_SPI_1_RX = { DMA2_Channel3, HAL_DMA2_CH3_SPI1_RX, DMA_PERIPH_TO_MEMORY, dma_id_3, &dma_init_struct_spi_i2c};
|
||||
const dma_descr_t dma_SPI_1_TX = { DMA2_Channel4, HAL_DMA2_CH4_SPI1_TX, DMA_MEMORY_TO_PERIPH, dma_id_4, &dma_init_struct_spi_i2c};
|
||||
|
||||
static const uint8_t dma_irqn[NSTREAM] = {
|
||||
DMA1_Ch1_IRQn,
|
||||
DMA1_Ch2_3_DMA2_Ch1_2_IRQn,
|
||||
DMA1_Ch2_3_DMA2_Ch1_2_IRQn,
|
||||
DMA1_Ch4_7_DMA2_Ch3_5_IRQn,
|
||||
DMA1_Ch4_7_DMA2_Ch3_5_IRQn,
|
||||
DMA1_Ch4_7_DMA2_Ch3_5_IRQn,
|
||||
DMA1_Ch4_7_DMA2_Ch3_5_IRQn,
|
||||
|
||||
DMA1_Ch2_3_DMA2_Ch1_2_IRQn,
|
||||
DMA1_Ch2_3_DMA2_Ch1_2_IRQn,
|
||||
DMA1_Ch4_7_DMA2_Ch3_5_IRQn,
|
||||
DMA1_Ch4_7_DMA2_Ch3_5_IRQn,
|
||||
DMA1_Ch4_7_DMA2_Ch3_5_IRQn,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
#elif defined(STM32F4) || defined(STM32F7)
|
||||
|
||||
#define NCONTROLLERS (2)
|
||||
#define NSTREAMS_PER_CONTROLLER (8)
|
||||
@ -381,8 +420,13 @@ volatile dma_idle_count_t dma_idle;
|
||||
|
||||
#define DMA_INVALID_CHANNEL 0xff // Value stored in dma_last_channel which means invalid
|
||||
|
||||
#if defined(STM32F0)
|
||||
#define DMA1_IS_CLK_ENABLED() ((RCC->AHBENR & RCC_AHBENR_DMA1EN) != 0)
|
||||
#define DMA2_IS_CLK_ENABLED() ((RCC->AHBENR & RCC_AHBENR_DMA2EN) != 0)
|
||||
#else
|
||||
#define DMA1_IS_CLK_ENABLED() ((RCC->AHB1ENR & RCC_AHB1ENR_DMA1EN) != 0)
|
||||
#define DMA2_IS_CLK_ENABLED() ((RCC->AHB1ENR & RCC_AHB1ENR_DMA2EN) != 0)
|
||||
#endif
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
|
||||
|
||||
@ -476,8 +520,10 @@ void dma_init_handle(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void
|
||||
#if defined(STM32L4) || defined(STM32H7)
|
||||
dma->Init.Request = dma_descr->sub_instance;
|
||||
#else
|
||||
#if !defined(STM32F0)
|
||||
dma->Init.Channel = dma_descr->sub_instance;
|
||||
#endif
|
||||
#endif
|
||||
// half of __HAL_LINKDMA(data, xxx, *dma)
|
||||
// caller must implement other half by doing: data->xxx = dma
|
||||
dma->Parent = data;
|
||||
@ -517,6 +563,13 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void *data){
|
||||
HAL_DMA_DeInit(dma);
|
||||
HAL_DMA_Init(dma);
|
||||
NVIC_SetPriority(IRQn_NONNEG(dma_irqn[dma_id]), IRQ_PRI_DMA);
|
||||
#if defined(STM32F0)
|
||||
if (dma->Instance < DMA2_Channel1) {
|
||||
__HAL_DMA1_REMAP(dma_descr->sub_instance);
|
||||
} else {
|
||||
__HAL_DMA2_REMAP(dma_descr->sub_instance);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// only necessary initialization
|
||||
dma->State = HAL_DMA_STATE_READY;
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
typedef struct _dma_descr_t dma_descr_t;
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
|
||||
|
||||
extern const dma_descr_t dma_I2C_1_RX;
|
||||
extern const dma_descr_t dma_SPI_3_RX;
|
||||
|
@ -133,6 +133,12 @@ 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)
|
||||
EXTI0_1_IRQn, EXTI0_1_IRQn, EXTI2_3_IRQn, EXTI2_3_IRQn,
|
||||
EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn,
|
||||
EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn, EXTI4_15_IRQn,
|
||||
#else
|
||||
EXTI0_IRQn, EXTI1_IRQn, EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn,
|
||||
EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn,
|
||||
EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn,
|
||||
@ -148,6 +154,7 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
|
||||
OTG_HS_WKUP_IRQn,
|
||||
TAMP_STAMP_IRQn,
|
||||
RTC_WKUP_IRQn,
|
||||
#endif
|
||||
};
|
||||
|
||||
// Set override_callback_obj to true if you want to unconditionally set the
|
||||
@ -282,7 +289,7 @@ void extint_enable(uint line) {
|
||||
if (line >= EXTI_NUM_VECTORS) {
|
||||
return;
|
||||
}
|
||||
#if defined(STM32F7) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32H7)
|
||||
// The Cortex-M7 doesn't have bitband support.
|
||||
mp_uint_t irq_state = disable_irq();
|
||||
if (pyb_extint_mode[line] == EXTI_Mode_Interrupt) {
|
||||
@ -312,7 +319,7 @@ void extint_disable(uint line) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(STM32F7) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32H7)
|
||||
// The Cortex-M7 doesn't have bitband support.
|
||||
mp_uint_t irq_state = disable_irq();
|
||||
#if defined(STM32H7)
|
||||
|
@ -34,7 +34,13 @@ typedef struct {
|
||||
uint32_t sector_count;
|
||||
} flash_layout_t;
|
||||
|
||||
#if defined(STM32F4)
|
||||
#if defined(STM32F0)
|
||||
|
||||
static const flash_layout_t flash_layout[] = {
|
||||
{ FLASH_BASE, FLASH_PAGE_SIZE, (FLASH_BANK1_END + 1 - FLASH_BASE) / FLASH_PAGE_SIZE },
|
||||
};
|
||||
|
||||
#elif defined(STM32F4)
|
||||
|
||||
static const flash_layout_t flash_layout[] = {
|
||||
{ 0x08000000, 0x04000, 4 },
|
||||
@ -153,7 +159,12 @@ void flash_erase(uint32_t flash_dest, uint32_t num_word32) {
|
||||
|
||||
FLASH_EraseInitTypeDef EraseInitStruct;
|
||||
|
||||
#if defined(STM32L4)
|
||||
#if defined(STM32F0)
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
EraseInitStruct.PageAddress = flash_dest;
|
||||
EraseInitStruct.NbPages = (4 * num_word32 + FLASH_PAGE_SIZE - 4) / FLASH_PAGE_SIZE;
|
||||
#elif defined(STM32L4)
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
|
||||
|
||||
// erase the sector(s)
|
||||
|
@ -262,7 +262,7 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) {
|
||||
return num_acks;
|
||||
}
|
||||
|
||||
#elif defined(STM32F7)
|
||||
#elif defined(STM32F0) || defined(STM32F7)
|
||||
|
||||
int i2c_init(i2c_t *i2c, mp_hal_pin_obj_t scl, mp_hal_pin_obj_t sda, uint32_t freq) {
|
||||
uint32_t i2c_id = ((uint32_t)i2c - I2C1_BASE) / (I2C2_BASE - I2C1_BASE);
|
||||
@ -446,7 +446,7 @@ int i2c_write(i2c_t *i2c, const uint8_t *src, size_t len, size_t next_len) {
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
|
||||
|
||||
int i2c_readfrom(i2c_t *i2c, uint16_t addr, uint8_t *dest, size_t len, bool stop) {
|
||||
int ret;
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
STATIC const mp_obj_type_t machine_hard_i2c_type;
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
|
||||
|
||||
typedef struct _machine_hard_i2c_obj_t {
|
||||
mp_obj_base_t base;
|
||||
|
@ -110,7 +110,11 @@ void machine_init(void) {
|
||||
uint32_t state = RCC->RCC_SR;
|
||||
if (state & RCC_SR_IWDGRSTF || state & RCC_SR_WWDGRSTF) {
|
||||
reset_cause = PYB_RESET_WDT;
|
||||
} else if (state & RCC_SR_PORRSTF || state & RCC_SR_BORRSTF) {
|
||||
} else if (state & RCC_SR_PORRSTF
|
||||
#if !defined(STM32F0)
|
||||
|| state & RCC_SR_BORRSTF
|
||||
#endif
|
||||
) {
|
||||
reset_cause = PYB_RESET_POWER_ON;
|
||||
} else if (state & RCC_SR_PINRSTF) {
|
||||
reset_cause = PYB_RESET_HARD;
|
||||
@ -140,11 +144,18 @@ 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)
|
||||
printf("S=%u\nH=%u\nP1=%u\n",
|
||||
(unsigned int)HAL_RCC_GetSysClockFreq(),
|
||||
(unsigned int)HAL_RCC_GetHCLKFreq(),
|
||||
(unsigned int)HAL_RCC_GetPCLK1Freq());
|
||||
#else
|
||||
printf("S=%u\nH=%u\nP1=%u\nP2=%u\n",
|
||||
(unsigned int)HAL_RCC_GetSysClockFreq(),
|
||||
(unsigned int)HAL_RCC_GetHCLKFreq(),
|
||||
(unsigned int)HAL_RCC_GetPCLK1Freq(),
|
||||
(unsigned int)HAL_RCC_GetPCLK2Freq());
|
||||
#endif
|
||||
}
|
||||
|
||||
// to print info about memory
|
||||
@ -267,6 +278,7 @@ STATIC NORETURN mp_obj_t machine_bootloader(void) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(machine_bootloader_obj, machine_bootloader);
|
||||
|
||||
#if !(defined(STM32F0) || defined(STM32L4))
|
||||
// get or set the MCU frequencies
|
||||
STATIC mp_uint_t machine_freq_calc_ahb_div(mp_uint_t wanted_div) {
|
||||
if (wanted_div <= 1) { return RCC_SYSCLK_DIV1; }
|
||||
@ -286,23 +298,28 @@ STATIC mp_uint_t machine_freq_calc_apb_div(mp_uint_t wanted_div) {
|
||||
else if (wanted_div <= 8) { return RCC_HCLK_DIV8; }
|
||||
else { return RCC_SYSCLK_DIV16; }
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// get
|
||||
mp_obj_t tuple[4] = {
|
||||
mp_obj_t tuple[] = {
|
||||
mp_obj_new_int(HAL_RCC_GetSysClockFreq()),
|
||||
mp_obj_new_int(HAL_RCC_GetHCLKFreq()),
|
||||
mp_obj_new_int(HAL_RCC_GetPCLK1Freq()),
|
||||
#if !defined(STM32F0)
|
||||
mp_obj_new_int(HAL_RCC_GetPCLK2Freq()),
|
||||
#endif
|
||||
};
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
return mp_obj_new_tuple(MP_ARRAY_SIZE(tuple), tuple);
|
||||
} else {
|
||||
// set
|
||||
mp_int_t wanted_sysclk = mp_obj_get_int(args[0]) / 1000000;
|
||||
|
||||
#if defined(STM32L4)
|
||||
#if defined(STM32F0) || defined(STM32L4)
|
||||
mp_raise_NotImplementedError("machine.freq set not supported yet");
|
||||
#endif
|
||||
#else
|
||||
|
||||
mp_int_t wanted_sysclk = mp_obj_get_int(args[0]) / 1000000;
|
||||
|
||||
// default PLL parameters that give 48MHz on PLL48CK
|
||||
uint32_t m = HSE_VALUE / 1000000, n = 336, p = 2, q = 7;
|
||||
@ -458,6 +475,8 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
||||
fail:;
|
||||
void NORETURN __fatal_error(const char *msg);
|
||||
__fatal_error("can't change freq");
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 4, machine_freq);
|
||||
@ -492,8 +511,10 @@ STATIC mp_obj_t machine_sleep(void) {
|
||||
|
||||
#else
|
||||
|
||||
#if !defined(STM32F0)
|
||||
// takes longer to wake but reduces stop current
|
||||
HAL_PWREx_EnableFlashPowerDown();
|
||||
#endif
|
||||
|
||||
# if defined(STM32F7)
|
||||
HAL_PWR_EnterSTOPMode((PWR_CR1_LPDS | PWR_CR1_LPUDS | PWR_CR1_FPDS | PWR_CR1_UDEN), PWR_STOPENTRY_WFI);
|
||||
@ -542,16 +563,22 @@ STATIC mp_obj_t machine_deepsleep(void) {
|
||||
|
||||
// Note: we only support RTC ALRA, ALRB, WUT and TS.
|
||||
// TODO support TAMP and WKUP (PA0 external pin).
|
||||
uint32_t irq_bits = RTC_CR_ALRAIE | RTC_CR_ALRBIE | RTC_CR_WUTIE | RTC_CR_TSIE;
|
||||
#if defined(STM32F0)
|
||||
#define CR_BITS (RTC_CR_ALRAIE | RTC_CR_WUTIE | RTC_CR_TSIE)
|
||||
#define ISR_BITS (RTC_ISR_ALRAF | RTC_ISR_WUTF | RTC_ISR_TSF)
|
||||
#else
|
||||
#define CR_BITS (RTC_CR_ALRAIE | RTC_CR_ALRBIE | RTC_CR_WUTIE | RTC_CR_TSIE)
|
||||
#define ISR_BITS (RTC_ISR_ALRAF | RTC_ISR_ALRBF | RTC_ISR_WUTF | RTC_ISR_TSF)
|
||||
#endif
|
||||
|
||||
// save RTC interrupts
|
||||
uint32_t save_irq_bits = RTC->CR & irq_bits;
|
||||
uint32_t save_irq_bits = RTC->CR & CR_BITS;
|
||||
|
||||
// disable RTC interrupts
|
||||
RTC->CR &= ~irq_bits;
|
||||
RTC->CR &= ~CR_BITS;
|
||||
|
||||
// clear RTC wake-up flags
|
||||
RTC->ISR &= ~(RTC_ISR_ALRAF | RTC_ISR_ALRBF | RTC_ISR_WUTF | RTC_ISR_TSF);
|
||||
RTC->ISR &= ~ISR_BITS;
|
||||
|
||||
#if defined(STM32F7)
|
||||
// disable wake-up flags
|
||||
|
@ -110,8 +110,16 @@
|
||||
/*****************************************************************************/
|
||||
// General configuration
|
||||
|
||||
// Configuration for STM32F0 series
|
||||
#if defined(STM32F0)
|
||||
|
||||
#define MP_HAL_UNIQUE_ID_ADDRESS (0x1ffff7ac)
|
||||
#define PYB_EXTI_NUM_VECTORS (23)
|
||||
#define MICROPY_HW_MAX_TIMER (17)
|
||||
#define MICROPY_HW_MAX_UART (8)
|
||||
|
||||
// Configuration for STM32F4 series
|
||||
#if defined(STM32F4)
|
||||
#elif defined(STM32F4)
|
||||
|
||||
#define MP_HAL_UNIQUE_ID_ADDRESS (0x1fff7a10)
|
||||
#define PYB_EXTI_NUM_VECTORS (23)
|
||||
|
@ -111,7 +111,10 @@ void mp_hal_gpio_clock_enable(GPIO_TypeDef *gpio) {
|
||||
|
||||
// This logic assumes that all the GPIOx_EN bits are adjacent and ordered in one register
|
||||
|
||||
#if defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F0)
|
||||
#define AHBxENR AHBENR
|
||||
#define AHBxENR_GPIOAEN_Pos RCC_AHBENR_GPIOAEN_Pos
|
||||
#elif defined(STM32F4) || defined(STM32F7)
|
||||
#define AHBxENR AHB1ENR
|
||||
#define AHBxENR_GPIOAEN_Pos RCC_AHB1ENR_GPIOAEN_Pos
|
||||
#elif defined(STM32H7)
|
||||
|
@ -539,6 +539,10 @@ mp_obj_t pyb_rtc_datetime(size_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime);
|
||||
|
||||
#if defined(STM32F0)
|
||||
#define RTC_WKUP_IRQn RTC_IRQn
|
||||
#endif
|
||||
|
||||
// wakeup(None)
|
||||
// wakeup(ms, callback=None)
|
||||
// wakeup(wucksel, wut, callback)
|
||||
|
@ -203,6 +203,9 @@ STATIC void spi_set_params(const spi_t *spi_obj, uint32_t prescale, int32_t baud
|
||||
if (prescale == 0xffffffff) {
|
||||
// prescaler not given, so select one that yields at most the requested baudrate
|
||||
mp_uint_t spi_clock;
|
||||
#if defined(STM32F0)
|
||||
spi_clock = HAL_RCC_GetPCLK1Freq();
|
||||
#else
|
||||
if (spi->Instance == SPI2 || spi->Instance == SPI3) {
|
||||
// SPI2 and SPI3 are on APB1
|
||||
spi_clock = HAL_RCC_GetPCLK1Freq();
|
||||
@ -210,6 +213,7 @@ STATIC void spi_set_params(const spi_t *spi_obj, uint32_t prescale, int32_t baud
|
||||
// SPI1, SPI4, SPI5 and SPI6 are on APB2
|
||||
spi_clock = HAL_RCC_GetPCLK2Freq();
|
||||
}
|
||||
#endif
|
||||
prescale = spi_clock / baudrate;
|
||||
}
|
||||
if (prescale <= 2) { init->BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; }
|
||||
@ -500,7 +504,9 @@ STATIC void spi_print(const mp_print_t *print, const spi_t *spi_obj, bool legacy
|
||||
|
||||
uint spi_num = 1; // default to SPI1
|
||||
if (spi->Instance == SPI2) { spi_num = 2; }
|
||||
#if defined(SPI3)
|
||||
else if (spi->Instance == SPI3) { spi_num = 3; }
|
||||
#endif
|
||||
#if defined(SPI4)
|
||||
else if (spi->Instance == SPI4) { spi_num = 4; }
|
||||
#endif
|
||||
@ -516,6 +522,9 @@ STATIC void spi_print(const mp_print_t *print, const spi_t *spi_obj, bool legacy
|
||||
if (spi->Init.Mode == SPI_MODE_MASTER) {
|
||||
// compute baudrate
|
||||
uint spi_clock;
|
||||
#if defined(STM32F0)
|
||||
spi_clock = HAL_RCC_GetPCLK1Freq();
|
||||
#else
|
||||
if (spi->Instance == SPI2 || spi->Instance == SPI3) {
|
||||
// SPI2 and SPI3 are on APB1
|
||||
spi_clock = HAL_RCC_GetPCLK1Freq();
|
||||
@ -523,6 +532,7 @@ STATIC void spi_print(const mp_print_t *print, const spi_t *spi_obj, bool legacy
|
||||
// SPI1, SPI4, SPI5 and SPI6 are on APB2
|
||||
spi_clock = HAL_RCC_GetPCLK2Freq();
|
||||
}
|
||||
#endif
|
||||
uint log_prescaler = (spi->Init.BaudRatePrescaler >> 3) + 1;
|
||||
uint baudrate = spi_clock >> log_prescaler;
|
||||
if (legacy) {
|
||||
|
@ -579,6 +579,39 @@ void RTC_WKUP_IRQHandler(void) {
|
||||
IRQ_EXIT(RTC_WKUP_IRQn);
|
||||
}
|
||||
|
||||
#if defined(STM32F0)
|
||||
|
||||
void RTC_IRQHandler(void) {
|
||||
IRQ_ENTER(RTC_IRQn);
|
||||
RTC->ISR &= ~(1 << 10); // clear wakeup interrupt flag
|
||||
Handle_EXTI_Irq(EXTI_RTC_WAKEUP); // clear EXTI flag and execute optional callback
|
||||
IRQ_EXIT(RTC_IRQn);
|
||||
}
|
||||
|
||||
void EXTI0_1_IRQHandler(void) {
|
||||
IRQ_ENTER(EXTI0_1_IRQn);
|
||||
Handle_EXTI_Irq(0);
|
||||
Handle_EXTI_Irq(1);
|
||||
IRQ_EXIT(EXTI0_1_IRQn);
|
||||
}
|
||||
|
||||
void EXTI2_3_IRQHandler(void) {
|
||||
IRQ_ENTER(EXTI2_3_IRQn);
|
||||
Handle_EXTI_Irq(2);
|
||||
Handle_EXTI_Irq(3);
|
||||
IRQ_EXIT(EXTI2_3_IRQn);
|
||||
}
|
||||
|
||||
void EXTI4_15_IRQHandler(void) {
|
||||
IRQ_ENTER(EXTI4_15_IRQn);
|
||||
for (int i = 4; i <= 15; ++i) {
|
||||
Handle_EXTI_Irq(i);
|
||||
}
|
||||
IRQ_EXIT(EXTI4_15_IRQn);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void TIM1_BRK_TIM9_IRQHandler(void) {
|
||||
IRQ_ENTER(TIM1_BRK_TIM9_IRQn);
|
||||
timer_irq_handler(9);
|
||||
@ -718,6 +751,21 @@ void USART2_IRQHandler(void) {
|
||||
IRQ_EXIT(USART2_IRQn);
|
||||
}
|
||||
|
||||
#if defined(STM32F0)
|
||||
|
||||
void USART3_8_IRQHandler(void) {
|
||||
IRQ_ENTER(USART3_8_IRQn);
|
||||
uart_irq_handler(3);
|
||||
uart_irq_handler(4);
|
||||
uart_irq_handler(5);
|
||||
uart_irq_handler(6);
|
||||
uart_irq_handler(7);
|
||||
uart_irq_handler(8);
|
||||
IRQ_EXIT(USART3_8_IRQn);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void USART3_IRQHandler(void) {
|
||||
IRQ_ENTER(USART3_IRQn);
|
||||
uart_irq_handler(3);
|
||||
@ -758,6 +806,8 @@ void UART8_IRQHandler(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MICROPY_HW_CAN1_TX)
|
||||
void CAN1_RX0_IRQHandler(void) {
|
||||
IRQ_ENTER(CAN1_RX0_IRQn);
|
||||
|
203
ports/stm32/system_stm32f0.c
Normal file
203
ports/stm32/system_stm32f0.c
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* Taken from ST Cube library and modified. See below for original header.
|
||||
*/
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f0xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include STM32_HAL_H
|
||||
|
||||
#ifndef HSE_VALUE
|
||||
#define HSE_VALUE (8000000)
|
||||
#endif
|
||||
|
||||
#ifndef HSI_VALUE
|
||||
#define HSI_VALUE (8000000)
|
||||
#endif
|
||||
|
||||
#ifndef HSI48_VALUE
|
||||
#define HSI48_VALUE (48000000)
|
||||
#endif
|
||||
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock there is no need to
|
||||
call the 2 first functions listed above, since SystemCoreClock variable is
|
||||
updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 8000000;
|
||||
|
||||
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
void SystemInit(void) {
|
||||
// Set HSION bit
|
||||
RCC->CR |= (uint32_t)0x00000001U;
|
||||
|
||||
#if defined(STM32F051x8) || defined(STM32F058x8)
|
||||
// Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[2:0] bits
|
||||
RCC->CFGR &= (uint32_t)0xF8FFB80CU;
|
||||
#else
|
||||
// Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, MCOSEL[2:0], MCOPRE[2:0] and PLLNODIV bits
|
||||
RCC->CFGR &= (uint32_t)0x08FFB80CU;
|
||||
#endif
|
||||
|
||||
// Reset HSEON, CSSON and PLLON bits
|
||||
RCC->CR &= (uint32_t)0xFEF6FFFFU;
|
||||
|
||||
// Reset HSEBYP bit
|
||||
RCC->CR &= (uint32_t)0xFFFBFFFFU;
|
||||
|
||||
// Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits
|
||||
RCC->CFGR &= (uint32_t)0xFFC0FFFFU;
|
||||
|
||||
// Reset PREDIV[3:0] bits
|
||||
RCC->CFGR2 &= (uint32_t)0xFFFFFFF0U;
|
||||
|
||||
#if defined(STM32F072xB) || defined(STM32F078xx)
|
||||
// Reset USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFCFE2CU;
|
||||
#elif defined(STM32F071xB)
|
||||
// Reset USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW and ADCSW bits
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFCEACU;
|
||||
#elif defined(STM32F091xC) || defined(STM32F098xx)
|
||||
// Reset USART3SW[1:0], USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW and ADCSW bits
|
||||
RCC->CFGR3 &= (uint32_t)0xFFF0FEACU;
|
||||
#elif defined(STM32F030x6) || defined(STM32F030x8) || defined(STM32F031x6) || defined(STM32F038xx) || defined(STM32F030xC)
|
||||
// Reset USART1SW[1:0], I2C1SW and ADCSW bits
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFEECU;
|
||||
#elif defined(STM32F051x8) || defined(STM32F058xx)
|
||||
// Reset USART1SW[1:0], I2C1SW, CECSW and ADCSW bits
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFEACU;
|
||||
#elif defined(STM32F042x6) || defined(STM32F048xx)
|
||||
// Reset USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFE2CU;
|
||||
#elif defined(STM32F070x6) || defined(STM32F070xB)
|
||||
// Reset USART1SW[1:0], I2C1SW, USBSW and ADCSW bits
|
||||
RCC->CFGR3 &= (uint32_t)0xFFFFFE6CU;
|
||||
// Set default USB clock to PLLCLK, since there is no HSI48
|
||||
RCC->CFGR3 |= (uint32_t)0x00000080U;
|
||||
#else
|
||||
#warning "No target selected"
|
||||
#endif
|
||||
|
||||
// Reset HSI14 bit
|
||||
RCC->CR2 &= (uint32_t)0xFFFFFFFEU;
|
||||
|
||||
// Disable all interrupts
|
||||
RCC->CIR = 0x00000000U;
|
||||
|
||||
// dpgeorge: enable 8-byte stack alignment for IRQ handlers, in accord with EABI
|
||||
SCB->CCR |= SCB_CCR_STKALIGN_Msk;
|
||||
}
|
||||
|
||||
void SystemClock_Config(void) {
|
||||
// Set flash latency to 1 because SYSCLK > 24MHz
|
||||
FLASH->ACR = (FLASH->ACR & ~0x7) | 0x1;
|
||||
|
||||
// Use the 48MHz internal oscillator
|
||||
RCC->CR2 |= RCC_CR2_HSI48ON;
|
||||
while ((RCC->CR2 & RCC_CR2_HSI48RDY) == 0) {
|
||||
}
|
||||
RCC->CFGR |= 3 << RCC_CFGR_SW_Pos;
|
||||
while (((RCC->CFGR >> RCC_CFGR_SWS_Pos) & 0x3) != 0x03) {
|
||||
// Wait for SYSCLK source to change
|
||||
}
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
|
||||
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
|
||||
}
|
||||
|
||||
void SystemCoreClockUpdate(void) {
|
||||
// Get SYSCLK source
|
||||
uint32_t tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp) {
|
||||
case RCC_CFGR_SWS_HSI:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case RCC_CFGR_SWS_HSE:
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case RCC_CFGR_SWS_PLL: {
|
||||
/* Get PLL clock source and multiplication factor */
|
||||
uint32_t pllmull = RCC->CFGR & RCC_CFGR_PLLMUL;
|
||||
uint32_t pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
pllmull = (pllmull >> 18) + 2;
|
||||
uint32_t predivfactor = (RCC->CFGR2 & RCC_CFGR2_PREDIV) + 1;
|
||||
|
||||
if (pllsource == RCC_CFGR_PLLSRC_HSE_PREDIV) {
|
||||
/* HSE used as PLL clock source : SystemCoreClock = HSE/PREDIV * PLLMUL */
|
||||
SystemCoreClock = (HSE_VALUE/predivfactor) * pllmull;
|
||||
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F072xB) \
|
||||
|| defined(STM32F078xx) || defined(STM32F091xC) || defined(STM32F098xx)
|
||||
} else if (pllsource == RCC_CFGR_PLLSRC_HSI48_PREDIV) {
|
||||
/* HSI48 used as PLL clock source : SystemCoreClock = HSI48/PREDIV * PLLMUL */
|
||||
SystemCoreClock = (HSI48_VALUE/predivfactor) * pllmull;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(STM32F042x6) || defined(STM32F048xx) || defined(STM32F070x6) \
|
||||
|| defined(STM32F078xx) || defined(STM32F071xB) || defined(STM32F072xB) \
|
||||
|| defined(STM32F070xB) || defined(STM32F091xC) || defined(STM32F098xx) || defined(STM32F030xC)
|
||||
/* HSI used as PLL clock source : SystemCoreClock = HSI/PREDIV * PLLMUL */
|
||||
SystemCoreClock = (HSI_VALUE / predivfactor) * pllmull;
|
||||
#else
|
||||
/* HSI used as PLL clock source : SystemCoreClock = HSI/2 * PLLMUL */
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RCC_CFGR_SWS_HSI48:
|
||||
SystemCoreClock = HSI48_VALUE;
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// Compute HCLK clock frequency
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -231,16 +231,22 @@ 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)
|
||||
source = HAL_RCC_GetPCLK1Freq();
|
||||
clk_div = RCC->CFGR & RCC_CFGR_PPRE;
|
||||
#elif defined(STM32H7)
|
||||
source = HAL_RCC_GetPCLK2Freq();
|
||||
#if defined(STM32H7)
|
||||
clk_div = RCC->D2CFGR & RCC_D2CFGR_D2PPRE2;
|
||||
#else
|
||||
source = HAL_RCC_GetPCLK2Freq();
|
||||
clk_div = RCC->CFGR & RCC_CFGR_PPRE2;
|
||||
#endif
|
||||
} else {
|
||||
// TIM{2,3,4,5,6,7,12,13,14} are on APB1
|
||||
source = HAL_RCC_GetPCLK1Freq();
|
||||
#if defined(STM32H7)
|
||||
#if defined(STM32F0)
|
||||
clk_div = RCC->CFGR & RCC_CFGR_PPRE;
|
||||
#elif defined(STM32H7)
|
||||
clk_div = RCC->D2CFGR & RCC_D2CFGR_D2PPRE1;
|
||||
#else
|
||||
clk_div = RCC->CFGR & RCC_CFGR_PPRE1;
|
||||
@ -694,25 +700,27 @@ STATIC const uint32_t tim_instance_table[MICROPY_HW_MAX_TIMER] = {
|
||||
#if defined(TIM13)
|
||||
TIM_ENTRY(13, TIM8_UP_TIM13_IRQn),
|
||||
#endif
|
||||
#if defined(TIM14)
|
||||
#if defined(STM32F0)
|
||||
TIM_ENTRY(14, TIM14_IRQn),
|
||||
#elif defined(TIM14)
|
||||
TIM_ENTRY(14, TIM8_TRG_COM_TIM14_IRQn),
|
||||
#endif
|
||||
#if defined(TIM15)
|
||||
#if defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32H7)
|
||||
TIM_ENTRY(15, TIM15_IRQn),
|
||||
#else
|
||||
TIM_ENTRY(15, TIM1_BRK_TIM15_IRQn),
|
||||
#endif
|
||||
#endif
|
||||
#if defined(TIM16)
|
||||
#if defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32H7)
|
||||
TIM_ENTRY(16, TIM16_IRQn),
|
||||
#else
|
||||
TIM_ENTRY(16, TIM1_UP_TIM16_IRQn),
|
||||
#endif
|
||||
#endif
|
||||
#if defined(TIM17)
|
||||
#if defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32H7)
|
||||
TIM_ENTRY(17, TIM17_IRQn),
|
||||
#else
|
||||
TIM_ENTRY(17, TIM1_TRG_COM_TIM17_IRQn),
|
||||
|
@ -289,11 +289,17 @@ STATIC bool uart_init2(pyb_uart_obj_t *uart_obj) {
|
||||
#if defined(MICROPY_HW_UART8_TX) && defined(MICROPY_HW_UART8_RX)
|
||||
case PYB_UART_8:
|
||||
uart_unit = 8;
|
||||
#if defined(STM32F0)
|
||||
UARTx = USART8;
|
||||
irqn = USART3_8_IRQn;
|
||||
__HAL_RCC_USART8_CLK_ENABLE();
|
||||
#else
|
||||
UARTx = UART8;
|
||||
irqn = UART8_IRQn;
|
||||
__HAL_RCC_UART8_CLK_ENABLE();
|
||||
#endif
|
||||
pins[0] = MICROPY_HW_UART8_TX;
|
||||
pins[1] = MICROPY_HW_UART8_RX;
|
||||
__HAL_RCC_UART8_CLK_ENABLE();
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -390,7 +396,7 @@ int uart_rx_char(pyb_uart_obj_t *self) {
|
||||
return data;
|
||||
} else {
|
||||
// no buffering
|
||||
#if defined(STM32F7) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32L4) || defined(STM32H7)
|
||||
return self->uart.Instance->RDR & self->char_mask;
|
||||
#else
|
||||
return self->uart.Instance->DR & self->char_mask;
|
||||
@ -508,7 +514,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(STM32F7) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32L4) || defined(STM32H7)
|
||||
int data = self->uart.Instance->RDR; // clears UART_FLAG_RXNE
|
||||
#else
|
||||
int data = self->uart.Instance->DR; // clears UART_FLAG_RXNE
|
||||
@ -698,7 +704,9 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
|
||||
// compute actual baudrate that was configured
|
||||
// (this formula assumes UART_OVERSAMPLING_16)
|
||||
uint32_t actual_baudrate = 0;
|
||||
#if defined(STM32F7) || defined(STM32H7)
|
||||
#if defined(STM32F0)
|
||||
actual_baudrate = HAL_RCC_GetPCLK1Freq();
|
||||
#elif defined(STM32F7) || defined(STM32H7)
|
||||
UART_ClockSourceTypeDef clocksource = UART_CLOCKSOURCE_UNDEFINED;
|
||||
UART_GETCLOCKSOURCE(&self->uart, clocksource);
|
||||
switch (clocksource) {
|
||||
@ -854,7 +862,9 @@ STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
|
||||
__HAL_RCC_USART2_CLK_DISABLE();
|
||||
#if defined(USART3)
|
||||
} else if (uart->Instance == USART3) {
|
||||
#if !defined(STM32F0)
|
||||
HAL_NVIC_DisableIRQ(USART3_IRQn);
|
||||
#endif
|
||||
__HAL_RCC_USART3_FORCE_RESET();
|
||||
__HAL_RCC_USART3_RELEASE_RESET();
|
||||
__HAL_RCC_USART3_CLK_DISABLE();
|
||||
@ -949,7 +959,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 = self_in;
|
||||
#if defined(STM32F7) || defined(STM32L4) || defined(STM32H7)
|
||||
#if defined(STM32F0) || defined(STM32F7) || defined(STM32L4) || defined(STM32H7)
|
||||
self->uart.Instance->RQR = USART_RQR_SBKRQ; // write-only register
|
||||
#else
|
||||
self->uart.Instance->CR1 |= USART_CR1_SBK;
|
||||
|
Loading…
Reference in New Issue
Block a user