Skip to content

Commit

Permalink
stm32: Add support for STM32F0 MCUs.
Browse files Browse the repository at this point in the history
  • Loading branch information
dpgeorge committed May 28, 2018
1 parent 4a7d157 commit ea7e747
Show file tree
Hide file tree
Showing 18 changed files with 478 additions and 48 deletions.
30 changes: 26 additions & 4 deletions ports/stm32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 \
Expand All @@ -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/,\
Expand All @@ -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 \
Expand Down Expand Up @@ -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 \
Expand All @@ -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)
Expand Down
34 changes: 24 additions & 10 deletions ports/stm32/adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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();
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion ports/stm32/dac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
57 changes: 55 additions & 2 deletions ports/stm32/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion ports/stm32/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 9 additions & 2 deletions ports/stm32/extint.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 13 additions & 2 deletions ports/stm32/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions ports/stm32/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit ea7e747

Please sign in to comment.