diff --git a/arch/arm/soc/st_stm32/stm32f1/soc.c b/arch/arm/soc/st_stm32/stm32f1/soc.c index 421ebf41436..a0a05df1eeb 100644 --- a/arch/arm/soc/st_stm32/stm32f1/soc.c +++ b/arch/arm/soc/st_stm32/stm32f1/soc.c @@ -60,6 +60,9 @@ static int stm32f1_init(struct device *arg) irq_unlock(key); + /* Update CMSIS SystemCoreClock variable (HCLK) */ + SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; + return 0; } diff --git a/arch/arm/soc/st_stm32/stm32f4/soc.c b/arch/arm/soc/st_stm32/stm32f4/soc.c index 579ebfc7707..622b105ea28 100644 --- a/arch/arm/soc/st_stm32/stm32f4/soc.c +++ b/arch/arm/soc/st_stm32/stm32f4/soc.c @@ -61,6 +61,9 @@ static int st_stm32f4_init(struct device *arg) irq_unlock(key); + /* Update CMSIS SystemCoreClock variable (HCLK) */ + SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; + return 0; } diff --git a/drivers/serial/uart_stm32.c b/drivers/serial/uart_stm32.c index 4ce5a15fecf..abceff6cef5 100644 --- a/drivers/serial/uart_stm32.c +++ b/drivers/serial/uart_stm32.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016 Open-RnD Sp. z o.o. + * Copyright (c) 2016 Linaro Limited. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,89 +44,43 @@ #define DEV_DATA(dev) \ ((struct uart_stm32_data * const)(dev)->driver_data) #define UART_STRUCT(dev) \ - ((volatile struct uart_stm32 *)(DEV_CFG(dev))->uconf.base) + ((USART_TypeDef *)(DEV_CFG(dev))->uconf.base) -/** - * @brief set baud rate - * - */ -static void set_baud_rate(struct device *dev, uint32_t rate) -{ - volatile struct uart_stm32 *uart = UART_STRUCT(dev); - struct uart_stm32_data *data = DEV_DATA(dev); - const struct uart_stm32_config *cfg = DEV_CFG(dev); - uint32_t div, mantissa, fraction; - uint32_t clock; - /* Baud rate is controlled through BRR register. The values - * written into the register depend on the clock driving the - * peripheral. Ask clock_control for the current clock rate of - * our peripheral. - */ -#ifdef CONFIG_SOC_SERIES_STM32F1X - clock_control_get_rate(data->clock, cfg->clock_subsys, &clock); -#elif CONFIG_SOC_SERIES_STM32F4X - clock_control_get_rate(data->clock, - (clock_control_subsys_t *)&cfg->pclken, &clock); -#endif - - /* baud rate calculation: - * - * baud rate = f_clk / (16 * usartdiv) - * - * Example (STM32F10x, USART1, PCLK2 @ 36MHz, 9600bps): - * - * f_clk == PCLK2, - * usartdiv = 234.375, - * mantissa = 234, - * fraction = 6 (0.375 * 16) - */ - - div = clock / rate; - mantissa = div >> 4; - fraction = div & 0xf; - - uart->brr.bit.mantissa = mantissa; - uart->brr.bit.fraction = fraction; -} +#define TIMEOUT 1000 static int uart_stm32_poll_in(struct device *dev, unsigned char *c) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - /* check if RXNE is set */ - if (!uart->sr.bit.rxne) { + if (HAL_UART_Receive(UartHandle, (uint8_t *)c, 1, TIMEOUT) == HAL_OK) { + return 0; + } else { return -1; } - - /* read character */ - *c = (unsigned char)uart->dr.bit.dr; - - return 0; } static unsigned char uart_stm32_poll_out(struct device *dev, unsigned char c) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - /* wait for TXE to be set */ - while (!uart->sr.bit.txe) { - } + HAL_UART_Transmit(UartHandle, (uint8_t *)&c, 1, TIMEOUT); - uart->dr.bit.dr = c; return c; } static inline void __uart_stm32_get_clock(struct device *dev) { - struct uart_stm32_data *ddata = dev->driver_data; + struct uart_stm32_data *data = DEV_DATA(dev); struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); __ASSERT_NO_MSG(clk); - ddata->clock = clk; + data->clock = clk; } #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -133,12 +88,24 @@ static inline void __uart_stm32_get_clock(struct device *dev) static int uart_stm32_fifo_fill(struct device *dev, const uint8_t *tx_data, int size) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); - size_t num_tx = 0; + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; + uint8_t num_tx = 0; - /* FIXME: DMA maybe? */ - while ((size - num_tx > 0) && (uart->sr.bit.txe)) { - uart->dr.bit.dr = tx_data[num_tx++]; + while ((size - num_tx > 0) && __HAL_UART_GET_FLAG(UartHandle, + UART_FLAG_TXE)) { + /* TXE flag will be cleared with byte write to DR register */ + + /* Send a character (8bit , parity none) */ +#if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32F4X) + /* Use direct access for F1, F4 until Low Level API is available + * Once it is we can remove the if/else + */ + UartHandle->Instance->DR = (tx_data[num_tx++] & + (uint8_t)0x00FF); +#else + LL_USART_TransmitData8(UartHandle->Instance, tx_data[num_tx++]); +#endif } return num_tx; @@ -147,92 +114,131 @@ static int uart_stm32_fifo_fill(struct device *dev, const uint8_t *tx_data, static int uart_stm32_fifo_read(struct device *dev, uint8_t *rx_data, const int size) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); - size_t num_rx = 0; + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; + uint8_t num_rx = 0; - while ((size - num_rx > 0) && (uart->sr.bit.rxne)) { - rx_data[num_rx++] = (uint8_t) uart->dr.bit.dr; + while ((size - num_rx > 0) && __HAL_UART_GET_FLAG(UartHandle, + UART_FLAG_RXNE)) { + /* Clear the interrupt */ + __HAL_UART_CLEAR_FLAG(UartHandle, UART_FLAG_RXNE); + + /* Receive a character (8bit , parity none) */ +#if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32F4X) + /* Use direct access for F1, F4 until Low Level API is available + * Once it is we can remove the if/else + */ + rx_data[num_rx++] = (uint8_t)(UartHandle->Instance->DR & + (uint8_t)0x00FF); +#else + rx_data[num_rx++] = LL_USART_ReceiveData8(UartHandle->Instance); +#endif } return num_rx; } static void uart_stm32_irq_tx_enable(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - uart->cr1.bit.txeie = 1; + __HAL_UART_ENABLE_IT(UartHandle, UART_IT_TC); } static void uart_stm32_irq_tx_disable(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - uart->cr1.bit.txeie = 0; + __HAL_UART_DISABLE_IT(UartHandle, UART_IT_TC); } static int uart_stm32_irq_tx_ready(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - return uart->sr.bit.txe; + return __HAL_UART_GET_FLAG(UartHandle, UART_FLAG_TXE); } static int uart_stm32_irq_tx_empty(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - return uart->sr.bit.txe; + return __HAL_UART_GET_FLAG(UartHandle, UART_FLAG_TXE); } static void uart_stm32_irq_rx_enable(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - uart->cr1.bit.rxneie = 1; + __HAL_UART_ENABLE_IT(UartHandle, UART_IT_RXNE); } static void uart_stm32_irq_rx_disable(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - uart->cr1.bit.rxneie = 0; + __HAL_UART_DISABLE_IT(UartHandle, UART_IT_RXNE); } static int uart_stm32_irq_rx_ready(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - return uart->sr.bit.rxne; + return __HAL_UART_GET_FLAG(UartHandle, UART_FLAG_RXNE); } static void uart_stm32_irq_err_enable(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - uart->cr3.bit.eie = 1; + /* Enable FE, ORE interruptions */ + __HAL_UART_ENABLE_IT(UartHandle, UART_IT_ERR); + /* Enable Line break detection */ + __HAL_UART_ENABLE_IT(UartHandle, UART_IT_LBD); + /* Enable parity error interruption */ + __HAL_UART_ENABLE_IT(UartHandle, UART_IT_PE); } static void uart_stm32_irq_err_disable(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - uart->cr3.bit.eie = 0; + /* Disable FE, ORE interruptions */ + __HAL_UART_DISABLE_IT(UartHandle, UART_IT_ERR); + /* Disable Line break detection */ + __HAL_UART_DISABLE_IT(UartHandle, UART_IT_LBD); + /* Disable parity error interruption */ + __HAL_UART_DISABLE_IT(UartHandle, UART_IT_PE); } static int uart_stm32_irq_is_pending(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; - return uart->sr.bit.rxne || uart->sr.bit.txe; + return __HAL_UART_GET_FLAG(UartHandle, UART_FLAG_TXE | UART_FLAG_RXNE); } static int uart_stm32_irq_update(struct device *dev) { + struct uart_stm32_data *data = DEV_DATA(dev); + UART_HandleTypeDef *UartHandle = &data->huart; + + __HAL_UART_CLEAR_FLAG(UartHandle, UART_FLAG_TC); + return 1; } static void uart_stm32_irq_callback_set(struct device *dev, - uart_irq_callback_t cb) + uart_irq_callback_t cb) { struct uart_stm32_data *data = DEV_DATA(dev); @@ -284,42 +290,31 @@ static const struct uart_driver_api uart_stm32_driver_api = { */ static int uart_stm32_init(struct device *dev) { - volatile struct uart_stm32 *uart = UART_STRUCT(dev); + const struct uart_stm32_config *config = DEV_CFG(dev); struct uart_stm32_data *data = DEV_DATA(dev); - const struct uart_stm32_config *cfg = DEV_CFG(dev); + UART_HandleTypeDef *UartHandle = &data->huart; __uart_stm32_get_clock(dev); - /* enable clock */ #ifdef CONFIG_SOC_SERIES_STM32F1X - clock_control_on(data->clock, cfg->clock_subsys); + clock_control_on(data->clock, config->clock_subsys); #elif CONFIG_SOC_SERIES_STM32F4X - clock_control_on(data->clock, (clock_control_subsys_t *)&cfg->pclken); + clock_control_on(data->clock, + (clock_control_subsys_t *)&config->pclken); #endif - /* FIXME: hardcoded, clear stop bits */ - uart->cr2.bit.stop = 0; + UartHandle->Instance = UART_STRUCT(dev); + UartHandle->Init.WordLength = UART_WORDLENGTH_8B; + UartHandle->Init.StopBits = UART_STOPBITS_1; + UartHandle->Init.Parity = UART_PARITY_NONE; + UartHandle->Init.HwFlowCtl = UART_HWCONTROL_NONE; + UartHandle->Init.Mode = UART_MODE_TX_RX; + UartHandle->Init.OverSampling = UART_OVERSAMPLING_16; - uart->cr1.val = 0; - /* FIXME: hardcoded, 8n1 */ - uart->cr1.bit.m = 0; - uart->cr1.bit.pce = 0; - - /* FIXME: hardcoded, disable hardware flow control */ - uart->cr3.bit.ctse = 0; - uart->cr3.bit.rtse = 0; - - set_baud_rate(dev, data->baud_rate); - - /* enable TX/RX */ - uart->cr1.bit.te = 1; - uart->cr1.bit.re = 1; - - /* enable */ - uart->cr1.bit.ue = 1; + HAL_UART_Init(UartHandle); #ifdef CONFIG_UART_INTERRUPT_DRIVEN - cfg->uconf.irq_config_func(dev); + config->uconf.irq_config_func(dev); #endif return 0; } @@ -332,7 +327,7 @@ static void uart_stm32_irq_config_func_0(struct device *dev); static const struct uart_stm32_config uart_stm32_dev_cfg_0 = { .uconf = { - .base = (uint8_t *)USART1_ADDR, + .base = (uint8_t *)USART1_BASE, #ifdef CONFIG_UART_INTERRUPT_DRIVEN .irq_config_func = uart_stm32_irq_config_func_0, #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -346,7 +341,9 @@ static const struct uart_stm32_config uart_stm32_dev_cfg_0 = { }; static struct uart_stm32_data uart_stm32_dev_data_0 = { - .baud_rate = CONFIG_UART_STM32_PORT_0_BAUD_RATE, + .huart = { + .Init = { + .BaudRate = CONFIG_UART_STM32_PORT_0_BAUD_RATE} } }; DEVICE_AND_API_INIT(uart_stm32_0, CONFIG_UART_STM32_PORT_0_NAME, @@ -373,6 +370,7 @@ static void uart_stm32_irq_config_func_0(struct device *dev) #endif /* CONFIG_UART_STM32_PORT_0 */ + #ifdef CONFIG_UART_STM32_PORT_1 #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -381,7 +379,7 @@ static void uart_stm32_irq_config_func_1(struct device *dev); static const struct uart_stm32_config uart_stm32_dev_cfg_1 = { .uconf = { - .base = (uint8_t *)USART2_ADDR, + .base = (uint8_t *)USART2_BASE, #ifdef CONFIG_UART_INTERRUPT_DRIVEN .irq_config_func = uart_stm32_irq_config_func_1, #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -395,7 +393,9 @@ static const struct uart_stm32_config uart_stm32_dev_cfg_1 = { }; static struct uart_stm32_data uart_stm32_dev_data_1 = { - .baud_rate = CONFIG_UART_STM32_PORT_1_BAUD_RATE, + .huart = { + .Init = { + .BaudRate = CONFIG_UART_STM32_PORT_1_BAUD_RATE} } }; DEVICE_AND_API_INIT(uart_stm32_1, CONFIG_UART_STM32_PORT_1_NAME, @@ -422,6 +422,7 @@ static void uart_stm32_irq_config_func_1(struct device *dev) #endif /* CONFIG_UART_STM32_PORT_1 */ + #ifdef CONFIG_UART_STM32_PORT_2 #ifdef CONFIG_UART_INTERRUPT_DRIVEN @@ -430,7 +431,7 @@ static void uart_stm32_irq_config_func_2(struct device *dev); static const struct uart_stm32_config uart_stm32_dev_cfg_2 = { .uconf = { - .base = (uint8_t *)USART3_ADDR, + .base = (uint8_t *)USART3_BASE, #ifdef CONFIG_UART_INTERRUPT_DRIVEN .irq_config_func = uart_stm32_irq_config_func_2, #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ @@ -443,7 +444,9 @@ static const struct uart_stm32_config uart_stm32_dev_cfg_2 = { }; static struct uart_stm32_data uart_stm32_dev_data_2 = { - .baud_rate = CONFIG_UART_STM32_PORT_2_BAUD_RATE, + .huart = { + .Init = { + .BaudRate = CONFIG_UART_STM32_PORT_2_BAUD_RATE} } }; DEVICE_AND_API_INIT(uart_stm32_2, CONFIG_UART_STM32_PORT_2_NAME, diff --git a/drivers/serial/uart_stm32.h b/drivers/serial/uart_stm32.h index 942b651757a..06b89389420 100644 --- a/drivers/serial/uart_stm32.h +++ b/drivers/serial/uart_stm32.h @@ -15,149 +15,13 @@ */ /** - * @brief Driver for UART port on STM32F10x family processor. + * @brief Driver for UART port on STM32F10x, STM32F40x family processor. * - * Based on reference manual: - * STM32F101xx, STM32F102xx, STM32F103xx, STM32F105xx and STM32F107xx - * advanced ARM ® -based 32-bit MCUs - * - * Chapter 27: Universal synchronous asynchronous receiver - * transmitter (USART) */ #ifndef _STM32_UART_H_ #define _STM32_UART_H_ -/* 27.6.1 Status register (USART_SR) */ -union __sr { - uint32_t val; - struct { - uint32_t pe :1 __packed; - uint32_t fe :1 __packed; - uint32_t nf :1 __packed; - uint32_t ore :1 __packed; - uint32_t idle :1 __packed; - uint32_t rxne :1 __packed; - uint32_t tc :1 __packed; - uint32_t txe :1 __packed; - uint32_t lbd :1 __packed; - uint32_t cts :1 __packed; - uint32_t rsvd__10_15 : 6 __packed; - uint32_t rsvd__16_31 : 16 __packed; - } bit; -}; - -/* 27.6.2 Data register (USART_DR) */ -union __dr { - uint32_t val; - struct { - uint32_t dr :8 __packed; - uint32_t rsvd__9_31 :24 __packed; - } bit; -}; - -/* 27.6.3 Baud rate register (USART_BRR) */ -union __brr { - uint32_t val; - struct { - uint32_t fraction :4 __packed; - uint32_t mantissa :12 __packed; - uint32_t rsvd__16_31 :16 __packed; - } bit; -}; - -/* 27.6.4 Control register 1 (USART_CR1) */ -union __cr1 { - uint32_t val; - struct { - uint32_t sbk :1 __packed; - uint32_t rwu :1 __packed; - uint32_t re :1 __packed; - uint32_t te :1 __packed; - uint32_t idleie :1 __packed; - uint32_t rxneie :1 __packed; - uint32_t tcie :1 __packed; - uint32_t txeie :1 __packed; - uint32_t peie :1 __packed; - uint32_t ps :1 __packed; - uint32_t pce :1 __packed; - uint32_t wake :1 __packed; - uint32_t m :1 __packed; - uint32_t ue :1 __packed; -#ifdef CONFIG_SOC_SERIES_SOC32F1X - uint32_t rsvd__14_15 :2 __packed; -#elif CONFIG_SOC_SERIES_SOC32F4X - uint32_t rsvd__14 :1 __packed; - uint32_t over8 :1 __packed; -#endif - uint32_t rsvd__16_31 :16 __packed; - } bit; -}; - -/* 27.6.5 Control register 2 (USART_CR2) */ -union __cr2 { - uint32_t val; - struct { - uint32_t addr :4 __packed; - uint32_t rsvd__4 :1 __packed; - uint32_t lbdl :1 __packed; - uint32_t lbdie :1 __packed; - uint32_t rsvd__7 :1 __packed; - uint32_t lbcl :1 __packed; - uint32_t cpha :1 __packed; - uint32_t cpol :1 __packed; - uint32_t clken :1 __packed; - uint32_t stop :2 __packed; - uint32_t linen :1 __packed; - uint32_t rsvd__15_31 :17 __packed; - } bit; -}; - -/* 27.6.6 Control register 3 (USART_CR3) */ -union __cr3 { - uint32_t val; - struct { - uint32_t eie :1 __packed; - uint32_t iren :1 __packed; - uint32_t irlp :1 __packed; - uint32_t hdsel :1 __packed; - uint32_t nack :1 __packed; - uint32_t scen :1 __packed; - uint32_t dmar :1 __packed; - uint32_t dmat :1 __packed; - uint32_t rtse :1 __packed; - uint32_t ctse :1 __packed; - uint32_t ctsie :1 __packed; -#ifdef CONFIG_SOC_SERIES_SOC32F1X - uint32_t rsvd__11_31 :21 __packed; -#elif CONFIG_SOC_SERIES_SOC32F4X - uint32_t onebit :1 __packed; - uint32_t rsvd__12_31 :20 __packed; -#endif - } bit; -}; - -/* 27.6.7 Guard time and prescaler register (USART_GTPR) */ -union __gtpr { - uint32_t val; - struct { - uint32_t psc :8 __packed; - uint32_t gt :8 __packed; - uint32_t rsvd__16_31 :16 __packed; - } bit; -}; - -/* 27.6.8 USART register map */ -struct uart_stm32 { - union __sr sr; - union __dr dr; - union __brr brr; - union __cr1 cr1; - union __cr2 cr2; - union __cr3 cr3; - union __gtpr gtpr; -}; - /* device config */ struct uart_stm32_config { struct uart_device_config uconf; @@ -171,8 +35,8 @@ struct uart_stm32_config { /* driver data */ struct uart_stm32_data { - /* current baud rate */ - uint32_t baud_rate; + /* Uart peripheral handler */ + UART_HandleTypeDef huart; /* clock device */ struct device *clock; #ifdef CONFIG_UART_INTERRUPT_DRIVEN diff --git a/ext/hal/st/stm32cube/Kbuild b/ext/hal/st/stm32cube/Kbuild index 2a5fb4a6041..b38e8bff8fc 100644 --- a/ext/hal/st/stm32cube/Kbuild +++ b/ext/hal/st/stm32cube/Kbuild @@ -2,6 +2,8 @@ ifdef CONFIG_HAS_STM32CUBE ifdef CONFIG_SOC_SERIES_STM32F1X obj-y += stm32f1xx/drivers/src/stm32f1xx_hal.o +obj-y += stm32f1xx/drivers/src/stm32f1xx_hal_rcc.o +obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32f1xx/drivers/src/stm32f1xx_hal_uart.o obj-y += stm32f1xx/soc/system_stm32f1xx.o endif @@ -12,6 +14,8 @@ endif ifdef CONFIG_SOC_SERIES_STM32F4X obj-y += stm32f4xx/drivers/src/stm32f4xx_hal.o +obj-y += stm32f4xx/drivers/src/stm32f4xx_hal_rcc.o +obj-$(CONFIG_SERIAL_HAS_DRIVER) += stm32f4xx/drivers/src/stm32f4xx_hal_uart.o obj-y += stm32f4xx/soc/system_stm32f4xx.o endif