From b7e4013466a10a76a856b438748bf30501de4869 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 29 Jul 2024 13:27:15 +1000 Subject: [PATCH] l431: added bootloader --- Makefile | 4 +- .../STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c | 765 ------ .../Src/stm32l4xx_hal_can.c | 2437 ----------------- Mcu/l431/Inc/blutil.h | 135 + Mcu/l431/STM32L431KCUX_FLASH.ld | 187 ++ Mcu/l431/Src/stm32l4xx_it.c | 5 + Mcu/l431/Startup/startup_stm32l431xx.s | 846 +++--- Mcu/l431/openocd.cfg | 7 + bootloader/main.c | 5 + 9 files changed, 800 insertions(+), 3591 deletions(-) delete mode 100644 Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c delete mode 100644 Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c create mode 100644 Mcu/l431/Inc/blutil.h create mode 100644 Mcu/l431/STM32L431KCUX_FLASH.ld create mode 100644 Mcu/l431/openocd.cfg diff --git a/Makefile b/Makefile index 9d60bb08..67f58921 100644 --- a/Makefile +++ b/Makefile @@ -23,12 +23,12 @@ ROOT := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) include $(ROOT)/make/tools.mk # supported MCU types -MCU_TYPES := E230 F031 F051 F415 F421 G071 G431 +MCU_TYPES := E230 F031 F051 F415 F421 G071 G431 L431 MCU_TYPE := NONE # MCU types that we build a bootloader for - this should be $(MCU_TYPES) in the future # when all bootloader porting is completed -BL_MCU_TYPES := E230 F031 F051 F415 F421 G071 G431 +BL_MCU_TYPES := E230 F031 F051 F415 F421 G071 G431 L431 # Function to include makefile for each MCU type define INCLUDE_MCU_MAKEFILES diff --git a/Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c b/Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c deleted file mode 100644 index 87385fc5..00000000 --- a/Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c +++ /dev/null @@ -1,765 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_hal.c - * @author MCD Application Team - * @brief HAL module driver. - * This is the common part of the HAL initialization - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - The common HAL driver contains a set of generic and common APIs that can be - used by the PPP peripheral drivers and the user to start using the HAL. - [..] - The HAL contains two APIs' categories: - (+) Common HAL APIs - (+) Services HAL APIs - - @endverbatim - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx_hal.h" - -/** @addtogroup STM32L4xx_HAL_Driver - * @{ - */ - -/** @defgroup HAL HAL - * @brief HAL module driver - * @{ - */ - -#ifdef HAL_MODULE_ENABLED - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/** - * @brief STM32L4xx HAL Driver version number - */ -#define STM32L4XX_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */ -#define STM32L4XX_HAL_VERSION_SUB1 (0x0DU) /*!< [23:16] sub1 version */ -#define STM32L4XX_HAL_VERSION_SUB2 (0x04U) /*!< [15:8] sub2 version */ -#define STM32L4XX_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */ -#define STM32L4XX_HAL_VERSION ((STM32L4XX_HAL_VERSION_MAIN << 24U)\ - |(STM32L4XX_HAL_VERSION_SUB1 << 16U)\ - |(STM32L4XX_HAL_VERSION_SUB2 << 8U)\ - |(STM32L4XX_HAL_VERSION_RC)) - -#if defined(VREFBUF) -#define VREFBUF_TIMEOUT_VALUE 10U /* 10 ms (to be confirmed) */ -#endif /* VREFBUF */ - -/* ------------ SYSCFG registers bit address in the alias region ------------ */ -#define SYSCFG_OFFSET (SYSCFG_BASE - PERIPH_BASE) -/* --- MEMRMP Register ---*/ -/* Alias word address of FB_MODE bit */ -#define MEMRMP_OFFSET SYSCFG_OFFSET -#define FB_MODE_BitNumber 8U -#define FB_MODE_BB (PERIPH_BB_BASE + (MEMRMP_OFFSET * 32U) + (FB_MODE_BitNumber * 4U)) - -/* --- SCSR Register ---*/ -/* Alias word address of SRAM2ER bit */ -#define SCSR_OFFSET (SYSCFG_OFFSET + 0x18U) -#define BRER_BitNumber 0U -#define SCSR_SRAM2ER_BB (PERIPH_BB_BASE + (SCSR_OFFSET * 32U) + (BRER_BitNumber * 4U)) - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ - -/* Exported variables --------------------------------------------------------*/ - -/** @defgroup HAL_Exported_Variables HAL Exported Variables - * @{ - */ -__IO uint32_t uwTick; -uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid priority */ -HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */ -/** - * @} - */ - -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup HAL_Exported_Functions HAL Exported Functions - * @{ - */ - -/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions - * @brief Initialization and de-initialization functions - * -@verbatim - =============================================================================== - ##### Initialization and de-initialization functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Initialize the Flash interface, the NVIC allocation and initial time base - clock configuration. - (+) De-initialize common part of the HAL. - (+) Configure the time base source to have 1ms time base with a dedicated - Tick interrupt priority. - (++) SysTick timer is used by default as source of time base, but user - can eventually implement his proper time base source (a general purpose - timer for example or other time source), keeping in mind that Time base - duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and - handled in milliseconds basis. - (++) Time base configuration function (HAL_InitTick ()) is called automatically - at the beginning of the program after reset by HAL_Init() or at any time - when clock is configured, by HAL_RCC_ClockConfig(). - (++) Source of time base is configured to generate interrupts at regular - time intervals. Care must be taken if HAL_Delay() is called from a - peripheral ISR process, the Tick interrupt line must have higher priority - (numerically lower) than the peripheral interrupt. Otherwise the caller - ISR process will be blocked. - (++) functions affecting time base configurations are declared as __weak - to make override possible in case of other implementations in user file. -@endverbatim - * @{ - */ - -/** - * @brief Configure the Flash prefetch, the Instruction and Data caches, - * the time base source, NVIC and any required global low level hardware - * by calling the HAL_MspInit() callback function to be optionally defined in user file - * stm32l4xx_hal_msp.c. - * - * @note HAL_Init() function is called at the beginning of program after reset and before - * the clock configuration. - * - * @note In the default implementation the System Timer (Systick) is used as source of time base. - * The Systick configuration is based on MSI clock, as MSI is the clock - * used after a system Reset and the NVIC configuration is set to Priority group 4. - * Once done, time base tick starts incrementing: the tick variable counter is incremented - * each 1ms in the SysTick_Handler() interrupt handler. - * - * @retval HAL status - */ -HAL_StatusTypeDef HAL_Init(void) -{ - HAL_StatusTypeDef status = HAL_OK; - - /* Configure Flash prefetch, Instruction cache, Data cache */ - /* Default configuration at reset is: */ - /* - Prefetch disabled */ - /* - Instruction cache enabled */ - /* - Data cache enabled */ -#if (INSTRUCTION_CACHE_ENABLE == 0) - __HAL_FLASH_INSTRUCTION_CACHE_DISABLE(); -#endif /* INSTRUCTION_CACHE_ENABLE */ - -#if (DATA_CACHE_ENABLE == 0) - __HAL_FLASH_DATA_CACHE_DISABLE(); -#endif /* DATA_CACHE_ENABLE */ - -#if (PREFETCH_ENABLE != 0) - __HAL_FLASH_PREFETCH_BUFFER_ENABLE(); -#endif /* PREFETCH_ENABLE */ - - /* Set Interrupt Group Priority */ - HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); - - /* Use SysTick as time base source and configure 1ms tick (default clock after Reset is MSI) */ - if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) - { - status = HAL_ERROR; - } - else - { - /* Init the low level hardware */ - HAL_MspInit(); - } - - /* Return function status */ - return status; -} - -/** - * @brief De-initialize common part of the HAL and stop the source of time base. - * @note This function is optional. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_DeInit(void) -{ - /* Reset of all peripherals */ - __HAL_RCC_APB1_FORCE_RESET(); - __HAL_RCC_APB1_RELEASE_RESET(); - - __HAL_RCC_APB2_FORCE_RESET(); - __HAL_RCC_APB2_RELEASE_RESET(); - - __HAL_RCC_AHB1_FORCE_RESET(); - __HAL_RCC_AHB1_RELEASE_RESET(); - - __HAL_RCC_AHB2_FORCE_RESET(); - __HAL_RCC_AHB2_RELEASE_RESET(); - - __HAL_RCC_AHB3_FORCE_RESET(); - __HAL_RCC_AHB3_RELEASE_RESET(); - - /* De-Init the low level hardware */ - HAL_MspDeInit(); - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Initialize the MSP. - * @retval None - */ -__weak void HAL_MspInit(void) -{ - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_MspInit could be implemented in the user file - */ -} - -/** - * @brief DeInitialize the MSP. - * @retval None - */ -__weak void HAL_MspDeInit(void) -{ - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_MspDeInit could be implemented in the user file - */ -} - -/** - * @brief This function configures the source of the time base: - * The time source is configured to have 1ms time base with a dedicated - * Tick interrupt priority. - * @note This function is called automatically at the beginning of program after - * reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig(). - * @note In the default implementation, SysTick timer is the source of time base. - * It is used to generate interrupts at regular time intervals. - * Care must be taken if HAL_Delay() is called from a peripheral ISR process, - * The SysTick interrupt must have higher priority (numerically lower) - * than the peripheral interrupt. Otherwise the caller ISR process will be blocked. - * The function is declared as __weak to be overwritten in case of other - * implementation in user file. - * @param TickPriority Tick interrupt priority. - * @retval HAL status - */ -__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) -{ - HAL_StatusTypeDef status = HAL_OK; - - /* Check uwTickFreq for MisraC 2012 (even if uwTickFreq is a enum type that doesn't take the value zero)*/ - if ((uint32_t)uwTickFreq != 0U) - { - /*Configure the SysTick to have interrupt in 1ms time basis*/ - if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / (uint32_t)uwTickFreq)) == 0U) - { - /* Configure the SysTick IRQ priority */ - if (TickPriority < (1UL << __NVIC_PRIO_BITS)) - { - HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); - uwTickPrio = TickPriority; - } - else - { - status = HAL_ERROR; - } - } - else - { - status = HAL_ERROR; - } - } - else - { - status = HAL_ERROR; - } - - /* Return function status */ - return status; -} - -/** - * @} - */ - -/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions - * @brief HAL Control functions - * -@verbatim - =============================================================================== - ##### HAL Control functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Provide a tick value in millisecond - (+) Provide a blocking delay in millisecond - (+) Suspend the time base source interrupt - (+) Resume the time base source interrupt - (+) Get the HAL API driver version - (+) Get the device identifier - (+) Get the device revision identifier - -@endverbatim - * @{ - */ - -/** - * @brief This function is called to increment a global variable "uwTick" - * used as application time base. - * @note In the default implementation, this variable is incremented each 1ms - * in SysTick ISR. - * @note This function is declared as __weak to be overwritten in case of other - * implementations in user file. - * @retval None - */ -__weak void HAL_IncTick(void) -{ - uwTick += (uint32_t)uwTickFreq; -} - -/** - * @brief Provide a tick value in millisecond. - * @note This function is declared as __weak to be overwritten in case of other - * implementations in user file. - * @retval tick value - */ -__weak uint32_t HAL_GetTick(void) -{ - return uwTick; -} - -/** - * @brief This function returns a tick priority. - * @retval tick priority - */ -uint32_t HAL_GetTickPrio(void) -{ - return uwTickPrio; -} - -/** - * @brief Set new tick Freq. - * @param Freq tick frequency - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SetTickFreq(HAL_TickFreqTypeDef Freq) -{ - HAL_StatusTypeDef status = HAL_OK; - HAL_TickFreqTypeDef prevTickFreq; - - if (uwTickFreq != Freq) - { - /* Back up uwTickFreq frequency */ - prevTickFreq = uwTickFreq; - - /* Update uwTickFreq global variable used by HAL_InitTick() */ - uwTickFreq = Freq; - - /* Apply the new tick Freq */ - status = HAL_InitTick(uwTickPrio); - if (status != HAL_OK) - { - /* Restore previous tick frequency */ - uwTickFreq = prevTickFreq; - } - } - - return status; -} - -/** - * @brief Return tick frequency. - * @retval Tick frequency. - * Value of @ref HAL_TickFreqTypeDef. - */ -HAL_TickFreqTypeDef HAL_GetTickFreq(void) -{ - return uwTickFreq; -} - -/** - * @brief This function provides minimum delay (in milliseconds) based - * on variable incremented. - * @note In the default implementation , SysTick timer is the source of time base. - * It is used to generate interrupts at regular time intervals where uwTick - * is incremented. - * @note This function is declared as __weak to be overwritten in case of other - * implementations in user file. - * @param Delay specifies the delay time length, in milliseconds. - * @retval None - */ -__weak void HAL_Delay(uint32_t Delay) -{ - uint32_t tickstart = HAL_GetTick(); - uint32_t wait = Delay; - - /* Add a period to guaranty minimum wait */ - if (wait < HAL_MAX_DELAY) - { - wait += (uint32_t)uwTickFreq; - } - - while ((HAL_GetTick() - tickstart) < wait) - { - } -} - -/** - * @brief Suspend Tick increment. - * @note In the default implementation , SysTick timer is the source of time base. It is - * used to generate interrupts at regular time intervals. Once HAL_SuspendTick() - * is called, the SysTick interrupt will be disabled and so Tick increment - * is suspended. - * @note This function is declared as __weak to be overwritten in case of other - * implementations in user file. - * @retval None - */ -__weak void HAL_SuspendTick(void) -{ - /* Disable SysTick Interrupt */ - SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk; -} - -/** - * @brief Resume Tick increment. - * @note In the default implementation , SysTick timer is the source of time base. It is - * used to generate interrupts at regular time intervals. Once HAL_ResumeTick() - * is called, the SysTick interrupt will be enabled and so Tick increment - * is resumed. - * @note This function is declared as __weak to be overwritten in case of other - * implementations in user file. - * @retval None - */ -__weak void HAL_ResumeTick(void) -{ - /* Enable SysTick Interrupt */ - SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; -} - -/** - * @brief Return the HAL revision. - * @retval version : 0xXYZR (8bits for each decimal, R for RC) - */ -uint32_t HAL_GetHalVersion(void) -{ - return STM32L4XX_HAL_VERSION; -} - -/** - * @brief Return the device revision identifier. - * @retval Device revision identifier - */ -uint32_t HAL_GetREVID(void) -{ - return((DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> 16); -} - -/** - * @brief Return the device identifier. - * @retval Device identifier - */ -uint32_t HAL_GetDEVID(void) -{ - return(DBGMCU->IDCODE & DBGMCU_IDCODE_DEV_ID); -} - -/** - * @brief Return the first word of the unique device identifier (UID based on 96 bits) - * @retval Device identifier - */ -uint32_t HAL_GetUIDw0(void) -{ - return(READ_REG(*((uint32_t *)UID_BASE))); -} - -/** - * @brief Return the second word of the unique device identifier (UID based on 96 bits) - * @retval Device identifier - */ -uint32_t HAL_GetUIDw1(void) -{ - return(READ_REG(*((uint32_t *)(UID_BASE + 4U)))); -} - -/** - * @brief Return the third word of the unique device identifier (UID based on 96 bits) - * @retval Device identifier - */ -uint32_t HAL_GetUIDw2(void) -{ - return(READ_REG(*((uint32_t *)(UID_BASE + 8U)))); -} - -/** - * @} - */ - -/** @defgroup HAL_Exported_Functions_Group3 HAL Debug functions - * @brief HAL Debug functions - * -@verbatim - =============================================================================== - ##### HAL Debug functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Enable/Disable Debug module during SLEEP mode - (+) Enable/Disable Debug module during STOP0/STOP1/STOP2 modes - (+) Enable/Disable Debug module during STANDBY mode - -@endverbatim - * @{ - */ - -/** - * @brief Enable the Debug Module during SLEEP mode. - * @retval None - */ -void HAL_DBGMCU_EnableDBGSleepMode(void) -{ - SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); -} - -/** - * @brief Disable the Debug Module during SLEEP mode. - * @retval None - */ -void HAL_DBGMCU_DisableDBGSleepMode(void) -{ - CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); -} - -/** - * @brief Enable the Debug Module during STOP0/STOP1/STOP2 modes. - * @retval None - */ -void HAL_DBGMCU_EnableDBGStopMode(void) -{ - SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); -} - -/** - * @brief Disable the Debug Module during STOP0/STOP1/STOP2 modes. - * @retval None - */ -void HAL_DBGMCU_DisableDBGStopMode(void) -{ - CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); -} - -/** - * @brief Enable the Debug Module during STANDBY mode. - * @retval None - */ -void HAL_DBGMCU_EnableDBGStandbyMode(void) -{ - SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); -} - -/** - * @brief Disable the Debug Module during STANDBY mode. - * @retval None - */ -void HAL_DBGMCU_DisableDBGStandbyMode(void) -{ - CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY); -} - -/** - * @} - */ - -/** @defgroup HAL_Exported_Functions_Group4 HAL SYSCFG configuration functions - * @brief HAL SYSCFG configuration functions - * -@verbatim - =============================================================================== - ##### HAL SYSCFG configuration functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Start a hardware SRAM2 erase operation - (+) Enable/Disable the Internal FLASH Bank Swapping - (+) Configure the Voltage reference buffer - (+) Enable/Disable the Voltage reference buffer - (+) Enable/Disable the I/O analog switch voltage booster - -@endverbatim - * @{ - */ - -/** - * @brief Start a hardware SRAM2 erase operation. - * @note As long as SRAM2 is not erased the SRAM2ER bit will be set. - * This bit is automatically reset at the end of the SRAM2 erase operation. - * @retval None - */ -void HAL_SYSCFG_SRAM2Erase(void) -{ - /* unlock the write protection of the SRAM2ER bit */ - SYSCFG->SKR = 0xCA; - SYSCFG->SKR = 0x53; - /* Starts a hardware SRAM2 erase operation*/ - *(__IO uint32_t *) SCSR_SRAM2ER_BB = 0x00000001UL; -} - -/** - * @brief Enable the Internal FLASH Bank Swapping. - * - * @note This function can be used only for STM32L4xx devices. - * - * @note Flash Bank2 mapped at 0x08000000 (and aliased @0x00000000) - * and Flash Bank1 mapped at 0x08100000 (and aliased at 0x00100000) - * - * @retval None - */ -void HAL_SYSCFG_EnableMemorySwappingBank(void) -{ - *(__IO uint32_t *)FB_MODE_BB = 0x00000001UL; -} - -/** - * @brief Disable the Internal FLASH Bank Swapping. - * - * @note This function can be used only for STM32L4xx devices. - * - * @note The default state : Flash Bank1 mapped at 0x08000000 (and aliased @0x0000 0000) - * and Flash Bank2 mapped at 0x08100000 (and aliased at 0x00100000) - * - * @retval None - */ -void HAL_SYSCFG_DisableMemorySwappingBank(void) -{ - - *(__IO uint32_t *)FB_MODE_BB = 0x00000000UL; -} - -#if defined(VREFBUF) -/** - * @brief Configure the internal voltage reference buffer voltage scale. - * @param VoltageScaling specifies the output voltage to achieve - * This parameter can be one of the following values: - * @arg SYSCFG_VREFBUF_VOLTAGE_SCALE0: VREF_OUT1 around 2.048 V. - * This requires VDDA equal to or higher than 2.4 V. - * @arg SYSCFG_VREFBUF_VOLTAGE_SCALE1: VREF_OUT2 around 2.5 V. - * This requires VDDA equal to or higher than 2.8 V. - * @retval None - */ -void HAL_SYSCFG_VREFBUF_VoltageScalingConfig(uint32_t VoltageScaling) -{ - /* Check the parameters */ - assert_param(IS_SYSCFG_VREFBUF_VOLTAGE_SCALE(VoltageScaling)); - - MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_VRS, VoltageScaling); -} - -/** - * @brief Configure the internal voltage reference buffer high impedance mode. - * @param Mode specifies the high impedance mode - * This parameter can be one of the following values: - * @arg SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE: VREF+ pin is internally connect to VREFINT output. - * @arg SYSCFG_VREFBUF_HIGH_IMPEDANCE_ENABLE: VREF+ pin is high impedance. - * @retval None - */ -void HAL_SYSCFG_VREFBUF_HighImpedanceConfig(uint32_t Mode) -{ - /* Check the parameters */ - assert_param(IS_SYSCFG_VREFBUF_HIGH_IMPEDANCE(Mode)); - - MODIFY_REG(VREFBUF->CSR, VREFBUF_CSR_HIZ, Mode); -} - -/** - * @brief Tune the Internal Voltage Reference buffer (VREFBUF). - * @retval None - */ -void HAL_SYSCFG_VREFBUF_TrimmingConfig(uint32_t TrimmingValue) -{ - /* Check the parameters */ - assert_param(IS_SYSCFG_VREFBUF_TRIMMING(TrimmingValue)); - - MODIFY_REG(VREFBUF->CCR, VREFBUF_CCR_TRIM, TrimmingValue); -} - -/** - * @brief Enable the Internal Voltage Reference buffer (VREFBUF). - * @retval HAL_OK/HAL_TIMEOUT - */ -HAL_StatusTypeDef HAL_SYSCFG_EnableVREFBUF(void) -{ - uint32_t tickstart; - - SET_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); - - /* Get Start Tick*/ - tickstart = HAL_GetTick(); - - /* Wait for VRR bit */ - while(READ_BIT(VREFBUF->CSR, VREFBUF_CSR_VRR) == 0U) - { - if((HAL_GetTick() - tickstart) > VREFBUF_TIMEOUT_VALUE) - { - return HAL_TIMEOUT; - } - } - - return HAL_OK; -} - -/** - * @brief Disable the Internal Voltage Reference buffer (VREFBUF). - * - * @retval None - */ -void HAL_SYSCFG_DisableVREFBUF(void) -{ - CLEAR_BIT(VREFBUF->CSR, VREFBUF_CSR_ENVR); -} -#endif /* VREFBUF */ - -/** - * @brief Enable the I/O analog switch voltage booster - * - * @retval None - */ -void HAL_SYSCFG_EnableIOAnalogSwitchBooster(void) -{ - SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_BOOSTEN); -} - -/** - * @brief Disable the I/O analog switch voltage booster - * - * @retval None - */ -void HAL_SYSCFG_DisableIOAnalogSwitchBooster(void) -{ - CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_BOOSTEN); -} - -/** - * @} - */ - -/** - * @} - */ - -#endif /* HAL_MODULE_ENABLED */ -/** - * @} - */ - -/** - * @} - */ diff --git a/Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c b/Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c deleted file mode 100644 index 9c51e6fb..00000000 --- a/Mcu/l431/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_can.c +++ /dev/null @@ -1,2437 +0,0 @@ -/** - ****************************************************************************** - * @file stm32l4xx_hal_can.c - * @author MCD Application Team - * @brief CAN HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Controller Area Network (CAN) peripheral: - * + Initialization and de-initialization functions - * + Configuration functions - * + Control functions - * + Interrupts management - * + Callbacks functions - * + Peripheral State and Error functions - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - (#) Initialize the CAN low level resources by implementing the - HAL_CAN_MspInit(): - (++) Enable the CAN interface clock using __HAL_RCC_CANx_CLK_ENABLE() - (++) Configure CAN pins - (+++) Enable the clock for the CAN GPIOs - (+++) Configure CAN pins as alternate function open-drain - (++) In case of using interrupts (e.g. HAL_CAN_ActivateNotification()) - (+++) Configure the CAN interrupt priority using - HAL_NVIC_SetPriority() - (+++) Enable the CAN IRQ handler using HAL_NVIC_EnableIRQ() - (+++) In CAN IRQ handler, call HAL_CAN_IRQHandler() - - (#) Initialize the CAN peripheral using HAL_CAN_Init() function. This - function resorts to HAL_CAN_MspInit() for low-level initialization. - - (#) Configure the reception filters using the following configuration - functions: - (++) HAL_CAN_ConfigFilter() - - (#) Start the CAN module using HAL_CAN_Start() function. At this level - the node is active on the bus: it receive messages, and can send - messages. - - (#) To manage messages transmission, the following Tx control functions - can be used: - (++) HAL_CAN_AddTxMessage() to request transmission of a new - message. - (++) HAL_CAN_AbortTxRequest() to abort transmission of a pending - message. - (++) HAL_CAN_GetTxMailboxesFreeLevel() to get the number of free Tx - mailboxes. - (++) HAL_CAN_IsTxMessagePending() to check if a message is pending - in a Tx mailbox. - (++) HAL_CAN_GetTxTimestamp() to get the timestamp of Tx message - sent, if time triggered communication mode is enabled. - - (#) When a message is received into the CAN Rx FIFOs, it can be retrieved - using the HAL_CAN_GetRxMessage() function. The function - HAL_CAN_GetRxFifoFillLevel() allows to know how many Rx message are - stored in the Rx Fifo. - - (#) Calling the HAL_CAN_Stop() function stops the CAN module. - - (#) The deinitialization is achieved with HAL_CAN_DeInit() function. - - - *** Polling mode operation *** - ============================== - [..] - (#) Reception: - (++) Monitor reception of message using HAL_CAN_GetRxFifoFillLevel() - until at least one message is received. - (++) Then get the message using HAL_CAN_GetRxMessage(). - - (#) Transmission: - (++) Monitor the Tx mailboxes availability until at least one Tx - mailbox is free, using HAL_CAN_GetTxMailboxesFreeLevel(). - (++) Then request transmission of a message using - HAL_CAN_AddTxMessage(). - - - *** Interrupt mode operation *** - ================================ - [..] - (#) Notifications are activated using HAL_CAN_ActivateNotification() - function. Then, the process can be controlled through the - available user callbacks: HAL_CAN_xxxCallback(), using same APIs - HAL_CAN_GetRxMessage() and HAL_CAN_AddTxMessage(). - - (#) Notifications can be deactivated using - HAL_CAN_DeactivateNotification() function. - - (#) Special care should be taken for CAN_IT_RX_FIFO0_MSG_PENDING and - CAN_IT_RX_FIFO1_MSG_PENDING notifications. These notifications trig - the callbacks HAL_CAN_RxFIFO0MsgPendingCallback() and - HAL_CAN_RxFIFO1MsgPendingCallback(). User has two possible options - here. - (++) Directly get the Rx message in the callback, using - HAL_CAN_GetRxMessage(). - (++) Or deactivate the notification in the callback without - getting the Rx message. The Rx message can then be got later - using HAL_CAN_GetRxMessage(). Once the Rx message have been - read, the notification can be activated again. - - - *** Sleep mode *** - ================== - [..] - (#) The CAN peripheral can be put in sleep mode (low power), using - HAL_CAN_RequestSleep(). The sleep mode will be entered as soon as the - current CAN activity (transmission or reception of a CAN frame) will - be completed. - - (#) A notification can be activated to be informed when the sleep mode - will be entered. - - (#) It can be checked if the sleep mode is entered using - HAL_CAN_IsSleepActive(). - Note that the CAN state (accessible from the API HAL_CAN_GetState()) - is HAL_CAN_STATE_SLEEP_PENDING as soon as the sleep mode request is - submitted (the sleep mode is not yet entered), and become - HAL_CAN_STATE_SLEEP_ACTIVE when the sleep mode is effective. - - (#) The wake-up from sleep mode can be triggered by two ways: - (++) Using HAL_CAN_WakeUp(). When returning from this function, - the sleep mode is exited (if return status is HAL_OK). - (++) When a start of Rx CAN frame is detected by the CAN peripheral, - if automatic wake up mode is enabled. - - *** Callback registration *** - ============================================= - - The compilation define USE_HAL_CAN_REGISTER_CALLBACKS when set to 1 - allows the user to configure dynamically the driver callbacks. - Use Function HAL_CAN_RegisterCallback() to register an interrupt callback. - - Function HAL_CAN_RegisterCallback() allows to register following callbacks: - (+) TxMailbox0CompleteCallback : Tx Mailbox 0 Complete Callback. - (+) TxMailbox1CompleteCallback : Tx Mailbox 1 Complete Callback. - (+) TxMailbox2CompleteCallback : Tx Mailbox 2 Complete Callback. - (+) TxMailbox0AbortCallback : Tx Mailbox 0 Abort Callback. - (+) TxMailbox1AbortCallback : Tx Mailbox 1 Abort Callback. - (+) TxMailbox2AbortCallback : Tx Mailbox 2 Abort Callback. - (+) RxFifo0MsgPendingCallback : Rx Fifo 0 Message Pending Callback. - (+) RxFifo0FullCallback : Rx Fifo 0 Full Callback. - (+) RxFifo1MsgPendingCallback : Rx Fifo 1 Message Pending Callback. - (+) RxFifo1FullCallback : Rx Fifo 1 Full Callback. - (+) SleepCallback : Sleep Callback. - (+) WakeUpFromRxMsgCallback : Wake Up From Rx Message Callback. - (+) ErrorCallback : Error Callback. - (+) MspInitCallback : CAN MspInit. - (+) MspDeInitCallback : CAN MspDeInit. - This function takes as parameters the HAL peripheral handle, the Callback ID - and a pointer to the user callback function. - - Use function HAL_CAN_UnRegisterCallback() to reset a callback to the default - weak function. - HAL_CAN_UnRegisterCallback takes as parameters the HAL peripheral handle, - and the Callback ID. - This function allows to reset following callbacks: - (+) TxMailbox0CompleteCallback : Tx Mailbox 0 Complete Callback. - (+) TxMailbox1CompleteCallback : Tx Mailbox 1 Complete Callback. - (+) TxMailbox2CompleteCallback : Tx Mailbox 2 Complete Callback. - (+) TxMailbox0AbortCallback : Tx Mailbox 0 Abort Callback. - (+) TxMailbox1AbortCallback : Tx Mailbox 1 Abort Callback. - (+) TxMailbox2AbortCallback : Tx Mailbox 2 Abort Callback. - (+) RxFifo0MsgPendingCallback : Rx Fifo 0 Message Pending Callback. - (+) RxFifo0FullCallback : Rx Fifo 0 Full Callback. - (+) RxFifo1MsgPendingCallback : Rx Fifo 1 Message Pending Callback. - (+) RxFifo1FullCallback : Rx Fifo 1 Full Callback. - (+) SleepCallback : Sleep Callback. - (+) WakeUpFromRxMsgCallback : Wake Up From Rx Message Callback. - (+) ErrorCallback : Error Callback. - (+) MspInitCallback : CAN MspInit. - (+) MspDeInitCallback : CAN MspDeInit. - - By default, after the HAL_CAN_Init() and when the state is HAL_CAN_STATE_RESET, - all callbacks are set to the corresponding weak functions: - example HAL_CAN_ErrorCallback(). - Exception done for MspInit and MspDeInit functions that are - reset to the legacy weak function in the HAL_CAN_Init()/ HAL_CAN_DeInit() only when - these callbacks are null (not registered beforehand). - if not, MspInit or MspDeInit are not null, the HAL_CAN_Init()/ HAL_CAN_DeInit() - keep and use the user MspInit/MspDeInit callbacks (registered beforehand) - - Callbacks can be registered/unregistered in HAL_CAN_STATE_READY state only. - Exception done MspInit/MspDeInit that can be registered/unregistered - in HAL_CAN_STATE_READY or HAL_CAN_STATE_RESET state, - thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. - In that case first register the MspInit/MspDeInit user callbacks - using HAL_CAN_RegisterCallback() before calling HAL_CAN_DeInit() - or HAL_CAN_Init() function. - - When The compilation define USE_HAL_CAN_REGISTER_CALLBACKS is set to 0 or - not defined, the callback registration feature is not available and all callbacks - are set to the corresponding weak functions. - - @endverbatim - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32l4xx_hal.h" - -/** @addtogroup STM32L4xx_HAL_Driver - * @{ - */ - -#if defined(CAN1) - -/** @defgroup CAN CAN - * @brief CAN driver modules - * @{ - */ - -#ifdef HAL_CAN_MODULE_ENABLED - -#ifdef HAL_CAN_LEGACY_MODULE_ENABLED -#error "The CAN driver cannot be used with its legacy, Please enable only one CAN module at once" -#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/** @defgroup CAN_Private_Constants CAN Private Constants - * @{ - */ -#define CAN_TIMEOUT_VALUE 10U -/** - * @} - */ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup CAN_Exported_Functions CAN Exported Functions - * @{ - */ - -/** @defgroup CAN_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions - * -@verbatim - ============================================================================== - ##### Initialization and de-initialization functions ##### - ============================================================================== - [..] This section provides functions allowing to: - (+) HAL_CAN_Init : Initialize and configure the CAN. - (+) HAL_CAN_DeInit : De-initialize the CAN. - (+) HAL_CAN_MspInit : Initialize the CAN MSP. - (+) HAL_CAN_MspDeInit : DeInitialize the CAN MSP. - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the CAN peripheral according to the specified - * parameters in the CAN_InitStruct. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_Init(CAN_HandleTypeDef *hcan) -{ - uint32_t tickstart; - - /* Check CAN handle */ - if (hcan == NULL) - { - return HAL_ERROR; - } - - /* Check the parameters */ - assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance)); - assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TimeTriggeredMode)); - assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoBusOff)); - assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoWakeUp)); - assert_param(IS_FUNCTIONAL_STATE(hcan->Init.AutoRetransmission)); - assert_param(IS_FUNCTIONAL_STATE(hcan->Init.ReceiveFifoLocked)); - assert_param(IS_FUNCTIONAL_STATE(hcan->Init.TransmitFifoPriority)); - assert_param(IS_CAN_MODE(hcan->Init.Mode)); - assert_param(IS_CAN_SJW(hcan->Init.SyncJumpWidth)); - assert_param(IS_CAN_BS1(hcan->Init.TimeSeg1)); - assert_param(IS_CAN_BS2(hcan->Init.TimeSeg2)); - assert_param(IS_CAN_PRESCALER(hcan->Init.Prescaler)); - -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - if (hcan->State == HAL_CAN_STATE_RESET) - { - /* Reset callbacks to legacy functions */ - hcan->RxFifo0MsgPendingCallback = HAL_CAN_RxFifo0MsgPendingCallback; /* Legacy weak RxFifo0MsgPendingCallback */ - hcan->RxFifo0FullCallback = HAL_CAN_RxFifo0FullCallback; /* Legacy weak RxFifo0FullCallback */ - hcan->RxFifo1MsgPendingCallback = HAL_CAN_RxFifo1MsgPendingCallback; /* Legacy weak RxFifo1MsgPendingCallback */ - hcan->RxFifo1FullCallback = HAL_CAN_RxFifo1FullCallback; /* Legacy weak RxFifo1FullCallback */ - hcan->TxMailbox0CompleteCallback = HAL_CAN_TxMailbox0CompleteCallback; /* Legacy weak TxMailbox0CompleteCallback */ - hcan->TxMailbox1CompleteCallback = HAL_CAN_TxMailbox1CompleteCallback; /* Legacy weak TxMailbox1CompleteCallback */ - hcan->TxMailbox2CompleteCallback = HAL_CAN_TxMailbox2CompleteCallback; /* Legacy weak TxMailbox2CompleteCallback */ - hcan->TxMailbox0AbortCallback = HAL_CAN_TxMailbox0AbortCallback; /* Legacy weak TxMailbox0AbortCallback */ - hcan->TxMailbox1AbortCallback = HAL_CAN_TxMailbox1AbortCallback; /* Legacy weak TxMailbox1AbortCallback */ - hcan->TxMailbox2AbortCallback = HAL_CAN_TxMailbox2AbortCallback; /* Legacy weak TxMailbox2AbortCallback */ - hcan->SleepCallback = HAL_CAN_SleepCallback; /* Legacy weak SleepCallback */ - hcan->WakeUpFromRxMsgCallback = HAL_CAN_WakeUpFromRxMsgCallback; /* Legacy weak WakeUpFromRxMsgCallback */ - hcan->ErrorCallback = HAL_CAN_ErrorCallback; /* Legacy weak ErrorCallback */ - - if (hcan->MspInitCallback == NULL) - { - hcan->MspInitCallback = HAL_CAN_MspInit; /* Legacy weak MspInit */ - } - - /* Init the low level hardware: CLOCK, NVIC */ - hcan->MspInitCallback(hcan); - } - -#else - if (hcan->State == HAL_CAN_STATE_RESET) - { - /* Init the low level hardware: CLOCK, NVIC */ - HAL_CAN_MspInit(hcan); - } -#endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */ - - /* Request initialisation */ - SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Wait initialisation acknowledge */ - while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U) - { - if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE) - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT; - - /* Change CAN state */ - hcan->State = HAL_CAN_STATE_ERROR; - - return HAL_ERROR; - } - } - - /* Exit from sleep mode */ - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Check Sleep mode leave acknowledge */ - while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U) - { - if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE) - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT; - - /* Change CAN state */ - hcan->State = HAL_CAN_STATE_ERROR; - - return HAL_ERROR; - } - } - - /* Set the time triggered communication mode */ - if (hcan->Init.TimeTriggeredMode == ENABLE) - { - SET_BIT(hcan->Instance->MCR, CAN_MCR_TTCM); - } - else - { - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TTCM); - } - - /* Set the automatic bus-off management */ - if (hcan->Init.AutoBusOff == ENABLE) - { - SET_BIT(hcan->Instance->MCR, CAN_MCR_ABOM); - } - else - { - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_ABOM); - } - - /* Set the automatic wake-up mode */ - if (hcan->Init.AutoWakeUp == ENABLE) - { - SET_BIT(hcan->Instance->MCR, CAN_MCR_AWUM); - } - else - { - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_AWUM); - } - - /* Set the automatic retransmission */ - if (hcan->Init.AutoRetransmission == ENABLE) - { - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_NART); - } - else - { - SET_BIT(hcan->Instance->MCR, CAN_MCR_NART); - } - - /* Set the receive FIFO locked mode */ - if (hcan->Init.ReceiveFifoLocked == ENABLE) - { - SET_BIT(hcan->Instance->MCR, CAN_MCR_RFLM); - } - else - { - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_RFLM); - } - - /* Set the transmit FIFO priority */ - if (hcan->Init.TransmitFifoPriority == ENABLE) - { - SET_BIT(hcan->Instance->MCR, CAN_MCR_TXFP); - } - else - { - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_TXFP); - } - - /* Set the bit timing register */ - WRITE_REG(hcan->Instance->BTR, (uint32_t)(hcan->Init.Mode | - hcan->Init.SyncJumpWidth | - hcan->Init.TimeSeg1 | - hcan->Init.TimeSeg2 | - (hcan->Init.Prescaler - 1U))); - - /* Initialize the error code */ - hcan->ErrorCode = HAL_CAN_ERROR_NONE; - - /* Initialize the CAN state */ - hcan->State = HAL_CAN_STATE_READY; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Deinitializes the CAN peripheral registers to their default - * reset values. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_DeInit(CAN_HandleTypeDef *hcan) -{ - /* Check CAN handle */ - if (hcan == NULL) - { - return HAL_ERROR; - } - - /* Check the parameters */ - assert_param(IS_CAN_ALL_INSTANCE(hcan->Instance)); - - /* Stop the CAN module */ - (void)HAL_CAN_Stop(hcan); - -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - if (hcan->MspDeInitCallback == NULL) - { - hcan->MspDeInitCallback = HAL_CAN_MspDeInit; /* Legacy weak MspDeInit */ - } - - /* DeInit the low level hardware: CLOCK, NVIC */ - hcan->MspDeInitCallback(hcan); - -#else - /* DeInit the low level hardware: CLOCK, NVIC */ - HAL_CAN_MspDeInit(hcan); -#endif /* (USE_HAL_CAN_REGISTER_CALLBACKS) */ - - /* Reset the CAN peripheral */ - SET_BIT(hcan->Instance->MCR, CAN_MCR_RESET); - - /* Reset the CAN ErrorCode */ - hcan->ErrorCode = HAL_CAN_ERROR_NONE; - - /* Change CAN state */ - hcan->State = HAL_CAN_STATE_RESET; - - /* Return function status */ - return HAL_OK; -} - -/** - * @brief Initializes the CAN MSP. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_MspInit could be implemented in the user file - */ -} - -/** - * @brief DeInitializes the CAN MSP. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_MspDeInit could be implemented in the user file - */ -} - -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 -/** - * @brief Register a CAN CallBack. - * To be used instead of the weak predefined callback - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for CAN module - * @param CallbackID ID of the callback to be registered - * This parameter can be one of the following values: - * @arg @ref HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID Tx Mailbox 0 Complete callback ID - * @arg @ref HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID Tx Mailbox 1 Complete callback ID - * @arg @ref HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID Tx Mailbox 2 Complete callback ID - * @arg @ref HAL_CAN_TX_MAILBOX0_ABORT_CB_ID Tx Mailbox 0 Abort callback ID - * @arg @ref HAL_CAN_TX_MAILBOX1_ABORT_CB_ID Tx Mailbox 1 Abort callback ID - * @arg @ref HAL_CAN_TX_MAILBOX2_ABORT_CB_ID Tx Mailbox 2 Abort callback ID - * @arg @ref HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID Rx Fifo 0 message pending callback ID - * @arg @ref HAL_CAN_RX_FIFO0_FULL_CB_ID Rx Fifo 0 full callback ID - * @arg @ref HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID Rx Fifo 1 message pending callback ID - * @arg @ref HAL_CAN_RX_FIFO1_FULL_CB_ID Rx Fifo 1 full callback ID - * @arg @ref HAL_CAN_SLEEP_CB_ID Sleep callback ID - * @arg @ref HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID Wake Up from Rx message callback ID - * @arg @ref HAL_CAN_ERROR_CB_ID Error callback ID - * @arg @ref HAL_CAN_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_CAN_MSPDEINIT_CB_ID MspDeInit callback ID - * @param pCallback pointer to the Callback function - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_RegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID, - void (* pCallback)(CAN_HandleTypeDef *_hcan)) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - /* Update the error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK; - - return HAL_ERROR; - } - - if (hcan->State == HAL_CAN_STATE_READY) - { - switch (CallbackID) - { - case HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID : - hcan->TxMailbox0CompleteCallback = pCallback; - break; - - case HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID : - hcan->TxMailbox1CompleteCallback = pCallback; - break; - - case HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID : - hcan->TxMailbox2CompleteCallback = pCallback; - break; - - case HAL_CAN_TX_MAILBOX0_ABORT_CB_ID : - hcan->TxMailbox0AbortCallback = pCallback; - break; - - case HAL_CAN_TX_MAILBOX1_ABORT_CB_ID : - hcan->TxMailbox1AbortCallback = pCallback; - break; - - case HAL_CAN_TX_MAILBOX2_ABORT_CB_ID : - hcan->TxMailbox2AbortCallback = pCallback; - break; - - case HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID : - hcan->RxFifo0MsgPendingCallback = pCallback; - break; - - case HAL_CAN_RX_FIFO0_FULL_CB_ID : - hcan->RxFifo0FullCallback = pCallback; - break; - - case HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID : - hcan->RxFifo1MsgPendingCallback = pCallback; - break; - - case HAL_CAN_RX_FIFO1_FULL_CB_ID : - hcan->RxFifo1FullCallback = pCallback; - break; - - case HAL_CAN_SLEEP_CB_ID : - hcan->SleepCallback = pCallback; - break; - - case HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID : - hcan->WakeUpFromRxMsgCallback = pCallback; - break; - - case HAL_CAN_ERROR_CB_ID : - hcan->ErrorCallback = pCallback; - break; - - case HAL_CAN_MSPINIT_CB_ID : - hcan->MspInitCallback = pCallback; - break; - - case HAL_CAN_MSPDEINIT_CB_ID : - hcan->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK; - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (hcan->State == HAL_CAN_STATE_RESET) - { - switch (CallbackID) - { - case HAL_CAN_MSPINIT_CB_ID : - hcan->MspInitCallback = pCallback; - break; - - case HAL_CAN_MSPDEINIT_CB_ID : - hcan->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK; - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK; - - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} - -/** - * @brief Unregister a CAN CallBack. - * CAN callback is redirected to the weak predefined callback - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for CAN module - * @param CallbackID ID of the callback to be unregistered - * This parameter can be one of the following values: - * @arg @ref HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID Tx Mailbox 0 Complete callback ID - * @arg @ref HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID Tx Mailbox 1 Complete callback ID - * @arg @ref HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID Tx Mailbox 2 Complete callback ID - * @arg @ref HAL_CAN_TX_MAILBOX0_ABORT_CB_ID Tx Mailbox 0 Abort callback ID - * @arg @ref HAL_CAN_TX_MAILBOX1_ABORT_CB_ID Tx Mailbox 1 Abort callback ID - * @arg @ref HAL_CAN_TX_MAILBOX2_ABORT_CB_ID Tx Mailbox 2 Abort callback ID - * @arg @ref HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID Rx Fifo 0 message pending callback ID - * @arg @ref HAL_CAN_RX_FIFO0_FULL_CB_ID Rx Fifo 0 full callback ID - * @arg @ref HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID Rx Fifo 1 message pending callback ID - * @arg @ref HAL_CAN_RX_FIFO1_FULL_CB_ID Rx Fifo 1 full callback ID - * @arg @ref HAL_CAN_SLEEP_CB_ID Sleep callback ID - * @arg @ref HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID Wake Up from Rx message callback ID - * @arg @ref HAL_CAN_ERROR_CB_ID Error callback ID - * @arg @ref HAL_CAN_MSPINIT_CB_ID MspInit callback ID - * @arg @ref HAL_CAN_MSPDEINIT_CB_ID MspDeInit callback ID - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_UnRegisterCallback(CAN_HandleTypeDef *hcan, HAL_CAN_CallbackIDTypeDef CallbackID) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (hcan->State == HAL_CAN_STATE_READY) - { - switch (CallbackID) - { - case HAL_CAN_TX_MAILBOX0_COMPLETE_CB_ID : - hcan->TxMailbox0CompleteCallback = HAL_CAN_TxMailbox0CompleteCallback; - break; - - case HAL_CAN_TX_MAILBOX1_COMPLETE_CB_ID : - hcan->TxMailbox1CompleteCallback = HAL_CAN_TxMailbox1CompleteCallback; - break; - - case HAL_CAN_TX_MAILBOX2_COMPLETE_CB_ID : - hcan->TxMailbox2CompleteCallback = HAL_CAN_TxMailbox2CompleteCallback; - break; - - case HAL_CAN_TX_MAILBOX0_ABORT_CB_ID : - hcan->TxMailbox0AbortCallback = HAL_CAN_TxMailbox0AbortCallback; - break; - - case HAL_CAN_TX_MAILBOX1_ABORT_CB_ID : - hcan->TxMailbox1AbortCallback = HAL_CAN_TxMailbox1AbortCallback; - break; - - case HAL_CAN_TX_MAILBOX2_ABORT_CB_ID : - hcan->TxMailbox2AbortCallback = HAL_CAN_TxMailbox2AbortCallback; - break; - - case HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID : - hcan->RxFifo0MsgPendingCallback = HAL_CAN_RxFifo0MsgPendingCallback; - break; - - case HAL_CAN_RX_FIFO0_FULL_CB_ID : - hcan->RxFifo0FullCallback = HAL_CAN_RxFifo0FullCallback; - break; - - case HAL_CAN_RX_FIFO1_MSG_PENDING_CB_ID : - hcan->RxFifo1MsgPendingCallback = HAL_CAN_RxFifo1MsgPendingCallback; - break; - - case HAL_CAN_RX_FIFO1_FULL_CB_ID : - hcan->RxFifo1FullCallback = HAL_CAN_RxFifo1FullCallback; - break; - - case HAL_CAN_SLEEP_CB_ID : - hcan->SleepCallback = HAL_CAN_SleepCallback; - break; - - case HAL_CAN_WAKEUP_FROM_RX_MSG_CB_ID : - hcan->WakeUpFromRxMsgCallback = HAL_CAN_WakeUpFromRxMsgCallback; - break; - - case HAL_CAN_ERROR_CB_ID : - hcan->ErrorCallback = HAL_CAN_ErrorCallback; - break; - - case HAL_CAN_MSPINIT_CB_ID : - hcan->MspInitCallback = HAL_CAN_MspInit; - break; - - case HAL_CAN_MSPDEINIT_CB_ID : - hcan->MspDeInitCallback = HAL_CAN_MspDeInit; - break; - - default : - /* Update the error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK; - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (hcan->State == HAL_CAN_STATE_RESET) - { - switch (CallbackID) - { - case HAL_CAN_MSPINIT_CB_ID : - hcan->MspInitCallback = HAL_CAN_MspInit; - break; - - case HAL_CAN_MSPDEINIT_CB_ID : - hcan->MspDeInitCallback = HAL_CAN_MspDeInit; - break; - - default : - /* Update the error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK; - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_INVALID_CALLBACK; - - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - -/** - * @} - */ - -/** @defgroup CAN_Exported_Functions_Group2 Configuration functions - * @brief Configuration functions. - * -@verbatim - ============================================================================== - ##### Configuration functions ##### - ============================================================================== - [..] This section provides functions allowing to: - (+) HAL_CAN_ConfigFilter : Configure the CAN reception filters - -@endverbatim - * @{ - */ - -/** - * @brief Configures the CAN reception filter according to the specified - * parameters in the CAN_FilterInitStruct. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param sFilterConfig pointer to a CAN_FilterTypeDef structure that - * contains the filter configuration information. - * @retval None - */ -HAL_StatusTypeDef HAL_CAN_ConfigFilter(CAN_HandleTypeDef *hcan, const CAN_FilterTypeDef *sFilterConfig) -{ - uint32_t filternbrbitpos; - CAN_TypeDef *can_ip = hcan->Instance; - HAL_CAN_StateTypeDef state = hcan->State; - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check the parameters */ - assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdHigh)); - assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterIdLow)); - assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdHigh)); - assert_param(IS_CAN_FILTER_ID_HALFWORD(sFilterConfig->FilterMaskIdLow)); - assert_param(IS_CAN_FILTER_MODE(sFilterConfig->FilterMode)); - assert_param(IS_CAN_FILTER_SCALE(sFilterConfig->FilterScale)); - assert_param(IS_CAN_FILTER_FIFO(sFilterConfig->FilterFIFOAssignment)); - assert_param(IS_CAN_FILTER_ACTIVATION(sFilterConfig->FilterActivation)); - -#if defined(CAN2) - /* CAN1 and CAN2 are dual instances with 28 common filters banks */ - /* Select master instance to access the filter banks */ - can_ip = CAN1; - - /* Check the parameters */ - assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->FilterBank)); - assert_param(IS_CAN_FILTER_BANK_DUAL(sFilterConfig->SlaveStartFilterBank)); -#else - /* CAN1 is single instance with 14 dedicated filters banks */ - - /* Check the parameters */ - assert_param(IS_CAN_FILTER_BANK_SINGLE(sFilterConfig->FilterBank)); -#endif - - /* Initialisation mode for the filter */ - SET_BIT(can_ip->FMR, CAN_FMR_FINIT); - -#if defined(CAN2) - /* Select the start filter number of CAN2 slave instance */ - CLEAR_BIT(can_ip->FMR, CAN_FMR_CAN2SB); - SET_BIT(can_ip->FMR, sFilterConfig->SlaveStartFilterBank << CAN_FMR_CAN2SB_Pos); - -#endif - /* Convert filter number into bit position */ - filternbrbitpos = (uint32_t)1 << (sFilterConfig->FilterBank & 0x1FU); - - /* Filter Deactivation */ - CLEAR_BIT(can_ip->FA1R, filternbrbitpos); - - /* Filter Scale */ - if (sFilterConfig->FilterScale == CAN_FILTERSCALE_16BIT) - { - /* 16-bit scale for the filter */ - CLEAR_BIT(can_ip->FS1R, filternbrbitpos); - - /* First 16-bit identifier and First 16-bit mask */ - /* Or First 16-bit identifier and Second 16-bit identifier */ - can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 = - ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow) << 16U) | - (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow); - - /* Second 16-bit identifier and Second 16-bit mask */ - /* Or Third 16-bit identifier and Fourth 16-bit identifier */ - can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 = - ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) | - (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh); - } - - if (sFilterConfig->FilterScale == CAN_FILTERSCALE_32BIT) - { - /* 32-bit scale for the filter */ - SET_BIT(can_ip->FS1R, filternbrbitpos); - - /* 32-bit identifier or First 32-bit identifier */ - can_ip->sFilterRegister[sFilterConfig->FilterBank].FR1 = - ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdHigh) << 16U) | - (0x0000FFFFU & (uint32_t)sFilterConfig->FilterIdLow); - - /* 32-bit mask or Second 32-bit identifier */ - can_ip->sFilterRegister[sFilterConfig->FilterBank].FR2 = - ((0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdHigh) << 16U) | - (0x0000FFFFU & (uint32_t)sFilterConfig->FilterMaskIdLow); - } - - /* Filter Mode */ - if (sFilterConfig->FilterMode == CAN_FILTERMODE_IDMASK) - { - /* Id/Mask mode for the filter*/ - CLEAR_BIT(can_ip->FM1R, filternbrbitpos); - } - else /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FilterMode_IdList */ - { - /* Identifier list mode for the filter*/ - SET_BIT(can_ip->FM1R, filternbrbitpos); - } - - /* Filter FIFO assignment */ - if (sFilterConfig->FilterFIFOAssignment == CAN_FILTER_FIFO0) - { - /* FIFO 0 assignation for the filter */ - CLEAR_BIT(can_ip->FFA1R, filternbrbitpos); - } - else - { - /* FIFO 1 assignation for the filter */ - SET_BIT(can_ip->FFA1R, filternbrbitpos); - } - - /* Filter activation */ - if (sFilterConfig->FilterActivation == CAN_FILTER_ENABLE) - { - SET_BIT(can_ip->FA1R, filternbrbitpos); - } - - /* Leave the initialisation mode for the filter */ - CLEAR_BIT(can_ip->FMR, CAN_FMR_FINIT); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - return HAL_ERROR; - } -} - -/** - * @} - */ - -/** @defgroup CAN_Exported_Functions_Group3 Control functions - * @brief Control functions - * -@verbatim - ============================================================================== - ##### Control functions ##### - ============================================================================== - [..] This section provides functions allowing to: - (+) HAL_CAN_Start : Start the CAN module - (+) HAL_CAN_Stop : Stop the CAN module - (+) HAL_CAN_RequestSleep : Request sleep mode entry. - (+) HAL_CAN_WakeUp : Wake up from sleep mode. - (+) HAL_CAN_IsSleepActive : Check is sleep mode is active. - (+) HAL_CAN_AddTxMessage : Add a message to the Tx mailboxes - and activate the corresponding - transmission request - (+) HAL_CAN_AbortTxRequest : Abort transmission request - (+) HAL_CAN_GetTxMailboxesFreeLevel : Return Tx mailboxes free level - (+) HAL_CAN_IsTxMessagePending : Check if a transmission request is - pending on the selected Tx mailbox - (+) HAL_CAN_GetRxMessage : Get a CAN frame from the Rx FIFO - (+) HAL_CAN_GetRxFifoFillLevel : Return Rx FIFO fill level - -@endverbatim - * @{ - */ - -/** - * @brief Start the CAN module. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_Start(CAN_HandleTypeDef *hcan) -{ - uint32_t tickstart; - - if (hcan->State == HAL_CAN_STATE_READY) - { - /* Change CAN peripheral state */ - hcan->State = HAL_CAN_STATE_LISTENING; - - /* Request leave initialisation */ - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_INRQ); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Wait the acknowledge */ - while ((hcan->Instance->MSR & CAN_MSR_INAK) != 0U) - { - /* Check for the Timeout */ - if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE) - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT; - - /* Change CAN state */ - hcan->State = HAL_CAN_STATE_ERROR; - - return HAL_ERROR; - } - } - - /* Reset the CAN ErrorCode */ - hcan->ErrorCode = HAL_CAN_ERROR_NONE; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_READY; - - return HAL_ERROR; - } -} - -/** - * @brief Stop the CAN module and enable access to configuration registers. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_Stop(CAN_HandleTypeDef *hcan) -{ - uint32_t tickstart; - - if (hcan->State == HAL_CAN_STATE_LISTENING) - { - /* Request initialisation */ - SET_BIT(hcan->Instance->MCR, CAN_MCR_INRQ); - - /* Get tick */ - tickstart = HAL_GetTick(); - - /* Wait the acknowledge */ - while ((hcan->Instance->MSR & CAN_MSR_INAK) == 0U) - { - /* Check for the Timeout */ - if ((HAL_GetTick() - tickstart) > CAN_TIMEOUT_VALUE) - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT; - - /* Change CAN state */ - hcan->State = HAL_CAN_STATE_ERROR; - - return HAL_ERROR; - } - } - - /* Exit from sleep mode */ - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP); - - /* Change CAN peripheral state */ - hcan->State = HAL_CAN_STATE_READY; - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_STARTED; - - return HAL_ERROR; - } -} - -/** - * @brief Request the sleep mode (low power) entry. - * When returning from this function, Sleep mode will be entered - * as soon as the current CAN activity (transmission or reception - * of a CAN frame) has been completed. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL status. - */ -HAL_StatusTypeDef HAL_CAN_RequestSleep(CAN_HandleTypeDef *hcan) -{ - HAL_CAN_StateTypeDef state = hcan->State; - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Request Sleep mode */ - SET_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - /* Return function status */ - return HAL_ERROR; - } -} - -/** - * @brief Wake up from sleep mode. - * When returning with HAL_OK status from this function, Sleep mode - * is exited. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL status. - */ -HAL_StatusTypeDef HAL_CAN_WakeUp(CAN_HandleTypeDef *hcan) -{ - __IO uint32_t count = 0; - uint32_t timeout = 1000000U; - HAL_CAN_StateTypeDef state = hcan->State; - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Wake up request */ - CLEAR_BIT(hcan->Instance->MCR, CAN_MCR_SLEEP); - - /* Wait sleep mode is exited */ - do - { - /* Increment counter */ - count++; - - /* Check if timeout is reached */ - if (count > timeout) - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_TIMEOUT; - - return HAL_ERROR; - } - } - while ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - return HAL_ERROR; - } -} - -/** - * @brief Check is sleep mode is active. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval Status - * - 0 : Sleep mode is not active. - * - 1 : Sleep mode is active. - */ -uint32_t HAL_CAN_IsSleepActive(const CAN_HandleTypeDef *hcan) -{ - uint32_t status = 0U; - HAL_CAN_StateTypeDef state = hcan->State; - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check Sleep mode */ - if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U) - { - status = 1U; - } - } - - /* Return function status */ - return status; -} - -/** - * @brief Add a message to the first free Tx mailbox and activate the - * corresponding transmission request. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param pHeader pointer to a CAN_TxHeaderTypeDef structure. - * @param aData array containing the payload of the Tx frame. - * @param pTxMailbox pointer to a variable where the function will return - * the TxMailbox used to store the Tx message. - * This parameter can be a value of @arg CAN_Tx_Mailboxes. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, const CAN_TxHeaderTypeDef *pHeader, - const uint8_t aData[], uint32_t *pTxMailbox) -{ - uint32_t transmitmailbox; - HAL_CAN_StateTypeDef state = hcan->State; - uint32_t tsr = READ_REG(hcan->Instance->TSR); - - /* Check the parameters */ - assert_param(IS_CAN_IDTYPE(pHeader->IDE)); - assert_param(IS_CAN_RTR(pHeader->RTR)); - assert_param(IS_CAN_DLC(pHeader->DLC)); - if (pHeader->IDE == CAN_ID_STD) - { - assert_param(IS_CAN_STDID(pHeader->StdId)); - } - else - { - assert_param(IS_CAN_EXTID(pHeader->ExtId)); - } - assert_param(IS_FUNCTIONAL_STATE(pHeader->TransmitGlobalTime)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check that all the Tx mailboxes are not full */ - if (((tsr & CAN_TSR_TME0) != 0U) || - ((tsr & CAN_TSR_TME1) != 0U) || - ((tsr & CAN_TSR_TME2) != 0U)) - { - /* Select an empty transmit mailbox */ - transmitmailbox = (tsr & CAN_TSR_CODE) >> CAN_TSR_CODE_Pos; - - /* Store the Tx mailbox */ - *pTxMailbox = (uint32_t)1 << transmitmailbox; - - /* Set up the Id */ - if (pHeader->IDE == CAN_ID_STD) - { - hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->StdId << CAN_TI0R_STID_Pos) | - pHeader->RTR); - } - else - { - hcan->Instance->sTxMailBox[transmitmailbox].TIR = ((pHeader->ExtId << CAN_TI0R_EXID_Pos) | - pHeader->IDE | - pHeader->RTR); - } - - /* Set up the DLC */ - hcan->Instance->sTxMailBox[transmitmailbox].TDTR = (pHeader->DLC); - - /* Set up the Transmit Global Time mode */ - if (pHeader->TransmitGlobalTime == ENABLE) - { - SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TDTR, CAN_TDT0R_TGT); - } - - /* Set up the data field */ - WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDHR, - ((uint32_t)aData[7] << CAN_TDH0R_DATA7_Pos) | - ((uint32_t)aData[6] << CAN_TDH0R_DATA6_Pos) | - ((uint32_t)aData[5] << CAN_TDH0R_DATA5_Pos) | - ((uint32_t)aData[4] << CAN_TDH0R_DATA4_Pos)); - WRITE_REG(hcan->Instance->sTxMailBox[transmitmailbox].TDLR, - ((uint32_t)aData[3] << CAN_TDL0R_DATA3_Pos) | - ((uint32_t)aData[2] << CAN_TDL0R_DATA2_Pos) | - ((uint32_t)aData[1] << CAN_TDL0R_DATA1_Pos) | - ((uint32_t)aData[0] << CAN_TDL0R_DATA0_Pos)); - - /* Request transmission */ - SET_BIT(hcan->Instance->sTxMailBox[transmitmailbox].TIR, CAN_TI0R_TXRQ); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_PARAM; - - return HAL_ERROR; - } - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - return HAL_ERROR; - } -} - -/** - * @brief Abort transmission requests - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param TxMailboxes List of the Tx Mailboxes to abort. - * This parameter can be any combination of @arg CAN_Tx_Mailboxes. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_AbortTxRequest(CAN_HandleTypeDef *hcan, uint32_t TxMailboxes) -{ - HAL_CAN_StateTypeDef state = hcan->State; - - /* Check function parameters */ - assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check Tx Mailbox 0 */ - if ((TxMailboxes & CAN_TX_MAILBOX0) != 0U) - { - /* Add cancellation request for Tx Mailbox 0 */ - SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ0); - } - - /* Check Tx Mailbox 1 */ - if ((TxMailboxes & CAN_TX_MAILBOX1) != 0U) - { - /* Add cancellation request for Tx Mailbox 1 */ - SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ1); - } - - /* Check Tx Mailbox 2 */ - if ((TxMailboxes & CAN_TX_MAILBOX2) != 0U) - { - /* Add cancellation request for Tx Mailbox 2 */ - SET_BIT(hcan->Instance->TSR, CAN_TSR_ABRQ2); - } - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - return HAL_ERROR; - } -} - -/** - * @brief Return Tx Mailboxes free level: number of free Tx Mailboxes. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval Number of free Tx Mailboxes. - */ -uint32_t HAL_CAN_GetTxMailboxesFreeLevel(const CAN_HandleTypeDef *hcan) -{ - uint32_t freelevel = 0U; - HAL_CAN_StateTypeDef state = hcan->State; - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check Tx Mailbox 0 status */ - if ((hcan->Instance->TSR & CAN_TSR_TME0) != 0U) - { - freelevel++; - } - - /* Check Tx Mailbox 1 status */ - if ((hcan->Instance->TSR & CAN_TSR_TME1) != 0U) - { - freelevel++; - } - - /* Check Tx Mailbox 2 status */ - if ((hcan->Instance->TSR & CAN_TSR_TME2) != 0U) - { - freelevel++; - } - } - - /* Return Tx Mailboxes free level */ - return freelevel; -} - -/** - * @brief Check if a transmission request is pending on the selected Tx - * Mailboxes. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param TxMailboxes List of Tx Mailboxes to check. - * This parameter can be any combination of @arg CAN_Tx_Mailboxes. - * @retval Status - * - 0 : No pending transmission request on any selected Tx Mailboxes. - * - 1 : Pending transmission request on at least one of the selected - * Tx Mailbox. - */ -uint32_t HAL_CAN_IsTxMessagePending(const CAN_HandleTypeDef *hcan, uint32_t TxMailboxes) -{ - uint32_t status = 0U; - HAL_CAN_StateTypeDef state = hcan->State; - - /* Check function parameters */ - assert_param(IS_CAN_TX_MAILBOX_LIST(TxMailboxes)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check pending transmission request on the selected Tx Mailboxes */ - if ((hcan->Instance->TSR & (TxMailboxes << CAN_TSR_TME0_Pos)) != (TxMailboxes << CAN_TSR_TME0_Pos)) - { - status = 1U; - } - } - - /* Return status */ - return status; -} - -/** - * @brief Return timestamp of Tx message sent, if time triggered communication - mode is enabled. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param TxMailbox Tx Mailbox where the timestamp of message sent will be - * read. - * This parameter can be one value of @arg CAN_Tx_Mailboxes. - * @retval Timestamp of message sent from Tx Mailbox. - */ -uint32_t HAL_CAN_GetTxTimestamp(const CAN_HandleTypeDef *hcan, uint32_t TxMailbox) -{ - uint32_t timestamp = 0U; - uint32_t transmitmailbox; - HAL_CAN_StateTypeDef state = hcan->State; - - /* Check function parameters */ - assert_param(IS_CAN_TX_MAILBOX(TxMailbox)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Select the Tx mailbox */ - transmitmailbox = POSITION_VAL(TxMailbox); - - /* Get timestamp */ - timestamp = (hcan->Instance->sTxMailBox[transmitmailbox].TDTR & CAN_TDT0R_TIME) >> CAN_TDT0R_TIME_Pos; - } - - /* Return the timestamp */ - return timestamp; -} - -/** - * @brief Get an CAN frame from the Rx FIFO zone into the message RAM. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param RxFifo Fifo number of the received message to be read. - * This parameter can be a value of @arg CAN_receive_FIFO_number. - * @param pHeader pointer to a CAN_RxHeaderTypeDef structure where the header - * of the Rx frame will be stored. - * @param aData array where the payload of the Rx frame will be stored. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_GetRxMessage(CAN_HandleTypeDef *hcan, uint32_t RxFifo, - CAN_RxHeaderTypeDef *pHeader, uint8_t aData[]) -{ - HAL_CAN_StateTypeDef state = hcan->State; - - assert_param(IS_CAN_RX_FIFO(RxFifo)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check the Rx FIFO */ - if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */ - { - /* Check that the Rx FIFO 0 is not empty */ - if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) == 0U) - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_PARAM; - - return HAL_ERROR; - } - } - else /* Rx element is assigned to Rx FIFO 1 */ - { - /* Check that the Rx FIFO 1 is not empty */ - if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) == 0U) - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_PARAM; - - return HAL_ERROR; - } - } - - /* Get the header */ - pHeader->IDE = CAN_RI0R_IDE & hcan->Instance->sFIFOMailBox[RxFifo].RIR; - if (pHeader->IDE == CAN_ID_STD) - { - pHeader->StdId = (CAN_RI0R_STID & hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_TI0R_STID_Pos; - } - else - { - pHeader->ExtId = ((CAN_RI0R_EXID | CAN_RI0R_STID) & - hcan->Instance->sFIFOMailBox[RxFifo].RIR) >> CAN_RI0R_EXID_Pos; - } - pHeader->RTR = (CAN_RI0R_RTR & hcan->Instance->sFIFOMailBox[RxFifo].RIR); - if (((CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos) >= 8U) - { - /* Truncate DLC to 8 if received field is over range */ - pHeader->DLC = 8U; - } - else - { - pHeader->DLC = (CAN_RDT0R_DLC & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_DLC_Pos; - } - pHeader->FilterMatchIndex = (CAN_RDT0R_FMI & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_FMI_Pos; - pHeader->Timestamp = (CAN_RDT0R_TIME & hcan->Instance->sFIFOMailBox[RxFifo].RDTR) >> CAN_RDT0R_TIME_Pos; - - /* Get the data */ - aData[0] = (uint8_t)((CAN_RDL0R_DATA0 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA0_Pos); - aData[1] = (uint8_t)((CAN_RDL0R_DATA1 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA1_Pos); - aData[2] = (uint8_t)((CAN_RDL0R_DATA2 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA2_Pos); - aData[3] = (uint8_t)((CAN_RDL0R_DATA3 & hcan->Instance->sFIFOMailBox[RxFifo].RDLR) >> CAN_RDL0R_DATA3_Pos); - aData[4] = (uint8_t)((CAN_RDH0R_DATA4 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA4_Pos); - aData[5] = (uint8_t)((CAN_RDH0R_DATA5 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA5_Pos); - aData[6] = (uint8_t)((CAN_RDH0R_DATA6 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA6_Pos); - aData[7] = (uint8_t)((CAN_RDH0R_DATA7 & hcan->Instance->sFIFOMailBox[RxFifo].RDHR) >> CAN_RDH0R_DATA7_Pos); - - /* Release the FIFO */ - if (RxFifo == CAN_RX_FIFO0) /* Rx element is assigned to Rx FIFO 0 */ - { - /* Release RX FIFO 0 */ - SET_BIT(hcan->Instance->RF0R, CAN_RF0R_RFOM0); - } - else /* Rx element is assigned to Rx FIFO 1 */ - { - /* Release RX FIFO 1 */ - SET_BIT(hcan->Instance->RF1R, CAN_RF1R_RFOM1); - } - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - return HAL_ERROR; - } -} - -/** - * @brief Return Rx FIFO fill level. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param RxFifo Rx FIFO. - * This parameter can be a value of @arg CAN_receive_FIFO_number. - * @retval Number of messages available in Rx FIFO. - */ -uint32_t HAL_CAN_GetRxFifoFillLevel(const CAN_HandleTypeDef *hcan, uint32_t RxFifo) -{ - uint32_t filllevel = 0U; - HAL_CAN_StateTypeDef state = hcan->State; - - /* Check function parameters */ - assert_param(IS_CAN_RX_FIFO(RxFifo)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - if (RxFifo == CAN_RX_FIFO0) - { - filllevel = hcan->Instance->RF0R & CAN_RF0R_FMP0; - } - else /* RxFifo == CAN_RX_FIFO1 */ - { - filllevel = hcan->Instance->RF1R & CAN_RF1R_FMP1; - } - } - - /* Return Rx FIFO fill level */ - return filllevel; -} - -/** - * @} - */ - -/** @defgroup CAN_Exported_Functions_Group4 Interrupts management - * @brief Interrupts management - * -@verbatim - ============================================================================== - ##### Interrupts management ##### - ============================================================================== - [..] This section provides functions allowing to: - (+) HAL_CAN_ActivateNotification : Enable interrupts - (+) HAL_CAN_DeactivateNotification : Disable interrupts - (+) HAL_CAN_IRQHandler : Handles CAN interrupt request - -@endverbatim - * @{ - */ - -/** - * @brief Enable interrupts. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param ActiveITs indicates which interrupts will be enabled. - * This parameter can be any combination of @arg CAN_Interrupts. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_ActivateNotification(CAN_HandleTypeDef *hcan, uint32_t ActiveITs) -{ - HAL_CAN_StateTypeDef state = hcan->State; - - /* Check function parameters */ - assert_param(IS_CAN_IT(ActiveITs)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Enable the selected interrupts */ - __HAL_CAN_ENABLE_IT(hcan, ActiveITs); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - return HAL_ERROR; - } -} - -/** - * @brief Disable interrupts. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @param InactiveITs indicates which interrupts will be disabled. - * This parameter can be any combination of @arg CAN_Interrupts. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_DeactivateNotification(CAN_HandleTypeDef *hcan, uint32_t InactiveITs) -{ - HAL_CAN_StateTypeDef state = hcan->State; - - /* Check function parameters */ - assert_param(IS_CAN_IT(InactiveITs)); - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Disable the selected interrupts */ - __HAL_CAN_DISABLE_IT(hcan, InactiveITs); - - /* Return function status */ - return HAL_OK; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - return HAL_ERROR; - } -} - -/** - * @brief Handles CAN interrupt request - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -void HAL_CAN_IRQHandler(CAN_HandleTypeDef *hcan) -{ - uint32_t errorcode = HAL_CAN_ERROR_NONE; - uint32_t interrupts = READ_REG(hcan->Instance->IER); - uint32_t msrflags = READ_REG(hcan->Instance->MSR); - uint32_t tsrflags = READ_REG(hcan->Instance->TSR); - uint32_t rf0rflags = READ_REG(hcan->Instance->RF0R); - uint32_t rf1rflags = READ_REG(hcan->Instance->RF1R); - uint32_t esrflags = READ_REG(hcan->Instance->ESR); - - /* Transmit Mailbox empty interrupt management *****************************/ - if ((interrupts & CAN_IT_TX_MAILBOX_EMPTY) != 0U) - { - /* Transmit Mailbox 0 management *****************************************/ - if ((tsrflags & CAN_TSR_RQCP0) != 0U) - { - /* Clear the Transmission Complete flag (and TXOK0,ALST0,TERR0 bits) */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP0); - - if ((tsrflags & CAN_TSR_TXOK0) != 0U) - { - /* Transmission Mailbox 0 complete callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->TxMailbox0CompleteCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_TxMailbox0CompleteCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - else - { - if ((tsrflags & CAN_TSR_ALST0) != 0U) - { - /* Update error code */ - errorcode |= HAL_CAN_ERROR_TX_ALST0; - } - else if ((tsrflags & CAN_TSR_TERR0) != 0U) - { - /* Update error code */ - errorcode |= HAL_CAN_ERROR_TX_TERR0; - } - else - { - /* Transmission Mailbox 0 abort callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->TxMailbox0AbortCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_TxMailbox0AbortCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - } - - /* Transmit Mailbox 1 management *****************************************/ - if ((tsrflags & CAN_TSR_RQCP1) != 0U) - { - /* Clear the Transmission Complete flag (and TXOK1,ALST1,TERR1 bits) */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP1); - - if ((tsrflags & CAN_TSR_TXOK1) != 0U) - { - /* Transmission Mailbox 1 complete callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->TxMailbox1CompleteCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_TxMailbox1CompleteCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - else - { - if ((tsrflags & CAN_TSR_ALST1) != 0U) - { - /* Update error code */ - errorcode |= HAL_CAN_ERROR_TX_ALST1; - } - else if ((tsrflags & CAN_TSR_TERR1) != 0U) - { - /* Update error code */ - errorcode |= HAL_CAN_ERROR_TX_TERR1; - } - else - { - /* Transmission Mailbox 1 abort callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->TxMailbox1AbortCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_TxMailbox1AbortCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - } - - /* Transmit Mailbox 2 management *****************************************/ - if ((tsrflags & CAN_TSR_RQCP2) != 0U) - { - /* Clear the Transmission Complete flag (and TXOK2,ALST2,TERR2 bits) */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_RQCP2); - - if ((tsrflags & CAN_TSR_TXOK2) != 0U) - { - /* Transmission Mailbox 2 complete callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->TxMailbox2CompleteCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_TxMailbox2CompleteCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - else - { - if ((tsrflags & CAN_TSR_ALST2) != 0U) - { - /* Update error code */ - errorcode |= HAL_CAN_ERROR_TX_ALST2; - } - else if ((tsrflags & CAN_TSR_TERR2) != 0U) - { - /* Update error code */ - errorcode |= HAL_CAN_ERROR_TX_TERR2; - } - else - { - /* Transmission Mailbox 2 abort callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->TxMailbox2AbortCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_TxMailbox2AbortCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - } - } - - /* Receive FIFO 0 overrun interrupt management *****************************/ - if ((interrupts & CAN_IT_RX_FIFO0_OVERRUN) != 0U) - { - if ((rf0rflags & CAN_RF0R_FOVR0) != 0U) - { - /* Set CAN error code to Rx Fifo 0 overrun error */ - errorcode |= HAL_CAN_ERROR_RX_FOV0; - - /* Clear FIFO0 Overrun Flag */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV0); - } - } - - /* Receive FIFO 0 full interrupt management ********************************/ - if ((interrupts & CAN_IT_RX_FIFO0_FULL) != 0U) - { - if ((rf0rflags & CAN_RF0R_FULL0) != 0U) - { - /* Clear FIFO 0 full Flag */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF0); - - /* Receive FIFO 0 full Callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->RxFifo0FullCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_RxFifo0FullCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - - /* Receive FIFO 0 message pending interrupt management *********************/ - if ((interrupts & CAN_IT_RX_FIFO0_MSG_PENDING) != 0U) - { - /* Check if message is still pending */ - if ((hcan->Instance->RF0R & CAN_RF0R_FMP0) != 0U) - { - /* Receive FIFO 0 message pending Callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->RxFifo0MsgPendingCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_RxFifo0MsgPendingCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - - /* Receive FIFO 1 overrun interrupt management *****************************/ - if ((interrupts & CAN_IT_RX_FIFO1_OVERRUN) != 0U) - { - if ((rf1rflags & CAN_RF1R_FOVR1) != 0U) - { - /* Set CAN error code to Rx Fifo 1 overrun error */ - errorcode |= HAL_CAN_ERROR_RX_FOV1; - - /* Clear FIFO1 Overrun Flag */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FOV1); - } - } - - /* Receive FIFO 1 full interrupt management ********************************/ - if ((interrupts & CAN_IT_RX_FIFO1_FULL) != 0U) - { - if ((rf1rflags & CAN_RF1R_FULL1) != 0U) - { - /* Clear FIFO 1 full Flag */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_FF1); - - /* Receive FIFO 1 full Callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->RxFifo1FullCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_RxFifo1FullCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - - /* Receive FIFO 1 message pending interrupt management *********************/ - if ((interrupts & CAN_IT_RX_FIFO1_MSG_PENDING) != 0U) - { - /* Check if message is still pending */ - if ((hcan->Instance->RF1R & CAN_RF1R_FMP1) != 0U) - { - /* Receive FIFO 1 message pending Callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->RxFifo1MsgPendingCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_RxFifo1MsgPendingCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - - /* Sleep interrupt management *********************************************/ - if ((interrupts & CAN_IT_SLEEP_ACK) != 0U) - { - if ((msrflags & CAN_MSR_SLAKI) != 0U) - { - /* Clear Sleep interrupt Flag */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_SLAKI); - - /* Sleep Callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->SleepCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_SleepCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - - /* WakeUp interrupt management *********************************************/ - if ((interrupts & CAN_IT_WAKEUP) != 0U) - { - if ((msrflags & CAN_MSR_WKUI) != 0U) - { - /* Clear WakeUp Flag */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_WKU); - - /* WakeUp Callback */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->WakeUpFromRxMsgCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_WakeUpFromRxMsgCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } - } - - /* Error interrupts management *********************************************/ - if ((interrupts & CAN_IT_ERROR) != 0U) - { - if ((msrflags & CAN_MSR_ERRI) != 0U) - { - /* Check Error Warning Flag */ - if (((interrupts & CAN_IT_ERROR_WARNING) != 0U) && - ((esrflags & CAN_ESR_EWGF) != 0U)) - { - /* Set CAN error code to Error Warning */ - errorcode |= HAL_CAN_ERROR_EWG; - - /* No need for clear of Error Warning Flag as read-only */ - } - - /* Check Error Passive Flag */ - if (((interrupts & CAN_IT_ERROR_PASSIVE) != 0U) && - ((esrflags & CAN_ESR_EPVF) != 0U)) - { - /* Set CAN error code to Error Passive */ - errorcode |= HAL_CAN_ERROR_EPV; - - /* No need for clear of Error Passive Flag as read-only */ - } - - /* Check Bus-off Flag */ - if (((interrupts & CAN_IT_BUSOFF) != 0U) && - ((esrflags & CAN_ESR_BOFF) != 0U)) - { - /* Set CAN error code to Bus-Off */ - errorcode |= HAL_CAN_ERROR_BOF; - - /* No need for clear of Error Bus-Off as read-only */ - } - - /* Check Last Error Code Flag */ - if (((interrupts & CAN_IT_LAST_ERROR_CODE) != 0U) && - ((esrflags & CAN_ESR_LEC) != 0U)) - { - switch (esrflags & CAN_ESR_LEC) - { - case (CAN_ESR_LEC_0): - /* Set CAN error code to Stuff error */ - errorcode |= HAL_CAN_ERROR_STF; - break; - case (CAN_ESR_LEC_1): - /* Set CAN error code to Form error */ - errorcode |= HAL_CAN_ERROR_FOR; - break; - case (CAN_ESR_LEC_1 | CAN_ESR_LEC_0): - /* Set CAN error code to Acknowledgement error */ - errorcode |= HAL_CAN_ERROR_ACK; - break; - case (CAN_ESR_LEC_2): - /* Set CAN error code to Bit recessive error */ - errorcode |= HAL_CAN_ERROR_BR; - break; - case (CAN_ESR_LEC_2 | CAN_ESR_LEC_0): - /* Set CAN error code to Bit Dominant error */ - errorcode |= HAL_CAN_ERROR_BD; - break; - case (CAN_ESR_LEC_2 | CAN_ESR_LEC_1): - /* Set CAN error code to CRC error */ - errorcode |= HAL_CAN_ERROR_CRC; - break; - default: - break; - } - - /* Clear Last error code Flag */ - CLEAR_BIT(hcan->Instance->ESR, CAN_ESR_LEC); - } - } - - /* Clear ERRI Flag */ - __HAL_CAN_CLEAR_FLAG(hcan, CAN_FLAG_ERRI); - } - - /* Call the Error call Back in case of Errors */ - if (errorcode != HAL_CAN_ERROR_NONE) - { - /* Update error code in handle */ - hcan->ErrorCode |= errorcode; - - /* Call Error callback function */ -#if USE_HAL_CAN_REGISTER_CALLBACKS == 1 - /* Call registered callback*/ - hcan->ErrorCallback(hcan); -#else - /* Call weak (surcharged) callback */ - HAL_CAN_ErrorCallback(hcan); -#endif /* USE_HAL_CAN_REGISTER_CALLBACKS */ - } -} - -/** - * @} - */ - -/** @defgroup CAN_Exported_Functions_Group5 Callback functions - * @brief CAN Callback functions - * -@verbatim - ============================================================================== - ##### Callback functions ##### - ============================================================================== - [..] - This subsection provides the following callback functions: - (+) HAL_CAN_TxMailbox0CompleteCallback - (+) HAL_CAN_TxMailbox1CompleteCallback - (+) HAL_CAN_TxMailbox2CompleteCallback - (+) HAL_CAN_TxMailbox0AbortCallback - (+) HAL_CAN_TxMailbox1AbortCallback - (+) HAL_CAN_TxMailbox2AbortCallback - (+) HAL_CAN_RxFifo0MsgPendingCallback - (+) HAL_CAN_RxFifo0FullCallback - (+) HAL_CAN_RxFifo1MsgPendingCallback - (+) HAL_CAN_RxFifo1FullCallback - (+) HAL_CAN_SleepCallback - (+) HAL_CAN_WakeUpFromRxMsgCallback - (+) HAL_CAN_ErrorCallback - -@endverbatim - * @{ - */ - -/** - * @brief Transmission Mailbox 0 complete callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_TxMailbox0CompleteCallback could be implemented in the - user file - */ -} - -/** - * @brief Transmission Mailbox 1 complete callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_TxMailbox1CompleteCallback could be implemented in the - user file - */ -} - -/** - * @brief Transmission Mailbox 2 complete callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_TxMailbox2CompleteCallback could be implemented in the - user file - */ -} - -/** - * @brief Transmission Mailbox 0 Cancellation callback. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_TxMailbox0AbortCallback could be implemented in the - user file - */ -} - -/** - * @brief Transmission Mailbox 1 Cancellation callback. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_TxMailbox1AbortCallback could be implemented in the - user file - */ -} - -/** - * @brief Transmission Mailbox 2 Cancellation callback. - * @param hcan pointer to an CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_TxMailbox2AbortCallback could be implemented in the - user file - */ -} - -/** - * @brief Rx FIFO 0 message pending callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_RxFifo0MsgPendingCallback could be implemented in the - user file - */ -} - -/** - * @brief Rx FIFO 0 full callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_RxFifo0FullCallback could be implemented in the user - file - */ -} - -/** - * @brief Rx FIFO 1 message pending callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the - user file - */ -} - -/** - * @brief Rx FIFO 1 full callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_RxFifo1FullCallback could be implemented in the user - file - */ -} - -/** - * @brief Sleep callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_SleepCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_SleepCallback could be implemented in the user file - */ -} - -/** - * @brief WakeUp from Rx message callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_WakeUpFromRxMsgCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_WakeUpFromRxMsgCallback could be implemented in the - user file - */ -} - -/** - * @brief Error CAN callback. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval None - */ -__weak void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hcan); - - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_CAN_ErrorCallback could be implemented in the user file - */ -} - -/** - * @} - */ - -/** @defgroup CAN_Exported_Functions_Group6 Peripheral State and Error functions - * @brief CAN Peripheral State functions - * -@verbatim - ============================================================================== - ##### Peripheral State and Error functions ##### - ============================================================================== - [..] - This subsection provides functions allowing to : - (+) HAL_CAN_GetState() : Return the CAN state. - (+) HAL_CAN_GetError() : Return the CAN error codes if any. - (+) HAL_CAN_ResetError(): Reset the CAN error codes if any. - -@endverbatim - * @{ - */ - -/** - * @brief Return the CAN state. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL state - */ -HAL_CAN_StateTypeDef HAL_CAN_GetState(const CAN_HandleTypeDef *hcan) -{ - HAL_CAN_StateTypeDef state = hcan->State; - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Check sleep mode acknowledge flag */ - if ((hcan->Instance->MSR & CAN_MSR_SLAK) != 0U) - { - /* Sleep mode is active */ - state = HAL_CAN_STATE_SLEEP_ACTIVE; - } - /* Check sleep mode request flag */ - else if ((hcan->Instance->MCR & CAN_MCR_SLEEP) != 0U) - { - /* Sleep mode request is pending */ - state = HAL_CAN_STATE_SLEEP_PENDING; - } - else - { - /* Neither sleep mode request nor sleep mode acknowledge */ - } - } - - /* Return CAN state */ - return state; -} - -/** - * @brief Return the CAN error code. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval CAN Error Code - */ -uint32_t HAL_CAN_GetError(const CAN_HandleTypeDef *hcan) -{ - /* Return CAN error code */ - return hcan->ErrorCode; -} - -/** - * @brief Reset the CAN error code. - * @param hcan pointer to a CAN_HandleTypeDef structure that contains - * the configuration information for the specified CAN. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_CAN_ResetError(CAN_HandleTypeDef *hcan) -{ - HAL_StatusTypeDef status = HAL_OK; - HAL_CAN_StateTypeDef state = hcan->State; - - if ((state == HAL_CAN_STATE_READY) || - (state == HAL_CAN_STATE_LISTENING)) - { - /* Reset CAN error code */ - hcan->ErrorCode = 0U; - } - else - { - /* Update error code */ - hcan->ErrorCode |= HAL_CAN_ERROR_NOT_INITIALIZED; - - status = HAL_ERROR; - } - - /* Return the status */ - return status; -} - -/** - * @} - */ - -/** - * @} - */ - -#endif /* HAL_CAN_MODULE_ENABLED */ - -/** - * @} - */ - -#endif /* CAN1 */ - -/** - * @} - */ diff --git a/Mcu/l431/Inc/blutil.h b/Mcu/l431/Inc/blutil.h new file mode 100644 index 00000000..56491cee --- /dev/null +++ b/Mcu/l431/Inc/blutil.h @@ -0,0 +1,135 @@ +/* + MCU specific utility functions for the bootloader + */ +#pragma once + +#define GPIO_PIN(n) (1U<<(n)) + +#define GPIO_PULL_NONE LL_GPIO_PULL_NO +#define GPIO_PULL_UP LL_GPIO_PULL_UP +#define GPIO_PULL_DOWN LL_GPIO_PULL_DOWN + +#define GPIO_OUTPUT_PUSH_PULL LL_GPIO_OUTPUT_PUSHPULL + +static inline void gpio_mode_set_input(uint32_t pin, uint32_t pull_up_down) +{ + LL_GPIO_SetPinMode(input_port, pin, LL_GPIO_MODE_INPUT); + LL_GPIO_SetPinPull(input_port, pin, pull_up_down); +} + +static inline void gpio_mode_set_output(uint32_t pin, uint32_t output_mode) +{ + LL_GPIO_SetPinMode(input_port, pin, LL_GPIO_MODE_OUTPUT); + LL_GPIO_SetPinOutputType(input_port, pin, output_mode); +} + +static inline void gpio_set(uint32_t pin) +{ + LL_GPIO_SetOutputPin(input_port, pin); +} + +static inline void gpio_clear(uint32_t pin) +{ + LL_GPIO_ResetOutputPin(input_port, pin); +} + +static inline bool gpio_read(uint32_t pin) +{ + return LL_GPIO_IsInputPinSet(input_port, pin); +} + +#define BL_TIMER TIM2 + +/* + initialise timer for 1us per tick + */ +static inline void bl_timer_init(void) +{ + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + + TIM_InitStruct.Prescaler = 79; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 0xFFFFFFFF; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(BL_TIMER, &TIM_InitStruct); + LL_TIM_DisableARRPreload(BL_TIMER); + LL_TIM_SetClockSource(BL_TIMER, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_SetTriggerOutput(BL_TIMER, LL_TIM_TRGO_RESET); + LL_TIM_DisableMasterSlaveMode(BL_TIMER); + + LL_TIM_SetCounterMode(BL_TIMER, LL_TIM_COUNTERMODE_UP); + LL_TIM_EnableCounter(BL_TIMER); +} + +/* + disable timer ready for app start + */ +static inline void bl_timer_disable(void) +{ + LL_TIM_DeInit(BL_TIMER); +} + +static inline uint32_t bl_timer_us(void) +{ + return LL_TIM_GetCounter(BL_TIMER); +} + +static inline void bl_timer_reset(void) +{ + LL_TIM_SetCounter(BL_TIMER, 0); +} + +/* + initialise clocks + */ +static inline void bl_clock_config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); + while (LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_4) ; + LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); + while (LL_PWR_IsActiveFlag_VOS() != 0) ; + LL_RCC_MSI_Enable(); + + /* Wait till MSI is ready */ + while (LL_RCC_MSI_IsReady() != 1) ; + + LL_RCC_MSI_EnableRangeSelection(); + LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6); + LL_RCC_MSI_SetCalibTrimming(0); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_EnableDomain_SYS(); + LL_RCC_PLL_Enable(); + + /* Wait till PLL is ready */ + while (LL_RCC_PLL_IsReady() != 1) ; + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + + /* Wait till System clock is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) ; + + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); +} + +static inline void bl_gpio_init(void) +{ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_GPIO_ResetOutputPin(input_port, input_pin); +} + +/* + return true if the MCU booted under a software reset + */ +static inline bool bl_was_software_reset(void) +{ + return (RCC->CSR & RCC_CSR_SFTRSTF) != 0; +} + +void Error_Handler() +{ + while (1) {} +} diff --git a/Mcu/l431/STM32L431KCUX_FLASH.ld b/Mcu/l431/STM32L431KCUX_FLASH.ld new file mode 100644 index 00000000..9bbaf3c0 --- /dev/null +++ b/Mcu/l431/STM32L431KCUX_FLASH.ld @@ -0,0 +1,187 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** @brief : Linker script for STM32L431KCUx Device from STM32L4 series +** 256KBytes FLASH +** 64KBytes RAM +** 16KBytes RAM2 +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2024 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K + RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 16K + FLASH (rx) : ORIGIN = 0x8001000, LENGTH = 128K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/Mcu/l431/Src/stm32l4xx_it.c b/Mcu/l431/Src/stm32l4xx_it.c index 8826afae..6878b750 100644 --- a/Mcu/l431/Src/stm32l4xx_it.c +++ b/Mcu/l431/Src/stm32l4xx_it.c @@ -21,8 +21,10 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32l4xx_it.h" +#ifndef BOOTLOADER #include "ADC.h" #include "targets.h" +#endif //#include "WS2812.h" @@ -174,6 +176,7 @@ void SysTick_Handler(void) /* please refer to the startup file (startup_stm32l4xx.s). */ /******************************************************************************/ +#ifndef BOOTLOADER /** * @brief This function handles DMA1 channel4 global interrupt. */ @@ -287,3 +290,5 @@ void COMP_IRQHandler(void) } } +#endif // BOOTLOADER + diff --git a/Mcu/l431/Startup/startup_stm32l431xx.s b/Mcu/l431/Startup/startup_stm32l431xx.s index 090101df..f652136e 100644 --- a/Mcu/l431/Startup/startup_stm32l431xx.s +++ b/Mcu/l431/Startup/startup_stm32l431xx.s @@ -1,389 +1,461 @@ -;******************************************************************************* -;* File Name : startup_stm32l431xx.s -;* Author : MCD Application Team -;* Description : STM32L431xx Ultra Low Power devices vector table for MDK-ARM toolchain. -;* This module performs: -;* - Set the initial SP -;* - Set the initial PC == Reset_Handler -;* - Set the vector table entries with the exceptions ISR address -;* - Branches to __main in the C library (which eventually -;* calls main()). -;* After Reset the Cortex-M4 processor is in Thread mode, -;* priority is Privileged, and the Stack is set to Main. -;******************************************************************************** -;* @attention -;* -;* Copyright (c) 2017 STMicroelectronics. -;* All rights reserved. -;* -;* This software is licensed under terms that can be found in the LICENSE file -;* in the root directory of this software component. -;* If no LICENSE file comes with this software, it is provided AS-IS. -; -;******************************************************************************* -;* <<< Use Configuration Wizard in Context Menu >>> -; Amount of memory (in bytes) allocated for Stack -; Tailor this value to your application needs -; Stack Configuration -; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Stack_Size EQU 0x400 - - AREA STACK, NOINIT, READWRITE, ALIGN=3 -Stack_Mem SPACE Stack_Size -__initial_sp - - -; Heap Configuration -; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> -; - -Heap_Size EQU 0x200 - - AREA HEAP, NOINIT, READWRITE, ALIGN=3 -__heap_base -Heap_Mem SPACE Heap_Size -__heap_limit - - PRESERVE8 - THUMB - - -; Vector Table Mapped to Address 0 at Reset - AREA RESET, DATA, READONLY - EXPORT __Vectors - EXPORT __Vectors_End - EXPORT __Vectors_Size - -__Vectors DCD __initial_sp ; Top of Stack - DCD Reset_Handler ; Reset Handler - DCD NMI_Handler ; NMI Handler - DCD HardFault_Handler ; Hard Fault Handler - DCD MemManage_Handler ; MPU Fault Handler - DCD BusFault_Handler ; Bus Fault Handler - DCD UsageFault_Handler ; Usage Fault Handler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD SVC_Handler ; SVCall Handler - DCD DebugMon_Handler ; Debug Monitor Handler - DCD 0 ; Reserved - DCD PendSV_Handler ; PendSV Handler - DCD SysTick_Handler ; SysTick Handler - - ; External Interrupts - DCD WWDG_IRQHandler ; Window WatchDog - DCD PVD_PVM_IRQHandler ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection - DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line - DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line - DCD FLASH_IRQHandler ; FLASH - DCD RCC_IRQHandler ; RCC - DCD EXTI0_IRQHandler ; EXTI Line0 - DCD EXTI1_IRQHandler ; EXTI Line1 - DCD EXTI2_IRQHandler ; EXTI Line2 - DCD EXTI3_IRQHandler ; EXTI Line3 - DCD EXTI4_IRQHandler ; EXTI Line4 - DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1 - DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2 - DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3 - DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4 - DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5 - DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6 - DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7 - DCD ADC1_IRQHandler ; ADC1 - DCD CAN1_TX_IRQHandler ; CAN1 TX - DCD CAN1_RX0_IRQHandler ; CAN1 RX0 - DCD CAN1_RX1_IRQHandler ; CAN1 RX1 - DCD CAN1_SCE_IRQHandler ; CAN1 SCE - DCD EXTI9_5_IRQHandler ; External Line[9:5]s - DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15 - DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16 - DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation - DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare - DCD TIM2_IRQHandler ; TIM2 - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD I2C1_EV_IRQHandler ; I2C1 Event - DCD I2C1_ER_IRQHandler ; I2C1 Error - DCD I2C2_EV_IRQHandler ; I2C2 Event - DCD I2C2_ER_IRQHandler ; I2C2 Error - DCD SPI1_IRQHandler ; SPI1 - DCD SPI2_IRQHandler ; SPI2 - DCD USART1_IRQHandler ; USART1 - DCD USART2_IRQHandler ; USART2 - DCD USART3_IRQHandler ; USART3 - DCD EXTI15_10_IRQHandler ; External Line[15:10] - DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD SDMMC1_IRQHandler ; SDMMC1 - DCD 0 ; Reserved - DCD SPI3_IRQHandler ; SPI3 - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors - DCD TIM7_IRQHandler ; TIM7 - DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1 - DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2 - DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3 - DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4 - DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5 - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD COMP_IRQHandler ; COMP Interrupt - DCD LPTIM1_IRQHandler ; LP TIM1 interrupt - DCD LPTIM2_IRQHandler ; LP TIM2 interrupt - DCD 0 ; Reserved - DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6 - DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7 - DCD LPUART1_IRQHandler ; LP UART1 interrupt - DCD QUADSPI_IRQHandler ; Quad SPI global interrupt - DCD I2C3_EV_IRQHandler ; I2C3 event - DCD I2C3_ER_IRQHandler ; I2C3 error - DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt - DCD 0 ; Reserved - DCD SWPMI1_IRQHandler ; Serial Wire Interface 1 global interrupt - DCD TSC_IRQHandler ; Touch Sense Controller global interrupt - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD RNG_IRQHandler ; RNG global interrupt - DCD FPU_IRQHandler ; FPU - DCD CRS_IRQHandler ; CRS interrupt - -__Vectors_End - -__Vectors_Size EQU __Vectors_End - __Vectors - - AREA |.text|, CODE, READONLY - -; Reset handler -Reset_Handler PROC - EXPORT Reset_Handler [WEAK] - IMPORT SystemInit - IMPORT __main - - LDR R0, =SystemInit - BLX R0 - LDR R0, =__main - BX R0 - ENDP - -; Dummy Exception Handlers (infinite loops which can be modified) - -NMI_Handler PROC - EXPORT NMI_Handler [WEAK] - B . - ENDP -HardFault_Handler\ - PROC - EXPORT HardFault_Handler [WEAK] - B . - ENDP -MemManage_Handler\ - PROC - EXPORT MemManage_Handler [WEAK] - B . - ENDP -BusFault_Handler\ - PROC - EXPORT BusFault_Handler [WEAK] - B . - ENDP -UsageFault_Handler\ - PROC - EXPORT UsageFault_Handler [WEAK] - B . - ENDP -SVC_Handler PROC - EXPORT SVC_Handler [WEAK] - B . - ENDP -DebugMon_Handler\ - PROC - EXPORT DebugMon_Handler [WEAK] - B . - ENDP -PendSV_Handler PROC - EXPORT PendSV_Handler [WEAK] - B . - ENDP -SysTick_Handler PROC - EXPORT SysTick_Handler [WEAK] - B . - ENDP - -Default_Handler PROC - - EXPORT WWDG_IRQHandler [WEAK] - EXPORT PVD_PVM_IRQHandler [WEAK] - EXPORT TAMP_STAMP_IRQHandler [WEAK] - EXPORT RTC_WKUP_IRQHandler [WEAK] - EXPORT FLASH_IRQHandler [WEAK] - EXPORT RCC_IRQHandler [WEAK] - EXPORT EXTI0_IRQHandler [WEAK] - EXPORT EXTI1_IRQHandler [WEAK] - EXPORT EXTI2_IRQHandler [WEAK] - EXPORT EXTI3_IRQHandler [WEAK] - EXPORT EXTI4_IRQHandler [WEAK] - EXPORT DMA1_Channel1_IRQHandler [WEAK] - EXPORT DMA1_Channel2_IRQHandler [WEAK] - EXPORT DMA1_Channel3_IRQHandler [WEAK] - EXPORT DMA1_Channel4_IRQHandler [WEAK] - EXPORT DMA1_Channel5_IRQHandler [WEAK] - EXPORT DMA1_Channel6_IRQHandler [WEAK] - EXPORT DMA1_Channel7_IRQHandler [WEAK] - EXPORT ADC1_IRQHandler [WEAK] - EXPORT CAN1_TX_IRQHandler [WEAK] - EXPORT CAN1_RX0_IRQHandler [WEAK] - EXPORT CAN1_RX1_IRQHandler [WEAK] - EXPORT CAN1_SCE_IRQHandler [WEAK] - EXPORT EXTI9_5_IRQHandler [WEAK] - EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK] - EXPORT TIM1_UP_TIM16_IRQHandler [WEAK] - EXPORT TIM1_TRG_COM_IRQHandler [WEAK] - EXPORT TIM1_CC_IRQHandler [WEAK] - EXPORT TIM2_IRQHandler [WEAK] - EXPORT I2C1_EV_IRQHandler [WEAK] - EXPORT I2C1_ER_IRQHandler [WEAK] - EXPORT I2C2_EV_IRQHandler [WEAK] - EXPORT I2C2_ER_IRQHandler [WEAK] - EXPORT SPI1_IRQHandler [WEAK] - EXPORT SPI2_IRQHandler [WEAK] - EXPORT USART1_IRQHandler [WEAK] - EXPORT USART2_IRQHandler [WEAK] - EXPORT USART3_IRQHandler [WEAK] - EXPORT EXTI15_10_IRQHandler [WEAK] - EXPORT RTC_Alarm_IRQHandler [WEAK] - EXPORT SDMMC1_IRQHandler [WEAK] - EXPORT SPI3_IRQHandler [WEAK] - EXPORT TIM6_DAC_IRQHandler [WEAK] - EXPORT TIM7_IRQHandler [WEAK] - EXPORT DMA2_Channel1_IRQHandler [WEAK] - EXPORT DMA2_Channel2_IRQHandler [WEAK] - EXPORT DMA2_Channel3_IRQHandler [WEAK] - EXPORT DMA2_Channel4_IRQHandler [WEAK] - EXPORT DMA2_Channel5_IRQHandler [WEAK] - EXPORT COMP_IRQHandler [WEAK] - EXPORT LPTIM1_IRQHandler [WEAK] - EXPORT LPTIM2_IRQHandler [WEAK] - EXPORT DMA2_Channel6_IRQHandler [WEAK] - EXPORT DMA2_Channel7_IRQHandler [WEAK] - EXPORT LPUART1_IRQHandler [WEAK] - EXPORT QUADSPI_IRQHandler [WEAK] - EXPORT I2C3_EV_IRQHandler [WEAK] - EXPORT I2C3_ER_IRQHandler [WEAK] - EXPORT SAI1_IRQHandler [WEAK] - EXPORT SWPMI1_IRQHandler [WEAK] - EXPORT TSC_IRQHandler [WEAK] - EXPORT RNG_IRQHandler [WEAK] - EXPORT FPU_IRQHandler [WEAK] - EXPORT CRS_IRQHandler [WEAK] - -WWDG_IRQHandler -PVD_PVM_IRQHandler -TAMP_STAMP_IRQHandler -RTC_WKUP_IRQHandler -FLASH_IRQHandler -RCC_IRQHandler -EXTI0_IRQHandler -EXTI1_IRQHandler -EXTI2_IRQHandler -EXTI3_IRQHandler -EXTI4_IRQHandler -DMA1_Channel1_IRQHandler -DMA1_Channel2_IRQHandler -DMA1_Channel3_IRQHandler -DMA1_Channel4_IRQHandler -DMA1_Channel5_IRQHandler -DMA1_Channel6_IRQHandler -DMA1_Channel7_IRQHandler -ADC1_IRQHandler -CAN1_TX_IRQHandler -CAN1_RX0_IRQHandler -CAN1_RX1_IRQHandler -CAN1_SCE_IRQHandler -EXTI9_5_IRQHandler -TIM1_BRK_TIM15_IRQHandler -TIM1_UP_TIM16_IRQHandler -TIM1_TRG_COM_IRQHandler -TIM1_CC_IRQHandler -TIM2_IRQHandler -I2C1_EV_IRQHandler -I2C1_ER_IRQHandler -I2C2_EV_IRQHandler -I2C2_ER_IRQHandler -SPI1_IRQHandler -SPI2_IRQHandler -USART1_IRQHandler -USART2_IRQHandler -USART3_IRQHandler -EXTI15_10_IRQHandler -RTC_Alarm_IRQHandler -SDMMC1_IRQHandler -SPI3_IRQHandler -TIM6_DAC_IRQHandler -TIM7_IRQHandler -DMA2_Channel1_IRQHandler -DMA2_Channel2_IRQHandler -DMA2_Channel3_IRQHandler -DMA2_Channel4_IRQHandler -DMA2_Channel5_IRQHandler -COMP_IRQHandler -LPTIM1_IRQHandler -LPTIM2_IRQHandler -DMA2_Channel6_IRQHandler -DMA2_Channel7_IRQHandler -LPUART1_IRQHandler -QUADSPI_IRQHandler -I2C3_EV_IRQHandler -I2C3_ER_IRQHandler -SAI1_IRQHandler -SWPMI1_IRQHandler -TSC_IRQHandler -RNG_IRQHandler -FPU_IRQHandler -CRS_IRQHandler - - B . - - ENDP - - ALIGN - -;******************************************************************************* -; User Stack and Heap initialization -;******************************************************************************* - IF :DEF:__MICROLIB - - EXPORT __initial_sp - EXPORT __heap_base - EXPORT __heap_limit - - ELSE - - IMPORT __use_two_region_memory - EXPORT __user_initial_stackheap - -__user_initial_stackheap - - LDR R0, = Heap_Mem - LDR R1, =(Stack_Mem + Stack_Size) - LDR R2, = (Heap_Mem + Heap_Size) - LDR R3, = Stack_Mem - BX LR - - ALIGN - - ENDIF - - END +/** + ****************************************************************************** + * @file startup_stm32l431xx.s + * @author MCD Application Team + * @brief STM32L431xx devices vector table for GCC toolchain. + * This module performs: + * - Set the initial SP + * - Set the initial PC == Reset_Handler, + * - Set the vector table entries with the exceptions ISR address, + * - Configure the clock system + * - Branches to main in the C library (which eventually + * calls main()). + * After Reset the Cortex-M4 processor is in Thread mode, + * priority is Privileged, and the Stack is set to Main. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + + .syntax unified + .cpu cortex-m4 + .fpu softvfp + .thumb + +.global g_pfnVectors +.global Default_Handler + +/* start address for the initialization values of the .data section. +defined in linker script */ +.word _sidata +/* start address for the .data section. defined in linker script */ +.word _sdata +/* end address for the .data section. defined in linker script */ +.word _edata +/* start address for the .bss section. defined in linker script */ +.word _sbss +/* end address for the .bss section. defined in linker script */ +.word _ebss + +.equ BootRAM, 0xF1E0F85F +/** + * @brief This is the code that gets called when the processor first + * starts execution following a reset event. Only the absolutely + * necessary set is performed, after which the application + * supplied main() routine is called. + * @param None + * @retval : None +*/ + + .section .text.Reset_Handler + .weak Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + ldr sp, =_estack /* Set stack pointer */ + +/* Call the clock system initialization function.*/ + bl SystemInit + +/* Copy the data segment initializers from flash to SRAM */ + ldr r0, =_sdata + ldr r1, =_edata + ldr r2, =_sidata + movs r3, #0 + b LoopCopyDataInit + +CopyDataInit: + ldr r4, [r2, r3] + str r4, [r0, r3] + adds r3, r3, #4 + +LoopCopyDataInit: + adds r4, r0, r3 + cmp r4, r1 + bcc CopyDataInit + +/* Zero fill the bss segment. */ + ldr r2, =_sbss + ldr r4, =_ebss + movs r3, #0 + b LoopFillZerobss + +FillZerobss: + str r3, [r2] + adds r2, r2, #4 + +LoopFillZerobss: + cmp r2, r4 + bcc FillZerobss + +/* Call static constructors */ + bl __libc_init_array +/* Call the application's entry point.*/ + bl main + +LoopForever: + b LoopForever + +.size Reset_Handler, .-Reset_Handler + +/** + * @brief This is the code that gets called when the processor receives an + * unexpected interrupt. This simply enters an infinite loop, preserving + * the system state for examination by a debugger. + * + * @param None + * @retval : None +*/ + .section .text.Default_Handler,"ax",%progbits +Default_Handler: +Infinite_Loop: + b Infinite_Loop + .size Default_Handler, .-Default_Handler +/****************************************************************************** +* +* The minimal vector table for a Cortex-M4. Note that the proper constructs +* must be placed on this to ensure that it ends up at physical address +* 0x0000.0000. +* +******************************************************************************/ + .section .isr_vector,"a",%progbits + .type g_pfnVectors, %object + .size g_pfnVectors, .-g_pfnVectors + + +g_pfnVectors: + .word _estack + .word Reset_Handler + .word NMI_Handler + .word HardFault_Handler + .word MemManage_Handler + .word BusFault_Handler + .word UsageFault_Handler + .word 0 + .word 0 + .word 0 + .word 0 + .word SVC_Handler + .word DebugMon_Handler + .word 0 + .word PendSV_Handler + .word SysTick_Handler + .word WWDG_IRQHandler + .word PVD_PVM_IRQHandler + .word TAMP_STAMP_IRQHandler + .word RTC_WKUP_IRQHandler + .word FLASH_IRQHandler + .word RCC_IRQHandler + .word EXTI0_IRQHandler + .word EXTI1_IRQHandler + .word EXTI2_IRQHandler + .word EXTI3_IRQHandler + .word EXTI4_IRQHandler + .word DMA1_Channel1_IRQHandler + .word DMA1_Channel2_IRQHandler + .word DMA1_Channel3_IRQHandler + .word DMA1_Channel4_IRQHandler + .word DMA1_Channel5_IRQHandler + .word DMA1_Channel6_IRQHandler + .word DMA1_Channel7_IRQHandler + .word ADC1_IRQHandler + .word CAN1_TX_IRQHandler + .word CAN1_RX0_IRQHandler + .word CAN1_RX1_IRQHandler + .word CAN1_SCE_IRQHandler + .word EXTI9_5_IRQHandler + .word TIM1_BRK_TIM15_IRQHandler + .word TIM1_UP_TIM16_IRQHandler + .word TIM1_TRG_COM_IRQHandler + .word TIM1_CC_IRQHandler + .word TIM2_IRQHandler + .word 0 + .word 0 + .word I2C1_EV_IRQHandler + .word I2C1_ER_IRQHandler + .word I2C2_EV_IRQHandler + .word I2C2_ER_IRQHandler + .word SPI1_IRQHandler + .word SPI2_IRQHandler + .word USART1_IRQHandler + .word USART2_IRQHandler + .word USART3_IRQHandler + .word EXTI15_10_IRQHandler + .word RTC_Alarm_IRQHandler + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word 0 + .word SDMMC1_IRQHandler + .word 0 + .word SPI3_IRQHandler + .word 0 + .word 0 + .word TIM6_DAC_IRQHandler + .word TIM7_IRQHandler + .word DMA2_Channel1_IRQHandler + .word DMA2_Channel2_IRQHandler + .word DMA2_Channel3_IRQHandler + .word DMA2_Channel4_IRQHandler + .word DMA2_Channel5_IRQHandler + .word 0 + .word 0 + .word 0 + .word COMP_IRQHandler + .word LPTIM1_IRQHandler + .word LPTIM2_IRQHandler + .word 0 + .word DMA2_Channel6_IRQHandler + .word DMA2_Channel7_IRQHandler + .word LPUART1_IRQHandler + .word QUADSPI_IRQHandler + .word I2C3_EV_IRQHandler + .word I2C3_ER_IRQHandler + .word SAI1_IRQHandler + .word 0 + .word SWPMI1_IRQHandler + .word TSC_IRQHandler + .word 0 + .word 0 + .word RNG_IRQHandler + .word FPU_IRQHandler + .word CRS_IRQHandler + + +/******************************************************************************* +* +* Provide weak aliases for each Exception handler to the Default_Handler. +* As they are weak aliases, any function with the same name will override +* this definition. +* +*******************************************************************************/ + + .weak NMI_Handler + .thumb_set NMI_Handler,Default_Handler + + .weak HardFault_Handler + .thumb_set HardFault_Handler,Default_Handler + + .weak MemManage_Handler + .thumb_set MemManage_Handler,Default_Handler + + .weak BusFault_Handler + .thumb_set BusFault_Handler,Default_Handler + + .weak UsageFault_Handler + .thumb_set UsageFault_Handler,Default_Handler + + .weak SVC_Handler + .thumb_set SVC_Handler,Default_Handler + + .weak DebugMon_Handler + .thumb_set DebugMon_Handler,Default_Handler + + .weak PendSV_Handler + .thumb_set PendSV_Handler,Default_Handler + + .weak SysTick_Handler + .thumb_set SysTick_Handler,Default_Handler + + .weak WWDG_IRQHandler + .thumb_set WWDG_IRQHandler,Default_Handler + + .weak PVD_PVM_IRQHandler + .thumb_set PVD_PVM_IRQHandler,Default_Handler + + .weak TAMP_STAMP_IRQHandler + .thumb_set TAMP_STAMP_IRQHandler,Default_Handler + + .weak RTC_WKUP_IRQHandler + .thumb_set RTC_WKUP_IRQHandler,Default_Handler + + .weak FLASH_IRQHandler + .thumb_set FLASH_IRQHandler,Default_Handler + .weak RCC_IRQHandler + .thumb_set RCC_IRQHandler,Default_Handler + + .weak EXTI0_IRQHandler + .thumb_set EXTI0_IRQHandler,Default_Handler + + .weak EXTI1_IRQHandler + .thumb_set EXTI1_IRQHandler,Default_Handler + + .weak EXTI2_IRQHandler + .thumb_set EXTI2_IRQHandler,Default_Handler + + .weak EXTI3_IRQHandler + .thumb_set EXTI3_IRQHandler,Default_Handler + + .weak EXTI4_IRQHandler + .thumb_set EXTI4_IRQHandler,Default_Handler + + .weak DMA1_Channel1_IRQHandler + .thumb_set DMA1_Channel1_IRQHandler,Default_Handler + + .weak DMA1_Channel2_IRQHandler + .thumb_set DMA1_Channel2_IRQHandler,Default_Handler + + .weak DMA1_Channel3_IRQHandler + .thumb_set DMA1_Channel3_IRQHandler,Default_Handler + + .weak DMA1_Channel4_IRQHandler + .thumb_set DMA1_Channel4_IRQHandler,Default_Handler + + .weak DMA1_Channel5_IRQHandler + .thumb_set DMA1_Channel5_IRQHandler,Default_Handler + + .weak DMA1_Channel6_IRQHandler + .thumb_set DMA1_Channel6_IRQHandler,Default_Handler + + .weak DMA1_Channel7_IRQHandler + .thumb_set DMA1_Channel7_IRQHandler,Default_Handler + + .weak ADC1_IRQHandler + .thumb_set ADC1_IRQHandler,Default_Handler + + .weak CAN1_TX_IRQHandler + .thumb_set CAN1_TX_IRQHandler,Default_Handler + + .weak CAN1_RX0_IRQHandler + .thumb_set CAN1_RX0_IRQHandler,Default_Handler + + .weak CAN1_RX1_IRQHandler + .thumb_set CAN1_RX1_IRQHandler,Default_Handler + + .weak CAN1_SCE_IRQHandler + .thumb_set CAN1_SCE_IRQHandler,Default_Handler + + .weak EXTI9_5_IRQHandler + .thumb_set EXTI9_5_IRQHandler,Default_Handler + + .weak TIM1_BRK_TIM15_IRQHandler + .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler + + .weak TIM1_UP_TIM16_IRQHandler + .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler + + .weak TIM1_TRG_COM_IRQHandler + .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler + + .weak TIM1_CC_IRQHandler + .thumb_set TIM1_CC_IRQHandler,Default_Handler + + .weak TIM2_IRQHandler + .thumb_set TIM2_IRQHandler,Default_Handler + + .weak I2C1_EV_IRQHandler + .thumb_set I2C1_EV_IRQHandler,Default_Handler + + .weak I2C1_ER_IRQHandler + .thumb_set I2C1_ER_IRQHandler,Default_Handler + + .weak I2C2_EV_IRQHandler + .thumb_set I2C2_EV_IRQHandler,Default_Handler + + .weak I2C2_ER_IRQHandler + .thumb_set I2C2_ER_IRQHandler,Default_Handler + + .weak SPI1_IRQHandler + .thumb_set SPI1_IRQHandler,Default_Handler + + .weak SPI2_IRQHandler + .thumb_set SPI2_IRQHandler,Default_Handler + + .weak USART1_IRQHandler + .thumb_set USART1_IRQHandler,Default_Handler + + .weak USART2_IRQHandler + .thumb_set USART2_IRQHandler,Default_Handler + + .weak USART3_IRQHandler + .thumb_set USART3_IRQHandler,Default_Handler + + .weak EXTI15_10_IRQHandler + .thumb_set EXTI15_10_IRQHandler,Default_Handler + + .weak RTC_Alarm_IRQHandler + .thumb_set RTC_Alarm_IRQHandler,Default_Handler + + .weak SDMMC1_IRQHandler + .thumb_set SDMMC1_IRQHandler,Default_Handler + + .weak SPI3_IRQHandler + .thumb_set SPI3_IRQHandler,Default_Handler + + .weak TIM6_DAC_IRQHandler + .thumb_set TIM6_DAC_IRQHandler,Default_Handler + + .weak TIM7_IRQHandler + .thumb_set TIM7_IRQHandler,Default_Handler + + .weak DMA2_Channel1_IRQHandler + .thumb_set DMA2_Channel1_IRQHandler,Default_Handler + + .weak DMA2_Channel2_IRQHandler + .thumb_set DMA2_Channel2_IRQHandler,Default_Handler + + .weak DMA2_Channel3_IRQHandler + .thumb_set DMA2_Channel3_IRQHandler,Default_Handler + + .weak DMA2_Channel4_IRQHandler + .thumb_set DMA2_Channel4_IRQHandler,Default_Handler + + .weak DMA2_Channel5_IRQHandler + .thumb_set DMA2_Channel5_IRQHandler,Default_Handler + + .weak COMP_IRQHandler + .thumb_set COMP_IRQHandler,Default_Handler + + .weak LPTIM1_IRQHandler + .thumb_set LPTIM1_IRQHandler,Default_Handler + + .weak LPTIM2_IRQHandler + .thumb_set LPTIM2_IRQHandler,Default_Handler + + .weak DMA2_Channel6_IRQHandler + .thumb_set DMA2_Channel6_IRQHandler,Default_Handler + + .weak DMA2_Channel7_IRQHandler + .thumb_set DMA2_Channel7_IRQHandler,Default_Handler + + .weak LPUART1_IRQHandler + .thumb_set LPUART1_IRQHandler,Default_Handler + + .weak QUADSPI_IRQHandler + .thumb_set QUADSPI_IRQHandler,Default_Handler + + .weak I2C3_EV_IRQHandler + .thumb_set I2C3_EV_IRQHandler,Default_Handler + + .weak I2C3_ER_IRQHandler + .thumb_set I2C3_ER_IRQHandler,Default_Handler + + .weak SAI1_IRQHandler + .thumb_set SAI1_IRQHandler,Default_Handler + + .weak SWPMI1_IRQHandler + .thumb_set SWPMI1_IRQHandler,Default_Handler + + .weak TSC_IRQHandler + .thumb_set TSC_IRQHandler,Default_Handler + + .weak RNG_IRQHandler + .thumb_set RNG_IRQHandler,Default_Handler + + .weak FPU_IRQHandler + .thumb_set FPU_IRQHandler,Default_Handler + + .weak CRS_IRQHandler + .thumb_set CRS_IRQHandler,Default_Handler diff --git a/Mcu/l431/openocd.cfg b/Mcu/l431/openocd.cfg new file mode 100644 index 00000000..aa6305a2 --- /dev/null +++ b/Mcu/l431/openocd.cfg @@ -0,0 +1,7 @@ +# config for openocd for STM32G431 MCUs +source [find interface/stlink.cfg] +source [find target/stm32l4x.cfg] + +# use -gdb-max-connections to allow for live watch in vscode +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 -gdb-max-connections 4 +init diff --git a/bootloader/main.c b/bootloader/main.c index e2abd0df..a1de3dbe 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -22,6 +22,9 @@ // analyser on the input pin) //#define BOOTLOADER_TEST_CLOCK +// when there is no app fw yet, disable jump() +//#define DISABLE_JUMP + #include #define STM32_FLASH_START 0x08000000 @@ -135,6 +138,7 @@ static void delayMicroseconds(uint32_t micros) */ static void jump() { +#ifndef DISABLE_JUMP __disable_irq(); JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); uint8_t value = *(uint8_t*)(EEPROM_START_ADD); @@ -147,6 +151,7 @@ static void jump() __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); JumpToApplication(); +#endif }