Add AMI CAN DBC and verified SDC/BMS firmware handoff

This commit is contained in:
shenlefengnai-rgb
2026-10-03 15:57:54 +08:00
parent 39268e07d2
commit f1d1f6da5c
345 changed files with 360479 additions and 18 deletions
+20
View File
@@ -0,0 +1,20 @@
#ifndef AMI_APP_H
#define AMI_APP_H
#include "main.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Change to GPIO_PIN_RESET here if both board LEDs are wired active-low. */
#define AMI_LED_ACTIVE_LEVEL GPIO_PIN_SET
void AMI_App_Init(void);
void AMI_App_Service(void);
#ifdef __cplusplus
}
#endif
#endif /* AMI_APP_H */
+23
View File
@@ -0,0 +1,23 @@
#ifndef AMI_PROTOCOL_H
#define AMI_PROTOCOL_H
/* Both CAN ports use the same 500 kbit/s protocol and the same IDs. */
#define AMI_CAN_ID_SDC_HEARTBEAT 0x6A0U
#define AMI_CAN_ID_SDC_ADC 0x6A1U
#define AMI_CAN_ID_SDC_FREQUENCY 0x6A2U
#define AMI_CAN_ID_SDC_DAC_ACK 0x6A4U
#define AMI_CAN_ID_SDC_GPIO 0x6A6U
#define AMI_CAN_ID_BMS_STATUS 0x140U
#define AMI_CAN_ID_BMS_TEMPERATURE 0x156U
#define AMI_CAN_ID_BMS_STATUS_EXT 0x186040F3UL
#define AMI_CAN_ID_BMS_EXTREMES_EXT 0x186140F3UL
/* AMI task requests are not ASSI commands; no SDC mapping is defined. */
#define AMI_CAN_ID_TASK_REQUEST 0x300U
#define AMI_CAN_DATA_TIMEOUT_MS 500U
#define AMI_ADC_TIMEOUT_MS 1500U
#define AMI_BMS_TIMEOUT_MS 2000U
#define AMI_SCREEN_BOOT_DELAY_MS 800U
#define AMI_SCREEN_RESYNC_MS 5000U
#endif /* AMI_PROTOCOL_H */
+51
View File
@@ -0,0 +1,51 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.h
* @brief This file contains all the function prototypes for
* the dma.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DMA_H__
#define __DMA_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* DMA memory to memory transfer handles -------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_DMA_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __DMA_H__ */
+54
View File
@@ -0,0 +1,54 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file fdcan.h
* @brief This file contains all the function prototypes for
* the fdcan.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FDCAN_H__
#define __FDCAN_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern FDCAN_HandleTypeDef hfdcan1;
extern FDCAN_HandleTypeDef hfdcan2;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_FDCAN1_Init(void);
void MX_FDCAN2_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __FDCAN_H__ */
+48
View File
@@ -0,0 +1,48 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.h
* @brief This file contains all the function prototypes for
* the gpio.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_GPIO_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ GPIO_H__ */
+73
View File
@@ -0,0 +1,73 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32g0xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define STATUS_LED1_Pin GPIO_PIN_0
#define STATUS_LED1_GPIO_Port GPIOA
#define STATUS_LED2_Pin GPIO_PIN_1
#define STATUS_LED2_GPIO_Port GPIOA
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
+351
View File
@@ -0,0 +1,351 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32g0xx_hal_conf.h
* @author MCD Application Team
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* Copyright (c) 2018 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32G0xx_HAL_CONF_H
#define STM32G0xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/* #define HAL_ADC_MODULE_ENABLED */
/* #define HAL_CEC_MODULE_ENABLED */
/* #define HAL_COMP_MODULE_ENABLED */
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_EXTI_MODULE_ENABLED */
#define HAL_FDCAN_MODULE_ENABLED
/* #define HAL_HCD_MODULE_ENABLED */
/* #define HAL_I2C_MODULE_ENABLED */
/* #define HAL_I2S_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_LPTIM_MODULE_ENABLED */
/* #define HAL_PCD_MODULE_ENABLED */
/* #define HAL_RNG_MODULE_ENABLED */
/* #define HAL_RTC_MODULE_ENABLED */
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_SMBUS_MODULE_ENABLED */
/* #define HAL_SPI_MODULE_ENABLED */
/* #define HAL_TIM_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_EXTI_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## Register Callbacks selection ############################## */
/**
* @brief This is the list of modules where register callback can be used
*/
#define USE_HAL_ADC_REGISTER_CALLBACKS 0u
#define USE_HAL_CEC_REGISTER_CALLBACKS 0u
#define USE_HAL_COMP_REGISTER_CALLBACKS 0u
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u
#define USE_HAL_DAC_REGISTER_CALLBACKS 0u
#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0u
#define USE_HAL_HCD_REGISTER_CALLBACKS 0u
#define USE_HAL_I2C_REGISTER_CALLBACKS 0u
#define USE_HAL_I2S_REGISTER_CALLBACKS 0u
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u
#define USE_HAL_PCD_REGISTER_CALLBACKS 0u
#define USE_HAL_RNG_REGISTER_CALLBACKS 0u
#define USE_HAL_RTC_REGISTER_CALLBACKS 0u
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u
#define USE_HAL_SPI_REGISTER_CALLBACKS 0u
#define USE_HAL_TIM_REGISTER_CALLBACKS 0u
#define USE_HAL_UART_REGISTER_CALLBACKS 0u
#define USE_HAL_USART_REGISTER_CALLBACKS 0u
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u
/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE (8000000UL) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#if defined(STM32G0C1xx) || defined(STM32G0B1xx) || defined(STM32G0B0xx)
/**
* @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG.
* This internal oscillator is mainly dedicated to provide a high precision clock to
* the USB peripheral by means of a special Clock Recovery System (CRS) circuitry.
* When the CRS is not used, the HSI48 RC oscillator runs on it default frequency
* which is subject to manufacturing process variations.
*/
#if !defined (HSI48_VALUE)
#define HSI48_VALUE 48000000U /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz.
The real value my vary depending on manufacturing process variations.*/
#endif /* HSI48_VALUE */
#endif
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE (32768UL) /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for I2S1 peripheral
* This value is used by the RCC HAL module to compute the I2S1 clock source
* frequency.
*/
#if !defined (EXTERNAL_I2S1_CLOCK_VALUE)
#define EXTERNAL_I2S1_CLOCK_VALUE (48000UL) /*!< Value of the I2S1 External clock source in Hz*/
#endif /* EXTERNAL_I2S1_CLOCK_VALUE */
#if defined(STM32G0C1xx) || defined(STM32G0B1xx) || defined(STM32G0B0xx)
/**
* @brief External clock source for I2S2 peripheral
* This value is used by the RCC HAL module to compute the I2S2 clock source
* frequency.
*/
#if !defined (EXTERNAL_I2S2_CLOCK_VALUE)
#define EXTERNAL_I2S2_CLOCK_VALUE 48000U /*!< Value of the I2S2 External clock source in Hz*/
#endif /* EXTERNAL_I2S2_CLOCK_VALUE */
#endif
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY 3U /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* ################## CRYP peripheral configuration ########################## */
#define USE_HAL_CRYP_SUSPEND_RESUME 1U
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include modules header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32g0xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32g0xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32g0xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32g0xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32g0xx_hal_adc.h"
#include "stm32g0xx_hal_adc_ex.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED
#include "stm32g0xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED
#include "stm32g0xx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32g0xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32g0xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32g0xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32g0xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32g0xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_FDCAN_MODULE_ENABLED
#include "stm32g0xx_hal_fdcan.h"
#endif /* HAL_FDCAN_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32g0xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32g0xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED
#include "stm32g0xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32g0xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32g0xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32g0xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32g0xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32g0xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32g0xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32g0xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32g0xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32g0xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32g0xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32g0xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32g0xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32g0xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32g0xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for functions parameters check.
* @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t *file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* STM32G0xx_HAL_CONF_H */
+67
View File
@@ -0,0 +1,67 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32g0xx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32G0xx_IT_H
#define __STM32G0xx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void SVC_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void DMA1_Channel1_IRQHandler(void);
void DMA1_Channel2_3_IRQHandler(void);
void TIM16_FDCAN_IT0_IRQHandler(void);
void TIM17_FDCAN_IT1_IRQHandler(void);
void USART2_LPUART2_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32G0xx_IT_H */
+51
View File
@@ -0,0 +1,51 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.h
* @brief This file contains all the function prototypes for
* the usart.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern UART_HandleTypeDef huart2;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_USART2_UART_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __USART_H__ */
+687
View File
@@ -0,0 +1,687 @@
#include "ami_app.h"
#include "ami_protocol.h"
#include "fdcan.h"
#include "usart.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#define SCREEN_RX_DMA_SIZE 64U
#define SCREEN_TX_SIZE 32U
#define TASK_QUEUE_SIZE 4U
#define DIRTY_SPEED (1UL << 0)
#define DIRTY_TS_VOLTAGE (1UL << 1)
#define DIRTY_TORQUE (1UL << 2)
#define DIRTY_TS_CURRENT (1UL << 3)
#define DIRTY_MOTOR_TEMP (1UL << 4)
#define DIRTY_MCU_TEMP (1UL << 5)
#define DIRTY_CELL_TEMP (1UL << 6)
#define DIRTY_DEBUG(n) (1UL << (8U + (n)))
#define DIRTY_DASH_ALL 0x000000FFUL
#define DIRTY_COLOR(n) (1UL << (24U + (n)))
#define DIRTY_COLOR_ALL 0xFF000000UL
#define DIRTY_DEBUG_ALL 0x00FFFF00UL
typedef struct
{
/* speed, HV V, torque, HV A, motor C, MCU C, max cell C, LV 0.01V. */
int32_t dash_value[8];
uint8_t dash_valid;
uint8_t debug_state[16];
} AmiDisplayState;
static volatile AmiDisplayState display_state;
static volatile uint32_t display_dirty;
static volatile uint32_t dash_last_rx_ms;
static volatile uint32_t debug_last_rx_ms;
static volatile uint32_t adc_last_rx_ms;
static volatile uint32_t bms_status_last_rx_ms;
static volatile uint32_t bms_temperature_last_rx_ms;
/* Preserve the exact source units even where the HMI has integer controls. */
static volatile uint16_t sdc_adc_mv;
static volatile uint16_t sdc_frequency_hz[4];
static volatile uint16_t sdc_gpio_state;
static volatile uint16_t sdc_gpio_changed;
static volatile uint32_t sdc_gpio_timestamp_ms;
static volatile bool sdc_gpio_received;
static volatile uint16_t bms_voltage_tenths;
static volatile int32_t bms_current_tenths;
static volatile uint32_t can_port_last_rx_ms[2];
static volatile uint32_t can_rx_error_count;
static volatile uint32_t uart_rx_error_count;
static uint8_t screen_rx_dma[SCREEN_RX_DMA_SIZE];
static uint8_t screen_tx_dma[SCREEN_TX_SIZE];
static volatile bool screen_tx_busy;
static uint8_t parser_pos;
static uint8_t parser_task_id;
static volatile uint8_t task_queue[TASK_QUEUE_SIZE];
static volatile uint8_t task_head;
static volatile uint8_t task_tail;
static uint8_t task_sequence;
static uint8_t task_tx_mask;
static uint8_t task_target_mask;
static volatile uint32_t task_drop_count;
static GPIO_PinState LedInactiveLevel(void)
{
return (AMI_LED_ACTIVE_LEVEL == GPIO_PIN_SET) ? GPIO_PIN_RESET : GPIO_PIN_SET;
}
static uint32_t ReadBeU16(const uint8_t *data)
{
return ((uint32_t)data[0] << 8) | (uint32_t)data[1];
}
static uint32_t ReadLeU16(const uint8_t *data)
{
return (uint32_t)data[0] | ((uint32_t)data[1] << 8);
}
static int32_t RoundTenths(int32_t value)
{
return (value >= 0) ? ((value + 5) / 10) : ((value - 5) / 10);
}
static size_t AppendUnsigned(char *dst, uint32_t value)
{
char reversed[10];
size_t count = 0U;
size_t i;
do
{
reversed[count++] = (char)('0' + (value % 10U));
value /= 10U;
} while ((value != 0U) && (count < sizeof(reversed)));
for (i = 0U; i < count; ++i)
{
dst[i] = reversed[count - 1U - i];
}
return count;
}
static size_t AppendSigned(char *dst, int32_t value)
{
uint32_t magnitude;
size_t count = 0U;
if (value < 0)
{
dst[count++] = '-';
magnitude = (uint32_t)(-(value + 1)) + 1U;
}
else
{
magnitude = (uint32_t)value;
}
return count + AppendUnsigned(&dst[count], magnitude);
}
static bool StartScreenAssignment(const char *prefix, int32_t value)
{
size_t length = strlen(prefix);
if (screen_tx_busy || (length + 14U > sizeof(screen_tx_dma)))
{
return false;
}
memcpy(screen_tx_dma, prefix, length);
length += AppendSigned((char *)&screen_tx_dma[length], value);
screen_tx_dma[length++] = 0xFFU;
screen_tx_dma[length++] = 0xFFU;
screen_tx_dma[length++] = 0xFFU;
screen_tx_busy = true;
if (HAL_UART_Transmit_DMA(&huart2, screen_tx_dma, (uint16_t)length) != HAL_OK)
{
screen_tx_busy = false;
return false;
}
return true;
}
static void RestartScreenRx(void)
{
if (HAL_UARTEx_ReceiveToIdle_DMA(&huart2, screen_rx_dma,
sizeof(screen_rx_dma)) == HAL_OK)
{
__HAL_DMA_DISABLE_IT(huart2.hdmarx, DMA_IT_HT);
}
else
{
++uart_rx_error_count;
}
}
static void QueueTaskFromIsr(uint8_t task_id)
{
uint8_t next = (uint8_t)((task_head + 1U) % TASK_QUEUE_SIZE);
if (next == task_tail)
{
++task_drop_count;
return;
}
task_queue[task_head] = task_id;
task_head = next;
}
static void ParseScreenByte(uint8_t byte)
{
static const uint8_t fixed[6] = {0xAAU, 0x55U, 0x01U, 0x00U, 0x0DU, 0x0AU};
switch (parser_pos)
{
case 0U:
parser_pos = (byte == fixed[0]) ? 1U : 0U;
break;
case 1U:
parser_pos = (byte == fixed[1]) ? 2U : ((byte == fixed[0]) ? 1U : 0U);
break;
case 2U:
parser_pos = (byte == fixed[2]) ? 3U : ((byte == fixed[0]) ? 1U : 0U);
break;
case 3U:
if ((byte >= 1U) && (byte <= 6U))
{
parser_task_id = byte;
parser_pos = 4U;
}
else
{
parser_pos = (byte == fixed[0]) ? 1U : 0U;
}
break;
case 4U:
parser_pos = (byte == fixed[4]) ? 5U : ((byte == fixed[0]) ? 1U : 0U);
break;
case 5U:
if (byte == fixed[5])
{
QueueTaskFromIsr(parser_task_id);
}
parser_pos = (byte == fixed[0]) ? 1U : 0U;
break;
default:
parser_pos = 0U;
break;
}
}
static void SetDashValid(uint32_t index, bool valid)
{
uint8_t mask = (uint8_t)(1U << index);
bool previous = (display_state.dash_valid & mask) != 0U;
if (valid != previous)
{
if (valid) { display_state.dash_valid |= mask; }
else { display_state.dash_valid &= (uint8_t)~mask; }
display_dirty |= DIRTY_COLOR(index);
}
}
static void SetDashValue(uint32_t index, int32_t value)
{
if ((display_state.dash_value[index] != value) ||
((display_state.dash_valid & (1U << index)) == 0U))
{
display_state.dash_value[index] = value;
display_dirty |= (1UL << index);
}
SetDashValid(index, true);
}
static bool DecodeCan(uint32_t identifier, uint32_t id_type,
uint32_t length, const uint8_t *data)
{
uint32_t now = HAL_GetTick();
if (id_type == FDCAN_STANDARD_ID)
{
if ((identifier == AMI_CAN_ID_SDC_ADC) && (length == 2U))
{
sdc_adc_mv = (uint16_t)ReadLeU16(data);
/* Xfloat lvbat has two decimals: mV -> hundredths of a volt. */
SetDashValue(7U, (int32_t)((sdc_adc_mv + 5U) / 10U));
adc_last_rx_ms = now;
dash_last_rx_ms = now;
return true;
}
if ((identifier == AMI_CAN_ID_SDC_HEARTBEAT) && (length == 8U) &&
(data[0] == 0xA1U) && (data[1] == 1U))
{
debug_last_rx_ms = now;
return true;
}
if ((identifier == AMI_CAN_ID_SDC_FREQUENCY) && (length == 8U))
{
for (uint32_t i = 0U; i < 4U; ++i)
{
sdc_frequency_hz[i] = (uint16_t)ReadLeU16(&data[i * 2U]);
}
/* Hz is not km/h; wheel circumference and pulses/rev are undefined. */
return true;
}
if ((identifier == AMI_CAN_ID_SDC_GPIO) && (length == 8U))
{
sdc_gpio_state = (uint16_t)(ReadLeU16(data) & 0x7FFFU);
sdc_gpio_changed = (uint16_t)(ReadLeU16(&data[2]) & 0x7FFFU);
sdc_gpio_timestamp_ms = (uint32_t)data[4] | ((uint32_t)data[5] << 8) |
((uint32_t)data[6] << 16) | ((uint32_t)data[7] << 24);
sdc_gpio_received = true;
debug_last_rx_ms = now;
/* No PD0..PD14 -> named safety signals / normal polarity mapping. */
return true;
}
if ((identifier == AMI_CAN_ID_SDC_DAC_ACK) && (length == 4U))
{
return true;
}
if ((identifier == AMI_CAN_ID_BMS_TEMPERATURE) && (length == 8U))
{
int32_t maximum = -40;
bool valid = false;
for (uint32_t i = 0U; i < 8U; ++i)
{
if (data[i] != 0xFFU)
{
int32_t temperature = (int32_t)data[i] - 40;
if (!valid || (temperature > maximum)) { maximum = temperature; }
valid = true;
}
}
if (valid) { SetDashValue(6U, maximum); }
else { SetDashValid(6U, false); }
bms_temperature_last_rx_ms = now;
dash_last_rx_ms = now;
return true;
}
}
if (((id_type == FDCAN_STANDARD_ID) && (identifier == AMI_CAN_ID_BMS_STATUS)) ||
((id_type == FDCAN_EXTENDED_ID) && (identifier == AMI_CAN_ID_BMS_STATUS_EXT)))
{
if (length != 8U) { return false; }
bms_voltage_tenths = (uint16_t)ReadBeU16(data);
bms_current_tenths = (int32_t)ReadBeU16(&data[2]) - 5000;
SetDashValue(1U, RoundTenths(bms_voltage_tenths));
SetDashValue(3U, RoundTenths(bms_current_tenths));
bms_status_last_rx_ms = now;
dash_last_rx_ms = now;
return true;
}
if ((id_type == FDCAN_EXTENDED_ID) &&
(identifier == AMI_CAN_ID_BMS_EXTREMES_EXT) && (length == 8U))
{
if (data[4] != 0xFFU) { SetDashValue(6U, (int32_t)data[4] - 40); }
else { SetDashValid(6U, false); }
bms_temperature_last_rx_ms = now;
dash_last_rx_ms = now;
/* BMS LV bytes 6..7 do not override the SDC ADC source. */
return true;
}
return false;
}
static void ConfigureCanPort(FDCAN_HandleTypeDef *hfdcan)
{
FDCAN_FilterTypeDef filter = {0};
filter.IdType = FDCAN_STANDARD_ID;
filter.FilterIndex = 0U;
filter.FilterType = FDCAN_FILTER_RANGE;
filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
filter.FilterID1 = AMI_CAN_ID_SDC_HEARTBEAT;
filter.FilterID2 = AMI_CAN_ID_SDC_GPIO;
if (HAL_FDCAN_ConfigFilter(hfdcan, &filter) != HAL_OK) { Error_Handler(); }
filter.FilterIndex = 1U;
filter.FilterType = FDCAN_FILTER_MASK;
filter.FilterID1 = AMI_CAN_ID_BMS_STATUS;
filter.FilterID2 = 0x7FFU;
if (HAL_FDCAN_ConfigFilter(hfdcan, &filter) != HAL_OK) { Error_Handler(); }
filter.FilterIndex = 2U;
filter.FilterID1 = AMI_CAN_ID_BMS_TEMPERATURE;
if (HAL_FDCAN_ConfigFilter(hfdcan, &filter) != HAL_OK) { Error_Handler(); }
filter.IdType = FDCAN_EXTENDED_ID;
filter.FilterIndex = 0U;
filter.FilterType = FDCAN_FILTER_DUAL;
filter.FilterID1 = AMI_CAN_ID_BMS_STATUS_EXT;
filter.FilterID2 = AMI_CAN_ID_BMS_EXTREMES_EXT;
if (HAL_FDCAN_ConfigFilter(hfdcan, &filter) != HAL_OK) { Error_Handler(); }
}
static void ConfigureCan(void)
{
ConfigureCanPort(&hfdcan1);
ConfigureCanPort(&hfdcan2);
if ((HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT,
FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK) ||
(HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_REJECT, FDCAN_REJECT,
FDCAN_REJECT_REMOTE, FDCAN_REJECT_REMOTE) != HAL_OK) ||
(HAL_FDCAN_ActivateNotification(&hfdcan1,
FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0U) != HAL_OK) ||
(HAL_FDCAN_ActivateNotification(&hfdcan2,
FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0U) != HAL_OK) ||
(HAL_FDCAN_Start(&hfdcan1) != HAL_OK) ||
(HAL_FDCAN_Start(&hfdcan2) != HAL_OK))
{
Error_Handler();
}
}
static void SendPendingTask(void)
{
FDCAN_TxHeaderTypeDef header = {0};
uint8_t data[8];
uint8_t task_id;
uint32_t now;
if (task_tail == task_head)
{
return;
}
task_id = task_queue[task_tail];
now = HAL_GetTick();
if (task_target_mask == 0U)
{
if ((can_port_last_rx_ms[0] != 0U) &&
((now - can_port_last_rx_ms[0]) <= AMI_CAN_DATA_TIMEOUT_MS))
{
task_target_mask |= 0x01U;
}
if ((can_port_last_rx_ms[1] != 0U) &&
((now - can_port_last_rx_ms[1]) <= AMI_CAN_DATA_TIMEOUT_MS))
{
task_target_mask |= 0x02U;
}
if (task_target_mask == 0U)
{
task_target_mask = 0x03U;
}
}
data[0] = 1U;
data[1] = task_id;
data[2] = task_sequence;
data[3] = 1U;
data[4] = (uint8_t)now;
data[5] = (uint8_t)(now >> 8);
data[6] = (uint8_t)(now >> 16);
data[7] = (uint8_t)(now >> 24);
header.Identifier = AMI_CAN_ID_TASK_REQUEST;
header.IdType = FDCAN_STANDARD_ID;
header.TxFrameType = FDCAN_DATA_FRAME;
header.DataLength = FDCAN_DLC_BYTES_8;
header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
header.BitRateSwitch = FDCAN_BRS_OFF;
header.FDFormat = FDCAN_CLASSIC_CAN;
header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
header.MessageMarker = 0U;
if (((task_target_mask & 0x01U) != 0U) && ((task_tx_mask & 0x01U) == 0U) &&
(HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) > 0U) &&
(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &header, data) == HAL_OK))
{
task_tx_mask |= 0x01U;
}
if (((task_target_mask & 0x02U) != 0U) && ((task_tx_mask & 0x02U) == 0U) &&
(HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan2) > 0U) &&
(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &header, data) == HAL_OK))
{
task_tx_mask |= 0x02U;
}
if ((task_tx_mask & task_target_mask) == task_target_mask)
{
task_tail = (uint8_t)((task_tail + 1U) % TASK_QUEUE_SIZE);
++task_sequence;
task_tx_mask = 0U;
task_target_mask = 0U;
}
}
static void UpdateTimeoutsAndLeds(void)
{
static uint32_t last_heartbeat_ms;
static bool debug_timeout_applied;
uint32_t now = HAL_GetTick();
bool dash_timeout = (dash_last_rx_ms == 0U) ||
((now - dash_last_rx_ms) > AMI_CAN_DATA_TIMEOUT_MS);
bool debug_timeout = (debug_last_rx_ms == 0U) ||
((now - debug_last_rx_ms) > AMI_CAN_DATA_TIMEOUT_MS);
if ((now - last_heartbeat_ms) >= 500U)
{
HAL_GPIO_TogglePin(STATUS_LED1_GPIO_Port, STATUS_LED1_Pin);
last_heartbeat_ms = now;
}
HAL_GPIO_WritePin(STATUS_LED2_GPIO_Port, STATUS_LED2_Pin,
(dash_timeout || debug_timeout) ? AMI_LED_ACTIVE_LEVEL
: LedInactiveLevel());
/* Each physical source expires separately; other traffic cannot refresh it. */
__disable_irq();
/* Sample time after excluding RX IRQs: a newer timestamp must not underflow. */
now = HAL_GetTick();
if ((adc_last_rx_ms == 0U) || ((now - adc_last_rx_ms) > AMI_ADC_TIMEOUT_MS))
{
SetDashValid(7U, false);
}
if ((bms_status_last_rx_ms == 0U) || ((now - bms_status_last_rx_ms) > AMI_BMS_TIMEOUT_MS))
{
SetDashValid(1U, false);
SetDashValid(3U, false);
}
if ((bms_temperature_last_rx_ms == 0U) ||
((now - bms_temperature_last_rx_ms) > AMI_BMS_TIMEOUT_MS))
{
SetDashValid(6U, false);
}
__enable_irq();
if (debug_timeout && !debug_timeout_applied)
{
uint32_t i;
__disable_irq();
for (i = 0U; i < 16U; ++i)
{
display_state.debug_state[i] = 0U;
}
display_dirty |= DIRTY_DEBUG_ALL;
__enable_irq();
debug_timeout_applied = true;
}
else if (!debug_timeout)
{
debug_timeout_applied = false;
}
}
static void SendNextDirtyValue(void)
{
static const char *const dash_prefix[8] = {
"dash.speed.val=", "dash.ts.val=", "dash.mct.val=", "dash.dl.val=",
"dash.djwd.val=", "dash.mcuwd.val=", "dash.dtwd.val=", "dash.lvbat.val="
};
static const char *const color_prefix[8] = {
"dash.speed.pco=", "dash.ts.pco=", "dash.mct.pco=", "dash.dl.pco=",
"dash.djwd.pco=", "dash.mcuwd.pco=", "dash.dtwd.pco=", "dash.lvbat.pco="
};
static uint32_t cursor;
uint32_t dirty;
uint32_t bit;
uint32_t index;
int32_t value;
const char *prefix;
char debug_prefix[5] = {'d', '0', '=', '\0', '\0'};
if (screen_tx_busy || (HAL_GetTick() < AMI_SCREEN_BOOT_DELAY_MS))
{
return;
}
__disable_irq();
dirty = display_dirty;
__enable_irq();
if (dirty == 0U)
{
return;
}
/* Fair rotation prevents rapid source updates from starving other fields. */
for (uint32_t offset = 0U; offset < 32U; ++offset)
{
index = (cursor + offset) & 31U;
if ((dirty & (1UL << index)) != 0U) { break; }
}
bit = 1UL << index;
cursor = (index + 1U) & 31U;
__disable_irq();
if (index < 8U)
{
value = display_state.dash_value[index];
prefix = dash_prefix[index];
}
else if (index >= 24U)
{
uint32_t dash_index = index - 24U;
value = (display_state.dash_valid & (1U << dash_index)) ? 65535 : 16904;
prefix = color_prefix[dash_index];
}
else
{
uint32_t debug_index = index - 8U;
value = display_state.debug_state[debug_index];
if (debug_index >= 10U)
{
debug_prefix[1] = '1';
debug_prefix[2] = (char)('0' + (debug_index - 10U));
debug_prefix[3] = '=';
prefix = debug_prefix;
}
else
{
debug_prefix[1] = (char)('0' + debug_index);
prefix = debug_prefix;
}
}
display_dirty &= ~bit;
__enable_irq();
if (!StartScreenAssignment(prefix, value))
{
__disable_irq();
display_dirty |= bit;
__enable_irq();
}
}
void AMI_App_Init(void)
{
HAL_GPIO_WritePin(STATUS_LED1_GPIO_Port, STATUS_LED1_Pin, LedInactiveLevel());
HAL_GPIO_WritePin(STATUS_LED2_GPIO_Port, STATUS_LED2_Pin, AMI_LED_ACTIVE_LEVEL);
display_dirty = DIRTY_DASH_ALL | DIRTY_DEBUG_ALL | DIRTY_COLOR_ALL;
ConfigureCan();
RestartScreenRx();
}
void AMI_App_Service(void)
{
static uint32_t last_screen_sync_ms;
uint32_t now = HAL_GetTick();
SendPendingTask();
UpdateTimeoutsAndLeds();
/* The HMI may reboot/reconnect after the MCU has already sent its state. */
if ((now - last_screen_sync_ms) >= AMI_SCREEN_RESYNC_MS)
{
__disable_irq();
display_dirty |= DIRTY_DASH_ALL | DIRTY_DEBUG_ALL | DIRTY_COLOR_ALL;
__enable_irq();
last_screen_sync_ms = now;
}
SendNextDirtyValue();
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan,
uint32_t rx_fifo0_its)
{
FDCAN_RxHeaderTypeDef header;
uint8_t data[64]; /* HAL copies payload before validation, including FD DLCs. */
if ((rx_fifo0_its & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) == 0U)
{
return;
}
while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0U)
{
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &header, data) != HAL_OK)
{
++can_rx_error_count;
break;
}
if ((header.RxFrameType != FDCAN_DATA_FRAME) ||
(header.FDFormat != FDCAN_CLASSIC_CAN) ||
(header.DataLength > FDCAN_DLC_BYTES_8))
{
continue;
}
if (DecodeCan(header.Identifier, header.IdType, header.DataLength, data))
{
can_port_last_rx_ms[(hfdcan->Instance == FDCAN1) ? 0U : 1U] = HAL_GetTick();
}
}
}
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
{
(void)hfdcan;
++can_rx_error_count;
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size)
{
uint16_t i;
if (huart->Instance != USART2)
{
return;
}
for (i = 0U; i < size; ++i)
{
ParseScreenByte(screen_rx_dma[i]);
}
RestartScreenRx();
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2)
{
screen_tx_busy = false;
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2)
{
++uart_rx_error_count;
(void)HAL_UART_AbortReceive(huart);
RestartScreenRx();
}
}
+57
View File
@@ -0,0 +1,57 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.c
* @brief This file provides code for the configuration
* of all the requested memory to memory DMA transfers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure DMA */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
+285
View File
@@ -0,0 +1,285 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file fdcan.c
* @brief This file provides code for the configuration
* of the FDCAN instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "fdcan.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
FDCAN_HandleTypeDef hfdcan1;
FDCAN_HandleTypeDef hfdcan2;
/* FDCAN1 init function */
void MX_FDCAN1_Init(void)
{
/* USER CODE BEGIN FDCAN1_Init 0 */
/* USER CODE END FDCAN1_Init 0 */
/* USER CODE BEGIN FDCAN1_Init 1 */
/* USER CODE END FDCAN1_Init 1 */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = DISABLE;
hfdcan1.Init.NominalPrescaler = 8;
hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 13;
hfdcan1.Init.NominalTimeSeg2 = 2;
hfdcan1.Init.DataPrescaler = 8;
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 13;
hfdcan1.Init.DataTimeSeg2 = 2;
hfdcan1.Init.StdFiltersNbr = 3;
hfdcan1.Init.ExtFiltersNbr = 1;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN1_Init 2 */
/* USER CODE END FDCAN1_Init 2 */
}
/* FDCAN2 init function */
void MX_FDCAN2_Init(void)
{
/* USER CODE BEGIN FDCAN2_Init 0 */
/* USER CODE END FDCAN2_Init 0 */
/* USER CODE BEGIN FDCAN2_Init 1 */
/* USER CODE END FDCAN2_Init 1 */
hfdcan2.Instance = FDCAN2;
hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan2.Init.AutoRetransmission = ENABLE;
hfdcan2.Init.TransmitPause = DISABLE;
hfdcan2.Init.ProtocolException = DISABLE;
hfdcan2.Init.NominalPrescaler = 8;
hfdcan2.Init.NominalSyncJumpWidth = 1;
hfdcan2.Init.NominalTimeSeg1 = 13;
hfdcan2.Init.NominalTimeSeg2 = 2;
hfdcan2.Init.DataPrescaler = 8;
hfdcan2.Init.DataSyncJumpWidth = 1;
hfdcan2.Init.DataTimeSeg1 = 13;
hfdcan2.Init.DataTimeSeg2 = 2;
hfdcan2.Init.StdFiltersNbr = 3;
hfdcan2.Init.ExtFiltersNbr = 1;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN FDCAN2_Init 2 */
/* USER CODE END FDCAN2_Init 2 */
}
static uint32_t HAL_RCC_FDCAN_CLK_ENABLED=0;
void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* fdcanHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(fdcanHandle->Instance==FDCAN1)
{
/* USER CODE BEGIN FDCAN1_MspInit 0 */
/* USER CODE END FDCAN1_MspInit 0 */
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* FDCAN1 clock enable */
HAL_RCC_FDCAN_CLK_ENABLED++;
if(HAL_RCC_FDCAN_CLK_ENABLED==1){
__HAL_RCC_FDCAN_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**FDCAN1 GPIO Configuration
PA11 [PA9] ------> FDCAN1_RX
PA12 [PA10] ------> FDCAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF3_FDCAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* FDCAN1 interrupt Init */
HAL_NVIC_SetPriority(TIM16_FDCAN_IT0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM16_FDCAN_IT0_IRQn);
HAL_NVIC_SetPriority(TIM17_FDCAN_IT1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM17_FDCAN_IT1_IRQn);
/* USER CODE BEGIN FDCAN1_MspInit 1 */
/* USER CODE END FDCAN1_MspInit 1 */
}
else if(fdcanHandle->Instance==FDCAN2)
{
/* USER CODE BEGIN FDCAN2_MspInit 0 */
/* USER CODE END FDCAN2_MspInit 0 */
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* FDCAN2 clock enable */
HAL_RCC_FDCAN_CLK_ENABLED++;
if(HAL_RCC_FDCAN_CLK_ENABLED==1){
__HAL_RCC_FDCAN_CLK_ENABLE();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**FDCAN2 GPIO Configuration
PB0 ------> FDCAN2_RX
PB1 ------> FDCAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF3_FDCAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* FDCAN2 interrupt Init */
HAL_NVIC_SetPriority(TIM16_FDCAN_IT0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM16_FDCAN_IT0_IRQn);
HAL_NVIC_SetPriority(TIM17_FDCAN_IT1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM17_FDCAN_IT1_IRQn);
/* USER CODE BEGIN FDCAN2_MspInit 1 */
/* USER CODE END FDCAN2_MspInit 1 */
}
}
void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* fdcanHandle)
{
if(fdcanHandle->Instance==FDCAN1)
{
/* USER CODE BEGIN FDCAN1_MspDeInit 0 */
/* USER CODE END FDCAN1_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_FDCAN_CLK_ENABLED--;
if(HAL_RCC_FDCAN_CLK_ENABLED==0){
__HAL_RCC_FDCAN_CLK_DISABLE();
}
/**FDCAN1 GPIO Configuration
PA11 [PA9] ------> FDCAN1_RX
PA12 [PA10] ------> FDCAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* FDCAN1 interrupt Deinit */
/* USER CODE BEGIN FDCAN1:TIM16_FDCAN_IT0_IRQn disable */
/**
* Uncomment the line below to disable the "TIM16_FDCAN_IT0_IRQn" interrupt
* Be aware, disabling shared interrupt may affect other IPs
*/
/* HAL_NVIC_DisableIRQ(TIM16_FDCAN_IT0_IRQn); */
/* USER CODE END FDCAN1:TIM16_FDCAN_IT0_IRQn disable */
/* USER CODE BEGIN FDCAN1:TIM17_FDCAN_IT1_IRQn disable */
/**
* Uncomment the line below to disable the "TIM17_FDCAN_IT1_IRQn" interrupt
* Be aware, disabling shared interrupt may affect other IPs
*/
/* HAL_NVIC_DisableIRQ(TIM17_FDCAN_IT1_IRQn); */
/* USER CODE END FDCAN1:TIM17_FDCAN_IT1_IRQn disable */
/* USER CODE BEGIN FDCAN1_MspDeInit 1 */
/* USER CODE END FDCAN1_MspDeInit 1 */
}
else if(fdcanHandle->Instance==FDCAN2)
{
/* USER CODE BEGIN FDCAN2_MspDeInit 0 */
/* USER CODE END FDCAN2_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_FDCAN_CLK_ENABLED--;
if(HAL_RCC_FDCAN_CLK_ENABLED==0){
__HAL_RCC_FDCAN_CLK_DISABLE();
}
/**FDCAN2 GPIO Configuration
PB0 ------> FDCAN2_RX
PB1 ------> FDCAN2_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0|GPIO_PIN_1);
/* FDCAN2 interrupt Deinit */
/* USER CODE BEGIN FDCAN2:TIM16_FDCAN_IT0_IRQn disable */
/**
* Uncomment the line below to disable the "TIM16_FDCAN_IT0_IRQn" interrupt
* Be aware, disabling shared interrupt may affect other IPs
*/
/* HAL_NVIC_DisableIRQ(TIM16_FDCAN_IT0_IRQn); */
/* USER CODE END FDCAN2:TIM16_FDCAN_IT0_IRQn disable */
/* USER CODE BEGIN FDCAN2:TIM17_FDCAN_IT1_IRQn disable */
/**
* Uncomment the line below to disable the "TIM17_FDCAN_IT1_IRQn" interrupt
* Be aware, disabling shared interrupt may affect other IPs
*/
/* HAL_NVIC_DisableIRQ(TIM17_FDCAN_IT1_IRQn); */
/* USER CODE END FDCAN2:TIM17_FDCAN_IT1_IRQn disable */
/* USER CODE BEGIN FDCAN2_MspDeInit 1 */
/* USER CODE END FDCAN2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
+65
View File
@@ -0,0 +1,65 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.c
* @brief This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure GPIO */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, STATUS_LED1_Pin|STATUS_LED2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : STATUS_LED1_Pin STATUS_LED2_Pin */
GPIO_InitStruct.Pin = STATUS_LED1_Pin|STATUS_LED2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
+192
View File
@@ -0,0 +1,192 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "fdcan.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ami_app.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_FDCAN1_Init();
MX_FDCAN2_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
AMI_App_Init();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
AMI_App_Service();
__WFI();
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
RCC_OscInitStruct.PLL.PLLN = 16;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
+90
View File
@@ -0,0 +1,90 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32g0xx_hal_msp.c
* @brief This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/* SVC_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SVC_IRQn, 3, 0);
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 3, 0);
/** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
*/
HAL_SYSCFG_StrobeDBattpinsConfig(SYSCFG_CFGR1_UCPD1_STROBE | SYSCFG_CFGR1_UCPD2_STROBE);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
+221
View File
@@ -0,0 +1,221 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32g0xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32g0xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern FDCAN_HandleTypeDef hfdcan1;
extern FDCAN_HandleTypeDef hfdcan2;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern UART_HandleTypeDef huart2;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M0+ Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVC_IRQn 0 */
/* USER CODE END SVC_IRQn 0 */
/* USER CODE BEGIN SVC_IRQn 1 */
/* USER CODE END SVC_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32G0xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32g0xx.s). */
/******************************************************************************/
/**
* @brief This function handles DMA1 channel 1 interrupt.
*/
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_tx);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel 2 and channel 3 interrupts.
*/
void DMA1_Channel2_3_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel2_3_IRQn 0 */
/* USER CODE END DMA1_Channel2_3_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA1_Channel2_3_IRQn 1 */
/* USER CODE END DMA1_Channel2_3_IRQn 1 */
}
/**
* @brief This function handles TIM16, FDCAN1_IT0 and FDCAN2_IT0 Interrupt.
*/
void TIM16_FDCAN_IT0_IRQHandler(void)
{
/* USER CODE BEGIN TIM16_FDCAN_IT0_IRQn 0 */
/* USER CODE END TIM16_FDCAN_IT0_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan1);
HAL_FDCAN_IRQHandler(&hfdcan2);
/* USER CODE BEGIN TIM16_FDCAN_IT0_IRQn 1 */
/* USER CODE END TIM16_FDCAN_IT0_IRQn 1 */
}
/**
* @brief This function handles TIM17, FDCAN1_IT1 and FDCAN2_IT1 Interrupt.
*/
void TIM17_FDCAN_IT1_IRQHandler(void)
{
/* USER CODE BEGIN TIM17_FDCAN_IT1_IRQn 0 */
/* USER CODE END TIM17_FDCAN_IT1_IRQn 0 */
HAL_FDCAN_IRQHandler(&hfdcan1);
HAL_FDCAN_IRQHandler(&hfdcan2);
/* USER CODE BEGIN TIM17_FDCAN_IT1_IRQn 1 */
/* USER CODE END TIM17_FDCAN_IT1_IRQn 1 */
}
/**
* @brief This function handles USART2 + LPUART2 Interrupt.
*/
void USART2_LPUART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_LPUART2_IRQn 0 */
/* USER CODE END USART2_LPUART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_LPUART2_IRQn 1 */
/* USER CODE END USART2_LPUART2_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
+244
View File
@@ -0,0 +1,244 @@
/**
******************************************************************************
* @file syscalls.c
* @author Auto-generated by STM32CubeMX
* @brief Minimal System calls file
*
* For more information about which c-functions
* need which of these lowlevel functions
* please consult the Newlib or Picolibc libc-manual
******************************************************************************
* @attention
*
* Copyright (c) 2020-2025 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.
*
******************************************************************************
*/
/* Includes */
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
/* Variables */
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));
char *__env[1] = { 0 };
char **environ = __env;
/* Functions */
void initialise_monitor_handles()
{
}
int _getpid(void)
{
return 1;
}
int _kill(int pid, int sig)
{
(void)pid;
(void)sig;
errno = EINVAL;
return -1;
}
void _exit (int status)
{
_kill(status, -1);
while (1) {} /* Make sure we hang here */
}
__attribute__((weak)) int _read(int file, char *ptr, int len)
{
(void)file;
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
*ptr++ = __io_getchar();
}
return len;
}
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
(void)file;
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
__io_putchar(*ptr++);
}
return len;
}
int _close(int file)
{
(void)file;
return -1;
}
int _fstat(int file, struct stat *st)
{
(void)file;
st->st_mode = S_IFCHR;
return 0;
}
int _isatty(int file)
{
(void)file;
return 1;
}
int _lseek(int file, int ptr, int dir)
{
(void)file;
(void)ptr;
(void)dir;
return 0;
}
int _open(char *path, int flags, ...)
{
(void)path;
(void)flags;
/* Pretend like we always fail */
return -1;
}
int _wait(int *status)
{
(void)status;
errno = ECHILD;
return -1;
}
int _unlink(char *name)
{
(void)name;
errno = ENOENT;
return -1;
}
clock_t _times(struct tms *buf)
{
(void)buf;
return -1;
}
int _stat(const char *file, struct stat *st)
{
(void)file;
st->st_mode = S_IFCHR;
return 0;
}
int _link(char *old, char *new)
{
(void)old;
(void)new;
errno = EMLINK;
return -1;
}
int _fork(void)
{
errno = EAGAIN;
return -1;
}
int _execve(char *name, char **argv, char **env)
{
(void)name;
(void)argv;
(void)env;
errno = ENOMEM;
return -1;
}
// --- Picolibc Specific Section ---
#if defined(__PICOLIBC__)
/**
* @brief Picolibc helper function to output a character to a FILE stream.
* This redirects the output to the low-level __io_putchar function.
* @param c Character to write.
* @param file FILE stream pointer (ignored).
* @retval int The character written.
*/
static int starm_putc(char c, FILE *file)
{
(void) file;
__io_putchar(c);
return c;
}
/**
* @brief Picolibc helper function to input a character from a FILE stream.
* This redirects the input from the low-level __io_getchar function.
* @param file FILE stream pointer (ignored).
* @retval int The character read, cast to an unsigned char then int.
*/
static int starm_getc(FILE *file)
{
unsigned char c;
(void) file;
c = __io_getchar();
return c;
}
// Define and initialize the standard I/O streams for Picolibc.
// FDEV_SETUP_STREAM connects the starm_putc and starm_getc helper functions to a FILE structure.
// _FDEV_SETUP_RW indicates the stream is for reading and writing.
static FILE __stdio = FDEV_SETUP_STREAM(starm_putc,
starm_getc,
NULL,
_FDEV_SETUP_RW);
// Assign the standard stream pointers (stdin, stdout, stderr) to the initialized stream.
// Picolibc uses these pointers for standard I/O operations (printf, scanf, etc.).
FILE *const stdin = &__stdio;
__strong_reference(stdin, stdout);
__strong_reference(stdin, stderr);
// Create strong aliases mapping standard C library function names (without underscore)
// to the implemented system call stubs (with underscore). Picolibc uses these
// standard names internally, so this linking is required.
__strong_reference(_read, read);
__strong_reference(_write, write);
__strong_reference(_times, times);
__strong_reference(_execve, execve);
__strong_reference(_fork, fork);
__strong_reference(_link, link);
__strong_reference(_unlink, unlink);
__strong_reference(_stat, stat);
__strong_reference(_wait, wait);
__strong_reference(_open, open);
__strong_reference(_close, close);
__strong_reference(_lseek, lseek);
__strong_reference(_isatty, isatty);
__strong_reference(_fstat, fstat);
__strong_reference(_exit, exit);
__strong_reference(_kill, kill);
__strong_reference(_getpid, getpid);
#endif //__PICOLIBC__
+87
View File
@@ -0,0 +1,87 @@
/**
******************************************************************************
* @file sysmem.c
* @author Generated by STM32CubeMX
* @brief System Memory calls file
*
* For more information about which C functions
* need which of these lowlevel functions
* please consult the Newlib or Picolibc libc manual
******************************************************************************
* @attention
*
* Copyright (c) 2025 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.
*
******************************************************************************
*/
/* Includes */
#include <errno.h>
#include <stdint.h>
#include <stddef.h>
/**
* Pointer to the current high watermark of the heap usage
*/
static uint8_t *__sbrk_heap_end = NULL;
/**
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
* and others from the C library
*
* @verbatim
* ############################################################################
* # .data # .bss # newlib heap # MSP stack #
* # # # # Reserved by _Min_Stack_Size #
* ############################################################################
* ^-- RAM start ^-- _end _estack, RAM end --^
* @endverbatim
*
* This implementation starts allocating at the '_end' linker symbol
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
* The implementation considers '_estack' linker symbol to be RAM end
* NOTE: If the MSP stack, at any point during execution, grows larger than the
* reserved size, please increase the '_Min_Stack_Size'.
*
* @param incr Memory size
* @return Pointer to allocated memory
*/
void *_sbrk(ptrdiff_t incr)
{
extern uint8_t _end; /* Symbol defined in the linker script */
extern uint8_t _estack; /* Symbol defined in the linker script */
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
const uint8_t *max_heap = (uint8_t *)stack_limit;
uint8_t *prev_heap_end;
/* Initialize heap end at first call */
if (NULL == __sbrk_heap_end)
{
__sbrk_heap_end = &_end;
}
/* Protect heap from growing into the reserved MSP stack */
if (__sbrk_heap_end + incr > max_heap)
{
errno = ENOMEM;
return (void *)-1;
}
prev_heap_end = __sbrk_heap_end;
__sbrk_heap_end += incr;
return (void *)prev_heap_end;
}
#if defined(__PICOLIBC__)
// Picolibc expects syscalls without the leading underscore.
// This creates a strong alias so that
// calls to `sbrk()` are resolved to our `_sbrk()` implementation.
__strong_reference(_sbrk, sbrk);
#endif
+302
View File
@@ -0,0 +1,302 @@
/**
******************************************************************************
* @file system_stm32g0xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M0+ Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32g0xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the HSI (8 MHz then 16 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32g0xx.s" file, to
* configure the system clock before to branch to main program.
*
* This file configures the system clock as follows:
*=============================================================================
*-----------------------------------------------------------------------------
* System Clock source | HSI
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 16000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 16000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB Prescaler | 1
*-----------------------------------------------------------------------------
* HSI Division factor | 1
*-----------------------------------------------------------------------------
* PLL_M | 1
*-----------------------------------------------------------------------------
* PLL_N | 8
*-----------------------------------------------------------------------------
* PLL_P | 7
*-----------------------------------------------------------------------------
* PLL_Q | 2
*-----------------------------------------------------------------------------
* PLL_R | 2
*-----------------------------------------------------------------------------
* Require 48MHz for RNG | Disabled
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* Copyright (c) 2018-2021 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.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32g0xx_system
* @{
*/
/** @addtogroup STM32G0xx_System_Private_Includes
* @{
*/
#include "stm32g0xx.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE (8000000UL) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#if !defined (LSI_VALUE)
#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/
#endif /* LSI_VALUE */
#if !defined (LSE_VALUE)
#define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/
#endif /* LSE_VALUE */
/**
* @}
*/
/** @addtogroup STM32G0xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G0xx_System_Private_Defines
* @{
*/
/************************* Miscellaneous Configuration ************************/
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32G0xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G0xx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 16000000UL;
const uint32_t AHBPrescTable[16UL] = {0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL, 6UL, 7UL, 8UL, 9UL};
const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL};
/**
* @}
*/
/** @addtogroup STM32G0xx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32G0xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation */
#endif /* USER_VECT_TAB_ADDRESS */
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) / HSI division factor
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is LSI, SystemCoreClock will contain the LSI_VALUE
*
* - If SYSCLK source is LSE, SystemCoreClock will contain the LSE_VALUE
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (**) HSI_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32g0xx_hal_conf.h file (default value
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp;
uint32_t pllvco;
uint32_t pllr;
uint32_t pllsource;
uint32_t pllm;
uint32_t hsidiv;
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case RCC_CFGR_SWS_0: /* HSE used as system clock */
SystemCoreClock = HSE_VALUE;
break;
case (RCC_CFGR_SWS_1 | RCC_CFGR_SWS_0): /* LSI used as system clock */
SystemCoreClock = LSI_VALUE;
break;
case RCC_CFGR_SWS_2: /* LSE used as system clock */
SystemCoreClock = LSE_VALUE;
break;
case RCC_CFGR_SWS_1: /* PLL used as system clock */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL;
if(pllsource == 0x03UL) /* HSE used as PLL clock source */
{
pllvco = (HSE_VALUE / pllm);
}
else /* HSI used as PLL clock source */
{
pllvco = (HSI_VALUE / pllm);
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL);
SystemCoreClock = pllvco/pllr;
break;
case 0x00000000U: /* HSI used as system clock */
default: /* HSI used as system clock */
hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV))>> RCC_CR_HSIDIV_Pos));
SystemCoreClock = (HSI_VALUE/hsidiv);
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
/* HCLK clock frequency */
SystemCoreClock >>= tmp;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
+186
View File
@@ -0,0 +1,186 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart2_rx;
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 DMA Init */
/* USART2_TX Init */
hdma_usart2_tx.Instance = DMA1_Channel1;
hdma_usart2_tx.Init.Request = DMA_REQUEST_USART2_TX;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Channel2;
hdma_usart2_rx.Init.Request = DMA_REQUEST_USART2_RX;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_LPUART2_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART2_LPUART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* USART2 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmatx);
HAL_DMA_DeInit(uartHandle->hdmarx);
/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_LPUART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */