Compare commits

...

8 Commits

Author SHA1 Message Date
51f899bada 可以啊 2026-01-07 19:35:53 +08:00
88f306cdef 重构底层 2026-01-07 16:48:18 +08:00
0a9d6f80f4 太扯了 2026-01-07 02:23:52 +08:00
e0b2485aaf 改imu 2026-01-06 02:11:57 +08:00
31147537b5 dr16好了 2026-01-06 01:08:52 +08:00
21c0f7a4cd 2026-01-05 09:33:18 +08:00
3f43126f13 配置can 2026-01-03 00:28:44 +08:00
00cfee37c7 生成bsp 2026-01-02 23:29:19 +08:00
96 changed files with 10705 additions and 1948 deletions

BIN
.DS_Store vendored

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,7 @@ if(NOT CMAKE_BUILD_TYPE)
endif() endif()
# Set the project name # Set the project name
set(CMAKE_PROJECT_NAME balance_infantry) set(CMAKE_PROJECT_NAME CtrBoard-H7_ALL)
# Enable compile command to ease indexing with e.g. clangd # Enable compile command to ease indexing with e.g. clangd
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
@ -45,11 +45,47 @@ target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
# Add sources to executable # Add sources to executable
target_sources(${CMAKE_PROJECT_NAME} PRIVATE target_sources(${CMAKE_PROJECT_NAME} PRIVATE
# Add user sources here # Add user sources here
# User/bsp sources
User/bsp/fdcan.c
User/bsp/flash.c
User/bsp/gpio.c
User/bsp/mm.c
User/bsp/pwm.c
User/bsp/spi.c
User/bsp/time.c
User/bsp/uart.c
# User/component sources
User/component/ahrs.c
User/component/crc16.c
User/component/crc8.c
User/component/error_detect.c
User/component/filter.c
User/component/freertos_cli.c
User/component/pid.c
User/component/user_math.c
# User/device sources
User/device/bmi088.c
User/device/buzzer.c
User/device/dr16.c
User/device/motor.c
User/device/motor_dm.c
User/device/motor_lk.c
User/device/motor_lz.c
User/device/motor_rm.c
# User/task sources
User/task/atti_esit.c
User/task/init.c
User/task/rc.c
User/task/user_task.c
) )
# Add include paths # Add include paths
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
# Add user defined include paths # Add user defined include paths
User
) )
# Add project symbols (macros) # Add project symbols (macros)

View File

@ -68,7 +68,7 @@
#define configTICK_RATE_HZ ((TickType_t)1000) #define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 56 ) #define configMAX_PRIORITIES ( 56 )
#define configMINIMAL_STACK_SIZE ((uint16_t)128) #define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)15360) #define configTOTAL_HEAP_SIZE ((size_t)0x10000)
#define configMAX_TASK_NAME_LEN ( 16 ) #define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1 #define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0 #define configUSE_16_BIT_TICKS 0

View File

@ -59,24 +59,36 @@ void Error_Handler(void);
/* Private defines -----------------------------------------------------------*/ /* Private defines -----------------------------------------------------------*/
#define POWER_24V_2_Pin GPIO_PIN_13 #define POWER_24V_2_Pin GPIO_PIN_13
#define POWER_24V_2_GPIO_Port GPIOC #define POWER_24V_2_GPIO_Port GPIOC
#define POWER_24V_1_Pin GPIO_PIN_14
#define POWER_24V_1_GPIO_Port GPIOC
#define POWER_5V_Pin GPIO_PIN_15 #define POWER_5V_Pin GPIO_PIN_15
#define POWER_5V_GPIO_Port GPIOC #define POWER_5V_GPIO_Port GPIOC
#define ACC_CS_Pin GPIO_PIN_0 #define ACCL_CS_Pin GPIO_PIN_0
#define ACC_CS_GPIO_Port GPIOC #define ACCL_CS_GPIO_Port GPIOC
#define GYRO_CS_Pin GPIO_PIN_3 #define GYRO_CS_Pin GPIO_PIN_3
#define GYRO_CS_GPIO_Port GPIOC #define GYRO_CS_GPIO_Port GPIOC
#define ACC_INT_Pin GPIO_PIN_10 #define DCMI_PWDN_Pin GPIO_PIN_5
#define ACC_INT_GPIO_Port GPIOE #define DCMI_PWDN_GPIO_Port GPIOC
#define W25Q64_CS_Pin GPIO_PIN_11 #define IMU_HEAT_Pin GPIO_PIN_1
#define W25Q64_CS_GPIO_Port GPIOE #define IMU_HEAT_GPIO_Port GPIOB
#define ACCL_INT_Pin GPIO_PIN_10
#define ACCL_INT_GPIO_Port GPIOE
#define ACCL_INT_EXTI_IRQn EXTI15_10_IRQn
#define GYRO_INT_Pin GPIO_PIN_12 #define GYRO_INT_Pin GPIO_PIN_12
#define GYRO_INT_GPIO_Port GPIOE #define GYRO_INT_GPIO_Port GPIOE
#define GYRO_INT_EXTI_IRQn EXTI15_10_IRQn
#define LCD_CS_Pin GPIO_PIN_15 #define LCD_CS_Pin GPIO_PIN_15
#define LCD_CS_GPIO_Port GPIOE #define LCD_CS_GPIO_Port GPIOE
#define LCD_BLK_Pin GPIO_PIN_10 #define LCD_BLK_Pin GPIO_PIN_10
#define LCD_BLK_GPIO_Port GPIOB #define LCD_BLK_GPIO_Port GPIOB
#define LCD_RES_Pin GPIO_PIN_11 #define LCD_RES_Pin GPIO_PIN_11
#define LCD_RES_GPIO_Port GPIOB #define LCD_RES_GPIO_Port GPIOB
#define DCMI_REST_Pin GPIO_PIN_12
#define DCMI_REST_GPIO_Port GPIOB
#define BUZZER_Pin GPIO_PIN_15
#define BUZZER_GPIO_Port GPIOB
#define LCD_DC_Pin GPIO_PIN_10
#define LCD_DC_GPIO_Port GPIOD
/* USER CODE BEGIN Private defines */ /* USER CODE BEGIN Private defines */

View File

@ -1,9 +1,9 @@
/* USER CODE BEGIN Header */ /* USER CODE BEGIN Header */
/** /**
****************************************************************************** ******************************************************************************
* @file dac.h * @file octospi.h
* @brief This file contains all the function prototypes for * @brief This file contains all the function prototypes for
* the dac.c file * the octospi.c file
****************************************************************************** ******************************************************************************
* @attention * @attention
* *
@ -18,8 +18,8 @@
*/ */
/* USER CODE END Header */ /* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/ /* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DAC_H__ #ifndef __OCTOSPI_H__
#define __DAC_H__ #define __OCTOSPI_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -32,13 +32,13 @@ extern "C" {
/* USER CODE END Includes */ /* USER CODE END Includes */
extern DAC_HandleTypeDef hdac1; extern OSPI_HandleTypeDef hospi1;
/* USER CODE BEGIN Private defines */ /* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */ /* USER CODE END Private defines */
void MX_DAC1_Init(void); void MX_OCTOSPI1_Init(void);
/* USER CODE BEGIN Prototypes */ /* USER CODE BEGIN Prototypes */
@ -48,5 +48,5 @@ void MX_DAC1_Init(void);
} }
#endif #endif
#endif /* __DAC_H__ */ #endif /* __OCTOSPI_H__ */

View File

@ -32,16 +32,16 @@ extern "C" {
/* USER CODE END Includes */ /* USER CODE END Includes */
extern SPI_HandleTypeDef hspi2; extern SPI_HandleTypeDef hspi1;
extern SPI_HandleTypeDef hspi6; extern SPI_HandleTypeDef hspi2;
/* USER CODE BEGIN Private defines */ /* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */ /* USER CODE END Private defines */
void MX_SPI1_Init(void);
void MX_SPI2_Init(void); void MX_SPI2_Init(void);
void MX_SPI6_Init(void);
/* USER CODE BEGIN Prototypes */ /* USER CODE BEGIN Prototypes */

View File

@ -42,7 +42,7 @@
/* #define HAL_CORDIC_MODULE_ENABLED */ /* #define HAL_CORDIC_MODULE_ENABLED */
/* #define HAL_CRC_MODULE_ENABLED */ /* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */ /* #define HAL_CRYP_MODULE_ENABLED */
#define HAL_DAC_MODULE_ENABLED /* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_DCMI_MODULE_ENABLED */ /* #define HAL_DCMI_MODULE_ENABLED */
/* #define HAL_DMA2D_MODULE_ENABLED */ /* #define HAL_DMA2D_MODULE_ENABLED */
/* #define HAL_ETH_MODULE_ENABLED */ /* #define HAL_ETH_MODULE_ENABLED */
@ -58,7 +58,7 @@
/* #define HAL_GFXMMU_MODULE_ENABLED */ /* #define HAL_GFXMMU_MODULE_ENABLED */
/* #define HAL_JPEG_MODULE_ENABLED */ /* #define HAL_JPEG_MODULE_ENABLED */
/* #define HAL_OPAMP_MODULE_ENABLED */ /* #define HAL_OPAMP_MODULE_ENABLED */
/* #define HAL_OSPI_MODULE_ENABLED */ #define HAL_OSPI_MODULE_ENABLED
/* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */
/* #define HAL_SMBUS_MODULE_ENABLED */ /* #define HAL_SMBUS_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */

View File

@ -56,33 +56,21 @@ void DMA1_Stream0_IRQHandler(void);
void DMA1_Stream1_IRQHandler(void); void DMA1_Stream1_IRQHandler(void);
void DMA1_Stream2_IRQHandler(void); void DMA1_Stream2_IRQHandler(void);
void DMA1_Stream3_IRQHandler(void); void DMA1_Stream3_IRQHandler(void);
void DMA1_Stream4_IRQHandler(void);
void DMA1_Stream5_IRQHandler(void);
void DMA1_Stream6_IRQHandler(void);
void FDCAN1_IT0_IRQHandler(void); void FDCAN1_IT0_IRQHandler(void);
void FDCAN2_IT0_IRQHandler(void); void FDCAN2_IT0_IRQHandler(void);
void FDCAN1_IT1_IRQHandler(void); void FDCAN1_IT1_IRQHandler(void);
void FDCAN2_IT1_IRQHandler(void); void FDCAN2_IT1_IRQHandler(void);
void TIM4_IRQHandler(void);
void SPI2_IRQHandler(void); void SPI2_IRQHandler(void);
void USART1_IRQHandler(void); void USART1_IRQHandler(void);
void USART2_IRQHandler(void); void USART2_IRQHandler(void);
void USART3_IRQHandler(void); void USART3_IRQHandler(void);
void DMA1_Stream7_IRQHandler(void); void EXTI15_10_IRQHandler(void);
void UART5_IRQHandler(void); void UART5_IRQHandler(void);
void DMA2_Stream0_IRQHandler(void);
void DMA2_Stream1_IRQHandler(void);
void DMA2_Stream2_IRQHandler(void);
void DMA2_Stream3_IRQHandler(void);
void DMA2_Stream4_IRQHandler(void);
void DMA2_Stream5_IRQHandler(void);
void OTG_HS_IRQHandler(void);
void UART7_IRQHandler(void); void UART7_IRQHandler(void);
void SPI6_IRQHandler(void);
void BDMA_Channel0_IRQHandler(void);
void USART10_IRQHandler(void); void USART10_IRQHandler(void);
void FDCAN3_IT0_IRQHandler(void); void FDCAN3_IT0_IRQHandler(void);
void FDCAN3_IT1_IRQHandler(void); void FDCAN3_IT1_IRQHandler(void);
void TIM23_IRQHandler(void);
/* USER CODE BEGIN EFP */ /* USER CODE BEGIN EFP */
/* USER CODE END EFP */ /* USER CODE END EFP */

View File

@ -105,11 +105,30 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{ {
GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(adcHandle->Instance==ADC1) if(adcHandle->Instance==ADC1)
{ {
/* USER CODE BEGIN ADC1_MspInit 0 */ /* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */ /* USER CODE END ADC1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLL2.PLL2M = 2;
PeriphClkInitStruct.PLL2.PLL2N = 16;
PeriphClkInitStruct.PLL2.PLL2P = 2;
PeriphClkInitStruct.PLL2.PLL2Q = 2;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* ADC1 clock enable */ /* ADC1 clock enable */
__HAL_RCC_ADC12_CLK_ENABLE(); __HAL_RCC_ADC12_CLK_ENABLE();

View File

@ -1,55 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file bdma.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 "bdma.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_BDMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_BDMA_CLK_ENABLE();
/* DMA interrupt init */
/* BDMA_Channel0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(BDMA_Channel0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(BDMA_Channel0_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */

View File

@ -1,102 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dac.c
* @brief This file provides code for the configuration
* of the DAC 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 "dac.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
DAC_HandleTypeDef hdac1;
/* DAC1 init function */
void MX_DAC1_Init(void)
{
/* USER CODE BEGIN DAC1_Init 0 */
/* USER CODE END DAC1_Init 0 */
DAC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN DAC1_Init 1 */
/* USER CODE END DAC1_Init 1 */
/** DAC Initialization
*/
hdac1.Instance = DAC1;
if (HAL_DAC_Init(&hdac1) != HAL_OK)
{
Error_Handler();
}
/** DAC channel OUT2 config
*/
sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE;
sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN DAC1_Init 2 */
/* USER CODE END DAC1_Init 2 */
}
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{
if(dacHandle->Instance==DAC1)
{
/* USER CODE BEGIN DAC1_MspInit 0 */
/* USER CODE END DAC1_MspInit 0 */
/* DAC1 clock enable */
__HAL_RCC_DAC12_CLK_ENABLE();
/* USER CODE BEGIN DAC1_MspInit 1 */
/* USER CODE END DAC1_MspInit 1 */
}
}
void HAL_DAC_MspDeInit(DAC_HandleTypeDef* dacHandle)
{
if(dacHandle->Instance==DAC1)
{
/* USER CODE BEGIN DAC1_MspDeInit 0 */
/* USER CODE END DAC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_DAC12_CLK_DISABLE();
/* USER CODE BEGIN DAC1_MspDeInit 1 */
/* USER CODE END DAC1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@ -41,7 +41,6 @@ void MX_DMA_Init(void)
/* DMA controller clock enable */ /* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */ /* DMA interrupt init */
/* DMA1_Stream0_IRQn interrupt configuration */ /* DMA1_Stream0_IRQn interrupt configuration */
@ -56,36 +55,6 @@ void MX_DMA_Init(void)
/* DMA1_Stream3_IRQn interrupt configuration */ /* DMA1_Stream3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 5, 0); HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn); HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
/* DMA1_Stream4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
/* DMA1_Stream5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* DMA1_Stream6_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);
/* DMA1_Stream7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);
/* DMA2_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
/* DMA2_Stream1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
/* DMA2_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
/* DMA2_Stream3_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
/* DMA2_Stream4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);
/* DMA2_Stream5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
} }

View File

@ -42,31 +42,31 @@ void MX_FDCAN1_Init(void)
hfdcan1.Instance = FDCAN1; hfdcan1.Instance = FDCAN1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC; hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL; hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE; hfdcan1.Init.AutoRetransmission = DISABLE;
hfdcan1.Init.TransmitPause = DISABLE; hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = DISABLE; hfdcan1.Init.ProtocolException = DISABLE;
hfdcan1.Init.NominalPrescaler = 5; hfdcan1.Init.NominalPrescaler = 24;
hfdcan1.Init.NominalSyncJumpWidth = 10; hfdcan1.Init.NominalSyncJumpWidth = 1;
hfdcan1.Init.NominalTimeSeg1 = 9; hfdcan1.Init.NominalTimeSeg1 = 3;
hfdcan1.Init.NominalTimeSeg2 = 1; hfdcan1.Init.NominalTimeSeg2 = 1;
hfdcan1.Init.DataPrescaler = 1; hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 10; hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 9; hfdcan1.Init.DataTimeSeg1 = 1;
hfdcan1.Init.DataTimeSeg2 = 1; hfdcan1.Init.DataTimeSeg2 = 1;
hfdcan1.Init.MessageRAMOffset = 0; hfdcan1.Init.MessageRAMOffset = 0;
hfdcan1.Init.StdFiltersNbr = 1; hfdcan1.Init.StdFiltersNbr = 1;
hfdcan1.Init.ExtFiltersNbr = 1; hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.RxFifo0ElmtsNbr = 23; hfdcan1.Init.RxFifo0ElmtsNbr = 32;
hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64; hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxFifo1ElmtsNbr = 0; hfdcan1.Init.RxFifo1ElmtsNbr = 0;
hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64; hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.RxBuffersNbr = 0; hfdcan1.Init.RxBuffersNbr = 0;
hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_64; hfdcan1.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan1.Init.TxEventsNbr = 0; hfdcan1.Init.TxEventsNbr = 0;
hfdcan1.Init.TxBuffersNbr = 0; hfdcan1.Init.TxBuffersNbr = 0;
hfdcan1.Init.TxFifoQueueElmtsNbr = 23; hfdcan1.Init.TxFifoQueueElmtsNbr = 32;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_64; hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@ -90,31 +90,31 @@ void MX_FDCAN2_Init(void)
hfdcan2.Instance = FDCAN2; hfdcan2.Instance = FDCAN2;
hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan2.Init.AutoRetransmission = ENABLE; hfdcan2.Init.AutoRetransmission = DISABLE;
hfdcan2.Init.TransmitPause = DISABLE; hfdcan2.Init.TransmitPause = DISABLE;
hfdcan2.Init.ProtocolException = DISABLE; hfdcan2.Init.ProtocolException = DISABLE;
hfdcan2.Init.NominalPrescaler = 5; hfdcan2.Init.NominalPrescaler = 24;
hfdcan2.Init.NominalSyncJumpWidth = 10; hfdcan2.Init.NominalSyncJumpWidth = 1;
hfdcan2.Init.NominalTimeSeg1 = 9; hfdcan2.Init.NominalTimeSeg1 = 3;
hfdcan2.Init.NominalTimeSeg2 = 1; hfdcan2.Init.NominalTimeSeg2 = 1;
hfdcan2.Init.DataPrescaler = 1; hfdcan2.Init.DataPrescaler = 1;
hfdcan2.Init.DataSyncJumpWidth = 10; hfdcan2.Init.DataSyncJumpWidth = 1;
hfdcan2.Init.DataTimeSeg1 = 9; hfdcan2.Init.DataTimeSeg1 = 1;
hfdcan2.Init.DataTimeSeg2 = 1; hfdcan2.Init.DataTimeSeg2 = 1;
hfdcan2.Init.MessageRAMOffset = 831; hfdcan2.Init.MessageRAMOffset = 0x406;
hfdcan2.Init.StdFiltersNbr = 1; hfdcan2.Init.StdFiltersNbr = 1;
hfdcan2.Init.ExtFiltersNbr = 1; hfdcan2.Init.ExtFiltersNbr = 0;
hfdcan2.Init.RxFifo0ElmtsNbr = 0; hfdcan2.Init.RxFifo0ElmtsNbr = 32;
hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64; hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan2.Init.RxFifo1ElmtsNbr = 23; hfdcan2.Init.RxFifo1ElmtsNbr = 0;
hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64; hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan2.Init.RxBuffersNbr = 0; hfdcan2.Init.RxBuffersNbr = 0;
hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_64; hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan2.Init.TxEventsNbr = 0; hfdcan2.Init.TxEventsNbr = 0;
hfdcan2.Init.TxBuffersNbr = 0; hfdcan2.Init.TxBuffersNbr = 0;
hfdcan2.Init.TxFifoQueueElmtsNbr = 23; hfdcan2.Init.TxFifoQueueElmtsNbr = 32;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_64; hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@ -138,31 +138,31 @@ void MX_FDCAN3_Init(void)
hfdcan3.Instance = FDCAN3; hfdcan3.Instance = FDCAN3;
hfdcan3.Init.FrameFormat = FDCAN_FRAME_CLASSIC; hfdcan3.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan3.Init.Mode = FDCAN_MODE_NORMAL; hfdcan3.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan3.Init.AutoRetransmission = ENABLE; hfdcan3.Init.AutoRetransmission = DISABLE;
hfdcan3.Init.TransmitPause = DISABLE; hfdcan3.Init.TransmitPause = DISABLE;
hfdcan3.Init.ProtocolException = DISABLE; hfdcan3.Init.ProtocolException = DISABLE;
hfdcan3.Init.NominalPrescaler = 5; hfdcan3.Init.NominalPrescaler = 24;
hfdcan3.Init.NominalSyncJumpWidth = 10; hfdcan3.Init.NominalSyncJumpWidth = 1;
hfdcan3.Init.NominalTimeSeg1 = 9; hfdcan3.Init.NominalTimeSeg1 = 3;
hfdcan3.Init.NominalTimeSeg2 = 1; hfdcan3.Init.NominalTimeSeg2 = 1;
hfdcan3.Init.DataPrescaler = 1; hfdcan3.Init.DataPrescaler = 1;
hfdcan3.Init.DataSyncJumpWidth = 10; hfdcan3.Init.DataSyncJumpWidth = 1;
hfdcan3.Init.DataTimeSeg1 = 9; hfdcan3.Init.DataTimeSeg1 = 1;
hfdcan3.Init.DataTimeSeg2 = 1; hfdcan3.Init.DataTimeSeg2 = 1;
hfdcan3.Init.MessageRAMOffset = 1662; hfdcan3.Init.MessageRAMOffset = 0x812;
hfdcan3.Init.StdFiltersNbr = 1; hfdcan3.Init.StdFiltersNbr = 1;
hfdcan3.Init.ExtFiltersNbr = 1; hfdcan3.Init.ExtFiltersNbr = 0;
hfdcan3.Init.RxFifo0ElmtsNbr = 0; hfdcan3.Init.RxFifo0ElmtsNbr = 32;
hfdcan3.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64; hfdcan3.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan3.Init.RxFifo1ElmtsNbr = 23; hfdcan3.Init.RxFifo1ElmtsNbr = 0;
hfdcan3.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64; hfdcan3.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan3.Init.RxBuffersNbr = 0; hfdcan3.Init.RxBuffersNbr = 0;
hfdcan3.Init.RxBufferSize = FDCAN_DATA_BYTES_64; hfdcan3.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan3.Init.TxEventsNbr = 0; hfdcan3.Init.TxEventsNbr = 0;
hfdcan3.Init.TxBuffersNbr = 0; hfdcan3.Init.TxBuffersNbr = 0;
hfdcan3.Init.TxFifoQueueElmtsNbr = 23; hfdcan3.Init.TxFifoQueueElmtsNbr = 32;
hfdcan3.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; hfdcan3.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan3.Init.TxElmtSize = FDCAN_DATA_BYTES_64; hfdcan3.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
if (HAL_FDCAN_Init(&hfdcan3) != HAL_OK) if (HAL_FDCAN_Init(&hfdcan3) != HAL_OK)
{ {
Error_Handler(); Error_Handler();

View File

@ -26,6 +26,7 @@
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "task/user_task.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
@ -96,6 +97,7 @@ void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN RTOS_THREADS */ /* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */ /* add threads, ... */
osThreadNew(Task_Init, NULL, &attr_init); // 创建初始化任务
/* USER CODE END RTOS_THREADS */ /* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */ /* USER CODE BEGIN RTOS_EVENTS */
@ -114,11 +116,7 @@ void MX_FREERTOS_Init(void) {
void StartDefaultTask(void *argument) void StartDefaultTask(void *argument)
{ {
/* USER CODE BEGIN StartDefaultTask */ /* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */ osThreadTerminate(osThreadGetId());
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */ /* USER CODE END StartDefaultTask */
} }

View File

@ -38,6 +38,7 @@
* Output * Output
* EVENT_OUT * EVENT_OUT
* EXTI * EXTI
PA8 ------> RCC_MCO_1
*/ */
void MX_GPIO_Init(void) void MX_GPIO_Init(void)
{ {
@ -53,43 +54,47 @@ void MX_GPIO_Init(void)
__HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */ /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, POWER_24V_2_Pin|POWER_5V_Pin|ACC_CS_Pin|GYRO_CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC, POWER_24V_2_Pin|POWER_24V_1_Pin|POWER_5V_Pin|ACCL_CS_Pin
|GYRO_CS_Pin|DCMI_PWDN_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */ /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOE, W25Q64_CS_Pin|LCD_CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */ /*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LCD_BLK_Pin|LCD_RES_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOB, LCD_BLK_Pin|LCD_RES_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : POWER_24V_2_Pin PC14 POWER_5V_Pin */ /*Configure GPIO pin Output Level */
GPIO_InitStruct.Pin = POWER_24V_2_Pin|GPIO_PIN_14|POWER_5V_Pin; HAL_GPIO_WritePin(DCMI_REST_GPIO_Port, DCMI_REST_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LCD_DC_GPIO_Port, LCD_DC_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : POWER_24V_2_Pin POWER_24V_1_Pin POWER_5V_Pin */
GPIO_InitStruct.Pin = POWER_24V_2_Pin|POWER_24V_1_Pin|POWER_5V_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : ACC_CS_Pin GYRO_CS_Pin */ /*Configure GPIO pins : ACCL_CS_Pin GYRO_CS_Pin DCMI_PWDN_Pin */
GPIO_InitStruct.Pin = ACC_CS_Pin|GYRO_CS_Pin; GPIO_InitStruct.Pin = ACCL_CS_Pin|GYRO_CS_Pin|DCMI_PWDN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : ACC_INT_Pin GYRO_INT_Pin */ /*Configure GPIO pins : ACCL_INT_Pin GYRO_INT_Pin */
GPIO_InitStruct.Pin = ACC_INT_Pin|GYRO_INT_Pin; GPIO_InitStruct.Pin = ACCL_INT_Pin|GYRO_INT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/*Configure GPIO pins : W25Q64_CS_Pin LCD_CS_Pin */ /*Configure GPIO pin : LCD_CS_Pin */
GPIO_InitStruct.Pin = W25Q64_CS_Pin|LCD_CS_Pin; GPIO_InitStruct.Pin = LCD_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); HAL_GPIO_Init(LCD_CS_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : LCD_BLK_Pin LCD_RES_Pin */ /*Configure GPIO pins : LCD_BLK_Pin LCD_RES_Pin */
GPIO_InitStruct.Pin = LCD_BLK_Pin|LCD_RES_Pin; GPIO_InitStruct.Pin = LCD_BLK_Pin|LCD_RES_Pin;
@ -98,6 +103,28 @@ void MX_GPIO_Init(void)
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : DCMI_REST_Pin */
GPIO_InitStruct.Pin = DCMI_REST_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(DCMI_REST_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : LCD_DC_Pin */
GPIO_InitStruct.Pin = LCD_DC_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_DC_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : PA8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PA15 */ /*Configure GPIO pin : PA15 */
GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
@ -107,6 +134,10 @@ void MX_GPIO_Init(void)
/*AnalogSwitch Config */ /*AnalogSwitch Config */
HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_CLOSE); HAL_SYSCFG_AnalogSwitchConfig(SYSCFG_SWITCH_PC3, SYSCFG_SWITCH_PC3_CLOSE);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
} }
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */

View File

@ -20,10 +20,9 @@
#include "main.h" #include "main.h"
#include "cmsis_os.h" #include "cmsis_os.h"
#include "adc.h" #include "adc.h"
#include "bdma.h"
#include "dac.h"
#include "dma.h" #include "dma.h"
#include "fdcan.h" #include "fdcan.h"
#include "octospi.h"
#include "spi.h" #include "spi.h"
#include "tim.h" #include "tim.h"
#include "usart.h" #include "usart.h"
@ -58,7 +57,6 @@
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void); void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
void MX_FREERTOS_Init(void); void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP */ /* USER CODE BEGIN PFP */
@ -80,14 +78,6 @@ int main(void)
/* USER CODE END 1 */ /* USER CODE END 1 */
/* Enable the CPU Cache */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* MCU Configuration--------------------------------------------------------*/ /* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
@ -100,9 +90,6 @@ int main(void)
/* Configure the system clock */ /* Configure the system clock */
SystemClock_Config(); SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */ /* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */ /* USER CODE END SysInit */
@ -110,10 +97,9 @@ int main(void)
/* Initialize all configured peripherals */ /* Initialize all configured peripherals */
MX_GPIO_Init(); MX_GPIO_Init();
MX_DMA_Init(); MX_DMA_Init();
MX_BDMA_Init();
MX_ADC1_Init(); MX_ADC1_Init();
MX_TIM12_Init(); MX_TIM12_Init();
MX_SPI6_Init(); MX_SPI1_Init();
MX_SPI2_Init(); MX_SPI2_Init();
MX_TIM3_Init(); MX_TIM3_Init();
MX_USART1_UART_Init(); MX_USART1_UART_Init();
@ -126,7 +112,7 @@ int main(void)
MX_FDCAN3_Init(); MX_FDCAN3_Init();
MX_TIM1_Init(); MX_TIM1_Init();
MX_TIM2_Init(); MX_TIM2_Init();
MX_DAC1_Init(); MX_OCTOSPI1_Init();
MX_USB_OTG_HS_PCD_Init(); MX_USB_OTG_HS_PCD_Init();
MX_UART5_Init(); MX_UART5_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
@ -175,19 +161,22 @@ void SystemClock_Config(void)
/** Initializes the RCC Oscillators according to the specified parameters /** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure. * in the RCC_OscInitTypeDef structure.
*/ */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI
|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = 64;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 3; RCC_OscInitStruct.PLL.PLLM = 2;
RCC_OscInitStruct.PLL.PLLN = 68; RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLP = 1; RCC_OscInitStruct.PLL.PLLP = 1;
RCC_OscInitStruct.PLL.PLLQ = 10; RCC_OscInitStruct.PLL.PLLQ = 4;
RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 6144; RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@ -210,33 +199,7 @@ void SystemClock_Config(void)
{ {
Error_Handler(); Error_Handler();
} }
} HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1);
/**
* @brief Peripherals Common Clock Configuration
* @retval None
*/
void PeriphCommonClock_Config(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_SPI2;
PeriphClkInitStruct.PLL2.PLL2M = 2;
PeriphClkInitStruct.PLL2.PLL2N = 16;
PeriphClkInitStruct.PLL2.PLL2P = 3;
PeriphClkInitStruct.PLL2.PLL2Q = 2;
PeriphClkInitStruct.PLL2.PLL2R = 2;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL2;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
} }
/* USER CODE BEGIN 4 */ /* USER CODE BEGIN 4 */
@ -245,7 +208,7 @@ void PeriphCommonClock_Config(void)
/** /**
* @brief Period elapsed callback in non blocking mode * @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM4 interrupt took place, inside * @note This function is called when TIM23 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base. * a global variable "uwTick" used as application time base.
* @param htim : TIM handle * @param htim : TIM handle
@ -256,7 +219,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
/* USER CODE BEGIN Callback 0 */ /* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */ /* USER CODE END Callback 0 */
if (htim->Instance == TIM4) if (htim->Instance == TIM23)
{ {
HAL_IncTick(); HAL_IncTick();
} }

195
Core/Src/octospi.c Normal file
View File

@ -0,0 +1,195 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file octospi.c
* @brief This file provides code for the configuration
* of the OCTOSPI 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 "octospi.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
OSPI_HandleTypeDef hospi1;
/* OCTOSPI1 init function */
void MX_OCTOSPI1_Init(void)
{
/* USER CODE BEGIN OCTOSPI1_Init 0 */
/* USER CODE END OCTOSPI1_Init 0 */
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
/* USER CODE BEGIN OCTOSPI1_Init 1 */
/* USER CODE END OCTOSPI1_Init 1 */
hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 1;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
hospi1.Init.DeviceSize = 32;
hospi1.Init.ChipSelectHighTime = 1;
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
hospi1.Init.ClockPrescaler = 1;
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi1.Init.ChipSelectBoundary = 0;
hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi1.Init.MaxTran = 0;
hospi1.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}
sOspiManagerCfg.ClkPort = 1;
sOspiManagerCfg.NCSPort = 1;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI1_Init 2 */
/* USER CODE END OCTOSPI1_Init 2 */
}
void HAL_OSPI_MspInit(OSPI_HandleTypeDef* ospiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(ospiHandle->Instance==OCTOSPI1)
{
/* USER CODE BEGIN OCTOSPI1_MspInit 0 */
/* USER CODE END OCTOSPI1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
PeriphClkInitStruct.OspiClockSelection = RCC_OSPICLKSOURCE_D1HCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* OCTOSPI1 clock enable */
__HAL_RCC_OCTOSPIM_CLK_ENABLE();
__HAL_RCC_OSPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**OCTOSPI1 GPIO Configuration
PA1 ------> OCTOSPIM_P1_IO3
PA3 ------> OCTOSPIM_P1_IO2
PB0 ------> OCTOSPIM_P1_IO1
PB2 ------> OCTOSPIM_P1_CLK
PE11 ------> OCTOSPIM_P1_NCS
PD11 ------> OCTOSPIM_P1_IO0
*/
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF11_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN OCTOSPI1_MspInit 1 */
/* USER CODE END OCTOSPI1_MspInit 1 */
}
}
void HAL_OSPI_MspDeInit(OSPI_HandleTypeDef* ospiHandle)
{
if(ospiHandle->Instance==OCTOSPI1)
{
/* USER CODE BEGIN OCTOSPI1_MspDeInit 0 */
/* USER CODE END OCTOSPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_OCTOSPIM_CLK_DISABLE();
__HAL_RCC_OSPI1_CLK_DISABLE();
/**OCTOSPI1 GPIO Configuration
PA1 ------> OCTOSPIM_P1_IO3
PA3 ------> OCTOSPIM_P1_IO2
PB0 ------> OCTOSPIM_P1_IO1
PB2 ------> OCTOSPIM_P1_CLK
PE11 ------> OCTOSPIM_P1_NCS
PD11 ------> OCTOSPIM_P1_IO0
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_3);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0|GPIO_PIN_2);
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_11);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_11);
/* USER CODE BEGIN OCTOSPI1_MspDeInit 1 */
/* USER CODE END OCTOSPI1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@ -24,12 +24,53 @@
/* USER CODE END 0 */ /* USER CODE END 0 */
SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2; SPI_HandleTypeDef hspi2;
SPI_HandleTypeDef hspi6;
DMA_HandleTypeDef hdma_spi2_rx; DMA_HandleTypeDef hdma_spi2_rx;
DMA_HandleTypeDef hdma_spi2_tx; DMA_HandleTypeDef hdma_spi2_tx;
DMA_HandleTypeDef hdma_spi6_tx;
/* SPI1 init function */
void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 0x0;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
hspi1.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hspi1.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hspi1.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi1.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi1.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
hspi1.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
hspi1.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
hspi1.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
hspi1.Init.IOSwap = SPI_IO_SWAP_DISABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
/* SPI2 init function */ /* SPI2 init function */
void MX_SPI2_Init(void) void MX_SPI2_Init(void)
{ {
@ -71,48 +112,6 @@ void MX_SPI2_Init(void)
/* USER CODE END SPI2_Init 2 */ /* USER CODE END SPI2_Init 2 */
}
/* SPI6 init function */
void MX_SPI6_Init(void)
{
/* USER CODE BEGIN SPI6_Init 0 */
/* USER CODE END SPI6_Init 0 */
/* USER CODE BEGIN SPI6_Init 1 */
/* USER CODE END SPI6_Init 1 */
hspi6.Instance = SPI6;
hspi6.Init.Mode = SPI_MODE_MASTER;
hspi6.Init.Direction = SPI_DIRECTION_2LINES_TXONLY;
hspi6.Init.DataSize = SPI_DATASIZE_8BIT;
hspi6.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi6.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi6.Init.NSS = SPI_NSS_SOFT;
hspi6.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi6.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi6.Init.TIMode = SPI_TIMODE_DISABLE;
hspi6.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi6.Init.CRCPolynomial = 0x0;
hspi6.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
hspi6.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;
hspi6.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
hspi6.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi6.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
hspi6.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
hspi6.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
hspi6.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
hspi6.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
hspi6.Init.IOSwap = SPI_IO_SWAP_DISABLE;
if (HAL_SPI_Init(&hspi6) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI6_Init 2 */
/* USER CODE END SPI6_Init 2 */
} }
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
@ -120,12 +119,63 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(spiHandle->Instance==SPI2) if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI1 GPIO Configuration
PD7 ------> SPI1_MOSI
PB3(JTDO/TRACESWO) ------> SPI1_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
else if(spiHandle->Instance==SPI2)
{ {
/* USER CODE BEGIN SPI2_MspInit 0 */ /* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */ /* USER CODE END SPI2_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI2;
PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI2 clock enable */ /* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_SPI2_CLK_ENABLE();
@ -152,7 +202,7 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
/* SPI2 DMA Init */ /* SPI2 DMA Init */
/* SPI2_RX Init */ /* SPI2_RX Init */
hdma_spi2_rx.Instance = DMA1_Stream2; hdma_spi2_rx.Instance = DMA1_Stream1;
hdma_spi2_rx.Init.Request = DMA_REQUEST_SPI2_RX; hdma_spi2_rx.Init.Request = DMA_REQUEST_SPI2_RX;
hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
@ -170,7 +220,7 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
__HAL_LINKDMA(spiHandle,hdmarx,hdma_spi2_rx); __HAL_LINKDMA(spiHandle,hdmarx,hdma_spi2_rx);
/* SPI2_TX Init */ /* SPI2_TX Init */
hdma_spi2_tx.Instance = DMA1_Stream3; hdma_spi2_tx.Instance = DMA1_Stream2;
hdma_spi2_tx.Init.Request = DMA_REQUEST_SPI2_TX; hdma_spi2_tx.Init.Request = DMA_REQUEST_SPI2_TX;
hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
@ -194,75 +244,32 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
/* USER CODE END SPI2_MspInit 1 */ /* USER CODE END SPI2_MspInit 1 */
} }
else if(spiHandle->Instance==SPI6)
{
/* USER CODE BEGIN SPI6_MspInit 0 */
/* USER CODE END SPI6_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6;
PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_HSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* SPI6 clock enable */
__HAL_RCC_SPI6_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI6 GPIO Configuration
PA7 ------> SPI6_MOSI
PB3(JTDO/TRACESWO) ------> SPI6_SCK
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF8_SPI6;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = 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_AF8_SPI6;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI6 DMA Init */
/* SPI6_TX Init */
hdma_spi6_tx.Instance = BDMA_Channel0;
hdma_spi6_tx.Init.Request = BDMA_REQUEST_SPI6_TX;
hdma_spi6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi6_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi6_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi6_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi6_tx.Init.Mode = DMA_NORMAL;
hdma_spi6_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_spi6_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(spiHandle,hdmatx,hdma_spi6_tx);
/* SPI6 interrupt Init */
HAL_NVIC_SetPriority(SPI6_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI6_IRQn);
/* USER CODE BEGIN SPI6_MspInit 1 */
/* USER CODE END SPI6_MspInit 1 */
}
} }
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{ {
if(spiHandle->Instance==SPI2) if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */
/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**SPI1 GPIO Configuration
PD7 ------> SPI1_MOSI
PB3(JTDO/TRACESWO) ------> SPI1_SCK
*/
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_7);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3);
/* USER CODE BEGIN SPI1_MspDeInit 1 */
/* USER CODE END SPI1_MspDeInit 1 */
}
else if(spiHandle->Instance==SPI2)
{ {
/* USER CODE BEGIN SPI2_MspDeInit 0 */ /* USER CODE BEGIN SPI2_MspDeInit 0 */
@ -289,31 +296,6 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
/* USER CODE END SPI2_MspDeInit 1 */ /* USER CODE END SPI2_MspDeInit 1 */
} }
else if(spiHandle->Instance==SPI6)
{
/* USER CODE BEGIN SPI6_MspDeInit 0 */
/* USER CODE END SPI6_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI6_CLK_DISABLE();
/**SPI6 GPIO Configuration
PA7 ------> SPI6_MOSI
PB3(JTDO/TRACESWO) ------> SPI6_SCK
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_7);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3);
/* SPI6 DMA DeInit */
HAL_DMA_DeInit(spiHandle->hdmatx);
/* SPI6 interrupt Deinit */
HAL_NVIC_DisableIRQ(SPI6_IRQn);
/* USER CODE BEGIN SPI6_MspDeInit 1 */
/* USER CODE END SPI6_MspDeInit 1 */
}
} }
/* USER CODE BEGIN 1 */ /* USER CODE BEGIN 1 */

View File

@ -25,12 +25,12 @@
/* Private define ------------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim4; TIM_HandleTypeDef htim23;
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/ /* Private functions ---------------------------------------------------------*/
/** /**
* @brief This function configures the TIM4 as a time base source. * @brief This function configures the TIM23 as a time base source.
* The time source is configured to have 1ms time base with a dedicated * The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority. * Tick interrupt priority.
* @note This function is called automatically at the beginning of program after * @note This function is called automatically at the beginning of program after
@ -41,17 +41,17 @@ TIM_HandleTypeDef htim4;
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{ {
RCC_ClkInitTypeDef clkconfig; RCC_ClkInitTypeDef clkconfig;
uint32_t uwTimclock, uwAPB1Prescaler; uint32_t uwTimclock;
uint32_t uwPrescalerValue; uint32_t uwPrescalerValue;
uint32_t pFLatency; uint32_t pFLatency;
/*Configure the TIM4 IRQ priority */ /*Configure the TIM23 IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS)) if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{ {
HAL_NVIC_SetPriority(TIM4_IRQn, TickPriority ,0); HAL_NVIC_SetPriority(TIM23_IRQn, TickPriority ,0);
/* Enable the TIM4 global Interrupt */ /* Enable the TIM23 global Interrupt */
HAL_NVIC_EnableIRQ(TIM4_IRQn); HAL_NVIC_EnableIRQ(TIM23_IRQn);
uwTickPrio = TickPriority; uwTickPrio = TickPriority;
} }
else else
@ -59,45 +59,36 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
return HAL_ERROR; return HAL_ERROR;
} }
/* Enable TIM4 clock */ /* Enable TIM23 clock */
__HAL_RCC_TIM4_CLK_ENABLE(); __HAL_RCC_TIM23_CLK_ENABLE();
/* Get clock configuration */ /* Get clock configuration */
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
/* Get APB1 prescaler */ /* Compute TIM23 clock */
uwAPB1Prescaler = clkconfig.APB1CLKDivider; uwTimclock = 2*HAL_RCC_GetPCLK2Freq();
/* Compute TIM4 clock */
if (uwAPB1Prescaler == RCC_HCLK_DIV1)
{
uwTimclock = HAL_RCC_GetPCLK1Freq();
}
else
{
uwTimclock = 2UL * HAL_RCC_GetPCLK1Freq();
}
/* Compute the prescaler value to have TIM4 counter clock equal to 1MHz */ /* Compute the prescaler value to have TIM23 counter clock equal to 1MHz */
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U); uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
/* Initialize TIM4 */ /* Initialize TIM23 */
htim4.Instance = TIM4; htim23.Instance = TIM23;
/* Initialize TIMx peripheral as follow: /* Initialize TIMx peripheral as follow:
* Period = [(TIM4CLK/1000) - 1]. to have a (1/1000) s time base. * Period = [(TIM23CLK/1000) - 1]. to have a (1/1000) s time base.
* Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. * Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
* ClockDivision = 0 * ClockDivision = 0
* Counter direction = Up * Counter direction = Up
*/ */
htim4.Init.Period = (1000000U / 1000U) - 1U; htim23.Init.Period = (1000000U / 1000U) - 1U;
htim4.Init.Prescaler = uwPrescalerValue; htim23.Init.Prescaler = uwPrescalerValue;
htim4.Init.ClockDivision = 0; htim23.Init.ClockDivision = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim23.Init.CounterMode = TIM_COUNTERMODE_UP;
if(HAL_TIM_Base_Init(&htim4) == HAL_OK) if(HAL_TIM_Base_Init(&htim23) == HAL_OK)
{ {
/* Start the TIM time Base generation in interrupt mode */ /* Start the TIM time Base generation in interrupt mode */
return HAL_TIM_Base_Start_IT(&htim4); return HAL_TIM_Base_Start_IT(&htim23);
} }
/* Return function status */ /* Return function status */
@ -106,25 +97,25 @@ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
/** /**
* @brief Suspend Tick increment. * @brief Suspend Tick increment.
* @note Disable the tick increment by disabling TIM4 update interrupt. * @note Disable the tick increment by disabling TIM23 update interrupt.
* @param None * @param None
* @retval None * @retval None
*/ */
void HAL_SuspendTick(void) void HAL_SuspendTick(void)
{ {
/* Disable TIM4 update Interrupt */ /* Disable TIM23 update Interrupt */
__HAL_TIM_DISABLE_IT(&htim4, TIM_IT_UPDATE); __HAL_TIM_DISABLE_IT(&htim23, TIM_IT_UPDATE);
} }
/** /**
* @brief Resume Tick increment. * @brief Resume Tick increment.
* @note Enable the tick increment by Enabling TIM4 update interrupt. * @note Enable the tick increment by Enabling TIM23 update interrupt.
* @param None * @param None
* @retval None * @retval None
*/ */
void HAL_ResumeTick(void) void HAL_ResumeTick(void)
{ {
/* Enable TIM4 Update interrupt */ /* Enable TIM23 Update interrupt */
__HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE); __HAL_TIM_ENABLE_IT(&htim23, TIM_IT_UPDATE);
} }

View File

@ -61,28 +61,15 @@ extern FDCAN_HandleTypeDef hfdcan2;
extern FDCAN_HandleTypeDef hfdcan3; extern FDCAN_HandleTypeDef hfdcan3;
extern DMA_HandleTypeDef hdma_spi2_rx; extern DMA_HandleTypeDef hdma_spi2_rx;
extern DMA_HandleTypeDef hdma_spi2_tx; extern DMA_HandleTypeDef hdma_spi2_tx;
extern DMA_HandleTypeDef hdma_spi6_tx;
extern SPI_HandleTypeDef hspi2; extern SPI_HandleTypeDef hspi2;
extern SPI_HandleTypeDef hspi6;
extern DMA_HandleTypeDef hdma_uart5_rx; extern DMA_HandleTypeDef hdma_uart5_rx;
extern DMA_HandleTypeDef hdma_uart7_rx;
extern DMA_HandleTypeDef hdma_uart7_tx;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_usart3_rx;
extern DMA_HandleTypeDef hdma_usart3_tx;
extern DMA_HandleTypeDef hdma_usart10_rx;
extern DMA_HandleTypeDef hdma_usart10_tx;
extern UART_HandleTypeDef huart5; extern UART_HandleTypeDef huart5;
extern UART_HandleTypeDef huart7; extern UART_HandleTypeDef huart7;
extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2; extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3; extern UART_HandleTypeDef huart3;
extern UART_HandleTypeDef huart10; extern UART_HandleTypeDef huart10;
extern PCD_HandleTypeDef hpcd_USB_OTG_HS; extern TIM_HandleTypeDef htim23;
extern TIM_HandleTypeDef htim4;
/* USER CODE BEGIN EV */ /* USER CODE BEGIN EV */
@ -208,7 +195,7 @@ void DMA1_Stream1_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream1_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */
/* USER CODE END DMA1_Stream1_IRQn 0 */ /* USER CODE END DMA1_Stream1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart5_rx); HAL_DMA_IRQHandler(&hdma_spi2_rx);
/* USER CODE BEGIN DMA1_Stream1_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */
/* USER CODE END DMA1_Stream1_IRQn 1 */ /* USER CODE END DMA1_Stream1_IRQn 1 */
@ -222,7 +209,7 @@ void DMA1_Stream2_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream2_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */
/* USER CODE END DMA1_Stream2_IRQn 0 */ /* USER CODE END DMA1_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi2_rx); HAL_DMA_IRQHandler(&hdma_spi2_tx);
/* USER CODE BEGIN DMA1_Stream2_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */
/* USER CODE END DMA1_Stream2_IRQn 1 */ /* USER CODE END DMA1_Stream2_IRQn 1 */
@ -236,54 +223,12 @@ void DMA1_Stream3_IRQHandler(void)
/* USER CODE BEGIN DMA1_Stream3_IRQn 0 */ /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */
/* USER CODE END DMA1_Stream3_IRQn 0 */ /* USER CODE END DMA1_Stream3_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi2_tx); HAL_DMA_IRQHandler(&hdma_uart5_rx);
/* USER CODE BEGIN DMA1_Stream3_IRQn 1 */ /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */
/* USER CODE END DMA1_Stream3_IRQn 1 */ /* USER CODE END DMA1_Stream3_IRQn 1 */
} }
/**
* @brief This function handles DMA1 stream4 global interrupt.
*/
void DMA1_Stream4_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream4_IRQn 0 */
/* USER CODE END DMA1_Stream4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart7_rx);
/* USER CODE BEGIN DMA1_Stream4_IRQn 1 */
/* USER CODE END DMA1_Stream4_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream5 global interrupt.
*/
void DMA1_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */
/* USER CODE END DMA1_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_uart7_tx);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */
/* USER CODE END DMA1_Stream5_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream6 global interrupt.
*/
void DMA1_Stream6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream6_IRQn 0 */
/* USER CODE END DMA1_Stream6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_rx);
/* USER CODE BEGIN DMA1_Stream6_IRQn 1 */
/* USER CODE END DMA1_Stream6_IRQn 1 */
}
/** /**
* @brief This function handles FDCAN1 interrupt 0. * @brief This function handles FDCAN1 interrupt 0.
*/ */
@ -340,20 +285,6 @@ void FDCAN2_IT1_IRQHandler(void)
/* USER CODE END FDCAN2_IT1_IRQn 1 */ /* USER CODE END FDCAN2_IT1_IRQn 1 */
} }
/**
* @brief This function handles TIM4 global interrupt.
*/
void TIM4_IRQHandler(void)
{
/* USER CODE BEGIN TIM4_IRQn 0 */
/* USER CODE END TIM4_IRQn 0 */
HAL_TIM_IRQHandler(&htim4);
/* USER CODE BEGIN TIM4_IRQn 1 */
/* USER CODE END TIM4_IRQn 1 */
}
/** /**
* @brief This function handles SPI2 global interrupt. * @brief This function handles SPI2 global interrupt.
*/ */
@ -411,17 +342,18 @@ void USART3_IRQHandler(void)
} }
/** /**
* @brief This function handles DMA1 stream7 global interrupt. * @brief This function handles EXTI line[15:10] interrupts.
*/ */
void DMA1_Stream7_IRQHandler(void) void EXTI15_10_IRQHandler(void)
{ {
/* USER CODE BEGIN DMA1_Stream7_IRQn 0 */ /* USER CODE BEGIN EXTI15_10_IRQn 0 */
/* USER CODE END DMA1_Stream7_IRQn 0 */ /* USER CODE END EXTI15_10_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_tx); HAL_GPIO_EXTI_IRQHandler(ACCL_INT_Pin);
/* USER CODE BEGIN DMA1_Stream7_IRQn 1 */ HAL_GPIO_EXTI_IRQHandler(GYRO_INT_Pin);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */
/* USER CODE END DMA1_Stream7_IRQn 1 */ /* USER CODE END EXTI15_10_IRQn 1 */
} }
/** /**
@ -438,104 +370,6 @@ void UART5_IRQHandler(void)
/* USER CODE END UART5_IRQn 1 */ /* USER CODE END UART5_IRQn 1 */
} }
/**
* @brief This function handles DMA2 stream0 global interrupt.
*/
void DMA2_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
/* USER CODE END DMA2_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
/* USER CODE END DMA2_Stream0_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream1 global interrupt.
*/
void DMA2_Stream1_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream1_IRQn 0 */
/* USER CODE END DMA2_Stream1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_tx);
/* USER CODE BEGIN DMA2_Stream1_IRQn 1 */
/* USER CODE END DMA2_Stream1_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream2 global interrupt.
*/
void DMA2_Stream2_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
/* USER CODE END DMA2_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_rx);
/* USER CODE BEGIN DMA2_Stream2_IRQn 1 */
/* USER CODE END DMA2_Stream2_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream3 global interrupt.
*/
void DMA2_Stream3_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream3_IRQn 0 */
/* USER CODE END DMA2_Stream3_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_tx);
/* USER CODE BEGIN DMA2_Stream3_IRQn 1 */
/* USER CODE END DMA2_Stream3_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream4 global interrupt.
*/
void DMA2_Stream4_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream4_IRQn 0 */
/* USER CODE END DMA2_Stream4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart10_rx);
/* USER CODE BEGIN DMA2_Stream4_IRQn 1 */
/* USER CODE END DMA2_Stream4_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream5 global interrupt.
*/
void DMA2_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream5_IRQn 0 */
/* USER CODE END DMA2_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart10_tx);
/* USER CODE BEGIN DMA2_Stream5_IRQn 1 */
/* USER CODE END DMA2_Stream5_IRQn 1 */
}
/**
* @brief This function handles USB On The Go HS global interrupt.
*/
void OTG_HS_IRQHandler(void)
{
/* USER CODE BEGIN OTG_HS_IRQn 0 */
/* USER CODE END OTG_HS_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_OTG_HS);
/* USER CODE BEGIN OTG_HS_IRQn 1 */
/* USER CODE END OTG_HS_IRQn 1 */
}
/** /**
* @brief This function handles UART7 global interrupt. * @brief This function handles UART7 global interrupt.
*/ */
@ -550,34 +384,6 @@ void UART7_IRQHandler(void)
/* USER CODE END UART7_IRQn 1 */ /* USER CODE END UART7_IRQn 1 */
} }
/**
* @brief This function handles SPI6 global interrupt.
*/
void SPI6_IRQHandler(void)
{
/* USER CODE BEGIN SPI6_IRQn 0 */
/* USER CODE END SPI6_IRQn 0 */
HAL_SPI_IRQHandler(&hspi6);
/* USER CODE BEGIN SPI6_IRQn 1 */
/* USER CODE END SPI6_IRQn 1 */
}
/**
* @brief This function handles BDMA channel0 global interrupt.
*/
void BDMA_Channel0_IRQHandler(void)
{
/* USER CODE BEGIN BDMA_Channel0_IRQn 0 */
/* USER CODE END BDMA_Channel0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi6_tx);
/* USER CODE BEGIN BDMA_Channel0_IRQn 1 */
/* USER CODE END BDMA_Channel0_IRQn 1 */
}
/** /**
* @brief This function handles USART10 global interrupt. * @brief This function handles USART10 global interrupt.
*/ */
@ -620,6 +426,20 @@ void FDCAN3_IT1_IRQHandler(void)
/* USER CODE END FDCAN3_IT1_IRQn 1 */ /* USER CODE END FDCAN3_IT1_IRQn 1 */
} }
/**
* @brief This function handles TIM23 global interrupt.
*/
void TIM23_IRQHandler(void)
{
/* USER CODE BEGIN TIM23_IRQn 0 */
/* USER CODE END TIM23_IRQn 0 */
HAL_TIM_IRQHandler(&htim23);
/* USER CODE BEGIN TIM23_IRQn 1 */
/* USER CODE END TIM23_IRQn 1 */
}
/* USER CODE BEGIN 1 */ /* USER CODE BEGIN 1 */
/* USER CODE END 1 */ /* USER CODE END 1 */

View File

@ -340,12 +340,12 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
/**TIM3 GPIO Configuration /**TIM3 GPIO Configuration
PB1 ------> TIM3_CH4 PB1 ------> TIM3_CH4
*/ */
GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Pin = IMU_HEAT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3; GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(IMU_HEAT_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN TIM3_MspPostInit 1 */ /* USER CODE BEGIN TIM3_MspPostInit 1 */
@ -361,12 +361,12 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
/**TIM12 GPIO Configuration /**TIM12 GPIO Configuration
PB15 ------> TIM12_CH2 PB15 ------> TIM12_CH2
*/ */
GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Pin = BUZZER_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM12; GPIO_InitStruct.Alternate = GPIO_AF2_TIM12;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); HAL_GPIO_Init(BUZZER_GPIO_Port, &GPIO_InitStruct);
/* USER CODE BEGIN TIM12_MspPostInit 1 */ /* USER CODE BEGIN TIM12_MspPostInit 1 */

View File

@ -31,16 +31,6 @@ UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3; UART_HandleTypeDef huart3;
UART_HandleTypeDef huart10; UART_HandleTypeDef huart10;
DMA_HandleTypeDef hdma_uart5_rx; DMA_HandleTypeDef hdma_uart5_rx;
DMA_HandleTypeDef hdma_uart7_rx;
DMA_HandleTypeDef hdma_uart7_tx;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
DMA_HandleTypeDef hdma_usart3_rx;
DMA_HandleTypeDef hdma_usart3_tx;
DMA_HandleTypeDef hdma_usart10_rx;
DMA_HandleTypeDef hdma_usart10_tx;
/* UART5 init function */ /* UART5 init function */
void MX_UART5_Init(void) void MX_UART5_Init(void)
@ -350,7 +340,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
/* UART5 DMA Init */ /* UART5 DMA Init */
/* UART5_RX Init */ /* UART5_RX Init */
hdma_uart5_rx.Instance = DMA1_Stream1; hdma_uart5_rx.Instance = DMA1_Stream3;
hdma_uart5_rx.Init.Request = DMA_REQUEST_UART5_RX; hdma_uart5_rx.Init.Request = DMA_REQUEST_UART5_RX;
hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE;
@ -404,43 +394,6 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
GPIO_InitStruct.Alternate = GPIO_AF7_UART7; GPIO_InitStruct.Alternate = GPIO_AF7_UART7;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* UART7 DMA Init */
/* UART7_RX Init */
hdma_uart7_rx.Instance = DMA1_Stream4;
hdma_uart7_rx.Init.Request = DMA_REQUEST_UART7_RX;
hdma_uart7_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart7_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart7_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart7_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart7_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart7_rx.Init.Mode = DMA_NORMAL;
hdma_uart7_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart7_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_uart7_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_uart7_rx);
/* UART7_TX Init */
hdma_uart7_tx.Instance = DMA1_Stream5;
hdma_uart7_tx.Init.Request = DMA_REQUEST_UART7_TX;
hdma_uart7_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_uart7_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart7_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_uart7_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart7_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart7_tx.Init.Mode = DMA_NORMAL;
hdma_uart7_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart7_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_uart7_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_uart7_tx);
/* UART7 interrupt Init */ /* UART7 interrupt Init */
HAL_NVIC_SetPriority(UART7_IRQn, 5, 0); HAL_NVIC_SetPriority(UART7_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(UART7_IRQn); HAL_NVIC_EnableIRQ(UART7_IRQn);
@ -478,43 +431,6 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
GPIO_InitStruct.Alternate = GPIO_AF7_USART1; GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 DMA Init */
/* USART1_RX Init */
hdma_usart1_rx.Instance = DMA1_Stream6;
hdma_usart1_rx.Init.Request = DMA_REQUEST_USART1_RX;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
/* USART1_TX Init */
hdma_usart1_tx.Instance = DMA1_Stream7;
hdma_usart1_tx.Init.Request = DMA_REQUEST_USART1_TX;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
/* USART1 interrupt Init */ /* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn); HAL_NVIC_EnableIRQ(USART1_IRQn);
@ -553,43 +469,6 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
GPIO_InitStruct.Alternate = GPIO_AF7_USART2; GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA2_Stream0;
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_LOW;
hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx);
/* USART2_TX Init */
hdma_usart2_tx.Instance = DMA2_Stream1;
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_LOW;
hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx);
/* USART2 interrupt Init */ /* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 5, 0); HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn); HAL_NVIC_EnableIRQ(USART2_IRQn);
@ -636,43 +515,6 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
GPIO_InitStruct.Alternate = GPIO_AF7_USART3; GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USART3 DMA Init */
/* USART3_RX Init */
hdma_usart3_rx.Instance = DMA2_Stream2;
hdma_usart3_rx.Init.Request = DMA_REQUEST_USART3_RX;
hdma_usart3_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart3_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_rx.Init.Mode = DMA_NORMAL;
hdma_usart3_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart3_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart3_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart3_rx);
/* USART3_TX Init */
hdma_usart3_tx.Instance = DMA2_Stream3;
hdma_usart3_tx.Init.Request = DMA_REQUEST_USART3_TX;
hdma_usart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart3_tx.Init.Mode = DMA_NORMAL;
hdma_usart3_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart3_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart3_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart3_tx);
/* USART3 interrupt Init */ /* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 5, 0); HAL_NVIC_SetPriority(USART3_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn); HAL_NVIC_EnableIRQ(USART3_IRQn);
@ -717,43 +559,6 @@ void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
GPIO_InitStruct.Alternate = GPIO_AF11_USART10; GPIO_InitStruct.Alternate = GPIO_AF11_USART10;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
/* USART10 DMA Init */
/* USART10_RX Init */
hdma_usart10_rx.Instance = DMA2_Stream4;
hdma_usart10_rx.Init.Request = DMA_REQUEST_USART10_RX;
hdma_usart10_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart10_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart10_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart10_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart10_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart10_rx.Init.Mode = DMA_NORMAL;
hdma_usart10_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart10_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart10_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart10_rx);
/* USART10_TX Init */
hdma_usart10_tx.Instance = DMA2_Stream5;
hdma_usart10_tx.Init.Request = DMA_REQUEST_USART10_TX;
hdma_usart10_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart10_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart10_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart10_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart10_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart10_tx.Init.Mode = DMA_NORMAL;
hdma_usart10_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_usart10_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart10_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart10_tx);
/* USART10 interrupt Init */ /* USART10 interrupt Init */
HAL_NVIC_SetPriority(USART10_IRQn, 5, 0); HAL_NVIC_SetPriority(USART10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART10_IRQn); HAL_NVIC_EnableIRQ(USART10_IRQn);
@ -805,10 +610,6 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
*/ */
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8); HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8);
/* UART7 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* UART7 interrupt Deinit */ /* UART7 interrupt Deinit */
HAL_NVIC_DisableIRQ(UART7_IRQn); HAL_NVIC_DisableIRQ(UART7_IRQn);
/* USER CODE BEGIN UART7_MspDeInit 1 */ /* USER CODE BEGIN UART7_MspDeInit 1 */
@ -829,10 +630,6 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
*/ */
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART1 interrupt Deinit */ /* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn); HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE BEGIN USART1_MspDeInit 1 */
@ -854,10 +651,6 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
*/ */
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6); HAL_GPIO_DeInit(GPIOD, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
/* USART2 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART2 interrupt Deinit */ /* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn); HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */ /* USER CODE BEGIN USART2_MspDeInit 1 */
@ -881,10 +674,6 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9); HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9);
/* USART3 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART3 interrupt Deinit */ /* USART3 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART3_IRQn); HAL_NVIC_DisableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspDeInit 1 */ /* USER CODE BEGIN USART3_MspDeInit 1 */
@ -905,10 +694,6 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
*/ */
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2|GPIO_PIN_3); HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2|GPIO_PIN_3);
/* USART10 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART10 interrupt Deinit */ /* USART10 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART10_IRQn); HAL_NVIC_DisableIRQ(USART10_IRQn);
/* USER CODE BEGIN USART10_MspDeInit 1 */ /* USER CODE BEGIN USART10_MspDeInit 1 */

View File

@ -41,7 +41,7 @@ void MX_USB_OTG_HS_PCD_Init(void)
hpcd_USB_OTG_HS.Instance = USB_OTG_HS; hpcd_USB_OTG_HS.Instance = USB_OTG_HS;
hpcd_USB_OTG_HS.Init.dev_endpoints = 9; hpcd_USB_OTG_HS.Init.dev_endpoints = 9;
hpcd_USB_OTG_HS.Init.speed = PCD_SPEED_FULL; hpcd_USB_OTG_HS.Init.speed = PCD_SPEED_FULL;
hpcd_USB_OTG_HS.Init.dma_enable = ENABLE; hpcd_USB_OTG_HS.Init.dma_enable = DISABLE;
hpcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY; hpcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY;
hpcd_USB_OTG_HS.Init.Sof_enable = DISABLE; hpcd_USB_OTG_HS.Init.Sof_enable = DISABLE;
hpcd_USB_OTG_HS.Init.low_power_enable = DISABLE; hpcd_USB_OTG_HS.Init.low_power_enable = DISABLE;
@ -84,10 +84,6 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
/* USB_OTG_HS clock enable */ /* USB_OTG_HS clock enable */
__HAL_RCC_USB_OTG_HS_CLK_ENABLE(); __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
/* USB_OTG_HS interrupt Init */
HAL_NVIC_SetPriority(OTG_HS_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
/* USER CODE BEGIN USB_OTG_HS_MspInit 1 */ /* USER CODE BEGIN USB_OTG_HS_MspInit 1 */
/* USER CODE END USB_OTG_HS_MspInit 1 */ /* USER CODE END USB_OTG_HS_MspInit 1 */
@ -104,9 +100,6 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
/* USER CODE END USB_OTG_HS_MspDeInit 0 */ /* USER CODE END USB_OTG_HS_MspDeInit 0 */
/* Peripheral clock disable */ /* Peripheral clock disable */
__HAL_RCC_USB_OTG_HS_CLK_DISABLE(); __HAL_RCC_USB_OTG_HS_CLK_DISABLE();
/* USB_OTG_HS interrupt Deinit */
HAL_NVIC_DisableIRQ(OTG_HS_IRQn);
/* USER CODE BEGIN USB_OTG_HS_MspDeInit 1 */ /* USER CODE BEGIN USB_OTG_HS_MspDeInit 1 */
/* USER CODE END USB_OTG_HS_MspDeInit 1 */ /* USER CODE END USB_OTG_HS_MspDeInit 1 */

685
CtrBoard-H7_ALL.ioc Normal file
View File

@ -0,0 +1,685 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_4
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_19
ADC1.ClockPrescaler=ADC_CLOCK_ASYNC_DIV64
ADC1.ContinuousConvMode=ENABLE
ADC1.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,OffsetSignedSaturation-0\#ChannelRegularConversion,NbrOfConversionFlag,master,ClockPrescaler,ContinuousConvMode,ConversionDataManagement,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,OffsetSignedSaturation-1\#ChannelRegularConversion,NbrOfConversion
ADC1.NbrOfConversion=2
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetSignedSaturation-0\#ChannelRegularConversion=DISABLE
ADC1.OffsetSignedSaturation-1\#ChannelRegularConversion=DISABLE
ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.Rank-1\#ChannelRegularConversion=2
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
ADC1.master=1
CAD.formats=
CAD.pinconfig=
CAD.provider=
CORTEX_M7.BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings=0x24000000
CORTEX_M7.CPU_DCache=Disabled
CORTEX_M7.CPU_ICache=Disabled
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE
CORTEX_M7.IPParameters=CPU_DCache,CPU_ICache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,BaseAddress-Cortex_Memory_Protection_Unit_Region0_Settings,Size-Cortex_Memory_Protection_Unit_Region0_Settings,TypeExtField-Cortex_Memory_Protection_Unit_Region0_Settings,IsCacheable-Cortex_Memory_Protection_Unit_Region0_Settings,IsBufferable-Cortex_Memory_Protection_Unit_Region0_Settings
CORTEX_M7.IsBufferable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_BUFFERABLE
CORTEX_M7.IsCacheable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_ACCESS_CACHEABLE
CORTEX_M7.MPU_Control=__NULL
CORTEX_M7.Size-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_SIZE_512B
CORTEX_M7.TypeExtField-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_TEX_LEVEL1
Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.0.EventEnable=DISABLE
Dma.ADC1.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.ADC1.0.Instance=DMA1_Stream0
Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
Dma.ADC1.0.Mode=DMA_CIRCULAR
Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
Dma.ADC1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.ADC1.0.Priority=DMA_PRIORITY_LOW
Dma.ADC1.0.RequestNumber=1
Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.ADC1.0.SignalID=NONE
Dma.ADC1.0.SyncEnable=DISABLE
Dma.ADC1.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.ADC1.0.SyncRequestNumber=1
Dma.ADC1.0.SyncSignalID=NONE
Dma.Request0=ADC1
Dma.Request1=SPI2_RX
Dma.Request2=SPI2_TX
Dma.Request3=UART5_RX
Dma.RequestsNb=4
Dma.SPI2_RX.1.Direction=DMA_PERIPH_TO_MEMORY
Dma.SPI2_RX.1.EventEnable=DISABLE
Dma.SPI2_RX.1.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI2_RX.1.Instance=DMA1_Stream1
Dma.SPI2_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI2_RX.1.MemInc=DMA_MINC_ENABLE
Dma.SPI2_RX.1.Mode=DMA_NORMAL
Dma.SPI2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI2_RX.1.PeriphInc=DMA_PINC_DISABLE
Dma.SPI2_RX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SPI2_RX.1.Priority=DMA_PRIORITY_LOW
Dma.SPI2_RX.1.RequestNumber=1
Dma.SPI2_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SPI2_RX.1.SignalID=NONE
Dma.SPI2_RX.1.SyncEnable=DISABLE
Dma.SPI2_RX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SPI2_RX.1.SyncRequestNumber=1
Dma.SPI2_RX.1.SyncSignalID=NONE
Dma.SPI2_TX.2.Direction=DMA_MEMORY_TO_PERIPH
Dma.SPI2_TX.2.EventEnable=DISABLE
Dma.SPI2_TX.2.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI2_TX.2.Instance=DMA1_Stream2
Dma.SPI2_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI2_TX.2.MemInc=DMA_MINC_ENABLE
Dma.SPI2_TX.2.Mode=DMA_NORMAL
Dma.SPI2_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI2_TX.2.PeriphInc=DMA_PINC_DISABLE
Dma.SPI2_TX.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SPI2_TX.2.Priority=DMA_PRIORITY_LOW
Dma.SPI2_TX.2.RequestNumber=1
Dma.SPI2_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SPI2_TX.2.SignalID=NONE
Dma.SPI2_TX.2.SyncEnable=DISABLE
Dma.SPI2_TX.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SPI2_TX.2.SyncRequestNumber=1
Dma.SPI2_TX.2.SyncSignalID=NONE
Dma.UART5_RX.3.Direction=DMA_PERIPH_TO_MEMORY
Dma.UART5_RX.3.EventEnable=DISABLE
Dma.UART5_RX.3.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART5_RX.3.Instance=DMA1_Stream3
Dma.UART5_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.UART5_RX.3.MemInc=DMA_MINC_ENABLE
Dma.UART5_RX.3.Mode=DMA_NORMAL
Dma.UART5_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.UART5_RX.3.PeriphInc=DMA_PINC_DISABLE
Dma.UART5_RX.3.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.UART5_RX.3.Priority=DMA_PRIORITY_LOW
Dma.UART5_RX.3.RequestNumber=1
Dma.UART5_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.UART5_RX.3.SignalID=NONE
Dma.UART5_RX.3.SyncEnable=DISABLE
Dma.UART5_RX.3.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.UART5_RX.3.SyncRequestNumber=1
Dma.UART5_RX.3.SyncSignalID=NONE
FDCAN1.CalculateBaudRateNominal=1000000
FDCAN1.CalculateTimeBitNominal=1000
FDCAN1.CalculateTimeQuantumNominal=200.0
FDCAN1.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1
FDCAN1.NominalPrescaler=24
FDCAN1.NominalTimeSeg1=3
FDCAN1.RxFifo0ElmtsNbr=32
FDCAN1.StdFiltersNbr=1
FDCAN1.TxFifoQueueElmtsNbr=32
FDCAN2.CalculateBaudRateNominal=1000000
FDCAN2.CalculateTimeBitNominal=1000
FDCAN2.CalculateTimeQuantumNominal=200.0
FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1
FDCAN2.MessageRAMOffset=0x406
FDCAN2.NominalPrescaler=24
FDCAN2.NominalTimeSeg1=3
FDCAN2.RxFifo0ElmtsNbr=32
FDCAN2.StdFiltersNbr=1
FDCAN2.TxFifoQueueElmtsNbr=32
FDCAN3.CalculateBaudRateNominal=1000000
FDCAN3.CalculateTimeBitNominal=1000
FDCAN3.CalculateTimeQuantumNominal=200.0
FDCAN3.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1
FDCAN3.MessageRAMOffset=0x812
FDCAN3.NominalPrescaler=24
FDCAN3.NominalTimeSeg1=3
FDCAN3.RxFifo0ElmtsNbr=32
FDCAN3.StdFiltersNbr=1
FDCAN3.TxFifoQueueElmtsNbr=32
FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
FREERTOS.configTOTAL_HEAP_SIZE=0x10000
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
MMTAppRegionsCount=0
MMTConfigApplied=false
Mcu.CPN=STM32H723VGT6
Mcu.Family=STM32H7
Mcu.IP0=ADC1
Mcu.IP1=CORTEX_M7
Mcu.IP10=OCTOSPI1
Mcu.IP11=RCC
Mcu.IP12=SPI1
Mcu.IP13=SPI2
Mcu.IP14=SYS
Mcu.IP15=TIM1
Mcu.IP16=TIM2
Mcu.IP17=TIM3
Mcu.IP18=TIM12
Mcu.IP19=UART5
Mcu.IP2=DEBUG
Mcu.IP20=UART7
Mcu.IP21=USART1
Mcu.IP22=USART2
Mcu.IP23=USART3
Mcu.IP24=USART10
Mcu.IP25=USB_OTG_HS
Mcu.IP3=DMA
Mcu.IP4=FDCAN1
Mcu.IP5=FDCAN2
Mcu.IP6=FDCAN3
Mcu.IP7=FREERTOS
Mcu.IP8=MEMORYMAP
Mcu.IP9=NVIC
Mcu.IPNb=26
Mcu.Name=STM32H723VGTx
Mcu.Package=LQFP100
Mcu.Pin0=PE2
Mcu.Pin1=PE3
Mcu.Pin10=PC3_C
Mcu.Pin11=PA0
Mcu.Pin12=PA1
Mcu.Pin13=PA2
Mcu.Pin14=PA3
Mcu.Pin15=PA5
Mcu.Pin16=PC4
Mcu.Pin17=PC5
Mcu.Pin18=PB0
Mcu.Pin19=PB1
Mcu.Pin2=PC13
Mcu.Pin20=PB2
Mcu.Pin21=PE7
Mcu.Pin22=PE8
Mcu.Pin23=PE9
Mcu.Pin24=PE10
Mcu.Pin25=PE11
Mcu.Pin26=PE12
Mcu.Pin27=PE13
Mcu.Pin28=PE15
Mcu.Pin29=PB10
Mcu.Pin3=PC14-OSC32_IN
Mcu.Pin30=PB11
Mcu.Pin31=PB12
Mcu.Pin32=PB13
Mcu.Pin33=PB14
Mcu.Pin34=PB15
Mcu.Pin35=PD8
Mcu.Pin36=PD9
Mcu.Pin37=PD10
Mcu.Pin38=PD11
Mcu.Pin39=PD12
Mcu.Pin4=PC15-OSC32_OUT
Mcu.Pin40=PD13
Mcu.Pin41=PA8
Mcu.Pin42=PA9
Mcu.Pin43=PA10
Mcu.Pin44=PA11
Mcu.Pin45=PA12
Mcu.Pin46=PA13(JTMS/SWDIO)
Mcu.Pin47=PA14(JTCK/SWCLK)
Mcu.Pin48=PA15(JTDI)
Mcu.Pin49=PC12
Mcu.Pin5=PH0-OSC_IN
Mcu.Pin50=PD0
Mcu.Pin51=PD1
Mcu.Pin52=PD2
Mcu.Pin53=PD4
Mcu.Pin54=PD5
Mcu.Pin55=PD6
Mcu.Pin56=PD7
Mcu.Pin57=PB3(JTDO/TRACESWO)
Mcu.Pin58=PB5
Mcu.Pin59=PB6
Mcu.Pin6=PH1-OSC_OUT
Mcu.Pin60=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin61=VP_OCTOSPI1_VS_octo
Mcu.Pin62=VP_SYS_VS_tim23
Mcu.Pin63=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin7=PC0
Mcu.Pin8=PC1
Mcu.Pin9=PC2_C
Mcu.PinsNb=64
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32H723VGTx
MxCube.Version=6.15.0
MxDb.Version=DB.6.0.150
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.DMA1_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.EXTI15_10_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN1_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN1_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SPI2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=true
NVIC.SavedSystickIrqHandlerGenerated=true
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
NVIC.TIM23_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TimeBase=TIM23_IRQn
NVIC.TimeBaseIP=TIM23
NVIC.UART5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.UART7_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART10_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
PA0.Locked=true
PA0.Signal=S_TIM2_CH1_ETR
PA1.Locked=true
PA1.Mode=OCTOSPI1_IOL_Port1L
PA1.Signal=OCTOSPIM_P1_IO3
PA10.Locked=true
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA11.Mode=Device_Only_FS
PA11.Signal=USB_OTG_HS_DM
PA12.Mode=Device_Only_FS
PA12.Signal=USB_OTG_HS_DP
PA13(JTMS/SWDIO).Locked=true
PA13(JTMS/SWDIO).Mode=Serial_Wire
PA13(JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO
PA14(JTCK/SWCLK).Locked=true
PA14(JTCK/SWCLK).Mode=Serial_Wire
PA14(JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK
PA15(JTDI).Locked=true
PA15(JTDI).Signal=GPIO_Input
PA2.Locked=true
PA2.Signal=S_TIM2_CH3
PA3.Locked=true
PA3.Mode=OCTOSPI1_IOL_Port1L
PA3.Signal=OCTOSPIM_P1_IO2
PA5.Locked=true
PA5.Signal=ADCx_INP19
PA8.Locked=true
PA8.Mode=Clock-out-1
PA8.Signal=RCC_MCO_1
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB0.Locked=true
PB0.Mode=OCTOSPI1_IOL_Port1L
PB0.Signal=OCTOSPIM_P1_IO1
PB1.GPIOParameters=GPIO_Label
PB1.GPIO_Label=IMU_HEAT
PB1.Locked=true
PB1.Signal=S_TIM3_CH4
PB10.GPIOParameters=GPIO_Label
PB10.GPIO_Label=LCD_BLK
PB10.Locked=true
PB10.Signal=GPIO_Output
PB11.GPIOParameters=GPIO_Label
PB11.GPIO_Label=LCD_RES
PB11.Locked=true
PB11.Signal=GPIO_Output
PB12.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PB12.GPIO_Label=DCMI_REST
PB12.GPIO_PuPd=GPIO_PULLUP
PB12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PB12.Locked=true
PB12.PinState=GPIO_PIN_SET
PB12.Signal=GPIO_Output
PB13.GPIOParameters=GPIO_Speed
PB13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PB13.Locked=true
PB13.Mode=Full_Duplex_Master
PB13.Signal=SPI2_SCK
PB14.Mode=Hardware Flow Control (RS485)
PB14.Signal=USART3_DE
PB15.GPIOParameters=GPIO_Label
PB15.GPIO_Label=BUZZER
PB15.Locked=true
PB15.Signal=S_TIM12_CH2
PB2.Locked=true
PB2.Mode=O1_P1_CLK
PB2.Signal=OCTOSPIM_P1_CLK
PB3(JTDO/TRACESWO).GPIOParameters=GPIO_Speed
PB3(JTDO/TRACESWO).GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PB3(JTDO/TRACESWO).Mode=TX_Only_Simplex_Unidirect_Master
PB3(JTDO/TRACESWO).Signal=SPI1_SCK
PB5.Locked=true
PB5.Mode=FDCAN_Activate
PB5.Signal=FDCAN2_RX
PB6.Locked=true
PB6.Mode=FDCAN_Activate
PB6.Signal=FDCAN2_TX
PC0.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PC0.GPIO_Label=ACCL_CS
PC0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC0.Locked=true
PC0.PinState=GPIO_PIN_SET
PC0.Signal=GPIO_Output
PC1.GPIOParameters=GPIO_Speed
PC1.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC1.Mode=Full_Duplex_Master
PC1.Signal=SPI2_MOSI
PC12.Mode=Asynchronous
PC12.Signal=UART5_TX
PC13.GPIOParameters=PinState,GPIO_Label
PC13.GPIO_Label=POWER_24V_2
PC13.Locked=true
PC13.PinState=GPIO_PIN_SET
PC13.Signal=GPIO_Output
PC14-OSC32_IN.GPIOParameters=PinState,GPIO_Label
PC14-OSC32_IN.GPIO_Label=POWER_24V_1
PC14-OSC32_IN.Locked=true
PC14-OSC32_IN.PinState=GPIO_PIN_SET
PC14-OSC32_IN.Signal=GPIO_Output
PC15-OSC32_OUT.GPIOParameters=PinState,GPIO_Label
PC15-OSC32_OUT.GPIO_Label=POWER_5V
PC15-OSC32_OUT.Locked=true
PC15-OSC32_OUT.PinState=GPIO_PIN_SET
PC15-OSC32_OUT.Signal=GPIO_Output
PC2_C.GPIOParameters=GPIO_Speed
PC2_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC2_C.Mode=Full_Duplex_Master
PC2_C.Signal=SPI2_MISO
PC3_C.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PC3_C.GPIO_Label=GYRO_CS
PC3_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC3_C.Locked=true
PC3_C.PinState=GPIO_PIN_SET
PC3_C.Signal=GPIO_Output
PC4.Locked=true
PC4.Signal=ADCx_INP4
PC5.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
PC5.GPIO_Label=DCMI_PWDN
PC5.GPIO_PuPd=GPIO_NOPULL
PC5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC5.Locked=true
PC5.PinState=GPIO_PIN_SET
PC5.Signal=GPIO_Output
PD0.Mode=FDCAN_Activate
PD0.Signal=FDCAN1_RX
PD1.Locked=true
PD1.Mode=FDCAN_Activate
PD1.Signal=FDCAN1_TX
PD10.GPIOParameters=GPIO_Label
PD10.GPIO_Label=LCD_DC
PD10.Locked=true
PD10.Signal=GPIO_Output
PD11.Locked=true
PD11.Mode=OCTOSPI1_IOL_Port1L
PD11.Signal=OCTOSPIM_P1_IO0
PD12.Mode=FDCAN_Activate
PD12.Signal=FDCAN3_RX
PD13.Locked=true
PD13.Mode=FDCAN_Activate
PD13.Signal=FDCAN3_TX
PD2.Mode=Asynchronous
PD2.Signal=UART5_RX
PD4.Locked=true
PD4.Mode=Hardware Flow Control (RS485)
PD4.Signal=USART2_DE
PD5.Locked=true
PD5.Mode=Asynchronous
PD5.Signal=USART2_TX
PD6.Locked=true
PD6.Mode=Asynchronous
PD6.Signal=USART2_RX
PD7.GPIOParameters=GPIO_Speed
PD7.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PD7.Locked=true
PD7.Mode=TX_Only_Simplex_Unidirect_Master
PD7.Signal=SPI1_MOSI
PD8.Mode=Asynchronous
PD8.Signal=USART3_TX
PD9.Mode=Asynchronous
PD9.Signal=USART3_RX
PE10.GPIOParameters=GPIO_Label
PE10.GPIO_Label=ACCL_INT
PE10.Locked=true
PE10.Signal=GPXTI10
PE11.Locked=true
PE11.Mode=OCTOSPI1_Port1_NCS
PE11.Signal=OCTOSPIM_P1_NCS
PE12.GPIOParameters=GPIO_Label
PE12.GPIO_Label=GYRO_INT
PE12.Locked=true
PE12.Signal=GPXTI12
PE13.Signal=S_TIM1_CH3
PE15.GPIOParameters=GPIO_Label
PE15.GPIO_Label=LCD_CS
PE15.Locked=true
PE15.Signal=GPIO_Output
PE2.Mode=Asynchronous
PE2.Signal=USART10_RX
PE3.Mode=Asynchronous
PE3.Signal=USART10_TX
PE7.Mode=Asynchronous
PE7.Signal=UART7_RX
PE8.Mode=Asynchronous
PE8.Signal=UART7_TX
PE9.Locked=true
PE9.Signal=S_TIM1_CH1
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerLinker=GCC
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32H723VGTx
ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.12.1
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x1000
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=CtrBoard-H7_ALL.ioc
ProjectManager.ProjectName=CtrBoard-H7_ALL
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x2000
ProjectManager.TargetToolchain=CMake
ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_ADC1_Init-ADC1-false-HAL-true,5-MX_TIM12_Init-TIM12-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_USART1_UART_Init-USART1-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_USART3_UART_Init-USART3-false-HAL-true,12-MX_UART7_Init-UART7-false-HAL-true,13-MX_USART10_UART_Init-USART10-false-HAL-true,14-MX_FDCAN1_Init-FDCAN1-false-HAL-true,15-MX_FDCAN2_Init-FDCAN2-false-HAL-true,16-MX_FDCAN3_Init-FDCAN3-false-HAL-true,17-MX_TIM1_Init-TIM1-false-HAL-true,18-MX_TIM2_Init-TIM2-false-HAL-true,19-MX_OCTOSPI1_Init-OCTOSPI1-false-HAL-true,20-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-false-HAL-true,21-MX_UART5_Init-UART5-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
RCC.ADCFreq_Value=96000000
RCC.AHB12Freq_Value=240000000
RCC.AHB4Freq_Value=240000000
RCC.APB1Freq_Value=120000000
RCC.APB2Freq_Value=120000000
RCC.APB3Freq_Value=120000000
RCC.APB4Freq_Value=120000000
RCC.AXIClockFreq_Value=240000000
RCC.CECFreq_Value=32000
RCC.CKPERFreq_Value=64000000
RCC.CortexFreq_Value=480000000
RCC.CpuClockFreq_Value=480000000
RCC.D1CPREFreq_Value=480000000
RCC.D1PPRE=RCC_APB3_DIV2
RCC.D2PPRE1=RCC_APB1_DIV2
RCC.D2PPRE2=RCC_APB2_DIV2
RCC.D3PPRE=RCC_APB4_DIV2
RCC.DFSDMACLkFreq_Value=120000000
RCC.DFSDMFreq_Value=120000000
RCC.DIVM1=2
RCC.DIVM2=2
RCC.DIVN1=40
RCC.DIVN2=16
RCC.DIVP1=1
RCC.DIVP1Freq_Value=480000000
RCC.DIVP2Freq_Value=96000000
RCC.DIVP3Freq_Value=48375000
RCC.DIVQ1=4
RCC.DIVQ1Freq_Value=120000000
RCC.DIVQ2Freq_Value=96000000
RCC.DIVQ3Freq_Value=48375000
RCC.DIVR1Freq_Value=240000000
RCC.DIVR2Freq_Value=96000000
RCC.DIVR3Freq_Value=48375000
RCC.EnbaleCSS=false
RCC.FDCANFreq_Value=120000000
RCC.FMCFreq_Value=240000000
RCC.FamilyName=M
RCC.HCLK3ClockFreq_Value=240000000
RCC.HCLKFreq_Value=240000000
RCC.HPRE=RCC_HCLK_DIV2
RCC.HSE_VALUE=24000000
RCC.I2C123Freq_Value=120000000
RCC.I2C4Freq_Value=120000000
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVN1,DIVN2,DIVP1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,EnbaleCSS,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL2_VCI_Range-AdvancedSettings,PLL2_VCO_SEL-AdvancedSettings,PLL3FRACN,PLL3_VCO_SEL-AdvancedSettings,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6CLockSelection,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
RCC.LPTIM1Freq_Value=120000000
RCC.LPTIM2Freq_Value=120000000
RCC.LPTIM345Freq_Value=120000000
RCC.LPUART1Freq_Value=120000000
RCC.LTDCFreq_Value=48375000
RCC.MCO1PinFreq_Value=64000000
RCC.MCO2PinFreq_Value=480000000
RCC.PLL2FRACN=0
RCC.PLL2_VCI_Range-AdvancedSettings=RCC_PLL2VCIRANGE_0
RCC.PLL2_VCO_SEL-AdvancedSettings=RCC_PLL2VCOWIDE
RCC.PLL3FRACN=0
RCC.PLL3_VCO_SEL-AdvancedSettings=RCC_PLL3VCOMEDIUM
RCC.PLLFRACN=0
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.QSPIFreq_Value=240000000
RCC.RNGFreq_Value=48000000
RCC.RTCFreq_Value=32000
RCC.SAI1Freq_Value=120000000
RCC.SAI4AFreq_Value=120000000
RCC.SAI4BFreq_Value=120000000
RCC.SDMMCFreq_Value=120000000
RCC.SPDIFRXFreq_Value=120000000
RCC.SPI123Freq_Value=120000000
RCC.SPI45Freq_Value=120000000
RCC.SPI6CLockSelection=RCC_SPI6CLKSOURCE_HSE
RCC.SPI6Freq_Value=24000000
RCC.SWPMI1Freq_Value=120000000
RCC.SYSCLKFreq_VALUE=480000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.Tim1OutputFreq_Value=240000000
RCC.Tim2OutputFreq_Value=240000000
RCC.TraceFreq_Value=240000000
RCC.USART16Freq_Value=120000000
RCC.USART234578Freq_Value=120000000
RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48
RCC.USBFreq_Value=48000000
RCC.VCO1OutputFreq_Value=480000000
RCC.VCO2OutputFreq_Value=192000000
RCC.VCO3OutputFreq_Value=96750000
RCC.VCOInput1Freq_Value=12000000
RCC.VCOInput2Freq_Value=12000000
RCC.VCOInput3Freq_Value=750000
SH.ADCx_INP19.0=ADC1_INP19,IN19-Single-Ended
SH.ADCx_INP19.ConfNb=1
SH.ADCx_INP4.0=ADC1_INP4,IN4-Single-Ended
SH.ADCx_INP4.ConfNb=1
SH.GPXTI10.0=GPIO_EXTI10
SH.GPXTI10.ConfNb=1
SH.GPXTI12.0=GPIO_EXTI12
SH.GPXTI12.ConfNb=1
SH.S_TIM12_CH2.0=TIM12_CH2,PWM Generation2 CH2
SH.S_TIM12_CH2.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
SH.S_TIM1_CH1.ConfNb=1
SH.S_TIM1_CH3.0=TIM1_CH3,PWM Generation3 CH3
SH.S_TIM1_CH3.ConfNb=1
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
SH.S_TIM2_CH1_ETR.ConfNb=1
SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
SH.S_TIM2_CH3.ConfNb=1
SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4
SH.S_TIM3_CH4.ConfNb=1
SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4
SPI1.CLKPolarity=SPI_POLARITY_HIGH
SPI1.CalculateBaudRate=30.0 MBits/s
SPI1.DataSize=SPI_DATASIZE_8BIT
SPI1.Direction=SPI_DIRECTION_2LINES_TXONLY
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity
SPI1.Mode=SPI_MODE_MASTER
SPI1.VirtualType=VM_MASTER
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32
SPI2.CLKPhase=SPI_PHASE_2EDGE
SPI2.CLKPolarity=SPI_POLARITY_HIGH
SPI2.CalculateBaudRate=3.75 MBits/s
SPI2.DataSize=SPI_DATASIZE_8BIT
SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity,CLKPhase
SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM1.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation1 CH1,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
TIM1.Period=10000
TIM1.Prescaler=24
TIM1.Pulse-PWM\ Generation1\ CH1=5000
TIM1.Pulse-PWM\ Generation3\ CH3=5000
TIM12.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM12.IPParameters=Channel-PWM Generation2 CH2,Prescaler,Period
TIM12.Period=2000-1
TIM12.Prescaler=24-1
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM2.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation3 CH3,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
TIM2.Period=10000
TIM2.Prescaler=24
TIM2.Pulse-PWM\ Generation1\ CH1=5000
TIM2.Pulse-PWM\ Generation3\ CH3=5000
TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM3.IPParameters=Channel-PWM Generation4 CH4,Prescaler,Period,AutoReloadPreload
TIM3.Period=10000-1
TIM3.Prescaler=24-1
UART5.BaudRate=100000
UART5.IPParameters=Mode,WordLength,Parity,BaudRate
UART5.Mode=MODE_RX
UART5.Parity=PARITY_EVEN
UART5.WordLength=WORDLENGTH_9B
UART7.BaudRate=921600
UART7.IPParameters=BaudRate
USART1.BaudRate=921600
USART1.IPParameters=VirtualMode-Asynchronous,BaudRate
USART1.VirtualMode-Asynchronous=VM_ASYNC
USART10.BaudRate=921600
USART10.IPParameters=VirtualMode,BaudRate
USART10.VirtualMode=VM_ASYNC
USART2.BaudRate=921600
USART2.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
USART2.VirtualMode-Asynchronous=VM_ASYNC
USART2.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
USART3.BaudRate=921600
USART3.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
USART3.VirtualMode-Asynchronous=VM_ASYNC
USART3.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
USB_OTG_HS.IPParameters=VirtualMode-Device_Only_FS
USB_OTG_HS.VirtualMode-Device_Only_FS=Device_Only_FS
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
VP_OCTOSPI1_VS_octo.Mode=octo_mode
VP_OCTOSPI1_VS_octo.Signal=OCTOSPI1_VS_octo
VP_SYS_VS_tim23.Mode=TIM23
VP_SYS_VS_tim23.Signal=SYS_VS_tim23
board=custom

View File

@ -1,52 +1,43 @@
/* USER CODE BEGIN Header */ /**
/** ******************************************************************************
****************************************************************************** * @file usbd_cdc_if_template.h
* @file bdma.h * @author MCD Application Team
* @brief This file contains all the function prototypes for * @brief Header for usbd_cdc_if_template.c file.
* the bdma.c file ******************************************************************************
****************************************************************************** * @attention
* @attention *
* * Copyright (c) 2015 STMicroelectronics.
* Copyright (c) 2026 STMicroelectronics. * All rights reserved.
* All rights reserved. *
* * This software is licensed under terms that can be found in the LICENSE file
* This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component.
* in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS.
* If no LICENSE file comes with this software, it is provided AS-IS. *
* ******************************************************************************
****************************************************************************** */
*/
/* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/
/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __USBD_CDC_IF_TEMPLATE_H
#ifndef __BDMA_H__ #define __USBD_CDC_IF_TEMPLATE_H
#define __BDMA_H__
#ifdef __cplusplus
#ifdef __cplusplus extern "C" {
extern "C" { #endif
#endif
/* Includes ------------------------------------------------------------------*/
/* Includes ------------------------------------------------------------------*/ #include "usbd_cdc.h"
#include "main.h"
/* Exported types ------------------------------------------------------------*/
/* DMA memory to memory transfer handles -------------------------------------*/ /* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN Includes */ extern USBD_CDC_ItfTypeDef USBD_CDC_Template_fops;
/* USER CODE END Includes */ /* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* USER CODE BEGIN Private defines */
#ifdef __cplusplus
/* USER CODE END Private defines */ }
#endif
void MX_BDMA_Init(void);
#endif /* __USBD_CDC_IF_TEMPLATE_H */
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __BDMA_H__ */

View File

@ -0,0 +1,247 @@
/**
******************************************************************************
* @file usbd_cdc_if_template.c
* @author MCD Application Team
* @brief Generic media access Layer.
******************************************************************************
* @attention
*
* Copyright (c) 2015 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.
*
******************************************************************************
*/
/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
EndBSPDependencies */
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_if_template.h"
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CDC
* @brief usbd core module
* @{
*/
/** @defgroup USBD_CDC_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CDC_Private_Defines
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CDC_Private_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CDC_Private_FunctionPrototypes
* @{
*/
static int8_t TEMPLATE_Init(void);
static int8_t TEMPLATE_DeInit(void);
static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length);
static int8_t TEMPLATE_Receive(uint8_t *pbuf, uint32_t *Len);
static int8_t TEMPLATE_TransmitCplt(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
USBD_CDC_ItfTypeDef USBD_CDC_Template_fops =
{
TEMPLATE_Init,
TEMPLATE_DeInit,
TEMPLATE_Control,
TEMPLATE_Receive,
TEMPLATE_TransmitCplt
};
USBD_CDC_LineCodingTypeDef linecoding =
{
115200, /* baud rate*/
0x00, /* stop bits-1*/
0x00, /* parity - none*/
0x08 /* nb. of bits 8*/
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief TEMPLATE_Init
* Initializes the CDC media low layer
* @param None
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t TEMPLATE_Init(void)
{
/*
Add your initialization code here
*/
return (0);
}
/**
* @brief TEMPLATE_DeInit
* DeInitializes the CDC media low layer
* @param None
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t TEMPLATE_DeInit(void)
{
/*
Add your deinitialization code here
*/
return (0);
}
/**
* @brief TEMPLATE_Control
* Manage the CDC class requests
* @param Cmd: Command code
* @param Buf: Buffer containing command data (request parameters)
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t TEMPLATE_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
{
UNUSED(length);
switch (cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
/* Add your code here */
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
/* Add your code here */
break;
case CDC_SET_COMM_FEATURE:
/* Add your code here */
break;
case CDC_GET_COMM_FEATURE:
/* Add your code here */
break;
case CDC_CLEAR_COMM_FEATURE:
/* Add your code here */
break;
case CDC_SET_LINE_CODING:
linecoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) | \
(pbuf[2] << 16) | (pbuf[3] << 24));
linecoding.format = pbuf[4];
linecoding.paritytype = pbuf[5];
linecoding.datatype = pbuf[6];
/* Add your code here */
break;
case CDC_GET_LINE_CODING:
pbuf[0] = (uint8_t)(linecoding.bitrate);
pbuf[1] = (uint8_t)(linecoding.bitrate >> 8);
pbuf[2] = (uint8_t)(linecoding.bitrate >> 16);
pbuf[3] = (uint8_t)(linecoding.bitrate >> 24);
pbuf[4] = linecoding.format;
pbuf[5] = linecoding.paritytype;
pbuf[6] = linecoding.datatype;
/* Add your code here */
break;
case CDC_SET_CONTROL_LINE_STATE:
/* Add your code here */
break;
case CDC_SEND_BREAK:
/* Add your code here */
break;
default:
break;
}
return (0);
}
/**
* @brief TEMPLATE_Receive
* Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will issue a NAK packet on any OUT packet received on
* USB endpoint until exiting this function. If you exit this function
* before transfer is complete on CDC interface (ie. using DMA controller)
* it will result in receiving more data while previous ones are still
* not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t TEMPLATE_Receive(uint8_t *Buf, uint32_t *Len)
{
UNUSED(Buf);
UNUSED(Len);
return (0);
}
/**
* @brief TEMPLATE_TransmitCplt
* Data transmitted callback
*
* @note
* This function is IN transfer complete callback used to inform user that
* the submitted Data is successfully sent over USB.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t TEMPLATE_TransmitCplt(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
UNUSED(Buf);
UNUSED(Len);
UNUSED(epnum);
return (0);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,230 @@
/**
******************************************************************************
* @file usbd_conf_template.h
* @author MCD Application Team
* @brief Header file for the usbd_conf_template.c file
******************************************************************************
* @attention
*
* Copyright (c) 2015 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_CONF_TEMPLATE_H
#define __USBD_CONF_TEMPLATE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32fxxx.h" /* replace 'stm32xxx' with your HAL driver header filename, ex: stm32f4xx.h */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/** @addtogroup STM32_USB_DEVICE_LIBRARY
* @{
*/
/** @defgroup USBD_CONF
* @brief USB device low level driver configuration file
* @{
*/
/** @defgroup USBD_CONF_Exported_Defines
* @{
*/
#define USBD_MAX_NUM_INTERFACES 1U
#define USBD_MAX_NUM_CONFIGURATION 1U
#define USBD_MAX_STR_DESC_SIZ 0x100U
#define USBD_SELF_POWERED 1U
#define USBD_DEBUG_LEVEL 2U
/* #define USBD_USER_REGISTER_CALLBACK 1U */
/* ECM, RNDIS, DFU Class Config */
#define USBD_SUPPORT_USER_STRING_DESC 1U
/* BillBoard Class Config */
#define USBD_CLASS_USER_STRING_DESC 1U
#define USBD_CLASS_BOS_ENABLED 1U
#define USB_BB_MAX_NUM_ALT_MODE 0x2U
/* MSC Class Config */
#define MSC_MEDIA_PACKET 8192U
/* CDC Class Config */
#define USBD_CDC_INTERVAL 2000U
/* DFU Class Config */
/* #define USBD_DFU_VENDOR_CMD_ENABLED 1U */
/* #define USBD_DFU_VENDOR_EXIT_ENABLED 1U */
#define USBD_DFU_MAX_ITF_NUM 1U
#define USBD_DFU_XFERS_IZE 1024U
/* AUDIO Class Config */
#define USBD_AUDIO_FREQ 22100U
/* CustomHID Class Config */
#define CUSTOM_HID_HS_BINTERVAL 0x05U
#define CUSTOM_HID_FS_BINTERVAL 0x05U
#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE 0x02U
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE 163U
/* #define USBD_CUSTOMHID_CTRL_REQ_GET_REPORT_ENABLED */
/* #define USBD_CUSTOMHID_OUT_PREPARE_RECEIVE_DISABLED */
/* #define USBD_CUSTOMHID_EP0_OUT_PREPARE_RECEIVE_DISABLED */
/* #define USBD_CUSTOMHID_CTRL_REQ_COMPLETE_CALLBACK_ENABLED */
/* VIDEO Class Config */
#define UVC_1_1 /* #define UVC_1_0 */
/* To be used only with YUY2 and NV12 Video format, shouldn't be defined for MJPEG format */
#define USBD_UVC_FORMAT_UNCOMPRESSED
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
#define UVC_BITS_PER_PIXEL 12U
#define UVC_UNCOMPRESSED_GUID UVC_GUID_NV12 /* UVC_GUID_YUY2 */
/* refer to Table 3-18 Color Matching Descriptor video class v1.1 */
#define UVC_COLOR_PRIMARIE 0x01U
#define UVC_TFR_CHARACTERISTICS 0x01U
#define UVC_MATRIX_COEFFICIENTS 0x04U
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
/* Video Stream frame width and height */
#define UVC_WIDTH 176U
#define UVC_HEIGHT 144U
/* bEndpointAddress in Endpoint Descriptor */
#define UVC_IN_EP 0x81U
#define UVC_CAM_FPS_FS 10U
#define UVC_CAM_FPS_HS 5U
#define UVC_ISO_FS_MPS 512U
#define UVC_ISO_HS_MPS 512U
#define UVC_PACKET_SIZE UVC_ISO_FS_MPS
/* To be used with Device Only IP supporting double buffer mode */
/* #define UVC_HEADER_PACKET_CNT 0x02U */
/* #define UVC_PACKET_SIZE (UVC_ISO_FS_MPS * UVC_HEADER_PACKET_CNT) */
#define UVC_MAX_FRAME_SIZE (UVC_WIDTH * UVC_HEIGHT * 16U / 8U)
/** @defgroup USBD_Exported_Macros
* @{
*/
/* Memory management macros make sure to use static memory allocation */
/** Alias for memory allocation. */
#define USBD_malloc (void *)USBD_static_malloc
/** Alias for memory release. */
#define USBD_free USBD_static_free
/** Alias for memory set. */
#define USBD_memset memset
/** Alias for memory copy. */
#define USBD_memcpy memcpy
/** Alias for delay. */
#define USBD_Delay HAL_Delay
/* DEBUG macros */
#if (USBD_DEBUG_LEVEL > 0U)
#define USBD_UsrLog(...) do { \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBD_UsrLog(...) do {} while (0)
#endif /* (USBD_DEBUG_LEVEL > 0U) */
#if (USBD_DEBUG_LEVEL > 1U)
#define USBD_ErrLog(...) do { \
printf("ERROR: ") ; \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBD_ErrLog(...) do {} while (0)
#endif /* (USBD_DEBUG_LEVEL > 1U) */
#if (USBD_DEBUG_LEVEL > 2U)
#define USBD_DbgLog(...) do { \
printf("DEBUG : ") ; \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define USBD_DbgLog(...) do {} while (0)
#endif /* (USBD_DEBUG_LEVEL > 2U) */
/**
* @}
*/
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Types
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Macros
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Variables
* @{
*/
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_FunctionsPrototype
* @{
*/
/* Exported functions -------------------------------------------------------*/
void *USBD_static_malloc(uint32_t size);
void USBD_static_free(void *p);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __USBD_CONF_TEMPLATE_H */
/**
* @}
*/
/**
* @}
*/

View File

@ -0,0 +1,61 @@
/**
******************************************************************************
* @file usbd_desc_template.h
* @author MCD Application Team
* @brief Header for usbd_desc_template.c module
******************************************************************************
* @attention
*
* Copyright (c) 2015 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.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USBD_DESC_TEMPLATE_H
#define __USBD_DESC_TEMPLATE_H
/* Includes ------------------------------------------------------------------*/
#include "usbd_def.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define DEVICE_ID1 (UID_BASE)
#define DEVICE_ID2 (UID_BASE + 0x4U)
#define DEVICE_ID3 (UID_BASE + 0x8U)
/*
* USB Billboard Class USER string desc Defines Template
* index should start form 0x10 to avoid using the reserved device string desc indexes
*/
#if (USBD_CLASS_USER_STRING_DESC == 1)
#define USBD_BB_IF_STRING_INDEX 0x10U
#define USBD_BB_URL_STRING_INDEX 0x11U
#define USBD_BB_ALTMODE0_STRING_INDEX 0x12U
#define USBD_BB_ALTMODE1_STRING_INDEX 0x13U
/* Add Specific USER string Desc */
#define USBD_BB_IF_STR_DESC (uint8_t *)"STM32 BillBoard Interface"
#define USBD_BB_URL_STR_DESC (uint8_t *)"www.st.com"
#define USBD_BB_ALTMODE0_STR_DESC (uint8_t *)"STM32 Alternate0 Mode"
#define USBD_BB_ALTMODE1_STR_DESC (uint8_t *)"STM32 Alternate1 Mode"
#endif /* USBD_CLASS_USER_STRING_DESC */
#define USB_SIZ_STRING_SERIAL 0x1AU
#if (USBD_LPM_ENABLED == 1)
#define USB_SIZ_BOS_DESC 0x0CU
#elif (USBD_CLASS_BOS_ENABLED == 1)
#define USB_SIZ_BOS_DESC 0x5DU
#endif /* USBD_LPM_ENABLED */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
extern USBD_DescriptorsTypeDef XXX_Desc; /* Replace 'XXX_Desc' with your active USB device class, ex: HID_Desc */
#endif /* __USBD_DESC_TEMPLATE_H*/

View File

@ -0,0 +1,283 @@
/**
******************************************************************************
* @file usbd_conf_template.c
* @author MCD Application Team
* @brief USB Device configuration and interface file
* This template should be copied to the user folder,
* renamed and customized following user needs.
******************************************************************************
* @attention
*
* Copyright (c) 2015 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 "usbd_core.h"
#include "usbd_hid.h" /* Include class header file */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the Low Level portion of the Device driver.
* @param pdev: Device handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
{
UNUSED(pdev);
return USBD_OK;
}
/**
* @brief De-Initializes the Low Level portion of the Device driver.
* @param pdev: Device handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
{
UNUSED(pdev);
return USBD_OK;
}
/**
* @brief Starts the Low Level portion of the Device driver.
* @param pdev: Device handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
{
UNUSED(pdev);
return USBD_OK;
}
/**
* @brief Stops the Low Level portion of the Device driver.
* @param pdev: Device handle
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
{
UNUSED(pdev);
return USBD_OK;
}
/**
* @brief Opens an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @param ep_type: Endpoint Type
* @param ep_mps: Endpoint Max Packet Size
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t ep_type, uint16_t ep_mps)
{
UNUSED(pdev);
UNUSED(ep_addr);
UNUSED(ep_type);
UNUSED(ep_mps);
return USBD_OK;
}
/**
* @brief Closes an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
UNUSED(pdev);
UNUSED(ep_addr);
return USBD_OK;
}
/**
* @brief Flushes an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
UNUSED(pdev);
UNUSED(ep_addr);
return USBD_OK;
}
/**
* @brief Sets a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
UNUSED(pdev);
UNUSED(ep_addr);
return USBD_OK;
}
/**
* @brief Clears a Stall condition on an endpoint of the Low Level Driver.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev,
uint8_t ep_addr)
{
UNUSED(pdev);
UNUSED(ep_addr);
return USBD_OK;
}
/**
* @brief Returns Stall condition.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @retval Stall (1: Yes, 0: No)
*/
uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
UNUSED(pdev);
UNUSED(ep_addr);
return 0U;
}
/**
* @brief Assigns a USB address to the device.
* @param pdev: Device handle
* @param dev_addr: Endpoint Number
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev,
uint8_t dev_addr)
{
UNUSED(pdev);
UNUSED(dev_addr);
return USBD_OK;
}
/**
* @brief Transmits data over an endpoint.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @param pbuf: Pointer to data to be sent
* @param size: Data size
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr,
uint8_t *pbuf, uint32_t size)
{
UNUSED(pdev);
UNUSED(ep_addr);
UNUSED(pbuf);
UNUSED(size);
return USBD_OK;
}
/**
* @brief Prepares an endpoint for reception.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @param pbuf: Pointer to data to be received
* @param size: Data size
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
uint8_t ep_addr, uint8_t *pbuf,
uint32_t size)
{
UNUSED(pdev);
UNUSED(ep_addr);
UNUSED(pbuf);
UNUSED(size);
return USBD_OK;
}
/**
* @brief Returns the last transferred packet size.
* @param pdev: Device handle
* @param ep_addr: Endpoint Number
* @retval Received Data Size
*/
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
{
UNUSED(pdev);
UNUSED(ep_addr);
return 0U;
}
#ifdef USBD_HS_TESTMODE_ENABLE
/**
* @brief Set High speed Test mode.
* @param pdev: Device handle
* @param testmode: test mode
* @retval USBD Status
*/
USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode)
{
UNUSED(pdev);
UNUSED(testmode);
return USBD_OK;
}
#endif /* USBD_HS_TESTMODE_ENABLE */
/**
* @brief Static single allocation.
* @param size: Size of allocated memory
* @retval None
*/
void *USBD_static_malloc(uint32_t size)
{
UNUSED(size);
static uint32_t mem[(sizeof(USBD_HID_HandleTypeDef) / 4) + 1]; /* On 32-bit boundary */
return mem;
}
/**
* @brief Dummy memory free
* @param p: Pointer to allocated memory address
* @retval None
*/
void USBD_static_free(void *p)
{
UNUSED(p);
}
/**
* @brief Delays routine for the USB Device Library.
* @param Delay: Delay in ms
* @retval None
*/
void USBD_LL_Delay(uint32_t Delay)
{
UNUSED(Delay);
}

View File

@ -0,0 +1,454 @@
/**
******************************************************************************
* @file usbd_desc_template.c
* @author MCD Application Team
* @brief This file provides the USBD descriptors and string formatting method.
* This template should be copied to the user folder,
* renamed and customized following user needs.
******************************************************************************
* @attention
*
* Copyright (c) 2015 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 "usbd_core.h"
#include "usbd_desc.h"
#include "usbd_conf.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USBD_VID 0x0483
#define USBD_PID 0xaaaa /* Replace '0xaaaa' with your device product ID */
#define USBD_LANGID_STRING 0xbbb /* Replace '0xbbb' with your device language ID */
#define USBD_MANUFACTURER_STRING "xxxxx" /* Add your manufacturer string */
#define USBD_PRODUCT_HS_STRING "xxxxx" /* Add your product High Speed string */
#define USBD_PRODUCT_FS_STRING "xxxxx" /* Add your product Full Speed string */
#define USBD_CONFIGURATION_HS_STRING "xxxxx" /* Add your configuration High Speed string */
#define USBD_INTERFACE_HS_STRING "xxxxx" /* Add your Interface High Speed string */
#define USBD_CONFIGURATION_FS_STRING "xxxxx" /* Add your configuration Full Speed string */
#define USBD_INTERFACE_FS_STRING "xxxxx" /* Add your Interface Full Speed string */
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
uint8_t *USBD_Class_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_Class_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_Class_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_Class_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_Class_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_Class_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
uint8_t *USBD_Class_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
#if (USBD_CLASS_USER_STRING_DESC == 1)
uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
#endif /* USB_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
/* Private variables ---------------------------------------------------------*/
USBD_DescriptorsTypeDef Class_Desc =
{
USBD_Class_DeviceDescriptor,
USBD_Class_LangIDStrDescriptor,
USBD_Class_ManufacturerStrDescriptor,
USBD_Class_ProductStrDescriptor,
USBD_Class_SerialStrDescriptor,
USBD_Class_ConfigStrDescriptor,
USBD_Class_InterfaceStrDescriptor,
#if (USBD_CLASS_USER_STRING_DESC == 1)
USBD_CLASS_UserStrDescriptor,
#endif /* USB_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
USBD_USR_BOSDescriptor,
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
};
/* USB Standard Device Descriptor */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
0x12, /* bLength */
USB_DESC_TYPE_DEVICE, /* bDescriptorType */
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
0x01, /*bcdUSB */ /* changed to USB version 2.01
in order to support BOS Desc */
#else
0x00, /* bcdUSB */
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
0x02,
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
USB_MAX_EP0_SIZE, /* bMaxPacketSize */
LOBYTE(USBD_VID), /* idVendor */
HIBYTE(USBD_VID), /* idVendor */
LOBYTE(USBD_PID), /* idVendor */
HIBYTE(USBD_PID), /* idVendor */
0x00, /* bcdDevice rel. 2.00 */
0x02,
USBD_IDX_MFC_STR, /* Index of manufacturer string */
USBD_IDX_PRODUCT_STR, /* Index of product string */
USBD_IDX_SERIAL_STR, /* Index of serial number string */
USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */
}; /* USB_DeviceDescriptor */
/* USB Device LPM BOS descriptor */
#if (USBD_LPM_ENABLED == 1)
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
{
0x5,
USB_DESC_TYPE_BOS,
0xC,
0x0,
0x1, /* 1 device capability */
/* device capability */
0x7,
USB_DEVICE_CAPABITY_TYPE,
0x2,
0x6, /*LPM capability bit set */
0x0,
0x0,
0x0
};
#endif /* USBD_LPM_ENABLED */
/* USB Device Billboard BOS descriptor Template */
#if (USBD_CLASS_BOS_ENABLED == 1)
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END =
{
0x05, /* bLength */
USB_DESC_TYPE_BOS, /* Device Descriptor Type */
USB_SIZ_BOS_DESC, /* Total length of BOS descriptor and all of its sub descs */
0x00,
0x04, /* The number of separate device capability descriptors in the BOS */
/* ----------- Device Capability Descriptor: CONTAINER_ID ---------- */
0x14, /* bLength */
0x10, /* bDescriptorType: DEVICE CAPABILITY Type */
0x04, /* bDevCapabilityType: CONTAINER_ID */
0x00, /* bReserved */
0xa7, 0xd6, 0x1b, 0xfa, /* ContainerID: This is a Unique 128-bit number GUID */
0x91, 0xa6, 0xa8, 0x4e,
0xa8, 0x21, 0x9f, 0x2b,
0xaf, 0xf7, 0x94, 0xd4,
/* ----------- Device Capability Descriptor: BillBoard ---------- */
0x34, /* bLength */
0x10, /* bDescriptorType: DEVICE CAPABILITY Type */
0x0D, /* bDevCapabilityType: BILLBOARD_CAPABILITY */
USBD_BB_URL_STRING_INDEX, /* iAddtionalInfoURL: Index of string descriptor providing a URL where the user
can go to get more detailed information about the product and the various
Alternate Modes it supports */
0x02, /* bNumberOfAlternateModes: Number of Alternate modes supported. The
maximum value that this field can be set to is MAX_NUM_ALT_MODE. */
0x00, /* bPreferredAlternateMode: Index of the preferred Alternate Mode. System
software may use this information to provide the user with a better
user experience. */
0x00, 0x00, /* VCONN Power needed by the adapter for full functionality 000b = 1W */
0x01, 0x00, 0x00, 0x00, /* bmConfigured. 01b: Alternate Mode configuration not attempted or exited */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x21, 0x01, /* bcdVersion = 0x0121 */
0x00, /* bAdditionalFailureInfo */
0x00, /* bReserved */
LOBYTE(USBD_VID),
HIBYTE(USBD_VID), /* wSVID[0]: Standard or Vendor ID. This shall match one of the SVIDs
returned in response to a USB PD Discover SVIDs command */
0x00, /* bAlternateMode[0] Index of the Alternate Mode within the SVID as
returned in response to a Discover Modes command. Example:
0 first Mode entry
1 second mode entry */
USBD_BB_ALTMODE0_STRING_INDEX, /* iAlternateModeString[0]: Index of string descriptor describing protocol.
It is optional to support this string. */
LOBYTE(USBD_VID),
HIBYTE(USBD_VID), /* wSVID[1]: Standard or Vendor ID. This shall match one of the SVIDs
returned in response to a USB PD Discover SVIDs command */
0x01, /* bAlternateMode[1] Index of the Alternate Mode within the SVID as
returned in response to a Discover Modes command. Example:
0 first Mode entry
1 second Mode entry */
USBD_BB_ALTMODE1_STRING_INDEX, /* iAlternateModeString[1]: Index of string descriptor describing protocol.
It is optional to support this string. */
/* Alternate Mode Desc */
/* ----------- Device Capability Descriptor: BillBoard Alternate Mode Desc ---------- */
0x08, /* bLength */
0x10, /* bDescriptorType: Device Descriptor Type */
0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */
0x00, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */
0x10, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode
identified by bIndex */
0x08, /* bLength */
0x10, /* bDescriptorType: Device Descriptor Type */
0x0F, /* bDevCapabilityType: BILLBOARD ALTERNATE MODE CAPABILITY */
0x01, /* bIndex: Index of Alternate Mode described in the Billboard Capability Desc */
0x20, 0x00, 0x00, 0x00, /* dwAlternateModeVdo: contents of the Mode VDO for the alternate mode
identified by bIndex */
};
#endif /* USBD_CLASS_BOS_ENABLED */
/* USB Standard Device Descriptor */
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END =
{
USB_LEN_LANGID_STR_DESC,
USB_DESC_TYPE_STRING,
LOBYTE(USBD_LANGID_STRING),
HIBYTE(USBD_LANGID_STRING),
};
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] =
{
USB_SIZ_STRING_SERIAL,
USB_DESC_TYPE_STRING,
};
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
#pragma data_alignment=4
#endif /* __ICCARM__ */
__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
/* Private functions ---------------------------------------------------------*/
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len);
static void Get_SerialNum(void);
/**
* @brief Returns the device descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_DeviceDesc);
return (uint8_t *)USBD_DeviceDesc;
}
/**
* @brief Returns the LangID string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = sizeof(USBD_LangIDDesc);
return (uint8_t *)USBD_LangIDDesc;
}
/**
* @brief Returns the product string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == USBD_SPEED_HIGH)
{
USBD_GetString((uint8_t *)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Returns the manufacturer string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
return USBD_StrDesc;
}
/**
* @brief Returns the serial number string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
UNUSED(speed);
*length = USB_SIZ_STRING_SERIAL;
/* Update the serial number string descriptor with the data from the unique ID*/
Get_SerialNum();
return (uint8_t *)USBD_StringSerial;
}
/**
* @brief Returns the configuration string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == USBD_SPEED_HIGH)
{
USBD_GetString((uint8_t *)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Returns the interface string descriptor.
* @param speed: Current device speed
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
if (speed == USBD_SPEED_HIGH)
{
USBD_GetString((uint8_t *)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
}
else
{
USBD_GetString((uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
}
return USBD_StrDesc;
}
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
*/
static void Get_SerialNum(void)
{
uint32_t deviceserial0;
uint32_t deviceserial1;
uint32_t deviceserial2;
deviceserial0 = *(uint32_t *)DEVICE_ID1;
deviceserial1 = *(uint32_t *)DEVICE_ID2;
deviceserial2 = *(uint32_t *)DEVICE_ID3;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0U)
{
IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8U);
IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4U);
}
}
#if ((USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1))
/**
* @brief USBD_USR_BOSDescriptor
* return the BOS descriptor
* @param speed : current device speed
* @param length : pointer to data length variable
* @retval pointer to descriptor buffer
*/
uint8_t *USBD_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
*length = sizeof(USBD_BOSDesc);
return (uint8_t *)USBD_BOSDesc;
}
#endif /* (USBD_LPM_ENABLED == 1) || (USBD_CLASS_BOS_ENABLED == 1) */
#if (USBD_CLASS_USER_STRING_DESC == 1)
/**
* @brief Returns the Class User string descriptor.
* @param speed: Current device speed
* @param idx: index of string descriptor
* @param length: Pointer to data length variable
* @retval Pointer to descriptor buffer
*/
uint8_t *USBD_Class_UserStrDescriptor(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length)
{
static uint8_t USBD_StrDesc[255];
return USBD_StrDesc;
}
#endif /* USBD_CLASS_USER_STRING_DESC */
/**
* @brief Convert Hex 32Bits value into char
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void IntToUnicode(uint32_t value, uint8_t *pbuf, uint8_t len)
{
uint8_t idx = 0U;
for (idx = 0U ; idx < len ; idx ++)
{
if (((value >> 28)) < 0xAU)
{
pbuf[ 2U * idx] = (value >> 28) + '0';
}
else
{
pbuf[2U * idx] = (value >> 28) + 'A' - 10U;
}
value = value << 4;
pbuf[2U * idx + 1] = 0U;
}
}

View File

@ -0,0 +1,86 @@
This software component is provided to you as part of a software package and
applicable license terms are in the Package_license file. If you received this
software component outside of a package or without applicable license terms,
the terms of the SLA0044 license shall apply and are fully reproduced below:
SLA0044 Rev5/February 2018
Software license agreement
ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT
BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE
OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS
INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES
(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON
BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES
TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT.
Under STMicroelectronics intellectual property rights, the redistribution,
reproduction and use in source and binary forms of the software or any part
thereof, with or without modification, are permitted provided that the following
conditions are met:
1. Redistribution of source code (modified or not) must retain any copyright
notice, this list of conditions and the disclaimer set forth below as items 10
and 11.
2. Redistributions in binary form, except as embedded into microcontroller or
microprocessor device manufactured by or for STMicroelectronics or a software
update for such device, must reproduce any copyright notice provided with the
binary code, this list of conditions, and the disclaimer set forth below as
items 10 and 11, in documentation and/or other materials provided with the
distribution.
3. Neither the name of STMicroelectronics nor the names of other contributors to
this software may be used to endorse or promote products derived from this
software or part thereof without specific written permission.
4. This software or any part thereof, including modifications and/or derivative
works of this software, must be used and execute solely and exclusively on or in
combination with a microcontroller or microprocessor device manufactured by or
for STMicroelectronics.
5. No use, reproduction or redistribution of this software partially or totally
may be done in any manner that would subject this software to any Open Source
Terms. “Open Source Terms” shall mean any open source license which requires as
part of distribution of software that the source code of such software is
distributed therewith or otherwise made available, or open source license that
substantially complies with the Open Source definition specified at
www.opensource.org and any other comparable open source license such as for
example GNU General Public License (GPL), Eclipse Public License (EPL), Apache
Software License, BSD license or MIT license.
6. STMicroelectronics has no obligation to provide any maintenance, support or
updates for the software.
7. The software is and will remain the exclusive property of STMicroelectronics
and its licensors. The recipient will not take any action that jeopardizes
STMicroelectronics and its licensors' proprietary rights or acquire any rights
in the software, except the limited rights specified hereunder.
8. The recipient shall comply with all applicable laws and regulations affecting
the use of the software or any part thereof including any applicable export
control law or regulation.
9. Redistribution and use of this software or any part thereof other than as
permitted under this license is void and will automatically terminate your
rights under this license.
10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE
DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL
STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER
EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY
RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY.

View File

@ -1,15 +0,0 @@
# Balance Infantry
这是一个平衡步兵机器人项目。
## 项目描述
待补充...
## 使用方法
待补充...
## 贡献
待补充...

View File

@ -66,8 +66,8 @@ FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
/* Highest address of the user mode stack */ /* Highest address of the user mode stack */
_estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */ _estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */ /* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */ _Min_Heap_Size = 0x1000; /* required amount of heap */
_Min_Stack_Size = 0x800; /* required amount of stack */ _Min_Stack_Size = 0x2000; /* required amount of stack */
/* Define output sections */ /* Define output sections */
SECTIONS SECTIONS
@ -165,7 +165,7 @@ SECTIONS
*(.RamFunc*) /* .RamFunc* sections */ *(.RamFunc*) /* .RamFunc* sections */
. = ALIGN(4); . = ALIGN(4);
} >DTCMRAM AT> FLASH } >RAM_D1 AT> FLASH
/* Initialized TLS data section */ /* Initialized TLS data section */
.tdata : ALIGN(4) .tdata : ALIGN(4)
@ -175,7 +175,7 @@ SECTIONS
_edata = .; /* define a global symbol at data end */ _edata = .; /* define a global symbol at data end */
PROVIDE(__data_end = .); PROVIDE(__data_end = .);
PROVIDE(__tdata_end = .); PROVIDE(__tdata_end = .);
} >DTCMRAM AT> FLASH } >RAM_D1 AT> FLASH
PROVIDE( __tdata_start = ADDR(.tdata) ); PROVIDE( __tdata_start = ADDR(.tdata) );
PROVIDE( __tdata_size = __tdata_end - __tdata_start ); PROVIDE( __tdata_size = __tdata_end - __tdata_start );
@ -199,7 +199,7 @@ SECTIONS
*(.tbss .tbss.*) *(.tbss .tbss.*)
. = ALIGN(4); . = ALIGN(4);
PROVIDE( __tbss_end = . ); PROVIDE( __tbss_end = . );
} >DTCMRAM } >RAM_D1
PROVIDE( __tbss_start = ADDR(.tbss) ); PROVIDE( __tbss_start = ADDR(.tbss) );
PROVIDE( __tbss_size = __tbss_end - __tbss_start ); PROVIDE( __tbss_size = __tbss_end - __tbss_start );
@ -223,7 +223,7 @@ SECTIONS
_ebss = .; /* define a global symbol at bss end */ _ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss; __bss_end__ = _ebss;
PROVIDE( __bss_end = .); PROVIDE( __bss_end = .);
} >DTCMRAM } >RAM_D1
PROVIDE( __non_tls_bss_start = ADDR(.bss) ); PROVIDE( __non_tls_bss_start = ADDR(.bss) );
PROVIDE( __bss_start = __tbss_start ); PROVIDE( __bss_start = __tbss_start );

28
User/bsp/bsp.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
#define BSP_OK (0)
#define BSP_ERR (-1)
#define BSP_ERR_NULL (-2)
#define BSP_ERR_INITED (-3)
#define BSP_ERR_NO_DEV (-4)
#define BSP_ERR_TIMEOUT (-5)
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

123
User/bsp/bsp_config.yaml Normal file
View File

@ -0,0 +1,123 @@
fdcan:
devices:
- instance: FDCAN1
name: '1'
- instance: FDCAN2
name: '2'
- instance: FDCAN3
name: '3'
enabled: true
flash:
dual_bank: false
enabled: true
mcu_name: STM32H723VGTx
sectors: 8
gpio:
configs:
- custom_name: LCD_BLK
has_exti: false
ioc_label: LCD_BLK
pin: PB10
type: OUTPUT
- custom_name: LCD_RES
has_exti: false
ioc_label: LCD_RES
pin: PB11
type: OUTPUT
- custom_name: DCMI_REST
has_exti: false
ioc_label: DCMI_REST
pin: PB12
type: OUTPUT
- custom_name: ACCL_CS
has_exti: false
ioc_label: ACCL_CS
pin: PC0
type: OUTPUT
- custom_name: POWER_24V_2
has_exti: false
ioc_label: POWER_24V_2
pin: PC13
type: OUTPUT
- custom_name: POWER_24V_1
has_exti: false
ioc_label: POWER_24V_1
pin: PC14-OSC32_IN
type: OUTPUT
- custom_name: POWER_5V
has_exti: false
ioc_label: POWER_5V
pin: PC15-OSC32_OUT
type: OUTPUT
- custom_name: GYRO_CS
has_exti: false
ioc_label: GYRO_CS
pin: PC3_C
type: OUTPUT
- custom_name: DCMI_PWDN
has_exti: false
ioc_label: DCMI_PWDN
pin: PC5
type: OUTPUT
- custom_name: LCD_DC
has_exti: false
ioc_label: LCD_DC
pin: PD10
type: OUTPUT
- custom_name: ACCL_INT
has_exti: true
ioc_label: ACCL_INT
pin: PE10
type: EXTI
- custom_name: GYRO_INT
has_exti: true
ioc_label: GYRO_INT
pin: PE12
type: EXTI
- custom_name: LCD_CS
has_exti: false
ioc_label: LCD_CS
pin: PE15
type: OUTPUT
enabled: true
mm:
enabled: true
pwm:
configs:
- channel: TIM_CHANNEL_1
custom_name: TIM2_CH1
label: TIM2_CH1
timer: TIM2
- channel: TIM_CHANNEL_3
custom_name: TIM2_CH3
label: TIM2_CH3
timer: TIM2
- channel: TIM_CHANNEL_4
custom_name: IMU_HEAT
label: IMU_HEAT
timer: TIM3
- channel: TIM_CHANNEL_2
custom_name: BUZZER
label: BUZZER
timer: TIM12
- channel: TIM_CHANNEL_3
custom_name: TIM1_CH3
label: TIM1_CH3
timer: TIM1
- channel: TIM_CHANNEL_1
custom_name: TIM1_CH1
label: TIM1_CH1
timer: TIM1
enabled: true
spi:
devices:
- instance: SPI2
name: BMI088
enabled: true
time:
enabled: true
uart:
devices:
- instance: UART5
name: DR16
enabled: true

79
User/bsp/can.h Normal file
View File

@ -0,0 +1,79 @@
/**
* @file can.h
* @brief CAN兼容层 - CAN接口映射到FDCAN
* @note FDCAN兼容CAN接口使BSP_CAN_xxx接口
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "bsp/fdcan.h"
/* 类型映射 */
typedef BSP_FDCAN_t BSP_CAN_t;
typedef BSP_FDCAN_Callback_t BSP_CAN_Callback_t;
typedef BSP_FDCAN_Format_t BSP_CAN_Format_t;
typedef BSP_FDCAN_FrameType_t BSP_CAN_FrameType_t;
typedef BSP_FDCAN_Message_t BSP_CAN_Message_t;
typedef BSP_FDCAN_StdDataFrame_t BSP_CAN_StdDataFrame_t;
typedef BSP_FDCAN_ExtDataFrame_t BSP_CAN_ExtDataFrame_t;
typedef BSP_FDCAN_RemoteFrame_t BSP_CAN_RemoteFrame_t;
typedef BSP_FDCAN_IdParser_t BSP_CAN_IdParser_t;
/* 常量映射 */
#define BSP_CAN_MAX_DLC BSP_FDCAN_MAX_DLC
#define BSP_CAN_DEFAULT_QUEUE_SIZE BSP_FDCAN_DEFAULT_QUEUE_SIZE
#define BSP_CAN_TIMEOUT_IMMEDIATE BSP_FDCAN_TIMEOUT_IMMEDIATE
#define BSP_CAN_TIMEOUT_FOREVER BSP_FDCAN_TIMEOUT_FOREVER
#define BSP_CAN_TX_QUEUE_SIZE BSP_FDCAN_TX_QUEUE_SIZE
/* 枚举值映射 */
#define BSP_CAN_1 BSP_FDCAN_1
#define BSP_CAN_2 BSP_FDCAN_2
#define BSP_CAN_3 BSP_FDCAN_3
#define BSP_CAN_NUM BSP_FDCAN_NUM
#define BSP_CAN_ERR BSP_FDCAN_ERR
#define BSP_CAN_FORMAT_STD_DATA BSP_FDCAN_FORMAT_STD_DATA
#define BSP_CAN_FORMAT_EXT_DATA BSP_FDCAN_FORMAT_EXT_DATA
#define BSP_CAN_FORMAT_STD_REMOTE BSP_FDCAN_FORMAT_STD_REMOTE
#define BSP_CAN_FORMAT_EXT_REMOTE BSP_FDCAN_FORMAT_EXT_REMOTE
#define BSP_CAN_FRAME_STD_DATA BSP_FDCAN_FRAME_STD_DATA
#define BSP_CAN_FRAME_EXT_DATA BSP_FDCAN_FRAME_EXT_DATA
#define BSP_CAN_FRAME_STD_REMOTE BSP_FDCAN_FRAME_STD_REMOTE
#define BSP_CAN_FRAME_EXT_REMOTE BSP_FDCAN_FRAME_EXT_REMOTE
/* 函数映射 */
#define BSP_CAN_Init() BSP_FDCAN_Init()
#define BSP_CAN_GetHandle(can) BSP_FDCAN_GetHandle(can)
#define BSP_CAN_RegisterCallback(can, type, callback) \
BSP_FDCAN_RegisterCallback(can, type, callback)
#define BSP_CAN_Transmit(can, format, id, data, dlc) \
BSP_FDCAN_Transmit(can, format, id, data, dlc)
#define BSP_CAN_TransmitStdDataFrame(can, frame) \
BSP_FDCAN_TransmitStdDataFrame(can, frame)
#define BSP_CAN_TransmitExtDataFrame(can, frame) \
BSP_FDCAN_TransmitExtDataFrame(can, frame)
#define BSP_CAN_TransmitRemoteFrame(can, frame) \
BSP_FDCAN_TransmitRemoteFrame(can, frame)
#define BSP_CAN_RegisterId(can, can_id, queue_size) \
BSP_FDCAN_RegisterId(can, can_id, queue_size)
#define BSP_CAN_GetMessage(can, can_id, msg, timeout) \
BSP_FDCAN_GetMessage(can, can_id, msg, timeout)
#define BSP_CAN_GetQueueCount(can, can_id) \
BSP_FDCAN_GetQueueCount(can, can_id)
#define BSP_CAN_FlushQueue(can, can_id) \
BSP_FDCAN_FlushQueue(can, can_id)
#define BSP_CAN_RegisterIdParser(parser) \
BSP_FDCAN_RegisterIdParser(parser)
#define BSP_CAN_ParseId(original_id, frame_type) \
BSP_FDCAN_ParseId(original_id, frame_type)
#ifdef __cplusplus
}
#endif

576
User/bsp/fdcan.c Normal file
View File

@ -0,0 +1,576 @@
/* Includes ----------------------------------------------------------------- */
#include "fdcan.h"
#include "bsp/fdcan.h"
#include "bsp/bsp.h"
#include <fdcan.h>
#include <cmsis_os2.h>
#include <string.h>
/* Private define ----------------------------------------------------------- */
#define FDCAN_QUEUE_MUTEX_TIMEOUT 100
/* Private macro ------------------------------------------------------------ */
/* ===== FDCAN_FilterTypeDef 配置表 =====
* FDCAN实例的过滤器参数表
*
* idx idtype ftype id1 id2 rxidx
* ID1 ID2
*/
#ifdef FDCAN1_EN
#define FDCAN1_FILTER_CONFIG_TABLE(X) \
X(0, FDCAN_STANDARD_ID, FDCAN_FILTER_MASK, 0x000 , 0x000 , 0) \
X(1, FDCAN_EXTENDED_ID, FDCAN_FILTER_MASK, 0x00000000, 0x00000000, 0)
#define FDCAN1_GLOBAL_FILTER FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE/* 全局过滤器参数(用于 HAL_FDCAN_ConfigGlobalFilter */
#endif
#ifdef FDCAN2_EN
#define FDCAN2_FILTER_CONFIG_TABLE(X) \
X(0, FDCAN_STANDARD_ID, FDCAN_FILTER_MASK, 0x000 , 0x000 , 0) \
X(1, FDCAN_EXTENDED_ID, FDCAN_FILTER_MASK, 0x00000000, 0x00000000, 0)
#define FDCAN2_GLOBAL_FILTER FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE/* 全局过滤器参数(用于 HAL_FDCAN_ConfigGlobalFilter */
#endif
#ifdef FDCAN3_EN
#define FDCAN3_FILTER_CONFIG_TABLE(X) \
X(0, FDCAN_STANDARD_ID, FDCAN_FILTER_MASK, 0x000 , 0x000 , 0) \
X(1, FDCAN_EXTENDED_ID, FDCAN_FILTER_MASK, 0x00000000, 0x00000000, 0)
#define FDCAN3_GLOBAL_FILTER FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE/* 全局过滤器参数(用于 HAL_FDCAN_ConfigGlobalFilter */
#endif
/* ====宏展开实现==== */
#define FDCAN_FILTER_TO_RXFIFO_ENUM_INNER(FIFOIndex) FDCAN_FILTER_TO_RXFIFO##FIFOIndex
#define FDCAN_FILTER_TO_RXFIFO_ENUM(FIFOIndex) FDCAN_FILTER_TO_RXFIFO_ENUM_INNER(FIFOIndex)
#define FDCAN_CONFIG_FILTER(idx, idtype, ftype, id1, id2, rxidx) \
sFilterConfig.FilterIndex = (idx); \
sFilterConfig.IdType = (idtype); \
sFilterConfig.FilterType = (ftype); \
sFilterConfig.FilterConfig = (FDCAN_FILTER_TO_RXFIFO_ENUM(FDCANX_RX_FIFO)); \
sFilterConfig.FilterID1 = (id1); \
sFilterConfig.FilterID2 = (id2); \
sFilterConfig.RxBufferIndex = (rxidx); \
HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig);
#define FDCAN_NOTIFY_FLAG_RXFIFO_INNER(FIFO_IDX) FDCAN_IT_RX_FIFO##FIFO_IDX##_NEW_MESSAGE
#define FDCAN_NOTIFY_FLAG_RXFIFO(FIFO_IDX) FDCAN_NOTIFY_FLAG_RXFIFO_INNER(FIFO_IDX)
#define FDCANx_NOTIFY_FLAGS(FIFO_MACRO) (FDCAN_NOTIFY_FLAG_RXFIFO(FIFO_MACRO) | FDCAN_IT_TX_EVT_FIFO_NEW_DATA | FDCAN_IT_RAM_ACCESS_FAILURE)
#define FDCANX_MSG_PENDING_CB_INNER(FIFO_IDX) HAL_FDCAN_RX_FIFO##FIFO_IDX##_MSG_PENDING_CB
#define FDCANX_MSG_PENDING_CB(FIFO_IDX) FDCANX_MSG_PENDING_CB_INNER(FIFO_IDX)
/* Private typedef ---------------------------------------------------------- */
typedef struct BSP_FDCAN_QueueNode {
BSP_FDCAN_t fdcan;
uint32_t can_id;
osMessageQueueId_t queue;
uint8_t queue_size;
struct BSP_FDCAN_QueueNode *next;
} BSP_FDCAN_QueueNode_t;
/* Private variables -------------------------------------------------------- */
static BSP_FDCAN_QueueNode_t *queue_list = NULL;
static osMutexId_t queue_mutex = NULL;
static void (*FDCAN_Callback[BSP_FDCAN_NUM][HAL_FDCAN_CB_NUM])(void);
static bool inited = false;
static BSP_FDCAN_IdParser_t id_parser = NULL;
static BSP_FDCAN_TxQueue_t tx_queues[BSP_FDCAN_NUM];
static const uint8_t fdcan_dlc2len[16] = {0,1,2,3,4,5,6,7,8,12,16,20,24,32,48,64};
/* Private function prototypes ---------------------------------------------- */
static BSP_FDCAN_t FDCAN_Get(FDCAN_HandleTypeDef *hfdcan);
static osMessageQueueId_t BSP_FDCAN_FindQueue(BSP_FDCAN_t fdcan, uint32_t can_id);
static int8_t BSP_FDCAN_CreateIdQueue(BSP_FDCAN_t fdcan, uint32_t can_id, uint8_t queue_size);
static void BSP_FDCAN_RxFifo0Callback(void);
static void BSP_FDCAN_RxFifo1Callback(void);
static void BSP_FDCAN_TxCompleteCallback(void);
static BSP_FDCAN_FrameType_t BSP_FDCAN_GetFrameType(FDCAN_RxHeaderTypeDef *header);
static uint32_t BSP_FDCAN_DefaultIdParser(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type);
static void BSP_FDCAN_TxQueueInit(BSP_FDCAN_t fdcan);
static bool BSP_FDCAN_TxQueuePush(BSP_FDCAN_t fdcan, BSP_FDCAN_TxMessage_t *msg);
static bool BSP_FDCAN_TxQueuePop(BSP_FDCAN_t fdcan, BSP_FDCAN_TxMessage_t *msg);
static bool BSP_FDCAN_TxQueueIsEmpty(BSP_FDCAN_t fdcan);
/* Private functions -------------------------------------------------------- */
static BSP_FDCAN_t FDCAN_Get(FDCAN_HandleTypeDef *hfdcan) {
if (hfdcan == NULL) return BSP_FDCAN_ERR;
if (hfdcan->Instance == FDCAN1) return BSP_FDCAN_1;
else if (hfdcan->Instance == FDCAN2) return BSP_FDCAN_2;
else if (hfdcan->Instance == FDCAN3) return BSP_FDCAN_3;
else return BSP_FDCAN_ERR;
}
static osMessageQueueId_t BSP_FDCAN_FindQueue(BSP_FDCAN_t fdcan, uint32_t can_id) {
BSP_FDCAN_QueueNode_t *node = queue_list;
while (node != NULL) {
if (node->fdcan == fdcan && node->can_id == can_id) return node->queue;
node = node->next;
}
return NULL;
}
static int8_t BSP_FDCAN_CreateIdQueue(BSP_FDCAN_t fdcan, uint32_t can_id, uint8_t queue_size) {
if (queue_size == 0) queue_size = BSP_FDCAN_DEFAULT_QUEUE_SIZE;
if (osMutexAcquire(queue_mutex, FDCAN_QUEUE_MUTEX_TIMEOUT) != osOK) return BSP_ERR_TIMEOUT;
BSP_FDCAN_QueueNode_t *node = queue_list;
while (node != NULL) {
if (node->fdcan == fdcan && node->can_id == can_id) {
osMutexRelease(queue_mutex);
return BSP_ERR;
}
node = node->next;
}
BSP_FDCAN_QueueNode_t *new_node = (BSP_FDCAN_QueueNode_t *)BSP_Malloc(sizeof(BSP_FDCAN_QueueNode_t));
if (new_node == NULL) { osMutexRelease(queue_mutex); return BSP_ERR_NULL; }
new_node->queue = osMessageQueueNew(queue_size, sizeof(BSP_FDCAN_Message_t), NULL);
if (new_node->queue == NULL) { BSP_Free(new_node); osMutexRelease(queue_mutex); return BSP_ERR; }
new_node->fdcan = fdcan;
new_node->can_id = can_id;
new_node->queue_size = queue_size;
new_node->next = queue_list;
queue_list = new_node;
osMutexRelease(queue_mutex);
return BSP_OK;
}
static BSP_FDCAN_FrameType_t BSP_FDCAN_GetFrameType(FDCAN_RxHeaderTypeDef *header) {
if (header->RxFrameType == FDCAN_REMOTE_FRAME) {
return (header->IdType == FDCAN_EXTENDED_ID) ? BSP_FDCAN_FRAME_EXT_REMOTE : BSP_FDCAN_FRAME_STD_REMOTE;
} else {
return (header->IdType == FDCAN_EXTENDED_ID) ? BSP_FDCAN_FRAME_EXT_DATA : BSP_FDCAN_FRAME_STD_DATA;
}
}
static uint32_t BSP_FDCAN_DefaultIdParser(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type) {
(void)frame_type;
return original_id;
}
static uint32_t BSP_FDCAN_EncodeDLC(uint8_t dlc) {
if (dlc <= 8) return dlc;
if (dlc <= 12) return FDCAN_DLC_BYTES_12;
if (dlc <= 16) return FDCAN_DLC_BYTES_16;
if (dlc <= 20) return FDCAN_DLC_BYTES_20;
if (dlc <= 24) return FDCAN_DLC_BYTES_24;
if (dlc <= 32) return FDCAN_DLC_BYTES_32;
if (dlc <= 48) return FDCAN_DLC_BYTES_48;
return FDCAN_DLC_BYTES_64;
}
static void BSP_FDCAN_TxQueueInit(BSP_FDCAN_t fdcan) {
if (fdcan >= BSP_FDCAN_NUM) return;
tx_queues[fdcan].head = 0;
tx_queues[fdcan].tail = 0;
}
static bool BSP_FDCAN_TxQueuePush(BSP_FDCAN_t fdcan, BSP_FDCAN_TxMessage_t *msg) {
if (fdcan >= BSP_FDCAN_NUM || msg == NULL) return false;
BSP_FDCAN_TxQueue_t *queue = &tx_queues[fdcan];
uint32_t next_head = (queue->head + 1) % BSP_FDCAN_TX_QUEUE_SIZE;
if (next_head == queue->tail) return false;
queue->buffer[queue->head] = *msg;
queue->head = next_head;
return true;
}
static bool BSP_FDCAN_TxQueuePop(BSP_FDCAN_t fdcan, BSP_FDCAN_TxMessage_t *msg) {
if (fdcan >= BSP_FDCAN_NUM || msg == NULL) return false;
BSP_FDCAN_TxQueue_t *queue = &tx_queues[fdcan];
if (queue->head == queue->tail) return false;
*msg = queue->buffer[queue->tail];
queue->tail = (queue->tail + 1) % BSP_FDCAN_TX_QUEUE_SIZE;
return true;
}
static bool BSP_FDCAN_TxQueueIsEmpty(BSP_FDCAN_t fdcan) {
if (fdcan >= BSP_FDCAN_NUM) return true;
return tx_queues[fdcan].head == tx_queues[fdcan].tail;
}
static void BSP_FDCAN_TxCompleteCallback(void) {
for (int i = 0; i < BSP_FDCAN_NUM; i++) {
BSP_FDCAN_t fdcan = (BSP_FDCAN_t)i;
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle(fdcan);
if (hfdcan == NULL) continue;
// 消费所有 TX EVENT FIFO 事件,防止堵塞
FDCAN_TxEventFifoTypeDef tx_event;
while (HAL_FDCAN_GetTxEvent(hfdcan, &tx_event) == HAL_OK) {
// 可在此统计 MessageMarker、ID、时间戳等
}
// 续写软件队列到硬件 FIFO
BSP_FDCAN_TxMessage_t msg;
while (!BSP_FDCAN_TxQueueIsEmpty(fdcan)) {
if (HAL_FDCAN_GetTxFifoFreeLevel(hfdcan) == 0) break;
if (!BSP_FDCAN_TxQueuePop(fdcan, &msg)) break;
HAL_StatusTypeDef res = HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, &msg.header, msg.data);
if (res != HAL_OK) {
break;
}
}
}
}
static void BSP_FDCAN_RxFifo0Callback(void) {
FDCAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[BSP_FDCAN_MAX_DLC];
for (int fdcan_idx = 0; fdcan_idx < BSP_FDCAN_NUM; fdcan_idx++) {
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle((BSP_FDCAN_t)fdcan_idx);
if (hfdcan == NULL) continue;
while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) {
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, rx_data) == HAL_OK) {
uint32_t original_id = (rx_header.IdType == FDCAN_STANDARD_ID) ? rx_header.Identifier&0x7ff : rx_header.Identifier&0x1fffffff;
BSP_FDCAN_FrameType_t frame_type = BSP_FDCAN_GetFrameType(&rx_header);
uint32_t parsed_id = BSP_FDCAN_ParseId(original_id, frame_type);
osMessageQueueId_t queue = BSP_FDCAN_FindQueue((BSP_FDCAN_t)fdcan_idx, parsed_id);
if (queue != NULL) {
BSP_FDCAN_Message_t msg;
msg.frame_type = frame_type;
msg.original_id = original_id;
msg.parsed_id = parsed_id;
uint8_t real_len = fdcan_dlc2len[rx_header.DataLength & 0xF];
msg.dlc = real_len;
if (msg.dlc > BSP_FDCAN_MAX_DLC) msg.dlc = BSP_FDCAN_MAX_DLC;
memset(msg.data, 0, BSP_FDCAN_MAX_DLC);//现在是最大缓冲区写法所以全清零
memcpy(msg.data, rx_data, msg.dlc);
osMessageQueuePut(queue, &msg, 0, 0);
}
} else {
break;
}
}
}
}
static void BSP_FDCAN_RxFifo1Callback(void) {
FDCAN_RxHeaderTypeDef rx_header;
uint8_t rx_data[BSP_FDCAN_MAX_DLC];
for (int fdcan_idx = 0; fdcan_idx < BSP_FDCAN_NUM; fdcan_idx++) {
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle((BSP_FDCAN_t)fdcan_idx);
if (hfdcan == NULL) continue;
while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO1) > 0) {
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO1, &rx_header, rx_data) == HAL_OK) {
uint32_t original_id = (rx_header.IdType == FDCAN_STANDARD_ID) ? rx_header.Identifier&0x7ff : rx_header.Identifier&0x1fffffff;
BSP_FDCAN_FrameType_t frame_type = BSP_FDCAN_GetFrameType(&rx_header);
uint32_t parsed_id = BSP_FDCAN_ParseId(original_id, frame_type);
osMessageQueueId_t queue = BSP_FDCAN_FindQueue((BSP_FDCAN_t)fdcan_idx, parsed_id);
if (queue != NULL) {
BSP_FDCAN_Message_t msg;
msg.frame_type = frame_type;
msg.original_id = original_id;
msg.parsed_id = parsed_id;
uint8_t real_len = fdcan_dlc2len[rx_header.DataLength & 0xF];
msg.dlc = real_len;
if (msg.dlc > BSP_FDCAN_MAX_DLC) msg.dlc = BSP_FDCAN_MAX_DLC;
memset(msg.data, 0, BSP_FDCAN_MAX_DLC);//现在是最大缓冲区写法所以全清零
memcpy(msg.data, rx_data, msg.dlc);
osMessageQueuePut(queue, &msg, 0, 0);
}
} else {
break;
}
}
}
}
/* HAL Callback Stubs (map HAL FDCAN callbacks to user callbacks) */
void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t TxEventFifoITs) {
BSP_FDCAN_t bsp_fdcan = FDCAN_Get(hfdcan);
if (bsp_fdcan != BSP_FDCAN_ERR) {
if (FDCAN_Callback[bsp_fdcan][HAL_FDCAN_TX_EVENT_FIFO_CB])
FDCAN_Callback[bsp_fdcan][HAL_FDCAN_TX_EVENT_FIFO_CB]();
}
}
void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex) {
BSP_FDCAN_t bsp_fdcan = FDCAN_Get(hfdcan);
if (bsp_fdcan != BSP_FDCAN_ERR) {
if (FDCAN_Callback[bsp_fdcan][HAL_FDCAN_TX_BUFFER_COMPLETE_CB])
FDCAN_Callback[bsp_fdcan][HAL_FDCAN_TX_BUFFER_COMPLETE_CB]();
}
}
void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndex) {
BSP_FDCAN_t bsp_fdcan = FDCAN_Get(hfdcan);
if (bsp_fdcan != BSP_FDCAN_ERR) {
if (FDCAN_Callback[bsp_fdcan][HAL_FDCAN_TX_BUFFER_ABORT_CB])
FDCAN_Callback[bsp_fdcan][HAL_FDCAN_TX_BUFFER_ABORT_CB]();
}
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) {
BSP_FDCAN_t bsp_fdcan = FDCAN_Get(hfdcan);
if (bsp_fdcan != BSP_FDCAN_ERR) {
if (FDCAN_Callback[bsp_fdcan][HAL_FDCAN_RX_FIFO0_MSG_PENDING_CB])
FDCAN_Callback[bsp_fdcan][HAL_FDCAN_RX_FIFO0_MSG_PENDING_CB]();
}
}
void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs) {
BSP_FDCAN_t bsp_fdcan = FDCAN_Get(hfdcan);
if (bsp_fdcan != BSP_FDCAN_ERR) {
if (FDCAN_Callback[bsp_fdcan][HAL_FDCAN_RX_FIFO1_MSG_PENDING_CB])
FDCAN_Callback[bsp_fdcan][HAL_FDCAN_RX_FIFO1_MSG_PENDING_CB]();
}
}
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan) {
BSP_FDCAN_t bsp_fdcan = FDCAN_Get(hfdcan);
if (bsp_fdcan != BSP_FDCAN_ERR) {
if (FDCAN_Callback[bsp_fdcan][HAL_FDCAN_ERROR_CB])
FDCAN_Callback[bsp_fdcan][HAL_FDCAN_ERROR_CB]();
}
}
/* Exported functions ------------------------------------------------------- */
int8_t BSP_FDCAN_Init(void) {
if (inited) return BSP_ERR_INITED;
memset(FDCAN_Callback, 0, sizeof(FDCAN_Callback));
for (int i = 0; i < BSP_FDCAN_NUM; i++) BSP_FDCAN_TxQueueInit((BSP_FDCAN_t)i);
id_parser = BSP_FDCAN_DefaultIdParser;
queue_mutex = osMutexNew(NULL);
if (queue_mutex == NULL) return BSP_ERR;
inited = true;
/* 配置并启动 FDCAN 实例,绑定中断/回调 */
//========== 过滤器配置说明:==========================
// 过滤器编号相对于每个相当于经典can过滤器的bank
// sFilterConfig.FilterIndex = 0 to 127(标准ID) or 0 to 63(扩展ID);
// 关于过滤器索引的说明:
// 由stm32h7xx_hal_fdcan.c的第1874行代码可知滤波器地址计算方式如下
// StandardFilterSA字节 = SRAMCAN_BASE + (MessageRAMOffset * 4U)
// 标准滤波器物理地址(字节) = StandardFilterSA + (FilterIndex * 4U)(每个标准滤波器占 4 字节 = 1 word,扩展的则是8个字节
//
//
// 标识符类型:
// sFilterConfig.IdType = FDCAN_STANDARD_ID or FDCAN_EXTENDED_ID;
// 过滤器类型: (仅介绍掩码模式)
// sFilterConfig.FilterType = FDCAN_FILTER_MASK;(掩码模式)
// 过滤器配置:
// sFilterConfig.FilterConfig = FDCAN_FILTER_DISABLE; (禁用该过滤器条目)
// FDCAN_FILTER_TO_RXFIFO0; (将匹配的消息放入 FIFO 0普通优先级)
// FDCAN_FILTER_TO_RXFIFO1; (将匹配的消息放入 FIFO 1高优先级)
// FDCAN_FILTER_TO_RXBUFFER; (将匹配的消息放入 指定的接收缓冲区)
// FDCAN_FILTER_REJECT; (拒绝接收该标识符对应的报文)
// FDCAN_FILTER_ACCEPT; (接受所有消息)
// FDCAN_FILTER_HP (过滤器匹配时,将报文标记为高优先级)
// FDCAN_FILTER_TO_RXFIFO0_HP (过滤器匹配时将报文标记为高优先级并存储至接收FIFO 0)
// FDCAN_FILTER_TO_RXFIFO1_HP (过滤器匹配时将报文标记为高优先级并存储至接收FIFO 1)
// FDCAN_FILTER_TO_RXBUFFER (将报文存储至接收缓冲区过滤器类型FilterType配置项失效 )
// 过滤器ID与掩码(FilterType掩码模式下)
// 比较值(要匹配的 ID 的参考位)
// sFilterConfig.FilterID1 = 0 to 0x7FF; 标准ID
// 0 to 0x1FFFFFFF 扩展ID
// 掩码1=比较该位0=忽略该位)
// sFilterConfig.FilterID2 = 0 to 0x7FF; 标准ID
// 0 to 0x1FFFFFFF 扩展ID
// 接收缓冲区索引
// FilterConfig == FDCAN_FILTER_TO_RXBUFFER 时有效;必须小于RxBuffersNbr配置的实际Rx buffer数量
// sFilterConfig.RxBufferIndex = 0 to (RxBuffersNbr - 1);
// 标记校准信息(用于 FDCAN 校准/时钟相关单元作特殊处理或统计)
// 仅在FilterConfig 设为 FDCAN_FILTER_TO_RXBUFFER 时才有意义通常设置为0
// IsCalibrationMsg = 0 or 1;
// fdcan_filter_table.h
//=================================================================================
/* 依据上述说明配置过滤器并启动FDCAN */
FDCAN_FilterTypeDef sFilterConfig;
#ifdef FDCAN1_EN
#define hfdcan hfdcan1
#define FDCANX_RX_FIFO FDCAN1_RX_FIFO
FDCAN1_FILTER_CONFIG_TABLE(FDCAN_CONFIG_FILTER)
#undef hfdcan
#undef FDCANX_RX_FIFO
HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN1_GLOBAL_FILTER);
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCANx_NOTIFY_FLAGS(FDCAN1_RX_FIFO), 0);
BSP_FDCAN_RegisterCallback(BSP_FDCAN_1, FDCANX_MSG_PENDING_CB(FDCAN1_RX_FIFO), BSP_FDCAN_RxFifo0Callback);
BSP_FDCAN_RegisterCallback(BSP_FDCAN_1, HAL_FDCAN_TX_EVENT_FIFO_CB, BSP_FDCAN_TxCompleteCallback);
HAL_FDCAN_Start(&hfdcan1);
#endif
#ifdef FDCAN2_EN
#define hfdcan hfdcan2
#define FDCANX_RX_FIFO FDCAN2_RX_FIFO
FDCAN2_FILTER_CONFIG_TABLE(FDCAN_CONFIG_FILTER)
#undef hfdcan
#undef FDCANX_RX_FIFO
HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN2_GLOBAL_FILTER);
HAL_FDCAN_ActivateNotification(&hfdcan2, FDCANx_NOTIFY_FLAGS(FDCAN2_RX_FIFO), 0);
BSP_FDCAN_RegisterCallback(BSP_FDCAN_2, FDCANX_MSG_PENDING_CB(FDCAN2_RX_FIFO), BSP_FDCAN_RxFifo1Callback);
BSP_FDCAN_RegisterCallback(BSP_FDCAN_2, HAL_FDCAN_TX_EVENT_FIFO_CB, BSP_FDCAN_TxCompleteCallback);
HAL_FDCAN_Start(&hfdcan2);
#endif
#ifdef FDCAN3_EN
#define hfdcan hfdcan3
#define FDCANX_RX_FIFO FDCAN3_RX_FIFO
FDCAN3_FILTER_CONFIG_TABLE(FDCAN_CONFIG_FILTER)
#undef hfdcan
#undef FDCANX_RX_FIFO
HAL_FDCAN_ConfigGlobalFilter(&hfdcan3, FDCAN3_GLOBAL_FILTER);
HAL_FDCAN_ActivateNotification(&hfdcan3, FDCANx_NOTIFY_FLAGS(FDCAN3_RX_FIFO), 0);
BSP_FDCAN_RegisterCallback(BSP_FDCAN_3, FDCANX_MSG_PENDING_CB(FDCAN3_RX_FIFO), BSP_FDCAN_RxFifo1Callback);
BSP_FDCAN_RegisterCallback(BSP_FDCAN_3, HAL_FDCAN_TX_EVENT_FIFO_CB, BSP_FDCAN_TxCompleteCallback);
HAL_FDCAN_Start(&hfdcan3);
#endif
#undef FDCAN_FILTER_TO_RXFIFO_ENUM_INNER
#undef FDCAN_FILTER_TO_RXFIFO_ENUM
#undef FDCAN_CONFIG_FILTER
#undef FDCAN_NOTIFY_FLAG_RXFIFO_INNER
#undef FDCAN_NOTIFY_FLAG_RXFIFO
#undef FDCANx_NOTIFY_FLAGS
#undef FDCANX_MSG_PENDING_CB_INNER
#undef FDCANX_MSG_PENDING_CB
return BSP_OK;
}
FDCAN_HandleTypeDef *BSP_FDCAN_GetHandle(BSP_FDCAN_t fdcan) {
if (fdcan >= BSP_FDCAN_NUM) return NULL;
switch (fdcan) {
/* AUTO GENERATED BSP_FDCAN_GET_HANDLE BEGIN */
case BSP_FDCAN_1: return &hfdcan1;
case BSP_FDCAN_2: return &hfdcan2;
case BSP_FDCAN_3: return &hfdcan3;
/* AUTO GENERATED BSP_FDCAN_GET_HANDLE END */
default: return NULL;
}
}
int8_t BSP_FDCAN_RegisterCallback(BSP_FDCAN_t fdcan, BSP_FDCAN_Callback_t type, void (*callback)(void)) {
if (!inited) return BSP_ERR_INITED;
if (callback == NULL) return BSP_ERR_NULL;
if (fdcan >= BSP_FDCAN_NUM) return BSP_ERR;
if (type >= HAL_FDCAN_CB_NUM) return BSP_ERR;
FDCAN_Callback[fdcan][type] = callback;
return BSP_OK;
}
int8_t BSP_FDCAN_Transmit(BSP_FDCAN_t fdcan, BSP_FDCAN_Format_t format, uint32_t id, uint8_t *data, uint8_t dlc) {
if (!inited) return BSP_ERR_INITED;
if (fdcan >= BSP_FDCAN_NUM) return BSP_ERR;
if (data == NULL && format != BSP_FDCAN_FORMAT_STD_REMOTE && format != BSP_FDCAN_FORMAT_EXT_REMOTE) return BSP_ERR_NULL;
if (dlc > BSP_FDCAN_MAX_DLC) return BSP_ERR;
FDCAN_HandleTypeDef *hfdcan = BSP_FDCAN_GetHandle(fdcan);
if (hfdcan == NULL) return BSP_ERR_NULL;
BSP_FDCAN_TxMessage_t tx_msg = {0};
switch (format) {
case BSP_FDCAN_FORMAT_STD_DATA:
tx_msg.header.Identifier = id;
tx_msg.header.IdType = FDCAN_STANDARD_ID;
tx_msg.header.TxFrameType = FDCAN_DATA_FRAME;
break;
case BSP_FDCAN_FORMAT_EXT_DATA:
tx_msg.header.Identifier = id;
tx_msg.header.IdType = FDCAN_EXTENDED_ID;
tx_msg.header.TxFrameType = FDCAN_DATA_FRAME;
break;
case BSP_FDCAN_FORMAT_STD_REMOTE:
tx_msg.header.Identifier = id;
tx_msg.header.IdType = FDCAN_STANDARD_ID;
tx_msg.header.TxFrameType = FDCAN_REMOTE_FRAME;
break;
case BSP_FDCAN_FORMAT_EXT_REMOTE:
tx_msg.header.Identifier = id;
tx_msg.header.IdType = FDCAN_EXTENDED_ID;
tx_msg.header.TxFrameType = FDCAN_REMOTE_FRAME;
break;
default:
return BSP_ERR;
}
switch (hfdcan->Init.FrameFormat) {
case FDCAN_FRAME_FD_BRS:
tx_msg.header.BitRateSwitch = FDCAN_BRS_ON;
tx_msg.header.FDFormat = FDCAN_FD_CAN;
break;
case FDCAN_FRAME_FD_NO_BRS:
tx_msg.header.BitRateSwitch = FDCAN_BRS_OFF;
tx_msg.header.FDFormat = FDCAN_FD_CAN;
break;
case FDCAN_FRAME_CLASSIC:
default:
tx_msg.header.BitRateSwitch = FDCAN_BRS_OFF;
tx_msg.header.FDFormat = FDCAN_CLASSIC_CAN;
break;
}
tx_msg.header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
tx_msg.header.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
tx_msg.header.MessageMarker = 0x01;
tx_msg.header.DataLength = BSP_FDCAN_EncodeDLC(dlc);
memset(tx_msg.data, 0, dlc);
if (data != NULL && dlc > 0) {memcpy(tx_msg.data, data, dlc);}
if (HAL_FDCAN_GetTxFifoFreeLevel(hfdcan) > 0) {
if (HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, &tx_msg.header, tx_msg.data) == HAL_OK) return BSP_OK;
}
if (BSP_FDCAN_TxQueuePush(fdcan, &tx_msg)) return BSP_OK;
return BSP_ERR;
}
int8_t BSP_FDCAN_TransmitStdDataFrame(BSP_FDCAN_t fdcan, BSP_FDCAN_StdDataFrame_t *frame) {
if (frame == NULL) return BSP_ERR_NULL;
return BSP_FDCAN_Transmit(fdcan, BSP_FDCAN_FORMAT_STD_DATA, frame->id, frame->data, frame->dlc);
}
int8_t BSP_FDCAN_TransmitExtDataFrame(BSP_FDCAN_t fdcan, BSP_FDCAN_ExtDataFrame_t *frame) {
if (frame == NULL) return BSP_ERR_NULL;
return BSP_FDCAN_Transmit(fdcan, BSP_FDCAN_FORMAT_EXT_DATA, frame->id, frame->data, frame->dlc);
}
int8_t BSP_FDCAN_TransmitRemoteFrame(BSP_FDCAN_t fdcan, BSP_FDCAN_RemoteFrame_t *frame) {
if (frame == NULL) return BSP_ERR_NULL;
BSP_FDCAN_Format_t format = frame->is_extended ? BSP_FDCAN_FORMAT_EXT_REMOTE : BSP_FDCAN_FORMAT_STD_REMOTE;
return BSP_FDCAN_Transmit(fdcan, format, frame->id, NULL, frame->dlc);
}
int8_t BSP_FDCAN_RegisterId(BSP_FDCAN_t fdcan, uint32_t can_id, uint8_t queue_size) {
if (!inited) return BSP_ERR_INITED;
return BSP_FDCAN_CreateIdQueue(fdcan, can_id, queue_size);
}
int8_t BSP_FDCAN_GetMessage(BSP_FDCAN_t fdcan, uint32_t can_id, BSP_FDCAN_Message_t *msg, uint32_t timeout) {
if (!inited) return BSP_ERR_INITED;
if (msg == NULL) return BSP_ERR_NULL;
if (osMutexAcquire(queue_mutex, FDCAN_QUEUE_MUTEX_TIMEOUT) != osOK) return BSP_ERR_TIMEOUT;
osMessageQueueId_t queue = BSP_FDCAN_FindQueue(fdcan, can_id);
osMutexRelease(queue_mutex);
if (queue == NULL) return BSP_ERR_NO_DEV;
osStatus_t res = osMessageQueueGet(queue, msg, NULL, timeout);
return (res == osOK) ? BSP_OK : BSP_ERR;
}
int32_t BSP_FDCAN_GetQueueCount(BSP_FDCAN_t fdcan, uint32_t can_id) {
if (!inited) return -1;
if (osMutexAcquire(queue_mutex, FDCAN_QUEUE_MUTEX_TIMEOUT) != osOK) return -1;
osMessageQueueId_t queue = BSP_FDCAN_FindQueue(fdcan, can_id);
osMutexRelease(queue_mutex);
if (queue == NULL) return -1;
return (int32_t)osMessageQueueGetCount(queue);
}
int8_t BSP_FDCAN_FlushQueue(BSP_FDCAN_t fdcan, uint32_t can_id) {
if (!inited) return BSP_ERR_INITED;
if (osMutexAcquire(queue_mutex, FDCAN_QUEUE_MUTEX_TIMEOUT) != osOK) return BSP_ERR_TIMEOUT;
osMessageQueueId_t queue = BSP_FDCAN_FindQueue(fdcan, can_id);
osMutexRelease(queue_mutex);
if (queue == NULL) return BSP_ERR_NO_DEV;
BSP_FDCAN_Message_t tmp;
while (osMessageQueueGet(queue, &tmp, NULL, BSP_FDCAN_TIMEOUT_IMMEDIATE) == osOK) { }
return BSP_OK;
}
int8_t BSP_FDCAN_RegisterIdParser(BSP_FDCAN_IdParser_t parser) {
if (!inited) return BSP_ERR_INITED;
if (parser == NULL) return BSP_ERR_NULL;
id_parser = parser;
return BSP_OK;
}
uint32_t BSP_FDCAN_ParseId(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type) {
if (id_parser != NULL) return id_parser(original_id, frame_type);
return BSP_FDCAN_DefaultIdParser(original_id, frame_type);
}
/* */

137
User/bsp/fdcan.h Normal file
View File

@ -0,0 +1,137 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stdint.h>
#include <stdbool.h>
#include "bsp/bsp.h"
#include "bsp/mm.h"
#include <cmsis_os.h>
/* USER INCLUDE BEGIN */
#include <fdcan.h>
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
#define BSP_FDCAN_MAX_DLC 64
#define BSP_FDCAN_DEFAULT_QUEUE_SIZE 10
#define BSP_FDCAN_TIMEOUT_IMMEDIATE 0
#define BSP_FDCAN_TIMEOUT_FOREVER osWaitForever
#define BSP_FDCAN_TX_QUEUE_SIZE 32
/* Exported macro ----------------------------------------------------------- */
//FDCANX实例使能
/* AUTO GENERATED FDCAN_EN BEGIN */
#define FDCAN1_EN
#define FDCAN2_EN
#define FDCAN3_EN
/* AUTO GENERATED FDCAN_EN END */
// FDCANX接收FIFO选择0=FIFO0, 1=FIFO1
/* AUTO GENERATED FDCAN_RX_FIFO BEGIN */
#ifdef FDCAN1_EN
#define FDCAN1_RX_FIFO 0
#endif
#ifdef FDCAN2_EN
#define FDCAN2_RX_FIFO 1
#endif
#ifdef FDCAN3_EN
#define FDCAN3_RX_FIFO 1
#endif
/* AUTO GENERATED FDCAN_RX_FIFO END */
/* Exported types ----------------------------------------------------------- */
typedef enum {
/* AUTO GENERATED BSP_FDCAN_NAME BEGIN */
BSP_FDCAN_1,
BSP_FDCAN_2,
BSP_FDCAN_3,
/* AUTO GENERATED BSP_FDCAN_NAME END */
BSP_FDCAN_NUM,
BSP_FDCAN_ERR,
} BSP_FDCAN_t;
typedef enum {
HAL_FDCAN_TX_EVENT_FIFO_CB,
HAL_FDCAN_TX_BUFFER_COMPLETE_CB,
HAL_FDCAN_TX_BUFFER_ABORT_CB,
HAL_FDCAN_RX_FIFO0_MSG_PENDING_CB,
HAL_FDCAN_RX_FIFO0_FULL_CB,
HAL_FDCAN_RX_FIFO1_MSG_PENDING_CB,
HAL_FDCAN_RX_FIFO1_FULL_CB,
HAL_FDCAN_ERROR_CB,
HAL_FDCAN_CB_NUM,
} BSP_FDCAN_Callback_t;
typedef enum {
BSP_FDCAN_FORMAT_STD_DATA,
BSP_FDCAN_FORMAT_EXT_DATA,
BSP_FDCAN_FORMAT_STD_REMOTE,
BSP_FDCAN_FORMAT_EXT_REMOTE,
} BSP_FDCAN_Format_t;
typedef enum {
BSP_FDCAN_FRAME_STD_DATA,
BSP_FDCAN_FRAME_EXT_DATA,
BSP_FDCAN_FRAME_STD_REMOTE,
BSP_FDCAN_FRAME_EXT_REMOTE,
} BSP_FDCAN_FrameType_t;
typedef struct {
BSP_FDCAN_FrameType_t frame_type;
uint32_t original_id;
uint32_t parsed_id;
uint8_t dlc;
uint8_t data[BSP_FDCAN_MAX_DLC];
uint32_t timestamp;
} BSP_FDCAN_Message_t;
typedef struct {
uint32_t id;
uint8_t dlc;
uint8_t data[BSP_FDCAN_MAX_DLC];
} BSP_FDCAN_StdDataFrame_t;
typedef struct {
uint32_t id;
uint8_t dlc;
uint8_t data[BSP_FDCAN_MAX_DLC];
} BSP_FDCAN_ExtDataFrame_t;
typedef struct {
uint32_t id;
uint8_t dlc;
bool is_extended;
} BSP_FDCAN_RemoteFrame_t;
typedef uint32_t (*BSP_FDCAN_IdParser_t)(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type);
typedef struct {
FDCAN_TxHeaderTypeDef header; /* HAL FDCAN header type */
uint8_t data[BSP_FDCAN_MAX_DLC];
} BSP_FDCAN_TxMessage_t;
typedef struct {
BSP_FDCAN_TxMessage_t buffer[BSP_FDCAN_TX_QUEUE_SIZE];
volatile uint32_t head;
volatile uint32_t tail;
} BSP_FDCAN_TxQueue_t;
/* Exported functions prototypes -------------------------------------------- */
int8_t BSP_FDCAN_Init(void);
FDCAN_HandleTypeDef *BSP_FDCAN_GetHandle(BSP_FDCAN_t can);
int8_t BSP_FDCAN_RegisterCallback(BSP_FDCAN_t can, BSP_FDCAN_Callback_t type, void (*callback)(void));
int8_t BSP_FDCAN_Transmit(BSP_FDCAN_t can, BSP_FDCAN_Format_t format, uint32_t id, uint8_t *data, uint8_t dlc);
int8_t BSP_FDCAN_TransmitStdDataFrame(BSP_FDCAN_t can, BSP_FDCAN_StdDataFrame_t *frame);
int8_t BSP_FDCAN_TransmitExtDataFrame(BSP_FDCAN_t can, BSP_FDCAN_ExtDataFrame_t *frame);
int8_t BSP_FDCAN_TransmitRemoteFrame(BSP_FDCAN_t can, BSP_FDCAN_RemoteFrame_t *frame);
int8_t BSP_FDCAN_RegisterId(BSP_FDCAN_t can, uint32_t can_id, uint8_t queue_size);
int8_t BSP_FDCAN_GetMessage(BSP_FDCAN_t can, uint32_t can_id, BSP_FDCAN_Message_t *msg, uint32_t timeout);
int32_t BSP_FDCAN_GetQueueCount(BSP_FDCAN_t can, uint32_t can_id);
int8_t BSP_FDCAN_FlushQueue(BSP_FDCAN_t can, uint32_t can_id);
int8_t BSP_FDCAN_RegisterIdParser(BSP_FDCAN_IdParser_t parser);
uint32_t BSP_FDCAN_ParseId(uint32_t original_id, BSP_FDCAN_FrameType_t frame_type);
#ifdef __cplusplus
}
#endif

82
User/bsp/flash.c Normal file
View File

@ -0,0 +1,82 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp/flash.h"
#include <main.h>
#include <string.h>
/* Private define ----------------------------------------------------------- */
/* USER CODE BEGIN FLASH_MAX_SECTOR */
#define BSP_FLASH_MAX_SECTOR 7
/* USER CODE END FLASH_MAX_SECTOR */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void BSP_Flash_EraseSector(uint32_t sector) {
FLASH_EraseInitTypeDef flash_erase;
uint32_t sector_error;
/* USER CODE BEGIN FLASH_ERASE_CHECK */
if (sector > 0 && sector <= 7) {
/* USER CODE END FLASH_ERASE_CHECK */
flash_erase.Sector = sector;
flash_erase.TypeErase = FLASH_TYPEERASE_SECTORS;
flash_erase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
flash_erase.NbSectors = 1;
#if defined(STM32H7)
flash_erase.Banks = FLASH_BANK_1; // H7 requires Bank parameter
#endif
HAL_FLASH_Unlock();
#if defined(STM32H7)
while (FLASH_WaitForLastOperation(50, FLASH_BANK_1) != HAL_OK)
;
#else
while (FLASH_WaitForLastOperation(50) != HAL_OK)
;
#endif
HAL_FLASHEx_Erase(&flash_erase, &sector_error);
HAL_FLASH_Lock();
}
/* USER CODE BEGIN FLASH_ERASE_END */
/* USER CODE END FLASH_ERASE_END */
}
void BSP_Flash_WriteBytes(uint32_t address, const uint8_t *buf, size_t len) {
HAL_FLASH_Unlock();
#if defined(STM32H7)
// H7 uses FLASHWORD (32 bytes) programming
uint8_t flash_word[32] __attribute__((aligned(32)));
while (len > 0) {
size_t chunk = (len < 32) ? len : 32;
memset(flash_word, 0xFF, 32);
memcpy(flash_word, buf, chunk);
while (FLASH_WaitForLastOperation(50, FLASH_BANK_1) != HAL_OK)
;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address, (uint32_t)flash_word);
address += 32;
buf += chunk;
len -= chunk;
}
#else
// F4/F7 use byte programming
while (len > 0) {
while (FLASH_WaitForLastOperation(50) != HAL_OK)
;
HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, *buf);
address++;
buf++;
len--;
}
#endif
HAL_FLASH_Lock();
}
void BSP_Flash_ReadBytes(uint32_t address, void *buf, size_t len) {
memcpy(buf, (void *)address, len);
}

46
User/bsp/flash.h Normal file
View File

@ -0,0 +1,46 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------ */
#include <main.h>
#include "bsp/bsp.h"
/* Exported constants -------------------------------------------------------- */
/* Base address of the Flash sectors */
/* USER CODE BEGIN FLASH_SECTOR_DEFINES */
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000)
/* Base address of Sector 0, 128 Kbytes */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08020000)
/* Base address of Sector 1, 128 Kbytes */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08040000)
/* Base address of Sector 2, 128 Kbytes */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x08060000)
/* Base address of Sector 3, 128 Kbytes */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08080000)
/* Base address of Sector 4, 128 Kbytes */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x080A0000)
/* Base address of Sector 5, 128 Kbytes */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x080C0000)
/* Base address of Sector 6, 128 Kbytes */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x080E0000)
/* Base address of Sector 7, 128 Kbytes */
/* USER CODE END FLASH_SECTOR_DEFINES */
/* USER CODE BEGIN FLASH_END_ADDRESS */
#define ADDR_FLASH_END ((uint32_t)0x08100000) /* End address for flash */
/* USER CODE END FLASH_END_ADDRESS */
/* Exported macro ------------------------------------------------------------ */
/* Exported types ------------------------------------------------------------ */
/* Exported functions prototypes --------------------------------------------- */
void BSP_Flash_EraseSector(uint32_t sector);
void BSP_Flash_WriteBytes(uint32_t address, const uint8_t *buf, size_t len);
void BSP_Flash_ReadBytes(uint32_t address, void *buf, size_t len);
#ifdef __cplusplus
}
#endif

126
User/bsp/gpio.c Normal file
View File

@ -0,0 +1,126 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp/gpio.h"
#include <gpio.h>
#include <main.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
typedef struct {
uint16_t pin;
GPIO_TypeDef *gpio;
} BSP_GPIO_MAP_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
static const BSP_GPIO_MAP_t GPIO_Map[BSP_GPIO_NUM] = {
{LCD_BLK_Pin, LCD_BLK_GPIO_Port},
{LCD_RES_Pin, LCD_RES_GPIO_Port},
{DCMI_REST_Pin, DCMI_REST_GPIO_Port},
{ACCL_CS_Pin, ACCL_CS_GPIO_Port},
{POWER_24V_2_Pin, POWER_24V_2_GPIO_Port},
{POWER_24V_1_Pin, POWER_24V_1_GPIO_Port},
{POWER_5V_Pin, POWER_5V_GPIO_Port},
{GYRO_CS_Pin, GYRO_CS_GPIO_Port},
{DCMI_PWDN_Pin, DCMI_PWDN_GPIO_Port},
{LCD_DC_Pin, LCD_DC_GPIO_Port},
{ACCL_INT_Pin, ACCL_INT_GPIO_Port},
{GYRO_INT_Pin, GYRO_INT_GPIO_Port},
{LCD_CS_Pin, LCD_CS_GPIO_Port},
};
static void (*GPIO_Callback[16])(void);
/* Private function -------------------------------------------------------- */
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
for (uint8_t i = 0; i < 16; i++) {
if (GPIO_Pin & (1 << i)) {
if (GPIO_Callback[i]) {
GPIO_Callback[i]();
}
}
}
}
/* Exported functions ------------------------------------------------------- */
int8_t BSP_GPIO_RegisterCallback(BSP_GPIO_t gpio, void (*callback)(void)) {
if (callback == NULL) return BSP_ERR_NULL;
if (gpio >= BSP_GPIO_NUM) return BSP_ERR;
// 从GPIO映射中获取对应的pin值
uint16_t pin = GPIO_Map[gpio].pin;
for (uint8_t i = 0; i < 16; i++) {
if (pin & (1 << i)) {
GPIO_Callback[i] = callback;
break;
}
}
return BSP_OK;
}
int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio) {
switch (gpio) {
case BSP_GPIO_ACCL_INT:
#if defined(ACCL_INT_EXTI_IRQn)
HAL_NVIC_EnableIRQ(ACCL_INT_EXTI_IRQn);
#endif
return BSP_OK;
case BSP_GPIO_GYRO_INT:
#if defined(GYRO_INT_EXTI_IRQn)
HAL_NVIC_EnableIRQ(GYRO_INT_EXTI_IRQn);
#endif
return BSP_OK;
default:
return BSP_ERR;
}
}
int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio) {
switch (gpio) {
case BSP_GPIO_ACCL_INT:
#if defined(ACCL_INT_EXTI_IRQn)
HAL_NVIC_DisableIRQ(ACCL_INT_EXTI_IRQn);
#endif
return BSP_OK;
case BSP_GPIO_GYRO_INT:
#if defined(GYRO_INT_EXTI_IRQn)
HAL_NVIC_DisableIRQ(GYRO_INT_EXTI_IRQn);
#endif
return BSP_OK;
default:
return BSP_ERR;
}
}
int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value){
if (gpio >= BSP_GPIO_NUM) return BSP_ERR;
HAL_GPIO_WritePin(GPIO_Map[gpio].gpio, GPIO_Map[gpio].pin, value);
return BSP_OK;
}
int8_t BSP_GPIO_TogglePin(BSP_GPIO_t gpio){
if (gpio >= BSP_GPIO_NUM) return BSP_ERR;
HAL_GPIO_TogglePin(GPIO_Map[gpio].gpio, GPIO_Map[gpio].pin);
return BSP_OK;
}
bool BSP_GPIO_ReadPin(BSP_GPIO_t gpio){
if (gpio >= BSP_GPIO_NUM) return false;
return HAL_GPIO_ReadPin(GPIO_Map[gpio].gpio, GPIO_Map[gpio].pin) == GPIO_PIN_SET;
}

59
User/bsp/gpio.h Normal file
View File

@ -0,0 +1,59 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stdint.h>
#include <stdbool.h>
#include "bsp/bsp.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported types ----------------------------------------------------------- */
typedef enum {
BSP_GPIO_LCD_BLK,
BSP_GPIO_LCD_RES,
BSP_GPIO_DCMI_REST,
BSP_GPIO_ACCL_CS,
BSP_GPIO_POWER_24V_2,
BSP_GPIO_POWER_24V_1,
BSP_GPIO_POWER_5V,
BSP_GPIO_GYRO_CS,
BSP_GPIO_DCMI_PWDN,
BSP_GPIO_LCD_DC,
BSP_GPIO_ACCL_INT,
BSP_GPIO_GYRO_INT,
BSP_GPIO_LCD_CS,
BSP_GPIO_NUM,
BSP_GPIO_ERR,
} BSP_GPIO_t;
/* Exported functions prototypes -------------------------------------------- */
int8_t BSP_GPIO_RegisterCallback(BSP_GPIO_t gpio, void (*callback)(void));
int8_t BSP_GPIO_EnableIRQ(BSP_GPIO_t gpio);
int8_t BSP_GPIO_DisableIRQ(BSP_GPIO_t gpio);
int8_t BSP_GPIO_WritePin(BSP_GPIO_t gpio, bool value);
int8_t BSP_GPIO_TogglePin(BSP_GPIO_t gpio);
bool BSP_GPIO_ReadPin(BSP_GPIO_t gpio);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

30
User/bsp/mm.c Normal file
View File

@ -0,0 +1,30 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp/mm.h"
#include "FreeRTOS.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private function -------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
inline void *BSP_Malloc(size_t size) { return pvPortMalloc(size); }
inline void BSP_Free(void *pv) { vPortFree(pv); }
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

32
User/bsp/mm.h Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stddef.h>
#include <stdint.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported types ----------------------------------------------------------- */
/* Exported functions prototypes -------------------------------------------- */
void *BSP_Malloc(size_t size);
void BSP_Free(void *pv);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

115
User/bsp/pwm.c Normal file
View File

@ -0,0 +1,115 @@
/* Includes ----------------------------------------------------------------- */
#include "tim.h"
#include "bsp/pwm.h"
#include "bsp.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
typedef struct {
TIM_HandleTypeDef *tim;
uint16_t channel;
} BSP_PWM_Config_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
static const BSP_PWM_Config_t PWM_Map[BSP_PWM_NUM] = {
{&htim2, TIM_CHANNEL_1},
{&htim2, TIM_CHANNEL_3},
{&htim3, TIM_CHANNEL_4},
{&htim12, TIM_CHANNEL_2},
{&htim1, TIM_CHANNEL_3},
{&htim1, TIM_CHANNEL_1},
};
/* Private function -------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
int8_t BSP_PWM_Start(BSP_PWM_Channel_t ch) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
HAL_TIM_PWM_Start(PWM_Map[ch].tim, PWM_Map[ch].channel);
return BSP_OK;
}
int8_t BSP_PWM_SetComp(BSP_PWM_Channel_t ch, float duty_cycle) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
if (duty_cycle > 1.0f) {
duty_cycle = 1.0f;
}
if (duty_cycle < 0.0f) {
duty_cycle = 0.0f;
}
// 获取ARR值周期值
uint32_t arr = __HAL_TIM_GET_AUTORELOAD(PWM_Map[ch].tim);
// 计算比较值CCR = duty_cycle * (ARR + 1)
uint32_t ccr = (uint32_t)(duty_cycle * (arr + 1));
__HAL_TIM_SET_COMPARE(PWM_Map[ch].tim, PWM_Map[ch].channel, ccr);
return BSP_OK;
}
int8_t BSP_PWM_SetFreq(BSP_PWM_Channel_t ch, float freq) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
uint32_t timer_clock = HAL_RCC_GetPCLK1Freq(); // Get the timer clock frequency
uint32_t prescaler = PWM_Map[ch].tim->Init.Prescaler;
uint32_t period = (timer_clock / (prescaler + 1)) / freq - 1;
if (period > UINT16_MAX) {
return BSP_ERR; // Frequency too low
}
__HAL_TIM_SET_AUTORELOAD(PWM_Map[ch].tim, period);
return BSP_OK;
}
int8_t BSP_PWM_Stop(BSP_PWM_Channel_t ch) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
HAL_TIM_PWM_Stop(PWM_Map[ch].tim, PWM_Map[ch].channel);
return BSP_OK;
}
uint32_t BSP_PWM_GetAutoReloadPreload(BSP_PWM_Channel_t ch) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
return PWM_Map[ch].tim->Init.AutoReloadPreload;
}
TIM_HandleTypeDef* BSP_PWM_GetHandle(BSP_PWM_Channel_t ch) {
return PWM_Map[ch].tim;
}
uint16_t BSP_PWM_GetChannel(BSP_PWM_Channel_t ch) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
return PWM_Map[ch].channel;
}
int8_t BSP_PWM_Start_DMA(BSP_PWM_Channel_t ch, uint32_t *pData, uint16_t Length) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
HAL_TIM_PWM_Start_DMA(PWM_Map[ch].tim, PWM_Map[ch].channel, pData, Length);
return BSP_OK;
}
int8_t BSP_PWM_Stop_DMA(BSP_PWM_Channel_t ch) {
if (ch >= BSP_PWM_NUM) return BSP_ERR;
HAL_TIM_PWM_Stop_DMA(PWM_Map[ch].tim, PWM_Map[ch].channel);
return BSP_OK;
}

53
User/bsp/pwm.h Normal file
View File

@ -0,0 +1,53 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stdint.h>
#include "tim.h"
#include "bsp.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported types ----------------------------------------------------------- */
/* PWM通道 */
typedef enum {
BSP_PWM_TIM2_CH1,
BSP_PWM_TIM2_CH3,
BSP_PWM_IMU_HEAT,
BSP_PWM_BUZZER,
BSP_PWM_TIM1_CH3,
BSP_PWM_TIM1_CH1,
BSP_PWM_NUM,
BSP_PWM_ERR,
} BSP_PWM_Channel_t;
/* Exported functions prototypes -------------------------------------------- */
int8_t BSP_PWM_Start(BSP_PWM_Channel_t ch);
int8_t BSP_PWM_SetComp(BSP_PWM_Channel_t ch, float duty_cycle);
int8_t BSP_PWM_SetFreq(BSP_PWM_Channel_t ch, float freq);
int8_t BSP_PWM_Stop(BSP_PWM_Channel_t ch);
uint32_t BSP_PWM_GetAutoReloadPreload(BSP_PWM_Channel_t ch);
uint16_t BSP_PWM_GetChannel(BSP_PWM_Channel_t ch);
TIM_HandleTypeDef* BSP_PWM_GetHandle(BSP_PWM_Channel_t ch);
int8_t BSP_PWM_Start_DMA(BSP_PWM_Channel_t ch, uint32_t *pData, uint16_t Length);
int8_t BSP_PWM_Stop_DMA(BSP_PWM_Channel_t ch);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

181
User/bsp/spi.c Normal file
View File

@ -0,0 +1,181 @@
/* Includes ----------------------------------------------------------------- */
#include <spi.h>
#include "bsp/spi.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
static void (*SPI_Callback[BSP_SPI_NUM][BSP_SPI_CB_NUM])(void);
/* Private function -------------------------------------------------------- */
static BSP_SPI_t SPI_Get(SPI_HandleTypeDef *hspi) {
if (hspi->Instance == SPI2)
return BSP_SPI_BMI088;
else
return BSP_SPI_ERR;
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[bsp_spi][BSP_SPI_TX_CPLT_CB]) {
SPI_Callback[bsp_spi][BSP_SPI_TX_CPLT_CB]();
}
}
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[SPI_Get(hspi)][BSP_SPI_RX_CPLT_CB])
SPI_Callback[SPI_Get(hspi)][BSP_SPI_RX_CPLT_CB]();
}
}
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[SPI_Get(hspi)][BSP_SPI_TX_RX_CPLT_CB])
SPI_Callback[SPI_Get(hspi)][BSP_SPI_TX_RX_CPLT_CB]();
}
}
void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[SPI_Get(hspi)][BSP_SPI_TX_HALF_CPLT_CB])
SPI_Callback[SPI_Get(hspi)][BSP_SPI_TX_HALF_CPLT_CB]();
}
}
void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[SPI_Get(hspi)][BSP_SPI_RX_HALF_CPLT_CB])
SPI_Callback[SPI_Get(hspi)][BSP_SPI_RX_HALF_CPLT_CB]();
}
}
void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[SPI_Get(hspi)][BSP_SPI_TX_RX_HALF_CPLT_CB])
SPI_Callback[SPI_Get(hspi)][BSP_SPI_TX_RX_HALF_CPLT_CB]();
}
}
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[SPI_Get(hspi)][BSP_SPI_ERROR_CB])
SPI_Callback[SPI_Get(hspi)][BSP_SPI_ERROR_CB]();
}
}
void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) {
BSP_SPI_t bsp_spi = SPI_Get(hspi);
if (bsp_spi != BSP_SPI_ERR) {
if (SPI_Callback[SPI_Get(hspi)][BSP_SPI_ABORT_CPLT_CB])
SPI_Callback[SPI_Get(hspi)][BSP_SPI_ABORT_CPLT_CB]();
}
}
/* Exported functions ------------------------------------------------------- */
SPI_HandleTypeDef *BSP_SPI_GetHandle(BSP_SPI_t spi) {
switch (spi) {
case BSP_SPI_BMI088:
return &hspi2;
default:
return NULL;
}
}
int8_t BSP_SPI_RegisterCallback(BSP_SPI_t spi, BSP_SPI_Callback_t type,
void (*callback)(void)) {
if (callback == NULL) return BSP_ERR_NULL;
SPI_Callback[spi][type] = callback;
return BSP_OK;
}
int8_t BSP_SPI_Transmit(BSP_SPI_t spi, uint8_t *data, uint16_t size, bool dma) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi);
if (hspi == NULL) return BSP_ERR;
if (dma) {
return HAL_SPI_Transmit_DMA(hspi, data, size)!= HAL_OK;;
} else {
return HAL_SPI_Transmit(hspi, data, size, 20)!= HAL_OK;;
}
}
int8_t BSP_SPI_Receive(BSP_SPI_t spi, uint8_t *data, uint16_t size, bool dma) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi);
if (hspi == NULL) return BSP_ERR;
if (dma) {
return HAL_SPI_Receive_DMA(hspi, data, size)!= HAL_OK;;
} else {
return HAL_SPI_Receive(hspi, data, size, 20)!= HAL_OK;;
}
}
int8_t BSP_SPI_TransmitReceive(BSP_SPI_t spi, uint8_t *txData, uint8_t *rxData,
uint16_t size, bool dma) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
SPI_HandleTypeDef *hspi = BSP_SPI_GetHandle(spi);
if (hspi == NULL) return BSP_ERR;
if (dma) {
return HAL_SPI_TransmitReceive_DMA(hspi, txData, rxData, size)!= HAL_OK;;
} else {
return HAL_SPI_TransmitReceive(hspi, txData, rxData, size, 20)!= HAL_OK;;
}
}
uint8_t BSP_SPI_MemReadByte(BSP_SPI_t spi, uint8_t reg) {
if (spi >= BSP_SPI_NUM) return 0xFF;
uint8_t tmp[2] = {reg | 0x80, 0x00};
BSP_SPI_TransmitReceive(spi, tmp, tmp, 2u, true);
return tmp[1];
}
int8_t BSP_SPI_MemWriteByte(BSP_SPI_t spi, uint8_t reg, uint8_t data) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
uint8_t tmp[2] = {reg & 0x7f, data};
return BSP_SPI_Transmit(spi, tmp, 2u, true);
}
int8_t BSP_SPI_MemRead(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
if (data == NULL || size == 0) return BSP_ERR_NULL;
reg = reg | 0x80;
BSP_SPI_Transmit(spi, &reg, 1u, true);
return BSP_SPI_Receive(spi, data, size, true);
}
int8_t BSP_SPI_MemWrite(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size) {
if (spi >= BSP_SPI_NUM) return BSP_ERR;
if (data == NULL || size == 0) return BSP_ERR_NULL;
reg = reg & 0x7f;
BSP_SPI_Transmit(spi, &reg, 1u, true);
return BSP_SPI_Transmit(spi, data, size, true);
}
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

70
User/bsp/spi.h Normal file
View File

@ -0,0 +1,70 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <spi.h>
#include <stdint.h>
#include <stdbool.h>
#include "bsp/bsp.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported types ----------------------------------------------------------- */
/* 要添加使用SPI的新设备需要先在此添加对应的枚举值 */
/* SPI实体枚举与设备对应 */
typedef enum {
BSP_SPI_BMI088,
BSP_SPI_NUM,
BSP_SPI_ERR,
} BSP_SPI_t;
/* SPI支持的中断回调函数类型具体参考HAL中定义 */
typedef enum {
BSP_SPI_TX_CPLT_CB,
BSP_SPI_RX_CPLT_CB,
BSP_SPI_TX_RX_CPLT_CB,
BSP_SPI_TX_HALF_CPLT_CB,
BSP_SPI_RX_HALF_CPLT_CB,
BSP_SPI_TX_RX_HALF_CPLT_CB,
BSP_SPI_ERROR_CB,
BSP_SPI_ABORT_CPLT_CB,
BSP_SPI_CB_NUM,
} BSP_SPI_Callback_t;
/* Exported functions prototypes -------------------------------------------- */
SPI_HandleTypeDef *BSP_SPI_GetHandle(BSP_SPI_t spi);
int8_t BSP_SPI_RegisterCallback(BSP_SPI_t spi, BSP_SPI_Callback_t type,
void (*callback)(void));
int8_t BSP_SPI_Transmit(BSP_SPI_t spi, uint8_t *data, uint16_t size, bool dma);
int8_t BSP_SPI_Receive(BSP_SPI_t spi, uint8_t *data, uint16_t size, bool dma);
int8_t BSP_SPI_TransmitReceive(BSP_SPI_t spi, uint8_t *txData, uint8_t *rxData,
uint16_t size, bool dma);
uint8_t BSP_SPI_MemReadByte(BSP_SPI_t spi, uint8_t reg);
int8_t BSP_SPI_MemWriteByte(BSP_SPI_t spi, uint8_t reg, uint8_t data);
int8_t BSP_SPI_MemRead(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size);
int8_t BSP_SPI_MemWrite(BSP_SPI_t spi, uint8_t reg, uint8_t *data, uint16_t size);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

81
User/bsp/time.c Normal file
View File

@ -0,0 +1,81 @@
/* Includes ----------------------------------------------------------------- */
#include "bsp/time.h"
#include "bsp.h"
#include <cmsis_os2.h>
#include "FreeRTOS.h"
#include "main.h"
#include "task.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
uint32_t BSP_TIME_Get_ms() { return xTaskGetTickCount(); }
uint64_t BSP_TIME_Get_us() {
uint32_t tick_freq = osKernelGetTickFreq();
uint32_t ticks_old = xTaskGetTickCount()*(1000/tick_freq);
uint32_t tick_value_old = SysTick->VAL;
uint32_t ticks_new = xTaskGetTickCount()*(1000/tick_freq);
uint32_t tick_value_new = SysTick->VAL;
if (ticks_old == ticks_new) {
return ticks_new * 1000 + 1000 - tick_value_old * 1000 / (SysTick->LOAD + 1);
} else {
return ticks_new * 1000 + 1000 - tick_value_new * 1000 / (SysTick->LOAD + 1);
}
}
uint64_t BSP_TIME_Get() __attribute__((alias("BSP_TIME_Get_us")));
int8_t BSP_TIME_Delay_ms(uint32_t ms) {
uint32_t tick_period = 1000u / osKernelGetTickFreq();
uint32_t ticks = ms / tick_period;
switch (osKernelGetState()) {
case osKernelError:
case osKernelReserved:
case osKernelLocked:
case osKernelSuspended:
return BSP_ERR;
case osKernelRunning:
osDelay(ticks ? ticks : 1);
break;
case osKernelInactive:
case osKernelReady:
HAL_Delay(ms);
break;
}
return BSP_OK;
}
/*阻塞us延迟*/
int8_t BSP_TIME_Delay_us(uint32_t us) {
uint64_t start = BSP_TIME_Get_us();
while (BSP_TIME_Get_us() - start < us) {
// 等待us时间
}
return BSP_OK;
}
int8_t BSP_TIME_Delay(uint32_t ms) __attribute__((alias("BSP_TIME_Delay_ms")));
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

43
User/bsp/time.h Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stdint.h>
#include "bsp/bsp.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported types ----------------------------------------------------------- */
/* Exported functions prototypes -------------------------------------------- */
uint32_t BSP_TIME_Get_ms();
uint64_t BSP_TIME_Get_us();
uint64_t BSP_TIME_Get();
int8_t BSP_TIME_Delay_ms(uint32_t ms);
/*微秒阻塞延时,一般别用*/
int8_t BSP_TIME_Delay_us(uint32_t us);
int8_t BSP_TIME_Delay(uint32_t ms);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

155
User/bsp/uart.c Normal file
View File

@ -0,0 +1,155 @@
/* Includes ----------------------------------------------------------------- */
#include <usart.h>
#include "bsp/uart.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
static void (*UART_Callback[BSP_UART_NUM][BSP_UART_CB_NUM])(void);
/* Private function -------------------------------------------------------- */
static BSP_UART_t UART_Get(UART_HandleTypeDef *huart) {
if (huart->Instance == UART5)
return BSP_UART_DR16;
else
return BSP_UART_ERR;
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_TX_CPLT_CB]) {
UART_Callback[bsp_uart][BSP_UART_TX_CPLT_CB]();
}
}
}
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_TX_HALF_CPLT_CB]) {
UART_Callback[bsp_uart][BSP_UART_TX_HALF_CPLT_CB]();
}
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_RX_CPLT_CB]) {
UART_Callback[bsp_uart][BSP_UART_RX_CPLT_CB]();
}
}
}
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_RX_HALF_CPLT_CB]) {
UART_Callback[bsp_uart][BSP_UART_RX_HALF_CPLT_CB]();
}
}
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_ERROR_CB]) {
UART_Callback[bsp_uart][BSP_UART_ERROR_CB]();
}
}
}
void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_ABORT_CPLT_CB]) {
UART_Callback[bsp_uart][BSP_UART_ABORT_CPLT_CB]();
}
}
}
void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_ABORT_TX_CPLT_CB]) {
UART_Callback[bsp_uart][BSP_UART_ABORT_TX_CPLT_CB]();
}
}
}
void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart) {
BSP_UART_t bsp_uart = UART_Get(huart);
if (bsp_uart != BSP_UART_ERR) {
if (UART_Callback[bsp_uart][BSP_UART_ABORT_RX_CPLT_CB]) {
UART_Callback[bsp_uart][BSP_UART_ABORT_RX_CPLT_CB]();
}
}
}
/* Exported functions ------------------------------------------------------- */
void BSP_UART_IRQHandler(UART_HandleTypeDef *huart) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)) {
__HAL_UART_CLEAR_IDLEFLAG(huart);
if (UART_Callback[UART_Get(huart)][BSP_UART_IDLE_LINE_CB]) {
UART_Callback[UART_Get(huart)][BSP_UART_IDLE_LINE_CB]();
}
}
}
UART_HandleTypeDef *BSP_UART_GetHandle(BSP_UART_t uart) {
switch (uart) {
case BSP_UART_DR16:
return &huart5;
default:
return NULL;
}
}
int8_t BSP_UART_RegisterCallback(BSP_UART_t uart, BSP_UART_Callback_t type,
void (*callback)(void)) {
if (callback == NULL) return BSP_ERR_NULL;
if (uart >= BSP_UART_NUM || type >= BSP_UART_CB_NUM) return BSP_ERR;
UART_Callback[uart][type] = callback;
return BSP_OK;
}
int8_t BSP_UART_Transmit(BSP_UART_t uart, uint8_t *data, uint16_t size, bool dma) {
if (uart >= BSP_UART_NUM) return BSP_ERR;
if (data == NULL || size == 0) return BSP_ERR_NULL;
if (dma) {
return HAL_UART_Transmit_DMA(BSP_UART_GetHandle(uart), data, size);
} else {
return HAL_UART_Transmit_IT(BSP_UART_GetHandle(uart), data, size);
}
}
int8_t BSP_UART_Receive(BSP_UART_t uart, uint8_t *data, uint16_t size, bool dma) {
if (uart >= BSP_UART_NUM) return BSP_ERR;
if (data == NULL || size == 0) return BSP_ERR_NULL;
if (dma) {
return HAL_UART_Receive_DMA(BSP_UART_GetHandle(uart), data, size);
} else {
return HAL_UART_Receive_IT(BSP_UART_GetHandle(uart), data, size);
}
}
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

68
User/bsp/uart.h Normal file
View File

@ -0,0 +1,68 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <usart.h>
#include <stdint.h>
#include <stdbool.h>
#include "bsp/bsp.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported types ----------------------------------------------------------- */
/* 要添加使用UART的新设备需要先在此添加对应的枚举值 */
/* UART实体枚举与设备对应 */
typedef enum {
BSP_UART_DR16,
BSP_UART_NUM,
BSP_UART_ERR,
} BSP_UART_t;
/* UART支持的中断回调函数类型具体参考HAL中定义 */
typedef enum {
BSP_UART_TX_HALF_CPLT_CB,
BSP_UART_TX_CPLT_CB,
BSP_UART_RX_HALF_CPLT_CB,
BSP_UART_RX_CPLT_CB,
BSP_UART_ERROR_CB,
BSP_UART_ABORT_CPLT_CB,
BSP_UART_ABORT_TX_CPLT_CB,
BSP_UART_ABORT_RX_CPLT_CB,
BSP_UART_IDLE_LINE_CB,
BSP_UART_CB_NUM,
} BSP_UART_Callback_t;
/* Exported functions prototypes -------------------------------------------- */
UART_HandleTypeDef *BSP_UART_GetHandle(BSP_UART_t uart);
void BSP_UART_IRQHandler(UART_HandleTypeDef *huart);
int8_t BSP_UART_RegisterCallback(BSP_UART_t uart, BSP_UART_Callback_t type,
void (*callback)(void));
int8_t BSP_UART_Transmit(BSP_UART_t uart, uint8_t *data, uint16_t size, bool dma);
int8_t BSP_UART_Receive(BSP_UART_t uart, uint8_t *data, uint16_t size, bool dma);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

417
User/component/ahrs.c Normal file
View File

@ -0,0 +1,417 @@
/*
AHRS算法
MadgwickAHRS
*/
#include "ahrs.h"
#include <string.h>
#include "user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
#define BETA_IMU (0.033f)
#define BETA_AHRS (0.041f)
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* 2 * proportional gain (Kp) */
static float beta = BETA_IMU;
/**
* @brief 使姿
*
* @param ahrs 姿
* @param accl
* @param gyro
* @return int8_t 0
*/
static int8_t AHRS_UpdateIMU(AHRS_t *ahrs, const AHRS_Accl_t *accl,
const AHRS_Gyro_t *gyro) {
if (ahrs == NULL) return -1;
if (accl == NULL) return -1;
if (gyro == NULL) return -1;
beta = BETA_IMU;
float ax = accl->x;
float ay = accl->y;
float az = accl->z;
float gx = gyro->x;
float gy = gyro->y;
float gz = gyro->z;
float recip_norm;
float s0, s1, s2, s3;
float q_dot1, q_dot2, q_dot3, q_dot4;
float _2q0, _2q1, _2q2, _2q3, _4q0, _4q1, _4q2, _8q1, _8q2, q0q0, q1q1, q2q2,
q3q3;
/* Rate of change of quaternion from gyroscope */
q_dot1 = 0.5f * (-ahrs->quat.q1 * gx - ahrs->quat.q2 * gy -
ahrs->quat.q3 * gz);
q_dot2 = 0.5f * (ahrs->quat.q0 * gx + ahrs->quat.q2 * gz -
ahrs->quat.q3 * gy);
q_dot3 = 0.5f * (ahrs->quat.q0 * gy - ahrs->quat.q1 * gz +
ahrs->quat.q3 * gx);
q_dot4 = 0.5f * (ahrs->quat.q0 * gz + ahrs->quat.q1 * gy -
ahrs->quat.q2 * gx);
/* Compute feedback only if accelerometer measurement valid (avoids NaN in
* accelerometer normalisation) */
if (!((ax == 0.0f) && (ay == 0.0f) && (az == 0.0f))) {
/* Normalise accelerometer measurement */
recip_norm = InvSqrt(ax * ax + ay * ay + az * az);
ax *= recip_norm;
ay *= recip_norm;
az *= recip_norm;
/* Auxiliary variables to avoid repeated arithmetic */
_2q0 = 2.0f * ahrs->quat.q0;
_2q1 = 2.0f * ahrs->quat.q1;
_2q2 = 2.0f * ahrs->quat.q2;
_2q3 = 2.0f * ahrs->quat.q3;
_4q0 = 4.0f * ahrs->quat.q0;
_4q1 = 4.0f * ahrs->quat.q1;
_4q2 = 4.0f * ahrs->quat.q2;
_8q1 = 8.0f * ahrs->quat.q1;
_8q2 = 8.0f * ahrs->quat.q2;
q0q0 = ahrs->quat.q0 * ahrs->quat.q0;
q1q1 = ahrs->quat.q1 * ahrs->quat.q1;
q2q2 = ahrs->quat.q2 * ahrs->quat.q2;
q3q3 = ahrs->quat.q3 * ahrs->quat.q3;
/* Gradient decent algorithm corrective step */
s0 = _4q0 * q2q2 + _2q2 * ax + _4q0 * q1q1 - _2q1 * ay;
s1 = _4q1 * q3q3 - _2q3 * ax + 4.0f * q0q0 * ahrs->quat.q1 -
_2q0 * ay - _4q1 + _8q1 * q1q1 + _8q1 * q2q2 + _4q1 * az;
s2 = 4.0f * q0q0 * ahrs->quat.q2 + _2q0 * ax + _4q2 * q3q3 -
_2q3 * ay - _4q2 + _8q2 * q1q1 + _8q2 * q2q2 + _4q2 * az;
s3 = 4.0f * q1q1 * ahrs->quat.q3 - _2q1 * ax +
4.0f * q2q2 * ahrs->quat.q3 - _2q2 * ay;
/* normalise step magnitude */
recip_norm = InvSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3);
s0 *= recip_norm;
s1 *= recip_norm;
s2 *= recip_norm;
s3 *= recip_norm;
/* Apply feedback step */
q_dot1 -= beta * s0;
q_dot2 -= beta * s1;
q_dot3 -= beta * s2;
q_dot4 -= beta * s3;
}
/* Integrate rate of change of quaternion to yield quaternion */
ahrs->quat.q0 += q_dot1 * ahrs->inv_sample_freq;
ahrs->quat.q1 += q_dot2 * ahrs->inv_sample_freq;
ahrs->quat.q2 += q_dot3 * ahrs->inv_sample_freq;
ahrs->quat.q3 += q_dot4 * ahrs->inv_sample_freq;
/* Normalise quaternion */
recip_norm = InvSqrt(ahrs->quat.q0 * ahrs->quat.q0 +
ahrs->quat.q1 * ahrs->quat.q1 +
ahrs->quat.q2 * ahrs->quat.q2 +
ahrs->quat.q3 * ahrs->quat.q3);
ahrs->quat.q0 *= recip_norm;
ahrs->quat.q1 *= recip_norm;
ahrs->quat.q2 *= recip_norm;
ahrs->quat.q3 *= recip_norm;
return 0;
}
/**
* @brief 姿
*
* @param ahrs 姿
* @param magn
* @param sample_freq
* @return int8_t 0
*/
int8_t AHRS_Init(AHRS_t *ahrs, const AHRS_Magn_t *magn, float sample_freq) {
if (ahrs == NULL) return -1;
ahrs->inv_sample_freq = 1.0f / sample_freq;
ahrs->quat.q0 = 1.0f;
ahrs->quat.q1 = 0.0f;
ahrs->quat.q2 = 0.0f;
ahrs->quat.q3 = 0.0f;
if (magn) {
float yaw = -atan2(magn->y, magn->x);
if ((magn->x == 0.0f) && (magn->y == 0.0f) && (magn->z == 0.0f)) {
ahrs->quat.q0 = 0.800884545f;
ahrs->quat.q1 = 0.00862364192f;
ahrs->quat.q2 = -0.00283267116f;
ahrs->quat.q3 = 0.598749936f;
} else if ((yaw < (M_PI / 2.0f)) || (yaw > 0.0f)) {
ahrs->quat.q0 = 0.997458339f;
ahrs->quat.q1 = 0.000336312107f;
ahrs->quat.q2 = -0.0057230792f;
ahrs->quat.q3 = 0.0740156546;
} else if ((yaw < M_PI) || (yaw > (M_PI / 2.0f))) {
ahrs->quat.q0 = 0.800884545f;
ahrs->quat.q1 = 0.00862364192f;
ahrs->quat.q2 = -0.00283267116f;
ahrs->quat.q3 = 0.598749936f;
} else if ((yaw < 90.0f) || (yaw > M_PI)) {
ahrs->quat.q0 = 0.800884545f;
ahrs->quat.q1 = 0.00862364192f;
ahrs->quat.q2 = -0.00283267116f;
ahrs->quat.q3 = 0.598749936f;
} else if ((yaw < 90.0f) || (yaw > 0.0f)) {
ahrs->quat.q0 = 0.800884545f;
ahrs->quat.q1 = 0.00862364192f;
ahrs->quat.q2 = -0.00283267116f;
ahrs->quat.q3 = 0.598749936f;
}
}
return 0;
}
/**
* @brief 姿
* @note NED(North East Down)
*
* @param ahrs 姿
* @param accl
* @param gyro
* @param magn
* @return int8_t 0
*/
int8_t AHRS_Update(AHRS_t *ahrs, const AHRS_Accl_t *accl,
const AHRS_Gyro_t *gyro, const AHRS_Magn_t *magn) {
if (ahrs == NULL) return -1;
if (accl == NULL) return -1;
if (gyro == NULL) return -1;
beta = BETA_AHRS;
float recip_norm;
float s0, s1, s2, s3;
float q_dot1, q_dot2, q_dot3, q_dot4;
float hx, hy;
float _2q0mx, _2q0my, _2q0mz, _2q1mx, _2bx, _2bz, _4bx, _4bz, _2q0, _2q1,
_2q2, _2q3, _2q0q2, _2q2q3, q0q0, q0q1, q0q2, q0q3, q1q1, q1q2, q1q3,
q2q2, q2q3, q3q3;
if (magn == NULL) return AHRS_UpdateIMU(ahrs, accl, gyro);
float mx = magn->x;
float my = magn->y;
float mz = magn->z;
/* Use IMU algorithm if magnetometer measurement invalid (avoids NaN in */
/* magnetometer normalisation) */
if ((mx == 0.0f) && (my == 0.0f) && (mz == 0.0f)) {
return AHRS_UpdateIMU(ahrs, accl, gyro);
}
float ax = accl->x;
float ay = accl->y;
float az = accl->z;
float gx = gyro->x;
float gy = gyro->y;
float gz = gyro->z;
/* Rate of change of quaternion from gyroscope */
q_dot1 = 0.5f * (-ahrs->quat.q1 * gx - ahrs->quat.q2 * gy -
ahrs->quat.q3 * gz);
q_dot2 = 0.5f * (ahrs->quat.q0 * gx + ahrs->quat.q2 * gz -
ahrs->quat.q3 * gy);
q_dot3 = 0.5f * (ahrs->quat.q0 * gy - ahrs->quat.q1 * gz +
ahrs->quat.q3 * gx);
q_dot4 = 0.5f * (ahrs->quat.q0 * gz + ahrs->quat.q1 * gy -
ahrs->quat.q2 * gx);
/* Compute feedback only if accelerometer measurement valid (avoids NaN in
* accelerometer normalisation) */
if (!((ax == 0.0f) && (ay == 0.0f) && (az == 0.0f))) {
/* Normalise accelerometer measurement */
recip_norm = InvSqrt(ax * ax + ay * ay + az * az);
ax *= recip_norm;
ay *= recip_norm;
az *= recip_norm;
/* Normalise magnetometer measurement */
recip_norm = InvSqrt(mx * mx + my * my + mz * mz);
mx *= recip_norm;
my *= recip_norm;
mz *= recip_norm;
/* Auxiliary variables to avoid repeated arithmetic */
_2q0mx = 2.0f * ahrs->quat.q0 * mx;
_2q0my = 2.0f * ahrs->quat.q0 * my;
_2q0mz = 2.0f * ahrs->quat.q0 * mz;
_2q1mx = 2.0f * ahrs->quat.q1 * mx;
_2q0 = 2.0f * ahrs->quat.q0;
_2q1 = 2.0f * ahrs->quat.q1;
_2q2 = 2.0f * ahrs->quat.q2;
_2q3 = 2.0f * ahrs->quat.q3;
_2q0q2 = 2.0f * ahrs->quat.q0 * ahrs->quat.q2;
_2q2q3 = 2.0f * ahrs->quat.q2 * ahrs->quat.q3;
q0q0 = ahrs->quat.q0 * ahrs->quat.q0;
q0q1 = ahrs->quat.q0 * ahrs->quat.q1;
q0q2 = ahrs->quat.q0 * ahrs->quat.q2;
q0q3 = ahrs->quat.q0 * ahrs->quat.q3;
q1q1 = ahrs->quat.q1 * ahrs->quat.q1;
q1q2 = ahrs->quat.q1 * ahrs->quat.q2;
q1q3 = ahrs->quat.q1 * ahrs->quat.q3;
q2q2 = ahrs->quat.q2 * ahrs->quat.q2;
q2q3 = ahrs->quat.q2 * ahrs->quat.q3;
q3q3 = ahrs->quat.q3 * ahrs->quat.q3;
/* Reference direction of Earth's magnetic field */
hx = mx * q0q0 - _2q0my * ahrs->quat.q3 +
_2q0mz * ahrs->quat.q2 + mx * q1q1 +
_2q1 * my * ahrs->quat.q2 + _2q1 * mz * ahrs->quat.q3 -
mx * q2q2 - mx * q3q3;
hy = _2q0mx * ahrs->quat.q3 + my * q0q0 -
_2q0mz * ahrs->quat.q1 + _2q1mx * ahrs->quat.q2 -
my * q1q1 + my * q2q2 + _2q2 * mz * ahrs->quat.q3 - my * q3q3;
// _2bx = sqrtf(hx * hx + hy * hy);
// 改为invsqrt
_2bx = 1.f / InvSqrt(hx * hx + hy * hy);
_2bz = -_2q0mx * ahrs->quat.q2 + _2q0my * ahrs->quat.q1 +
mz * q0q0 + _2q1mx * ahrs->quat.q3 - mz * q1q1 +
_2q2 * my * ahrs->quat.q3 - mz * q2q2 + mz * q3q3;
_4bx = 2.0f * _2bx;
_4bz = 2.0f * _2bz;
/* Gradient decent algorithm corrective step */
s0 = -_2q2 * (2.0f * q1q3 - _2q0q2 - ax) +
_2q1 * (2.0f * q0q1 + _2q2q3 - ay) -
_2bz * ahrs->quat.q2 *
(_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) +
(-_2bx * ahrs->quat.q3 + _2bz * ahrs->quat.q1) *
(_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) +
_2bx * ahrs->quat.q2 *
(_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
s1 = _2q3 * (2.0f * q1q3 - _2q0q2 - ax) +
_2q0 * (2.0f * q0q1 + _2q2q3 - ay) -
4.0f * ahrs->quat.q1 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) +
_2bz * ahrs->quat.q3 *
(_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) +
(_2bx * ahrs->quat.q2 + _2bz * ahrs->quat.q0) *
(_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) +
(_2bx * ahrs->quat.q3 - _4bz * ahrs->quat.q1) *
(_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
s2 = -_2q0 * (2.0f * q1q3 - _2q0q2 - ax) +
_2q3 * (2.0f * q0q1 + _2q2q3 - ay) -
4.0f * ahrs->quat.q2 * (1 - 2.0f * q1q1 - 2.0f * q2q2 - az) +
(-_4bx * ahrs->quat.q2 - _2bz * ahrs->quat.q0) *
(_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) +
(_2bx * ahrs->quat.q1 + _2bz * ahrs->quat.q3) *
(_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) +
(_2bx * ahrs->quat.q0 - _4bz * ahrs->quat.q2) *
(_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
s3 = _2q1 * (2.0f * q1q3 - _2q0q2 - ax) +
_2q2 * (2.0f * q0q1 + _2q2q3 - ay) +
(-_4bx * ahrs->quat.q3 + _2bz * ahrs->quat.q1) *
(_2bx * (0.5f - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) +
(-_2bx * ahrs->quat.q0 + _2bz * ahrs->quat.q2) *
(_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) +
_2bx * ahrs->quat.q1 *
(_2bx * (q0q2 + q1q3) + _2bz * (0.5f - q1q1 - q2q2) - mz);
/* normalise step magnitude */
recip_norm = InvSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3);
s0 *= recip_norm;
s1 *= recip_norm;
s2 *= recip_norm;
s3 *= recip_norm;
/* Apply feedback step */
q_dot1 -= beta * s0;
q_dot2 -= beta * s1;
q_dot3 -= beta * s2;
q_dot4 -= beta * s3;
}
/* Integrate rate of change of quaternion to yield quaternion */
ahrs->quat.q0 += q_dot1 * ahrs->inv_sample_freq;
ahrs->quat.q1 += q_dot2 * ahrs->inv_sample_freq;
ahrs->quat.q2 += q_dot3 * ahrs->inv_sample_freq;
ahrs->quat.q3 += q_dot4 * ahrs->inv_sample_freq;
/* Normalise quaternion */
recip_norm = InvSqrt(ahrs->quat.q0 * ahrs->quat.q0 +
ahrs->quat.q1 * ahrs->quat.q1 +
ahrs->quat.q2 * ahrs->quat.q2 +
ahrs->quat.q3 * ahrs->quat.q3);
ahrs->quat.q0 *= recip_norm;
ahrs->quat.q1 *= recip_norm;
ahrs->quat.q2 *= recip_norm;
ahrs->quat.q3 *= recip_norm;
return 0;
}
/**
* @brief 姿
*
* @param eulr
* @param ahrs 姿
* @return int8_t 0
*/
int8_t AHRS_GetEulr(AHRS_Eulr_t *eulr, const AHRS_t *ahrs) {
if (eulr == NULL) return -1;
if (ahrs == NULL) return -1;
const float sinr_cosp = 2.0f * (ahrs->quat.q0 * ahrs->quat.q1 +
ahrs->quat.q2 * ahrs->quat.q3);
const float cosr_cosp =
1.0f - 2.0f * (ahrs->quat.q1 * ahrs->quat.q1 +
ahrs->quat.q2 * ahrs->quat.q2);
eulr->pit = atan2f(sinr_cosp, cosr_cosp);
const float sinp = 2.0f * (ahrs->quat.q0 * ahrs->quat.q2 -
ahrs->quat.q3 * ahrs->quat.q1);
if (fabsf(sinp) >= 1.0f)
eulr->rol = copysignf(M_PI / 2.0f, sinp);
else
eulr->rol = asinf(sinp);
const float siny_cosp = 2.0f * (ahrs->quat.q0 * ahrs->quat.q3 +
ahrs->quat.q1 * ahrs->quat.q2);
const float cosy_cosp =
1.0f - 2.0f * (ahrs->quat.q2 * ahrs->quat.q2 +
ahrs->quat.q3 * ahrs->quat.q3);
eulr->yaw = atan2f(siny_cosp, cosy_cosp);
#if 0
eulr->yaw *= M_RAD2DEG_MULT;
eulr->rol *= M_RAD2DEG_MULT;
eulr->pit *= M_RAD2DEG_MULT;
#endif
return 0;
}
/**
* \brief
*
* \param eulr
*/
void AHRS_ResetEulr(AHRS_Eulr_t *eulr) { memset(eulr, 0, sizeof(*eulr)); }
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

114
User/component/ahrs.h Normal file
View File

@ -0,0 +1,114 @@
/*
AHRS算法
MadgwickAHRS
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* 欧拉角Euler angle */
typedef struct {
float yaw; /* 偏航角Yaw angle */
float pit; /* 俯仰角Pitch angle */
float rol; /* 翻滚角Roll angle */
} AHRS_Eulr_t;
/* 加速度计 Accelerometer */
typedef struct {
float x;
float y;
float z;
} AHRS_Accl_t;
/* 陀螺仪 Gyroscope */
typedef struct {
float x;
float y;
float z;
} AHRS_Gyro_t;
/* 磁力计 Magnetometer */
typedef struct {
float x;
float y;
float z;
} AHRS_Magn_t;
/* 四元数 */
typedef struct {
float q0;
float q1;
float q2;
float q3;
} AHRS_Quaternion_t;
/* 姿态解算算法主结构体 */
typedef struct {
/* 四元数 */
AHRS_Quaternion_t quat;
float inv_sample_freq; /* 采样频率的的倒数 */
} AHRS_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/**
* @brief 姿
*
* @param ahrs 姿
* @param magn
* @param sample_freq
* @return int8_t 0
*/
int8_t AHRS_Init(AHRS_t *ahrs, const AHRS_Magn_t *magn, float sample_freq);
/**
* @brief 姿
*
* @param ahrs 姿
* @param accl
* @param gyro
* @param magn
* @return int8_t 0
*/
int8_t AHRS_Update(AHRS_t *ahrs, const AHRS_Accl_t *accl,
const AHRS_Gyro_t *gyro, const AHRS_Magn_t *magn);
/**
* @brief 姿
*
* @param eulr
* @param ahrs 姿
* @return int8_t 0
*/
int8_t AHRS_GetEulr(AHRS_Eulr_t *eulr, const AHRS_t *ahrs);
/**
* \brief
*
* \param eulr
*/
void AHRS_ResetEulr(AHRS_Eulr_t *eulr);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,28 @@
ahrs:
dependencies:
- component/user_math.h
enabled: true
crc16:
dependencies: []
enabled: true
crc8:
dependencies: []
enabled: true
error_detect:
dependencies:
- bsp/mm
enabled: true
filter:
dependencies:
- component/ahrs
enabled: true
freertos_cli:
dependencies: []
enabled: true
pid:
dependencies:
- component/filter
enabled: true
user_math:
dependencies: []
enabled: true

62
User/component/crc16.c Normal file
View File

@ -0,0 +1,62 @@
#include "crc16.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
static const uint16_t crc16_tab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48,
0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108,
0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb,
0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399,
0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e,
0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e,
0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd,
0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285,
0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44,
0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014,
0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5,
0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3,
0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862,
0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e,
0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1,
0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483,
0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50,
0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710,
0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7,
0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1,
0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72,
0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e,
0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf,
0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d,
0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c,
0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
static inline uint16_t CRC16_Byte(uint16_t crc, const uint8_t data) {
return (crc >> 8) ^ crc16_tab[(crc ^ data) & 0xff];
}
uint16_t CRC16_Calc(const uint8_t *buf, size_t len, uint16_t crc) {
while (len--) crc = CRC16_Byte(crc, *buf++);
return crc;
}
bool CRC16_Verify(const uint8_t *buf, size_t len) {
if (len < 2) return false;
uint16_t expected = CRC16_Calc(buf, len - sizeof(uint16_t), CRC16_INIT);
return expected ==
((const uint16_t *)((const uint8_t *)buf +
(len % 2)))[len / sizeof(uint16_t) - 1];
}
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

30
User/component/crc16.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
#define CRC16_INIT 0XFFFF
uint16_t CRC16_Calc(const uint8_t *buf, size_t len, uint16_t crc);
bool CRC16_Verify(const uint8_t *buf, size_t len);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

52
User/component/crc8.c Normal file
View File

@ -0,0 +1,52 @@
#include "crc8.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
static const uint8_t crc8_tab[256] = {
0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 0x20,
0xa3, 0xfd, 0x1f, 0x41, 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 0x23, 0x7d, 0x9f, 0xc1,
0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 0x9e,
0x1d, 0x43, 0xa1, 0xff, 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07, 0xdb, 0x85, 0x67, 0x39,
0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 0x45,
0xc6, 0x98, 0x7a, 0x24, 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 0x8c, 0xd2, 0x30, 0x6e,
0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 0xd3, 0x8d, 0x6f, 0x31,
0xb2, 0xec, 0x0e, 0x50, 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee, 0x32, 0x6c, 0x8e, 0xd0,
0x53, 0x0d, 0xef, 0xb1, 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 0x08, 0x56, 0xb4, 0xea,
0x69, 0x37, 0xd5, 0x8b, 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, 0xe9, 0xb7, 0x55, 0x0b,
0x88, 0xd6, 0x34, 0x6a, 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 0x54,
0xd7, 0x89, 0x6b, 0x35,
};
uint8_t CRC8_Calc(const uint8_t *buf, size_t len, uint8_t crc) {
/* loop over the buffer data */
while (len-- > 0) crc = crc8_tab[(crc ^ *buf++) & 0xff];
return crc;
}
bool CRC8_Verify(const uint8_t *buf, size_t len) {
if (len < 2) return false;
uint8_t expected = CRC8_Calc(buf, len - sizeof(uint8_t), CRC8_INIT);
return expected == buf[len - sizeof(uint8_t)];
}
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

30
User/component/crc8.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
#define CRC8_INIT 0xFF
uint8_t CRC8_Calc(const uint8_t *buf, size_t len, uint8_t crc);
bool CRC8_Verify(const uint8_t *buf, size_t len);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,67 @@
/*
*/
#include "error_detect.h"
#include <stddef.h>
#include <string.h>
#include "bsp/mm.h"
static ErrorDetect_t ged;
static bool inited = false;
int8_t ErrorDetect_Init(void) {
if (inited) return -1;
memset(&ged, 0x00, sizeof(ged));
for (uint8_t i = 0; i < ERROR_DETECT_UNIT_NUM; i++) {
ged.error[i].enable = true;
ged.error[i].priority = i;
ged.error[i].patient_lost = 500;
ged.error[i].patient_work = 500;
}
return 0;
}
void ErrorDetect_Processing(uint32_t sys_time) {
for (uint8_t i = 0; i < ERROR_DETECT_UNIT_NUM; i++) {
if (!ged.error[i].enable) continue;
if (sys_time - ged.error[i].showup > ged.error[i].patient_lost) {
ged.error[i].is_lost = true;
ged.error[i].found_lost = sys_time;
} else if (sys_time - ged.error[i].showup > ged.error[i].patient_lost) {
} else {
ged.error[i].cycle_time = ged.error[i].showup - ged.error[i].showup_last;
}
}
}
bool ErrorDetect_ErrorExist(ErrorDetect_Unit_t unit) {
if (unit == ERROR_DETECT_UNIT_NO_DEV) {
for (uint8_t i = ERROR_DETECT_UNIT_NUM; i > 0; i--) {
if (ged.error[i].error_exist) return true;
}
return false;
} else {
return ged.error[unit].error_exist;
}
}
ErrorDetect_Unit_t ErrorDetect_GetErrorUnit(void) {
for (uint8_t i = ERROR_DETECT_UNIT_NUM; i > 0; i--) {
if (ged.error[i].error_exist) return i;
}
return ERROR_DETECT_UNIT_NO_DEV;
}
const ErrorDetect_Error_t *ErrorDetect_GetDetail(ErrorDetect_Unit_t unit) {
return &ged.error[unit];
}
void ErrorDetect_Update(ErrorDetect_Unit_t unit, uint32_t time_current) {
ged.error[unit].showup = time_current;
}

View File

@ -0,0 +1,82 @@
/*
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
typedef enum {
/* Low priority */
ERROR_DETECT_UNIT_NO_DEV = 0,
ERROR_DETECT_UNIT_REFEREE,
ERROR_DETECT_UNIT_CHASSIS_M1,
ERROR_DETECT_UNIT_CHASSIS_M2,
ERROR_DETECT_UNIT_CHASSIS_M3,
ERROR_DETECT_UNIT_CHASSIS_M4,
ERROR_DETECT_UNIT_TRIGGER,
ERROR_DETECT_UNIT_FEED,
ERROR_DETECT_UNIT_GIMBAL_YAW,
ERROR_DETECT_UNIT_GIMBAL_PIT,
ERROR_DETECT_UNIT_GYRO,
ERROR_DETECT_UNIT_ACCL,
ERROR_DETECT_UNIT_MAGN,
ERROR_DETECT_UNIT_DBUS,
ERROR_DETECT_UNIT_NUM,
/* High priority */
} ErrorDetect_Unit_t;
typedef struct {
bool enable;
uint8_t priority;
uint32_t patient_lost;
uint32_t patient_work;
uint32_t showup;
uint32_t showup_last;
uint32_t cycle_time;
uint32_t duration_lost;
uint32_t duration_work;
uint32_t found_lost;
bool error_exist;
bool is_lost;
uint8_t data_is_error;
} ErrorDetect_Error_t;
typedef struct {
ErrorDetect_Error_t error[ERROR_DETECT_UNIT_NUM];
} ErrorDetect_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
int8_t ErrorDetect_Init(void);
void ErrorDetect_Processing(uint32_t sys_time);
bool ErrorDetect_ErrorExist(ErrorDetect_Unit_t unit);
ErrorDetect_Unit_t ErrorDetect_GetErrorUnit(void);
const ErrorDetect_Error_t *ErrorDetect_GetDetail(ErrorDetect_Unit_t unit);
void ErrorDetect_Update(ErrorDetect_Unit_t unit, uint32_t time_current);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

185
User/component/filter.c Normal file
View File

@ -0,0 +1,185 @@
/*
*/
#include "filter.h"
#include "user_math.h"
/**
* @brief
*
* @param f
* @param sample_freq
* @param cutoff_freq
*/
void LowPassFilter2p_Init(LowPassFilter2p_t *f, float sample_freq,
float cutoff_freq) {
if (f == NULL) return;
f->cutoff_freq = cutoff_freq;
f->delay_element_1 = 0.0f;
f->delay_element_2 = 0.0f;
if (f->cutoff_freq <= 0.0f) {
/* no filtering */
f->b0 = 1.0f;
f->b1 = 0.0f;
f->b2 = 0.0f;
f->a1 = 0.0f;
f->a2 = 0.0f;
return;
}
const float fr = sample_freq / f->cutoff_freq;
const float ohm = tanf(M_PI / fr);
const float c = 1.0f + 2.0f * cosf(M_PI / 4.0f) * ohm + ohm * ohm;
f->b0 = ohm * ohm / c;
f->b1 = 2.0f * f->b0;
f->b2 = f->b0;
f->a1 = 2.0f * (ohm * ohm - 1.0f) / c;
f->a2 = (1.0f - 2.0f * cosf(M_PI / 4.0f) * ohm + ohm * ohm) / c;
}
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
float LowPassFilter2p_Apply(LowPassFilter2p_t *f, float sample) {
if (f == NULL) return 0.0f;
/* do the filtering */
float delay_element_0 =
sample - f->delay_element_1 * f->a1 - f->delay_element_2 * f->a2;
if (isinf(delay_element_0)) {
/* don't allow bad values to propagate via the filter */
delay_element_0 = sample;
}
const float output = delay_element_0 * f->b0 + f->delay_element_1 * f->b1 +
f->delay_element_2 * f->b2;
f->delay_element_2 = f->delay_element_1;
f->delay_element_1 = delay_element_0;
/* return the value. Should be no need to check limits */
return output;
}
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
float LowPassFilter2p_Reset(LowPassFilter2p_t *f, float sample) {
if (f == NULL) return 0.0f;
const float dval = sample / (f->b0 + f->b1 + f->b2);
if (isfinite(dval)) {
f->delay_element_1 = dval;
f->delay_element_2 = dval;
} else {
f->delay_element_1 = sample;
f->delay_element_2 = sample;
}
return LowPassFilter2p_Apply(f, sample);
}
/**
* @brief
*
* @param f
* @param sample_freq
* @param notch_freq
* @param bandwidth
*/
void NotchFilter_Init(NotchFilter_t *f, float sample_freq, float notch_freq,
float bandwidth) {
if (f == NULL) return;
f->notch_freq = notch_freq;
f->bandwidth = bandwidth;
f->delay_element_1 = 0.0f;
f->delay_element_2 = 0.0f;
if (notch_freq <= 0.0f) {
/* no filtering */
f->b0 = 1.0f;
f->b1 = 0.0f;
f->b2 = 0.0f;
f->a1 = 0.0f;
f->a2 = 0.0f;
return;
}
const float alpha = tanf(M_PI * bandwidth / sample_freq);
const float beta = -cosf(M_2PI * notch_freq / sample_freq);
const float a0_inv = 1.0f / (alpha + 1.0f);
f->b0 = a0_inv;
f->b1 = 2.0f * beta * a0_inv;
f->b2 = a0_inv;
f->a1 = f->b1;
f->a2 = (1.0f - alpha) * a0_inv;
}
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
inline float NotchFilter_Apply(NotchFilter_t *f, float sample) {
if (f == NULL) return 0.0f;
/* Direct Form II implementation */
const float delay_element_0 =
sample - f->delay_element_1 * f->a1 - f->delay_element_2 * f->a2;
const float output = delay_element_0 * f->b0 + f->delay_element_1 * f->b1 +
f->delay_element_2 * f->b2;
f->delay_element_2 = f->delay_element_1;
f->delay_element_1 = delay_element_0;
return output;
}
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
float NotchFilter_Reset(NotchFilter_t *f, float sample) {
if (f == NULL) return 0.0f;
float dval = sample;
if (fabsf(f->b0 + f->b1 + f->b2) > FLT_EPSILON) {
dval = dval / (f->b0 + f->b1 + f->b2);
}
f->delay_element_1 = dval;
f->delay_element_2 = dval;
return NotchFilter_Apply(f, sample);
}

120
User/component/filter.h Normal file
View File

@ -0,0 +1,120 @@
/*
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* 二阶低通滤波器 */
typedef struct {
float cutoff_freq; /* 截止频率 */
float a1;
float a2;
float b0;
float b1;
float b2;
float delay_element_1;
float delay_element_2;
} LowPassFilter2p_t;
/* 带阻滤波器 */
typedef struct {
float notch_freq; /* 阻止频率 */
float bandwidth; /* 带宽 */
float a1;
float a2;
float b0;
float b1;
float b2;
float delay_element_1;
float delay_element_2;
} NotchFilter_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/**
* @brief
*
* @param f
* @param sample_freq
* @param cutoff_freq
*/
void LowPassFilter2p_Init(LowPassFilter2p_t *f, float sample_freq,
float cutoff_freq);
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
float LowPassFilter2p_Apply(LowPassFilter2p_t *f, float sample);
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
float LowPassFilter2p_Reset(LowPassFilter2p_t *f, float sample);
/**
* @brief
*
* @param f
* @param sample_freq
* @param notch_freq
* @param bandwidth
*/
void NotchFilter_Init(NotchFilter_t *f, float sample_freq, float notch_freq,
float bandwidth);
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
float NotchFilter_Apply(NotchFilter_t *f, float sample);
/**
* @brief
*
* @param f
* @param sample
* @return float
*/
float NotchFilter_Reset(NotchFilter_t *f, float sample);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,352 @@
/*
* FreeRTOS+CLI V1.0.4
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* Standard includes. */
#include <string.h>
#include <stdint.h>
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
/* Utils includes. */
#include "FreeRTOS_CLI.h"
/* If the application writer needs to place the buffer used by the CLI at a
fixed address then set configAPPLICATION_PROVIDES_cOutputBuffer to 1 in
FreeRTOSConfig.h, then declare an array with the following name and size in
one of the application files:
char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
*/
#ifndef configAPPLICATION_PROVIDES_cOutputBuffer
#define configAPPLICATION_PROVIDES_cOutputBuffer 0
#endif
typedef struct xCOMMAND_INPUT_LIST
{
const CLI_Command_Definition_t *pxCommandLineDefinition;
struct xCOMMAND_INPUT_LIST *pxNext;
} CLI_Definition_List_Item_t;
/*
* The callback function that is executed when "help" is entered. This is the
* only default command that is always present.
*/
static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/*
* Return the number of parameters that follow the command name.
*/
static int8_t prvGetNumberOfParameters( const char *pcCommandString );
/* The definition of the "help" command. This command is always at the front
of the list of registered commands. */
static const CLI_Command_Definition_t xHelpCommand =
{
"help",
"\r\nhelp:\r\n Lists all the registered commands\r\n\r\n",
prvHelpCommand,
0
};
/* The definition of the list of commands. Commands that are registered are
added to this list. */
static CLI_Definition_List_Item_t xRegisteredCommands =
{
&xHelpCommand, /* The first command in the list is always the help command, defined in this file. */
NULL /* The next pointer is initialised to NULL, as there are no other registered commands yet. */
};
/* A buffer into which command outputs can be written is declared here, rather
than in the command console implementation, to allow multiple command consoles
to share the same buffer. For example, an application may allow access to the
command interpreter by UART and by Ethernet. Sharing a buffer is done purely
to save RAM. Note, however, that the command console itself is not re-entrant,
so only one command interpreter interface can be used at any one time. For that
reason, no attempt at providing mutual exclusion to the cOutputBuffer array is
attempted.
configAPPLICATION_PROVIDES_cOutputBuffer is provided to allow the application
writer to provide their own cOutputBuffer declaration in cases where the
buffer needs to be placed at a fixed address (rather than by the linker). */
#if( configAPPLICATION_PROVIDES_cOutputBuffer == 0 )
static char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
#else
extern char cOutputBuffer[ configCOMMAND_INT_MAX_OUTPUT_SIZE ];
#endif
/*---------------------------------------------------------- */
BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister )
{
static CLI_Definition_List_Item_t *pxLastCommandInList = &xRegisteredCommands;
CLI_Definition_List_Item_t *pxNewListItem;
BaseType_t xReturn = pdFAIL;
/* Check the parameter is not NULL. */
configASSERT( pxCommandToRegister );
/* Create a new list item that will reference the command being registered. */
pxNewListItem = ( CLI_Definition_List_Item_t * ) pvPortMalloc( sizeof( CLI_Definition_List_Item_t ) );
configASSERT( pxNewListItem );
if( pxNewListItem != NULL )
{
taskENTER_CRITICAL();
{
/* Reference the command being registered from the newly created
list item. */
pxNewListItem->pxCommandLineDefinition = pxCommandToRegister;
/* The new list item will get added to the end of the list, so
pxNext has nowhere to point. */
pxNewListItem->pxNext = NULL;
/* Add the newly created list item to the end of the already existing
list. */
pxLastCommandInList->pxNext = pxNewListItem;
/* Set the end of list marker to the new list item. */
pxLastCommandInList = pxNewListItem;
}
taskEXIT_CRITICAL();
xReturn = pdPASS;
}
return xReturn;
}
/*---------------------------------------------------------- */
BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen )
{
static const CLI_Definition_List_Item_t *pxCommand = NULL;
BaseType_t xReturn = pdTRUE;
const char *pcRegisteredCommandString;
size_t xCommandStringLength;
/* Note: This function is not re-entrant. It must not be called from more
thank one task. */
if( pxCommand == NULL )
{
/* Search for the command string in the list of registered commands. */
for( pxCommand = &xRegisteredCommands; pxCommand != NULL; pxCommand = pxCommand->pxNext )
{
pcRegisteredCommandString = pxCommand->pxCommandLineDefinition->pcCommand;
xCommandStringLength = strlen( pcRegisteredCommandString );
/* To ensure the string lengths match exactly, so as not to pick up
a sub-string of a longer command, check the byte after the expected
end of the string is either the end of the string or a space before
a parameter. */
if( ( pcCommandInput[ xCommandStringLength ] == ' ' ) || ( pcCommandInput[ xCommandStringLength ] == 0x00 ) )
{
if( strncmp( pcCommandInput, pcRegisteredCommandString, xCommandStringLength ) == 0 )
{
/* The command has been found. Check it has the expected
number of parameters. If cExpectedNumberOfParameters is -1,
then there could be a variable number of parameters and no
check is made. */
if( pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters >= 0 )
{
if( prvGetNumberOfParameters( pcCommandInput ) != pxCommand->pxCommandLineDefinition->cExpectedNumberOfParameters )
{
xReturn = pdFALSE;
}
}
break;
}
}
}
}
if( ( pxCommand != NULL ) && ( xReturn == pdFALSE ) )
{
/* The command was found, but the number of parameters with the command
was incorrect. */
strncpy( pcWriteBuffer, "Incorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n", xWriteBufferLen );
pxCommand = NULL;
}
else if( pxCommand != NULL )
{
/* Call the callback function that is registered to this command. */
xReturn = pxCommand->pxCommandLineDefinition->pxCommandInterpreter( pcWriteBuffer, xWriteBufferLen, pcCommandInput );
/* If xReturn is pdFALSE, then no further strings will be returned
after this one, and pxCommand can be reset to NULL ready to search
for the next entered command. */
if( xReturn == pdFALSE )
{
pxCommand = NULL;
}
}
else
{
/* pxCommand was NULL, the command was not found. */
strncpy( pcWriteBuffer, "Command not recognised. Enter 'help' to view a list of available commands.\r\n\r\n", xWriteBufferLen );
xReturn = pdFALSE;
}
return xReturn;
}
/*---------------------------------------------------------- */
char *FreeRTOS_CLIGetOutputBuffer( void )
{
return cOutputBuffer;
}
/*---------------------------------------------------------- */
const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength )
{
UBaseType_t uxParametersFound = 0;
const char *pcReturn = NULL;
*pxParameterStringLength = 0;
while( uxParametersFound < uxWantedParameter )
{
/* Index the character pointer past the current word. If this is the start
of the command string then the first word is the command itself. */
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
{
pcCommandString++;
}
/* Find the start of the next string. */
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) == ' ' ) )
{
pcCommandString++;
}
/* Was a string found? */
if( *pcCommandString != 0x00 )
{
/* Is this the start of the required parameter? */
uxParametersFound++;
if( uxParametersFound == uxWantedParameter )
{
/* How long is the parameter? */
pcReturn = pcCommandString;
while( ( ( *pcCommandString ) != 0x00 ) && ( ( *pcCommandString ) != ' ' ) )
{
( *pxParameterStringLength )++;
pcCommandString++;
}
if( *pxParameterStringLength == 0 )
{
pcReturn = NULL;
}
break;
}
}
else
{
break;
}
}
return pcReturn;
}
/*---------------------------------------------------------- */
static BaseType_t prvHelpCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
{
static const CLI_Definition_List_Item_t * pxCommand = NULL;
BaseType_t xReturn;
( void ) pcCommandString;
if( pxCommand == NULL )
{
/* Reset the pxCommand pointer back to the start of the list. */
pxCommand = &xRegisteredCommands;
}
/* Return the next command help string, before moving the pointer on to
the next command in the list. */
strncpy( pcWriteBuffer, pxCommand->pxCommandLineDefinition->pcHelpString, xWriteBufferLen );
pxCommand = pxCommand->pxNext;
if( pxCommand == NULL )
{
/* There are no more commands in the list, so there will be no more
strings to return after this one and pdFALSE should be returned. */
xReturn = pdFALSE;
}
else
{
xReturn = pdTRUE;
}
return xReturn;
}
/*---------------------------------------------------------- */
static int8_t prvGetNumberOfParameters( const char *pcCommandString )
{
int8_t cParameters = 0;
BaseType_t xLastCharacterWasSpace = pdFALSE;
/* Count the number of space delimited words in pcCommandString. */
while( *pcCommandString != 0x00 )
{
if( ( *pcCommandString ) == ' ' )
{
if( xLastCharacterWasSpace != pdTRUE )
{
cParameters++;
xLastCharacterWasSpace = pdTRUE;
}
}
else
{
xLastCharacterWasSpace = pdFALSE;
}
pcCommandString++;
}
/* If the command string ended with spaces, then there will have been too
many parameters counted. */
if( xLastCharacterWasSpace == pdTRUE )
{
cParameters--;
}
/* The value returned is one less than the number of space delimited words,
as the first word should be the command itself. */
return cParameters;
}

View File

@ -0,0 +1,108 @@
/*
* FreeRTOS+CLI V1.0.4
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#ifndef COMMAND_INTERPRETER_H
#define COMMAND_INTERPRETER_H
/* This config should be defined in FreeRTOSConfig.h. But due to the limition of CubeMX I put it here. */
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 512
/* The prototype to which callback functions used to process command line
commands must comply. pcWriteBuffer is a buffer into which the output from
executing the command can be written, xWriteBufferLen is the length, in bytes of
the pcWriteBuffer buffer, and pcCommandString is the entire string as input by
the user (from which parameters can be extracted).*/
typedef BaseType_t (*pdCOMMAND_LINE_CALLBACK)( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString );
/* The structure that defines command line commands. A command line command
should be defined by declaring a const structure of this type. */
typedef struct xCOMMAND_LINE_INPUT
{
const char * const pcCommand; /* The command that causes pxCommandInterpreter to be executed. For example "help". Must be all lower case. */
const char * const pcHelpString; /* String that describes how to use the command. Should start with the command itself, and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */
const pdCOMMAND_LINE_CALLBACK pxCommandInterpreter; /* A pointer to the callback function that will return the output generated by the command. */
int8_t cExpectedNumberOfParameters; /* Commands expect a fixed number of parameters, which may be zero. */
} CLI_Command_Definition_t;
/* For backward compatibility. */
#define xCommandLineInput CLI_Command_Definition_t
/*
* Register the command passed in using the pxCommandToRegister parameter.
* Registering a command adds the command to the list of commands that are
* handled by the command interpreter. Once a command has been registered it
* can be executed from the command line.
*/
BaseType_t FreeRTOS_CLIRegisterCommand( const CLI_Command_Definition_t * const pxCommandToRegister );
/*
* Runs the command interpreter for the command string "pcCommandInput". Any
* output generated by running the command will be placed into pcWriteBuffer.
* xWriteBufferLen must indicate the size, in bytes, of the buffer pointed to
* by pcWriteBuffer.
*
* FreeRTOS_CLIProcessCommand should be called repeatedly until it returns pdFALSE.
*
* pcCmdIntProcessCommand is not reentrant. It must not be called from more
* than one task - or at least - by more than one task at a time.
*/
BaseType_t FreeRTOS_CLIProcessCommand( const char * const pcCommandInput, char * pcWriteBuffer, size_t xWriteBufferLen );
/*---------------------------------------------------------- */
/*
* A buffer into which command outputs can be written is declared in the
* main command interpreter, rather than in the command console implementation,
* to allow application that provide access to the command console via multiple
* interfaces to share a buffer, and therefore save RAM. Note, however, that
* the command interpreter itself is not re-entrant, so only one command
* console interface can be used at any one time. For that reason, no attempt
* is made to provide any mutual exclusion mechanism on the output buffer.
*
* FreeRTOS_CLIGetOutputBuffer() returns the address of the output buffer.
*/
char *FreeRTOS_CLIGetOutputBuffer( void );
/*
* Return a pointer to the xParameterNumber'th word in pcCommandString.
*/
const char *FreeRTOS_CLIGetParameter( const char *pcCommandString, UBaseType_t uxWantedParameter, BaseType_t *pxParameterStringLength );
#endif /* COMMAND_INTERPRETER_H */

158
User/component/pid.c Normal file
View File

@ -0,0 +1,158 @@
/*
Modified from
https://github.com/PX4/Firmware/blob/master/src/lib/pid/pid.cpp
https://github.com/PX4/Firmware/issues/12362
https://dev.px4.io/master/en/flight_stack/controller_diagrams.html
https://docs.px4.io/master/en/config_mc/pid_tuning_guide_multicopter.html#standard_form
https://www.controleng.com/articles/not-all-pid-controllers-are-the-same/
https://en.wikipedia.org/wiki/PID_controller
http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-derivative-kick/
*/
#include "pid.h"
#define SIGMA 0.000001f
/**
* @brief PID
*
* @param pid PID结构体
* @param mode PID模式
* @param sample_freq
* @param param PID参数
* @return int8_t 0
*/
int8_t PID_Init(KPID_t *pid, KPID_Mode_t mode, float sample_freq,
const KPID_Params_t *param) {
if (pid == NULL) return -1;
if (!isfinite(param->p)) return -1;
if (!isfinite(param->i)) return -1;
if (!isfinite(param->d)) return -1;
if (!isfinite(param->i_limit)) return -1;
if (!isfinite(param->out_limit)) return -1;
pid->param = param;
float dt_min = 1.0f / sample_freq;
if (isfinite(dt_min))
pid->dt_min = dt_min;
else
return -1;
LowPassFilter2p_Init(&(pid->dfilter), sample_freq, pid->param->d_cutoff_freq);
pid->mode = mode;
PID_Reset(pid);
return 0;
}
/**
* @brief PID计算
*
* @param pid PID结构体
* @param sp
* @param fb
* @param fb_dot
* @param dt
* @return float
*/
float PID_Calc(KPID_t *pid, float sp, float fb, float fb_dot, float dt) {
if (!isfinite(sp) || !isfinite(fb) || !isfinite(fb_dot) || !isfinite(dt)) {
return pid->last.out;
}
/* 计算误差值 */
const float err = CircleError(sp, fb, pid->param->range);
/* 计算P项 */
const float k_err = err * pid->param->k;
/* 计算D项 */
const float k_fb = pid->param->k * fb;
const float filtered_k_fb = LowPassFilter2p_Apply(&(pid->dfilter), k_fb);
float d;
switch (pid->mode) {
case KPID_MODE_CALC_D:
/* 通过fb计算D避免了由于sp变化导致err突变的问题 */
/* 当sp不变时err的微分等于负的fb的微分 */
d = (filtered_k_fb - pid->last.k_fb) / fmaxf(dt, pid->dt_min);
break;
case KPID_MODE_SET_D:
d = fb_dot;
break;
case KPID_MODE_NO_D:
d = 0.0f;
break;
}
pid->last.err = err;
pid->last.k_fb = filtered_k_fb;
if (!isfinite(d)) d = 0.0f;
/* 计算PD输出 */
float output = (k_err * pid->param->p) - (d * pid->param->d);
/* 计算I项 */
const float i = pid->i + (k_err * dt);
const float i_out = i * pid->param->i;
if (pid->param->i > SIGMA) {
/* 检查是否饱和 */
if (isfinite(i)) {
if ((fabsf(output + i_out) <= pid->param->out_limit) &&
(fabsf(i) <= pid->param->i_limit)) {
/* 未饱和,使用新积分 */
pid->i = i;
}
}
}
/* 计算PID输出 */
output += i_out;
/* 限制输出 */
if (isfinite(output)) {
if (pid->param->out_limit > SIGMA) {
output = AbsClip(output, pid->param->out_limit);
}
pid->last.out = output;
}
return pid->last.out;
}
/**
* @brief
*
* @param pid PID结构体
* @return int8_t 0
*/
int8_t PID_ResetIntegral(KPID_t *pid) {
if (pid == NULL) return -1;
pid->i = 0.0f;
return 0;
}
/**
* @brief PID
*
* @param pid PID结构体
* @return int8_t 0
*/
int8_t PID_Reset(KPID_t *pid) {
if (pid == NULL) return -1;
pid->i = 0.0f;
pid->last.err = 0.0f;
pid->last.k_fb = 0.0f;
pid->last.out = 0.0f;
LowPassFilter2p_Reset(&(pid->dfilter), 0.0f);
return 0;
}

107
User/component/pid.h Normal file
View File

@ -0,0 +1,107 @@
/*
Modified from
https://github.com/PX4/Firmware/blob/master/src/lib/pid/pid.h
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "filter.h"
#include "user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* PID模式 */
typedef enum {
KPID_MODE_NO_D = 0, /* 不使用微分项PI控制器 */
KPID_MODE_CALC_D, /* 根据反馈的值计算离散微分忽略PID_Calc中的fb_dot */
KPID_MODE_SET_D /* 直接提供微分值PID_Calc中的fb_dot将被使用(Gyros) */
} KPID_Mode_t;
/* PID参数 */
typedef struct {
float k; /* 控制器增益设置为1用于并行模式 */
float p; /* 比例项增益设置为1用于标准形式 */
float i; /* 积分项增益 */
float d; /* 微分项增益 */
float i_limit; /* 积分项上限 */
float out_limit; /* 输出绝对值限制 */
float d_cutoff_freq; /* D项低通截止频率 */
float range; /* 计算循环误差时使用大于0时启用 */
} KPID_Params_t;
/* PID主结构体 */
typedef struct {
KPID_Mode_t mode;
const KPID_Params_t *param;
float dt_min; /* 最小PID_Calc调用间隔 */
float i; /* 积分 */
struct {
float err; /* 上次误差 */
float k_fb; /* 上次反馈值 */
float out; /* 上次输出 */
} last;
LowPassFilter2p_t dfilter; /* D项低通滤波器 */
} KPID_t;
/**
* @brief PID
*
* @param pid PID结构体
* @param mode PID模式
* @param sample_freq
* @param param PID参数
* @return int8_t 0
*/
int8_t PID_Init(KPID_t *pid, KPID_Mode_t mode, float sample_freq,
const KPID_Params_t *param);
/**
* @brief PID计算
*
* @param pid PID结构体
* @param sp
* @param fb
* @param fb_dot
* @param dt
* @return float
*/
float PID_Calc(KPID_t *pid, float sp, float fb, float fb_dot, float dt);
/**
* @brief
*
* @param pid PID结构体
* @return int8_t 0
*/
int8_t PID_ResetIntegral(KPID_t *pid);
/**
* @brief PID
*
* @param pid PID结构体
* @return int8_t 0
*/
int8_t PID_Reset(KPID_t *pid);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

134
User/component/user_math.c Normal file
View File

@ -0,0 +1,134 @@
/*
*/
#include "user_math.h"
#include <string.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
inline float InvSqrt(float x) {
//#if 0
/* Fast inverse square-root */
/* See: http://en.wikipedia.org/wiki/Fast_inverse_square_root */
float halfx = 0.5f * x;
float y = x;
long i = *(long*)&y;
i = 0x5f3759df - (i>>1);
y = *(float*)&i;
y = y * (1.5f - (halfx * y * y));
y = y * (1.5f - (halfx * y * y));
return y;
//#else
// return 1.0f / sqrtf(x);
//#endif
}
inline float AbsClip(float in, float limit) {
return (in < -limit) ? -limit : ((in > limit) ? limit : in);
}
float fAbs(float in){
return (in > 0) ? in : -in;
}
inline void Clip(float *origin, float min, float max) {
if (*origin > max) *origin = max;
if (*origin < min) *origin = min;
}
inline float Sign(float in) { return (in > 0) ? 1.0f : 0.0f; }
/**
* \brief
*
* \param mv
*/
inline void ResetMoveVector(MoveVector_t *mv) { memset(mv, 0, sizeof(*mv)); }
/**
* \brief x,yrange应设定为y-x
* -M_PI,M_PIrange=M_2PI;(0,M_2PI)range=M_2PI;a,a+brange=b;
* \param sp
* \param fb
* \param range
* \return
*/
inline float CircleError(float sp, float fb, float range) {
float error = sp - fb;
if (range > 0.0f) {
float half_range = range / 2.0f;
if (error > half_range)
error -= range;
else if (error < -half_range)
error += range;
}
return error;
}
/**
* \brief 0,range
* \param origin
* \param delta
* \param range
*/
inline void CircleAdd(float *origin, float delta, float range) {
float out = *origin + delta;
if (range > 0.0f) {
if (out >= range)
out -= range;
else if (out < 0.0f)
out += range;
}
*origin = out;
}
/**
* @brief
*
* @param origin
*/
inline void CircleReverse(float *origin) { *origin = -(*origin) + M_2PI; }
/**
* @brief
*
* @param bullet_speed
* @param fric_radius
* @param is17mm 17mm
* @return
*/
inline float CalculateRpm(float bullet_speed, float fric_radius, bool is17mm) {
if (bullet_speed == 0.0f) return 0.f;
if (is17mm) {
if (bullet_speed == 15.0f) return 4670.f;
if (bullet_speed == 18.0f) return 5200.f;
if (bullet_speed == 30.0f) return 7350.f;
} else {
if (bullet_speed == 10.0f) return 4450.f;
if (bullet_speed == 16.0f) return 5800.f;
}
/* 不为裁判系统设定值时,计算转速 */
return 60.0f * (float)bullet_speed / (M_2PI * fric_radius);
}
// /**
// * @brief 断言失败处理
// *
// * @param file 文件名
// * @param line 行号
// */
// void VerifyFailed(const char *file, uint32_t line) {
// UNUSED(file);
// UNUSED(line);
// while (1) {
// __NOP();
// }
// }
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

179
User/component/user_math.h Normal file
View File

@ -0,0 +1,179 @@
/*
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
#define M_DEG2RAD_MULT (0.01745329251f)
#define M_RAD2DEG_MULT (57.2957795131f)
#ifndef M_PI_2
#define M_PI_2 1.57079632679f
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846f
#endif
#ifndef M_2PI
#define M_2PI 6.28318530717958647692f
#endif
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif /* __packed */
#define max(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#define min(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* 移动向量 */
typedef struct {
float vx; /* 前后平移 */
float vy; /* 左右平移 */
float wz; /* 转动 */
} MoveVector_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
float InvSqrt(float x);
float AbsClip(float in, float limit);
float fAbs(float in);
void Clip(float *origin, float min, float max);
float Sign(float in);
/**
* \brief
*
* \param mv
*/
void ResetMoveVector(MoveVector_t *mv);
/**
* \brief x,yrange应设定为y-x
* -M_PI,M_PIrange=M_2PI;(0,M_2PI)range=M_2PI;a,a+brange=b;
* \param sp
* \param fb
* \param range
* \return
*/
float CircleError(float sp, float fb, float range);
/**
* \brief 0,range
* \param origin
* \param delta
* \param range
*/
void CircleAdd(float *origin, float delta, float range);
/**
* @brief
*
* @param origin
*/
void CircleReverse(float *origin);
/**
* @brief
*
* @param bullet_speed
* @param fric_radius
* @param is17mm 17mm
* @return
*/
float CalculateRpm(float bullet_speed, float fric_radius, bool is17mm);
#ifdef __cplusplus
}
#endif
#ifdef DEBUG
/**
* @brief
*
*/
#define ASSERT(expr) \
do { \
if (!(expr)) { \
VerifyFailed(__FILE__, __LINE__); \
} \
} while (0)
#else
/**
* @brief DEBUG
*
*/
#define ASSERT(expr) ((void)(0))
#endif
#ifdef DEBUG
/**
* @brief
*
*/
#define VERIFY(expr) \
do { \
if (!(expr)) { \
VerifyFailed(__FILE__, __LINE__); \
} \
} while (0)
#else
/**
* @brief
*
*/
#define VERIFY(expr) ((void)(expr))
#endif
// /**
// * @brief 断言失败处理
// *
// * @param file 文件名
// * @param line 行号
// */
// void VerifyFailed(const char *file, uint32_t line);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

381
User/device/bmi088.c Normal file
View File

@ -0,0 +1,381 @@
/*
BMI088 +
*/
/* Includes ----------------------------------------------------------------- */
#include "bmi088.h"
#include <cmsis_os2.h>
#include <gpio.h>
#include <stdbool.h>
#include <string.h>
#include "bsp/time.h"
#include "bsp/gpio.h"
#include "bsp/spi.h"
#include "component/user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
#define BMI088_REG_ACCL_CHIP_ID (0x00)
#define BMI088_REG_ACCL_ERR (0x02)
#define BMI088_REG_ACCL_STATUS (0x03)
#define BMI088_REG_ACCL_X_LSB (0x12)
#define BMI088_REG_ACCL_X_MSB (0x13)
#define BMI088_REG_ACCL_Y_LSB (0x14)
#define BMI088_REG_ACCL_Y_MSB (0x15)
#define BMI088_REG_ACCL_Z_LSB (0x16)
#define BMI088_REG_ACCL_Z_MSB (0x17)
#define BMI088_REG_ACCL_SENSORTIME_0 (0x18)
#define BMI088_REG_ACCL_SENSORTIME_1 (0x19)
#define BMI088_REG_ACCL_SENSORTIME_2 (0x1A)
#define BMI088_REG_ACCL_INT_STAT_1 (0x1D)
#define BMI088_REG_ACCL_TEMP_MSB (0x22)
#define BMI088_REG_ACCL_TEMP_LSB (0x23)
#define BMI088_REG_ACCL_CONF (0x40)
#define BMI088_REG_ACCL_RANGE (0x41)
#define BMI088_REG_ACCL_INT1_IO_CONF (0x53)
#define BMI088_REG_ACCL_INT2_IO_CONF (0x54)
#define BMI088_REG_ACCL_INT1_INT2_MAP_DATA (0x58)
#define BMI088_REG_ACCL_SELF_TEST (0x6D)
#define BMI088_REG_ACCL_PWR_CONF (0x7C)
#define BMI088_REG_ACCL_PWR_CTRL (0x7D)
#define BMI088_REG_ACCL_SOFTRESET (0x7E)
#define BMI088_REG_GYRO_CHIP_ID (0x00)
#define BMI088_REG_GYRO_X_LSB (0x02)
#define BMI088_REG_GYRO_X_MSB (0x03)
#define BMI088_REG_GYRO_Y_LSB (0x04)
#define BMI088_REG_GYRO_Y_MSB (0x05)
#define BMI088_REG_GYRO_Z_LSB (0x06)
#define BMI088_REG_GYRO_Z_MSB (0x07)
#define BMI088_REG_GYRO_INT_STAT_1 (0x0A)
#define BMI088_REG_GYRO_RANGE (0x0F)
#define BMI088_REG_GYRO_BANDWIDTH (0x10)
#define BMI088_REG_GYRO_LPM1 (0x11)
#define BMI088_REG_GYRO_SOFTRESET (0x14)
#define BMI088_REG_GYRO_INT_CTRL (0x15)
#define BMI088_REG_GYRO_INT3_INT4_IO_CONF (0x16)
#define BMI088_REG_GYRO_INT3_INT4_IO_MAP (0x18)
#define BMI088_REG_GYRO_SELF_TEST (0x3C)
#define BMI088_CHIP_ID_ACCL (0x1E)
#define BMI088_CHIP_ID_GYRO (0x0F)
#define BMI088_LEN_RX_BUFF (19)
/* Private macro ------------------------------------------------------------ */
#define BMI088_ACCL_NSS_SET() \
BSP_GPIO_WritePin(BSP_GPIO_ACCL_CS, GPIO_PIN_SET)
#define BMI088_ACCL_NSS_RESET() \
BSP_GPIO_WritePin(BSP_GPIO_ACCL_CS, GPIO_PIN_RESET)
#define BMI088_GYRO_NSS_SET() \
BSP_GPIO_WritePin(BSP_GPIO_GYRO_CS, GPIO_PIN_SET)
#define BMI088_GYRO_NSS_RESET() \
BSP_GPIO_WritePin(BSP_GPIO_GYRO_CS, GPIO_PIN_RESET)
/* Private typedef ---------------------------------------------------------- */
typedef enum {
BMI_ACCL,
BMI_GYRO,
} BMI_Device_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
static uint8_t buffer[2];
static uint8_t bmi088_rxbuf[BMI088_LEN_RX_BUFF];
static osThreadId_t thread_alert;
static bool inited = false;
/* Private function -------------------------------------------------------- */
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
static void BMI_WriteSingle(BMI_Device_t dv, uint8_t reg, uint8_t data) {
buffer[0] = (reg & 0x7f);
buffer[1] = data;
BSP_TIME_Delay(1);
switch (dv) {
case BMI_ACCL:
BMI088_ACCL_NSS_RESET();
break;
case BMI_GYRO:
BMI088_GYRO_NSS_RESET();
break;
}
BSP_SPI_Transmit(BSP_SPI_BMI088, buffer, 2u, false);
switch (dv) {
case BMI_ACCL:
BMI088_ACCL_NSS_SET();
break;
case BMI_GYRO:
BMI088_GYRO_NSS_SET();
break;
}
}
static uint8_t BMI_ReadSingle(BMI_Device_t dv, uint8_t reg) {
BSP_TIME_Delay(1);
switch (dv) {
case BMI_ACCL:
BMI088_ACCL_NSS_RESET();
break;
case BMI_GYRO:
BMI088_GYRO_NSS_RESET();
break;
}
buffer[0] = (uint8_t)(reg | 0x80);
BSP_SPI_Transmit(BSP_SPI_BMI088, buffer, 1u, false);
BSP_SPI_Receive(BSP_SPI_BMI088, buffer, 2u, false);
switch (dv) {
case BMI_ACCL:
BMI088_ACCL_NSS_SET();
return buffer[1];
case BMI_GYRO:
BMI088_GYRO_NSS_SET();
return buffer[0];
}
}
static void BMI_Read(BMI_Device_t dv, uint8_t reg, uint8_t *data, uint8_t len) {
if (data == NULL) return;
switch (dv) {
case BMI_ACCL:
BMI088_ACCL_NSS_RESET();
break;
case BMI_GYRO:
BMI088_GYRO_NSS_RESET();
break;
}
buffer[0] = (uint8_t)(reg | 0x80);
BSP_SPI_Transmit(BSP_SPI_BMI088, buffer, 1u, false);
BSP_SPI_Receive(BSP_SPI_BMI088, data, len, true);
}
static void BMI088_RxCpltCallback(void) {
if (BSP_GPIO_ReadPin(BSP_GPIO_ACCL_CS) == GPIO_PIN_RESET) {
BMI088_ACCL_NSS_SET();
osThreadFlagsSet(thread_alert, SIGNAL_BMI088_ACCL_RAW_REDY);
}
if (BSP_GPIO_ReadPin(BSP_GPIO_GYRO_CS) == GPIO_PIN_RESET) {
BMI088_GYRO_NSS_SET();
osThreadFlagsSet(thread_alert, SIGNAL_BMI088_GYRO_RAW_REDY);
}
}
static void BMI088_AcclIntCallback(void) {
osThreadFlagsSet(thread_alert, SIGNAL_BMI088_ACCL_NEW_DATA);
}
static void BMI088_GyroIntCallback(void) {
osThreadFlagsSet(thread_alert, SIGNAL_BMI088_GYRO_NEW_DATA);
}
/* Exported functions ------------------------------------------------------- */
int8_t BMI088_Init(BMI088_t *bmi088, const BMI088_Cali_t *cali) {
if (bmi088 == NULL) return DEVICE_ERR_NULL;
if (cali == NULL) return DEVICE_ERR_NULL;
if (inited) return DEVICE_ERR_INITED;
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
bmi088->cali = cali;
BMI_WriteSingle(BMI_ACCL, BMI088_REG_ACCL_SOFTRESET, 0xB6);
BMI_WriteSingle(BMI_GYRO, BMI088_REG_GYRO_SOFTRESET, 0xB6);
BSP_TIME_Delay(30);
/* Switch accl to SPI mode. */
BMI_ReadSingle(BMI_ACCL, BMI088_CHIP_ID_ACCL);
if (BMI_ReadSingle(BMI_ACCL, BMI088_REG_ACCL_CHIP_ID) != BMI088_CHIP_ID_ACCL)
return DEVICE_ERR_NO_DEV;
if (BMI_ReadSingle(BMI_GYRO, BMI088_REG_GYRO_CHIP_ID) != BMI088_CHIP_ID_GYRO)
return DEVICE_ERR_NO_DEV;
BSP_GPIO_DisableIRQ(BSP_GPIO_ACCL_INT);
BSP_GPIO_DisableIRQ(BSP_GPIO_GYRO_INT);
BSP_SPI_RegisterCallback(BSP_SPI_BMI088, BSP_SPI_RX_CPLT_CB,
BMI088_RxCpltCallback);
BSP_GPIO_RegisterCallback(BSP_GPIO_ACCL_INT, BMI088_AcclIntCallback);
BSP_GPIO_RegisterCallback(BSP_GPIO_GYRO_INT, BMI088_GyroIntCallback);
/* Accl init. */
/* Filter setting: Normal. */
/* ODR: 0xAB: 800Hz. 0xAA: 400Hz. 0xA9: 200Hz. 0xA8: 100Hz. 0xA6: 25Hz. */
BMI_WriteSingle(BMI_ACCL, BMI088_REG_ACCL_CONF, 0xAA);
/* 0x00: +-3G. 0x01: +-6G. 0x02: +-12G. 0x03: +-24G. */
BMI_WriteSingle(BMI_ACCL, BMI088_REG_ACCL_RANGE, 0x01);
/* INT1 as output. Push-pull. Active low. Output. */
BMI_WriteSingle(BMI_ACCL, BMI088_REG_ACCL_INT1_IO_CONF, 0x08);
/* Map data ready interrupt to INT1. */
BMI_WriteSingle(BMI_ACCL, BMI088_REG_ACCL_INT1_INT2_MAP_DATA, 0x04);
/* Turn on accl. Now we can read data. */
BMI_WriteSingle(BMI_ACCL, BMI088_REG_ACCL_PWR_CTRL, 0x04);
BSP_TIME_Delay(50);
/* Gyro init. */
/* 0x00: +-2000. 0x01: +-1000. 0x02: +-500. 0x03: +-250. 0x04: +-125. */
BMI_WriteSingle(BMI_GYRO, BMI088_REG_GYRO_RANGE, 0x01);
/* Filter bw: 47Hz. */
/* ODR: 0x02: 1000Hz. 0x03: 400Hz. 0x06: 200Hz. 0x07: 100Hz. */
BMI_WriteSingle(BMI_GYRO, BMI088_REG_GYRO_BANDWIDTH, 0x03);
/* INT3 and INT4 as output. Push-pull. Active low. */
BMI_WriteSingle(BMI_GYRO, BMI088_REG_GYRO_INT3_INT4_IO_CONF, 0x00);
/* Map data ready interrupt to INT3. */
BMI_WriteSingle(BMI_GYRO, BMI088_REG_GYRO_INT3_INT4_IO_MAP, 0x01);
/* Enable new data interrupt. */
BMI_WriteSingle(BMI_GYRO, BMI088_REG_GYRO_INT_CTRL, 0x80);
BSP_TIME_Delay(10);
inited = true;
BSP_GPIO_EnableIRQ(BSP_GPIO_ACCL_INT);
BSP_GPIO_EnableIRQ(BSP_GPIO_GYRO_INT);
return DEVICE_OK;
}
bool BMI088_GyroStable(AHRS_Gyro_t *gyro) {
return ((gyro->x < 0.03f) && (gyro->y < 0.03f) && (gyro->z < 0.03f));
}
uint32_t BMI088_WaitNew() {
return osThreadFlagsWait(
SIGNAL_BMI088_ACCL_NEW_DATA | SIGNAL_BMI088_GYRO_NEW_DATA, osFlagsWaitAll,
osWaitForever);
}
int8_t BMI088_AcclStartDmaRecv() {
BMI_Read(BMI_ACCL, BMI088_REG_ACCL_X_LSB, bmi088_rxbuf, BMI088_LEN_RX_BUFF);
return DEVICE_OK;
}
uint32_t BMI088_AcclWaitDmaCplt() {
return osThreadFlagsWait(SIGNAL_BMI088_ACCL_RAW_REDY, osFlagsWaitAll,
osWaitForever);
}
int8_t BMI088_GyroStartDmaRecv() {
BMI_Read(BMI_GYRO, BMI088_REG_GYRO_X_LSB, bmi088_rxbuf + 7, 6u);
return DEVICE_OK;
}
uint32_t BMI088_GyroWaitDmaCplt() {
return osThreadFlagsWait(SIGNAL_BMI088_GYRO_RAW_REDY, osFlagsWaitAll,
osWaitForever);
}
int8_t BMI088_ParseAccl(BMI088_t *bmi088) {
if (bmi088 == NULL) return DEVICE_ERR_NULL;
#if 1
int16_t raw_x, raw_y, raw_z;
memcpy(&raw_x, bmi088_rxbuf + 1, sizeof(raw_x));
memcpy(&raw_y, bmi088_rxbuf + 3, sizeof(raw_y));
memcpy(&raw_z, bmi088_rxbuf + 5, sizeof(raw_z));
bmi088->accl.x = (float)raw_x;
bmi088->accl.y = (float)raw_y;
bmi088->accl.z = (float)raw_z;
#else
const int16_t *praw_x = (int16_t *)(bmi088_rxbuf + 1);
const int16_t *praw_y = (int16_t *)(bmi088_rxbuf + 3);
const int16_t *praw_z = (int16_t *)(bmi088_rxbuf + 5);
bmi088->accl.x = (float)*praw_x;
bmi088->accl.y = (float)*praw_y;
bmi088->accl.z = (float)*praw_z;
#endif
/* 3G: 10920. 6G: 5460. 12G: 2730. 24G: 1365. */
bmi088->accl.x /= 5460.0f;
bmi088->accl.y /= 5460.0f;
bmi088->accl.z /= 5460.0f;
int16_t raw_temp =
(uint16_t)((bmi088_rxbuf[17] << 3) | (bmi088_rxbuf[18] >> 5));
if (raw_temp > 1023) raw_temp -= 2048;
bmi088->temp = (float)raw_temp * 0.125f + 23.0f;
return DEVICE_OK;
}
int8_t BMI088_ParseGyro(BMI088_t *bmi088) {
if (bmi088 == NULL) return DEVICE_ERR_NULL;
#if 1
/* Gyroscope imu_raw -> degrees/sec -> radians/sec */
int16_t raw_x, raw_y, raw_z;
memcpy(&raw_x, bmi088_rxbuf + 7, sizeof(raw_x));
memcpy(&raw_y, bmi088_rxbuf + 9, sizeof(raw_y));
memcpy(&raw_z, bmi088_rxbuf + 11, sizeof(raw_z));
bmi088->gyro.x = (float)raw_x;
bmi088->gyro.y = (float)raw_y;
bmi088->gyro.z = (float)raw_z;
#else
/* Gyroscope imu_raw -> degrees/sec -> radians/sec */
const int16_t *raw_x = (int16_t *)(bmi088_rxbuf + 7);
const int16_t *raw_y = (int16_t *)(bmi088_rxbuf + 9);
const int16_t *raw_z = (int16_t *)(bmi088_rxbuf + 11);
bmi088->gyro.x = (float)*raw_x;
bmi088->gyro.y = (float)*raw_y;
bmi088->gyro.z = (float)*raw_z;
#endif
/* FS125: 262.144. FS250: 131.072. FS500: 65.536. FS1000: 32.768.
* FS2000: 16.384.*/
bmi088->gyro.x /= 32.768f;
bmi088->gyro.y /= 32.768f;
bmi088->gyro.z /= 32.768f;
bmi088->gyro.x *= M_DEG2RAD_MULT;
bmi088->gyro.y *= M_DEG2RAD_MULT;
bmi088->gyro.z *= M_DEG2RAD_MULT;
bmi088->gyro.x -= bmi088->cali->gyro_offset.x;
bmi088->gyro.y -= bmi088->cali->gyro_offset.y;
bmi088->gyro.z -= bmi088->cali->gyro_offset.z;
return DEVICE_ERR_NULL;
}
float BMI088_GetUpdateFreq(BMI088_t *bmi088) {
(void)bmi088;
return 400.0f;
}

81
User/device/bmi088.h Normal file
View File

@ -0,0 +1,81 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <stdbool.h>
#include <stdint.h>
#include "component/ahrs.h"
#include "device/device.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef struct {
struct {
float x;
float y;
float z;
} gyro_offset; /* 陀螺仪偏置 */
} BMI088_Cali_t; /* BMI088校准数据 */
typedef struct {
DEVICE_Header_t header;
AHRS_Accl_t accl;
AHRS_Gyro_t gyro;
float temp; /* 温度 */
const BMI088_Cali_t *cali;
} BMI088_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Exported functions prototypes -------------------------------------------- */
int8_t BMI088_Init(BMI088_t *bmi088, const BMI088_Cali_t *cali);
int8_t BMI088_Restart(void);
bool BMI088_GyroStable(AHRS_Gyro_t *gyro);
/* Sensor use right-handed coordinate system. */
/*
x < R(logo)
y
UP is z
All implementation should follow this rule.
*/
uint32_t BMI088_WaitNew();
/*
BMI088的Accl和Gyro共用同一个DMA通道
BMI088_AcclStartDmaRecv() BMI088_AcclWaitDmaCplt()
BMI088_GyroStartDmaRecv()
*/
int8_t BMI088_AcclStartDmaRecv();
uint32_t BMI088_AcclWaitDmaCplt();
int8_t BMI088_GyroStartDmaRecv();
uint32_t BMI088_GyroWaitDmaCplt();
int8_t BMI088_ParseAccl(BMI088_t *bmi088);
int8_t BMI088_ParseGyro(BMI088_t *bmi088);
float BMI088_GetUpdateFreq(BMI088_t *bmi088);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

171
User/device/buzzer.c Normal file
View File

@ -0,0 +1,171 @@
#include "device/buzzer.h"
#include "bsp/time.h"
#include <math.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
#define MUSIC_DEFAULT_VOLUME 0.5f
#define MUSIC_A4_FREQ 440.0f // A4音符频率
/* USER MUSIC MENU BEGIN */
// RM音乐
const Tone_t RM[] = {
{NOTE_B, 5, 200},
{NOTE_G, 4, 200},
{NOTE_B, 5, 400},
{NOTE_G, 4, 200},
{NOTE_B, 5, 400},
{NOTE_G, 4, 200},
{NOTE_D, 5, 400},
{NOTE_G, 4, 200},
{NOTE_C, 5, 200},
{NOTE_C, 5, 200},
{NOTE_G, 4, 200},
{NOTE_B, 5, 200},
{NOTE_C, 5, 200}
};
// Nokia 经典铃声音符
const Tone_t NOKIA[] = {
{NOTE_E, 5, 125}, {NOTE_D, 5, 125}, {NOTE_FS, 4, 250}, {NOTE_GS, 4, 250},
{NOTE_CS, 5, 125}, {NOTE_B, 4, 125}, {NOTE_D, 4, 250}, {NOTE_E, 4, 250},
{NOTE_B, 4, 125}, {NOTE_A, 4, 125}, {NOTE_CS, 4, 250}, {NOTE_E, 4, 250},
{NOTE_A, 4, 500}
};
/* USER MUSIC MENU END */
static void BUZZER_Update(BUZZER_t *buzzer){
buzzer->header.online = true;
buzzer->header.last_online_time = BSP_TIME_Get_ms();
}
// 根据音符和八度计算频率的辅助函数
static float BUZZER_CalcFreq(NOTE_t note, uint8_t octave) {
if (note == NOTE_REST) {
return 0.0f; // 休止符返回0频率
}
// 将音符和八度转换为MIDI音符编号
int midi_num = (int)note + (int)((octave + 1) * 12);
// 使用A4 (440Hz) 作为参考,计算频率
// 公式: freq = 440 * 2^((midi_num - 69)/12)
float freq = 440.0f * powf(2.0f, ((float)midi_num - 69.0f) / 12.0f);
return freq;
}
// 播放单个音符
static int8_t BUZZER_PlayTone(BUZZER_t *buzzer, NOTE_t note, uint8_t octave, uint16_t duration_ms) {
if (buzzer == NULL || !buzzer->header.online)
return DEVICE_ERR;
float freq = BUZZER_CalcFreq(note, octave);
if (freq > 0.0f) {
// 播放音符
if (BUZZER_Set(buzzer, freq, MUSIC_DEFAULT_VOLUME) != DEVICE_OK)
return DEVICE_ERR;
if (BUZZER_Start(buzzer) != DEVICE_OK)
return DEVICE_ERR;
} else {
// 休止符,停止播放
BUZZER_Stop(buzzer);
}
// 等待指定时间
BSP_TIME_Delay_ms(duration_ms);
// 停止当前音符,为下一个音符做准备
BUZZER_Stop(buzzer);
BSP_TIME_Delay_ms(20); // 短暂间隔
return DEVICE_OK;
}
int8_t BUZZER_Init(BUZZER_t *buzzer, BSP_PWM_Channel_t channel) {
if (buzzer == NULL) return DEVICE_ERR;
buzzer->channel = channel;
buzzer->header.online = true;
BUZZER_Stop(buzzer);
return DEVICE_OK ;
}
int8_t BUZZER_Start(BUZZER_t *buzzer) {
if (buzzer == NULL || !buzzer->header.online)
return DEVICE_ERR;
BUZZER_Update(buzzer);
return (BSP_PWM_Start(buzzer->channel) == BSP_OK) ?
DEVICE_OK : DEVICE_ERR;
}
int8_t BUZZER_Stop(BUZZER_t *buzzer) {
if (buzzer == NULL || !buzzer->header.online)
return DEVICE_ERR;
BUZZER_Update(buzzer);
return (BSP_PWM_Stop(buzzer->channel) == BSP_OK) ?
DEVICE_OK : DEVICE_ERR;
}
int8_t BUZZER_Set(BUZZER_t *buzzer, float freq, float duty_cycle) {
if (buzzer == NULL || !buzzer->header.online)
return DEVICE_ERR;
int result = DEVICE_OK ;
BUZZER_Update(buzzer);
if (BSP_PWM_SetFreq(buzzer->channel, freq) != BSP_OK)
result = DEVICE_ERR;
if (BSP_PWM_SetComp(buzzer->channel, duty_cycle) != BSP_OK)
result = DEVICE_ERR;
return result;
}
int8_t BUZZER_PlayMusic(BUZZER_t *buzzer, MUSIC_t music) {
if (buzzer == NULL || !buzzer->header.online)
return DEVICE_ERR;
const Tone_t *melody = NULL;
size_t melody_length = 0;
// 根据音乐类型选择对应的音符数组
switch (music) {
case MUSIC_RM:
melody = RM;
melody_length = sizeof(RM) / sizeof(Tone_t);
break;
case MUSIC_NOKIA:
melody = NOKIA;
melody_length = sizeof(NOKIA) / sizeof(Tone_t);
break;
default:
return DEVICE_ERR;
}
// 播放整首音乐
for (size_t i = 0; i < melody_length; i++) {
if (BUZZER_PlayTone(buzzer, melody[i].note, melody[i].octave, melody[i].duration_ms) != DEVICE_OK) {
BUZZER_Stop(buzzer); // 出错时停止播放
return DEVICE_ERR;
}
}
// 音乐播放完成后停止
BUZZER_Stop(buzzer);
return DEVICE_OK;
}
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

138
User/device/buzzer.h Normal file
View File

@ -0,0 +1,138 @@
/**
* @file buzzer.h
* @brief
* @details
* @author Generated by STM32CubeMX
* @date 20251023
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "bsp/pwm.h" // PWM底层硬件抽象层
#include "device.h" // 设备通用头文件
#include <stddef.h> // 标准定义
#include <stdint.h> // 标准整型定义
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported types ----------------------------------------------------------- */
/**
* @brief
* @details
*/
typedef enum {
NOTE_C = 0, ///< Do音符
NOTE_CS = 1, ///< Do#音符 (升Do)
NOTE_D = 2, ///< Re音符
NOTE_DS = 3, ///< Re#音符 (升Re)
NOTE_E = 4, ///< Mi音符
NOTE_F = 5, ///< Fa音符
NOTE_FS = 6, ///< Fa#音符 (升Fa)
NOTE_G = 7, ///< Sol音符
NOTE_GS = 8, ///< Sol#音符 (升Sol)
NOTE_A = 9, ///< La音符
NOTE_AS = 10, ///< La#音符 (升La)
NOTE_B = 11, ///< Si音符
NOTE_REST = 255 ///< 休止符 (无声音)
} NOTE_t;
/**
* @brief
* @details
*/
typedef struct {
NOTE_t note; ///< 音符名称 (使用NOTE_t枚举)
uint8_t octave; ///< 八度 (0-8通常使用3-7)
uint16_t duration_ms; ///< 持续时间,单位毫秒
} Tone_t;
/**
* @brief
* @details
*/
typedef enum {
/* USER MUSIC MENU BEGIN */
MUSIC_RM, ///< RM战队音乐
MUSIC_NOKIA, ///< 诺基亚经典铃声
/* USER MUSIC MENU END */
} MUSIC_t;
/**
* @brief
* @details PWM通道
*/
typedef struct {
DEVICE_Header_t header; ///< 设备通用头信息 (在线状态、时间戳等)
BSP_PWM_Channel_t channel; ///< PWM输出通道
} BUZZER_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Exported functions prototypes -------------------------------------------- */
/**
* @brief
* @param buzzer
* @param channel PWM输出通道
* @return int8_t DEVICE_OK(0) DEVICE_ERR(-1)
* @note
*/
int8_t BUZZER_Init(BUZZER_t *buzzer, BSP_PWM_Channel_t channel);
/**
* @brief
* @param buzzer
* @return int8_t DEVICE_OK(0) DEVICE_ERR(-1)
* @note BUZZER_Set设置频率和占空比
*/
int8_t BUZZER_Start(BUZZER_t *buzzer);
/**
* @brief
* @param buzzer
* @return int8_t DEVICE_OK(0) DEVICE_ERR(-1)
*/
int8_t BUZZER_Stop(BUZZER_t *buzzer);
/**
* @brief
* @param buzzer
* @param freq (Hz)20Hz-20kHz
* @param duty_cycle (0.0-1.0)
* @return int8_t DEVICE_OK(0) DEVICE_ERR(-1)
* @note BUZZER_Start才能听到声音
*/
int8_t BUZZER_Set(BUZZER_t *buzzer, float freq, float duty_cycle);
/**
* @brief
* @param buzzer
* @param music (使MUSIC_t枚举)
* @return int8_t DEVICE_OK(0) DEVICE_ERR(-1)
* @note
*/
int8_t BUZZER_PlayMusic(BUZZER_t *buzzer, MUSIC_t music);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

51
User/device/device.h Normal file
View File

@ -0,0 +1,51 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
#define DEVICE_OK (0)
#define DEVICE_ERR (-1)
#define DEVICE_ERR_NULL (-2)
#define DEVICE_ERR_INITED (-3)
#define DEVICE_ERR_NO_DEV (-4)
/* AUTO GENERATED SIGNALS BEGIN */
#define SIGNAL_DR16_RAW_REDY (1u << 0)
#define SIGNAL_BMI088_ACCL_RAW_REDY (1u << 1)
#define SIGNAL_BMI088_GYRO_RAW_REDY (1u << 2)
#define SIGNAL_BMI088_ACCL_NEW_DATA (1u << 3)
#define SIGNAL_BMI088_GYRO_NEW_DATA (1u << 4)
/* AUTO GENERATED SIGNALS END */
/* USER SIGNALS BEGIN */
/* USER SIGNALS END */
/*设备层通用Header*/
typedef struct {
bool online;
uint64_t last_online_time;
} DEVICE_Header_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,31 @@
bmi088:
bsp_config:
BSP_GPIO_ACCL_CS: BSP_GPIO_ACCL_CS
BSP_GPIO_ACCL_INT: BSP_GPIO_ACCL_INT
BSP_GPIO_GYRO_CS: BSP_GPIO_GYRO_CS
BSP_GPIO_GYRO_INT: BSP_GPIO_GYRO_INT
BSP_SPI_BMI088: BSP_SPI_BMI088
enabled: true
buzzer:
bsp_config:
BSP_PWM_BUZZER: BSP_PWM_TIM2_CH1
enabled: true
dr16:
bsp_config:
BSP_UART_DR16: BSP_UART_DR16
enabled: true
motor:
bsp_config: {}
enabled: true
motor_dm:
bsp_config: {}
enabled: true
motor_lk:
bsp_config: {}
enabled: true
motor_lz:
bsp_config: {}
enabled: true
motor_rm:
bsp_config: {}
enabled: true

169
User/device/dr16.c Normal file
View File

@ -0,0 +1,169 @@
/*
DR16接收机
Example
DR16_Init(&dr16);
while (1) {
DR16_StartDmaRecv(&dr16);
if (DR16_WaitDmaCplt(20)) {
DR16_ParseData(&dr16);
} else {
DR16_Offline(&dr16);
}
}
*/
/* Includes ----------------------------------------------------------------- */
#include "dr16.h"
#include "bsp/uart.h"
#include "bsp/time.h"
#include "device.h"
#include <string.h>
#include <stdbool.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
#define DR16_CH_VALUE_MIN (364u)
#define DR16_CH_VALUE_MID (1024u)
#define DR16_CH_VALUE_MAX (1684u)
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static osThreadId_t thread_alert;
static bool inited = false;
/* Private function -------------------------------------------------------- */
static void DR16_RxCpltCallback(void) {
osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY);
}
static bool DR16_DataCorrupted(const DR16_t *dr16) {
if (dr16 == NULL) return DEVICE_ERR_NULL;
if ((dr16->raw_data.ch_r_x < DR16_CH_VALUE_MIN) ||
(dr16->raw_data.ch_r_x > DR16_CH_VALUE_MAX))
return DEVICE_ERR;
if ((dr16->raw_data.ch_r_y < DR16_CH_VALUE_MIN) ||
(dr16->raw_data.ch_r_y > DR16_CH_VALUE_MAX))
return DEVICE_ERR;
if ((dr16->raw_data.ch_l_x < DR16_CH_VALUE_MIN) ||
(dr16->raw_data.ch_l_x > DR16_CH_VALUE_MAX))
return DEVICE_ERR;
if ((dr16->raw_data.ch_l_y < DR16_CH_VALUE_MIN) ||
(dr16->raw_data.ch_l_y > DR16_CH_VALUE_MAX))
return DEVICE_ERR;
if (dr16->raw_data.sw_l == 0) return DEVICE_ERR;
if (dr16->raw_data.sw_r == 0) return DEVICE_ERR;
return DEVICE_OK;
}
/* Exported functions ------------------------------------------------------- */
int8_t DR16_Init(DR16_t *dr16) {
if (dr16 == NULL) return DEVICE_ERR_NULL;
if (inited) return DEVICE_ERR_INITED;
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
BSP_UART_RegisterCallback(BSP_UART_DR16, BSP_UART_RX_CPLT_CB,
DR16_RxCpltCallback);
inited = true;
return DEVICE_OK;
}
int8_t DR16_Restart(void) {
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_DR16));
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_DR16));
return DEVICE_OK;
}
int8_t DR16_StartDmaRecv(DR16_t *dr16) {
if (HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_DR16),
(uint8_t *)&(dr16->raw_data),
sizeof(dr16->raw_data)) == HAL_OK)
return DEVICE_OK;
return DEVICE_ERR;
}
bool DR16_WaitDmaCplt(uint32_t timeout) {
return (osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, timeout) ==
SIGNAL_DR16_RAW_REDY);
}
int8_t DR16_ParseData(DR16_t *dr16){
if (dr16 == NULL) return DEVICE_ERR_NULL;
if (DR16_DataCorrupted(dr16)) {
return DEVICE_ERR;
}
dr16->header.online = true;
dr16->header.last_online_time = BSP_TIME_Get_us();
memset(&(dr16->data), 0, sizeof(dr16->data));
float full_range = (float)(DR16_CH_VALUE_MAX - DR16_CH_VALUE_MIN);
// 解析摇杆数据
dr16->data.ch_r_x = 2.0f * ((float)dr16->raw_data.ch_r_x - DR16_CH_VALUE_MID) / full_range;
dr16->data.ch_r_y = 2.0f * ((float)dr16->raw_data.ch_r_y - DR16_CH_VALUE_MID) / full_range;
dr16->data.ch_l_x = 2.0f * ((float)dr16->raw_data.ch_l_x - DR16_CH_VALUE_MID) / full_range;
dr16->data.ch_l_y = 2.0f * ((float)dr16->raw_data.ch_l_y - DR16_CH_VALUE_MID) / full_range;
// 解析拨杆位置
dr16->data.sw_l = (DR16_SwitchPos_t)dr16->raw_data.sw_l;
dr16->data.sw_r = (DR16_SwitchPos_t)dr16->raw_data.sw_r;
// 解析鼠标数据
dr16->data.mouse.x = dr16->raw_data.x;
dr16->data.mouse.y = dr16->raw_data.y;
dr16->data.mouse.z = dr16->raw_data.z;
dr16->data.mouse.l_click = dr16->raw_data.press_l;
dr16->data.mouse.r_click = dr16->raw_data.press_r;
// 解析键盘按键 - 使用union简化代码
uint16_t key_value = dr16->raw_data.key;
// 解析键盘位映射W-B键位0-15
for (int i = DR16_KEY_W; i <= DR16_KEY_B; i++) {
dr16->data.keyboard.key[i] = (key_value & (1 << i)) != 0;
}
// 解析鼠标点击
dr16->data.keyboard.key[DR16_L_CLICK] = dr16->data.mouse.l_click;
dr16->data.keyboard.key[DR16_R_CLICK] = dr16->data.mouse.r_click;
// 解析第五通道
dr16->data.ch_res = 2.0f * ((float)dr16->raw_data.res - DR16_CH_VALUE_MID) / full_range;
return DEVICE_OK;
}
int8_t DR16_Offline(DR16_t *dr16){
if (dr16 == NULL) return DEVICE_ERR_NULL;
dr16->header.online = false;
memset(&(dr16->data), 0, sizeof(dr16->data));
return DEVICE_OK;
}
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */

117
User/device/dr16.h Normal file
View File

@ -0,0 +1,117 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <cmsis_os2.h>
#include "component/user_math.h"
#include "device.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef struct __packed {
uint16_t ch_r_x : 11;
uint16_t ch_r_y : 11;
uint16_t ch_l_x : 11;
uint16_t ch_l_y : 11;
uint8_t sw_r : 2;
uint8_t sw_l : 2;
int16_t x;
int16_t y;
int16_t z;
uint8_t press_l;
uint8_t press_r;
uint16_t key;
uint16_t res;
} DR16_RawData_t;
typedef enum {
DR16_SW_ERR = 0,
DR16_SW_UP = 1,
DR16_SW_MID = 3,
DR16_SW_DOWN = 2,
} DR16_SwitchPos_t;
/* 键盘按键值 */
typedef enum {
DR16_KEY_W = 0,
DR16_KEY_S,
DR16_KEY_A,
DR16_KEY_D,
DR16_KEY_SHIFT,
DR16_KEY_CTRL,
DR16_KEY_Q,
DR16_KEY_E,
DR16_KEY_R,
DR16_KEY_F,
DR16_KEY_G,
DR16_KEY_Z,
DR16_KEY_X,
DR16_KEY_C,
DR16_KEY_V,
DR16_KEY_B,
DR16_L_CLICK,
DR16_R_CLICK,
DR16_KEY_NUM,
} DR16_Key_t;
typedef struct {
float ch_l_x; /* 遥控器左侧摇杆横轴值,上为正 */
float ch_l_y; /* 遥控器左侧摇杆纵轴值,右为正 */
float ch_r_x; /* 遥控器右侧摇杆横轴值,上为正 */
float ch_r_y; /* 遥控器右侧摇杆纵轴值,右为正 */
float ch_res; /* 第五通道值 */
DR16_SwitchPos_t sw_r; /* 右侧拨杆位置 */
DR16_SwitchPos_t sw_l; /* 左侧拨杆位置 */
struct {
int16_t x;
int16_t y;
int16_t z;
bool l_click; /* 左键 */
bool r_click; /* 右键 */
} mouse; /* 鼠标值 */
union {
bool key[DR16_KEY_NUM]; /* 键盘按键值 */
uint16_t value; /* 键盘按键值的位映射 */
} keyboard;
uint16_t res; /* 保留,未启用 */
} DR16_Data_t;
typedef struct {
DEVICE_Header_t header;
DR16_RawData_t raw_data;
DR16_Data_t data;
} DR16_t;
/* Exported functions prototypes -------------------------------------------- */
int8_t DR16_Init(DR16_t *dr16);
int8_t DR16_Restart(void);
int8_t DR16_StartDmaRecv(DR16_t *dr16);
bool DR16_WaitDmaCplt(uint32_t timeout);
int8_t DR16_ParseData(DR16_t *dr16);
int8_t DR16_Offline(DR16_t *dr16);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

52
User/device/motor.c Normal file
View File

@ -0,0 +1,52 @@
/*
*/
/* Includes ----------------------------------------------------------------- */
#include "motor.h"
#include <string.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
/* Private function -------------------------------------------------------- */
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
/* Exported functions ------------------------------------------------------- */
float MOTOR_GetRotorAbsAngle(const MOTOR_t *motor) {
if (motor == NULL) return DEVICE_ERR_NULL;
return motor->feedback.rotor_abs_angle;
}
float MOTOR_GetRotorSpeed(const MOTOR_t *motor) {
if (motor == NULL) return DEVICE_ERR_NULL;
return motor->feedback.rotor_speed;
}
float MOTOR_GetTorqueCurrent(const MOTOR_t *motor) {
if (motor == NULL) return DEVICE_ERR_NULL;
return motor->feedback.torque_current;
}
float MOTOR_GetTemp(const MOTOR_t *motor) {
if (motor == NULL) return DEVICE_ERR_NULL;
return motor->feedback.temp;
}

68
User/device/motor.h Normal file
View File

@ -0,0 +1,68 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "device/device.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported constants ------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef struct {
float rotor_abs_angle; /* 转子绝对角度 */
float rotor_speed; /* 实际转子转速 */
float torque_current; /* 转矩电流 */
float temp; /* 温度 */
} MOTOR_Feedback_t;
/**
* @brief mit电机输出参数结构体
*/
typedef struct {
float torque; /* 目标力矩 */
float velocity; /* 目标速度 */
float angle; /* 目标位置 */
float kp; /* 位置环增益 */
float kd; /* 速度环增益 */
} MOTOR_MIT_Output_t;
/**
* @brief
*/
typedef struct {
float current; /* 目标电流 */
} MOTOR_Current_Output_t;
typedef struct {
DEVICE_Header_t header;
bool reverse; /* 是否反装 true表示反装 */
MOTOR_Feedback_t feedback;
} MOTOR_t;
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Exported functions prototypes -------------------------------------------- */
float MOTOR_GetRotorAbsAngle(const MOTOR_t *motor);
float MOTOR_GetRotorSpeed(const MOTOR_t *motor);
float MOTOR_GetTorqueCurrent(const MOTOR_t *motor);
float MOTOR_GetTemp(const MOTOR_t *motor);
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
#ifdef __cplusplus
}
#endif

496
User/device/motor_dm.c Normal file
View File

@ -0,0 +1,496 @@
#define MOTOR_DM_FLOAT_TO_INT_SIGNED(x, x_min, x_max, bits) \
((int32_t)roundf(((x) / ((x_max) - (x_min))) * (1 << (bits)) + (1 << ((bits) - 1))))
#define MOTOR_DM_INT_TO_FLOAT_SIGNED(x_int, x_min, x_max, bits) \
(((float)((int32_t)(x_int) - (1 << ((bits) - 1))) * ((x_max) - (x_min)) / (float)(1 << (bits))))
/* Includes ----------------------------------------------------------------- */
#include "device/motor_dm.h"
#include "bsp/mm.h"
#include "bsp/time.h"
#include "component/user_math.h"
#include "string.h"
#include "math.h"
/* Private constants -------------------------------------------------------- */
/* DM电机数据映射范围 */
#define DM_P_MIN (-12.56637f)
#define DM_P_MAX (12.56637f)
#define DM_V_MIN (-30.0f)
#define DM_V_MAX (30.0f)
#define DM_T_MIN (-12.0f)
#define DM_T_MAX (12.0f)
#define DM_KP_MIN (0.0f)
#define DM_KP_MAX (500.0f)
#define DM_KD_MIN (0.0f)
#define DM_KD_MAX (5.0f)
/* CAN ID偏移量 */
#define DM_CAN_ID_OFFSET_POS_VEL 0x100
#define DM_CAN_ID_OFFSET_VEL 0x200
/* Private macro ------------------------------------------------------------ */
#define FLOAT_TO_UINT(x, x_min, x_max, bits) \
(uint32_t)((x - x_min) * ((1 << bits) - 1) / (x_max - x_min))
#define UINT_TO_FLOAT(x_int, x_min, x_max, bits) \
((float)(x_int) * (x_max - x_min) / ((1 << bits) - 1) + x_min)
/* Private variables -------------------------------------------------------- */
static MOTOR_DM_CANManager_t *can_managers[BSP_CAN_NUM] = {NULL};
static int float_to_uint(float x_float, float x_min, float x_max, int bits)
{
/* Converts a float to an unsigned int, given range and number of bits */
float span = x_max - x_min;
float offset = x_min;
return (int) ((x_float-offset)*((float)((1<<bits)-1))/span);
}
static float uint_to_float(int x_int, float x_min, float x_max, int bits)
{
/* converts unsigned int to float, given range and number of bits */
float span = x_max - x_min;
float offset = x_min;
return ((float)x_int)*span/((float)((1<<bits)-1)) + offset;
}
/* Private function prototypes ---------------------------------------------- */
static int8_t MOTOR_DM_ParseFeedbackFrame(MOTOR_DM_t *motor, const uint8_t *data);
static int8_t MOTOR_DM_SendMITCmd(MOTOR_DM_t *motor, MOTOR_MIT_Output_t *output);
static int8_t MOTOR_DM_SendPosVelCmd(MOTOR_DM_t *motor, float pos, float vel);
static int8_t MOTOR_DM_SendVelCmd(MOTOR_DM_t *motor, float vel);
static MOTOR_DM_CANManager_t* MOTOR_DM_GetCANManager(BSP_CAN_t can);
/* Private functions -------------------------------------------------------- */
/**
* @brief DM电机反馈帧
* @param motor
* @param data CAN数据
* @return
*/
static int8_t MOTOR_DM_ParseFeedbackFrame(MOTOR_DM_t *motor, const uint8_t *data) {
if (motor == NULL || data == NULL) {
return DEVICE_ERR_NULL;
}
uint16_t p_int=(data[1]<<8)|data[2];
motor->motor.feedback.rotor_abs_angle = uint_to_float(p_int, DM_P_MIN, DM_P_MAX, 16); // (-12.5,12.5)
uint16_t v_int=(data[3]<<4)|(data[4]>>4);
motor->motor.feedback.rotor_speed = uint_to_float(v_int, DM_V_MIN, DM_V_MAX, 12); // (-30.0,30.0)
uint16_t t_int=((data[4]&0xF)<<8)|data[5];
motor->motor.feedback.torque_current = uint_to_float(t_int, DM_T_MIN, DM_T_MAX, 12); // (-12.0,12.0)
motor->motor.feedback.temp = (float)(data[6]);
while (motor->motor.feedback.rotor_abs_angle < 0) {
motor->motor.feedback.rotor_abs_angle += M_2PI;
}
while (motor->motor.feedback.rotor_abs_angle >= M_2PI) {
motor->motor.feedback.rotor_abs_angle -= M_2PI;
}
if (motor->param.reverse) {
motor->motor.feedback.rotor_abs_angle = M_2PI - motor->motor.feedback.rotor_abs_angle;
motor->motor.feedback.rotor_speed = -motor->motor.feedback.rotor_speed;
motor->motor.feedback.torque_current = -motor->motor.feedback.torque_current;
}
return DEVICE_OK;
}
/**
* @brief MIT模式控制命令
* @param motor
* @param output MIT控制参数
* @return
*/
static int8_t MOTOR_DM_SendMITCmd(MOTOR_DM_t *motor, MOTOR_MIT_Output_t *output) {
if (motor == NULL || output == NULL) {
return DEVICE_ERR_NULL;
}
uint8_t data[8];
uint16_t pos_tmp,vel_tmp,kp_tmp,kd_tmp,tor_tmp;
uint16_t id = motor->param.can_id;
pos_tmp = float_to_uint(output->angle, DM_P_MIN , DM_P_MAX, 16);
vel_tmp = float_to_uint(output->velocity, DM_V_MIN , DM_V_MAX, 12);
kp_tmp = float_to_uint(output->kp, DM_KP_MIN, DM_KP_MAX, 12);
kd_tmp = float_to_uint(output->kd, DM_KD_MIN, DM_KD_MAX, 12);
tor_tmp = float_to_uint(output->torque, DM_T_MIN , DM_T_MAX, 12);
/* 打包数据 */
data[0] = (pos_tmp >> 8);
data[1] = pos_tmp;
data[2] = (vel_tmp >> 4);
data[3] = ((vel_tmp&0xF)<<4)|(kp_tmp>>8);
data[4] = kp_tmp;
data[5] = (kd_tmp >> 4);
data[6] = ((kd_tmp&0xF)<<4)|(tor_tmp>>8);
data[7] = tor_tmp;
/* 发送CAN消息 */
BSP_CAN_StdDataFrame_t frame;
frame.id = motor->param.can_id;
frame.dlc = 8;
memcpy(frame.data, data, 8);
return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
/**
* @brief
* @param motor
* @param pos
* @param vel
* @return
*/
static int8_t MOTOR_DM_SendPosVelCmd(MOTOR_DM_t *motor, float pos, float vel) {
if (motor == NULL) {
return DEVICE_ERR_NULL;
}
uint8_t data[8] = {0};
/* 直接发送浮点数数据 */
memcpy(&data[0], &pos, 4); // 位置,低位在前
memcpy(&data[4], &vel, 4); // 速度,低位在前
/* 发送CAN消息ID为原ID+0x100 */
uint32_t can_id = DM_CAN_ID_OFFSET_POS_VEL + motor->param.can_id;
BSP_CAN_StdDataFrame_t frame;
frame.id = can_id;
frame.dlc = 8;
memcpy(frame.data, data, 8);
return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
/**
* @brief
* @param motor
* @param vel
* @return
*/
static int8_t MOTOR_DM_SendVelCmd(MOTOR_DM_t *motor, float vel) {
if (motor == NULL) {
return DEVICE_ERR_NULL;
}
uint8_t data[4] = {0};
/* 直接发送浮点数数据 */
memcpy(&data[0], &vel, 4); // 速度,低位在前
/* 发送CAN消息ID为原ID+0x200 */
uint32_t can_id = DM_CAN_ID_OFFSET_VEL + motor->param.can_id;
BSP_CAN_StdDataFrame_t frame;
frame.id = can_id;
frame.dlc = 4;
memcpy(frame.data, data, 4);
return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
/**
* @brief CAN总线的管理器
* @param can CAN总线
* @return CAN管理器指针
*/
static MOTOR_DM_CANManager_t* MOTOR_DM_GetCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) {
return NULL;
}
return can_managers[can];
}
/**
* @brief CAN管理器
* @param can CAN总线
* @return
*/
static int8_t MOTOR_DM_CreateCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) return DEVICE_ERR;
if (can_managers[can] != NULL) return DEVICE_OK;
can_managers[can] = (MOTOR_DM_CANManager_t*)BSP_Malloc(sizeof(MOTOR_DM_CANManager_t));
if (can_managers[can] == NULL) return DEVICE_ERR;
memset(can_managers[can], 0, sizeof(MOTOR_DM_CANManager_t));
can_managers[can]->can = can;
return DEVICE_OK;
}
/* Exported functions ------------------------------------------------------- */
/**
* @brief DM电机
* @param param
* @return
*/
int8_t MOTOR_DM_Register(MOTOR_DM_Param_t *param) {
if (param == NULL) {
return DEVICE_ERR_NULL;
}
/* 创建CAN管理器 */
if (MOTOR_DM_CreateCANManager(param->can) != DEVICE_OK) {
return DEVICE_ERR;
}
/* 获取CAN管理器 */
MOTOR_DM_CANManager_t *manager = MOTOR_DM_GetCANManager(param->can);
if (manager == NULL) {
return DEVICE_ERR;
}
/* 检查是否已注册 */
for (int i = 0; i < manager->motor_count; i++) {
if (manager->motors[i] && manager->motors[i]->param.master_id == param->master_id) {
return DEVICE_ERR_INITED;
}
}
/* 检查是否已达到最大数量 */
if (manager->motor_count >= MOTOR_DM_MAX_MOTORS) {
return DEVICE_ERR;
}
/* 分配内存 */
MOTOR_DM_t *motor = (MOTOR_DM_t *)BSP_Malloc(sizeof(MOTOR_DM_t));
if (motor == NULL) {
return DEVICE_ERR;
}
/* 初始化电机 */
memset(motor, 0, sizeof(MOTOR_DM_t));
memcpy(&motor->param, param, sizeof(MOTOR_DM_Param_t));
motor->motor.header.online = false;
motor->motor.reverse = param->reverse;
/* 注册CAN接收ID - DM电机使用Master ID接收反馈 */
uint16_t feedback_id = param->master_id;
if (BSP_CAN_RegisterId(param->can, feedback_id, 3) != BSP_OK) {
BSP_Free(motor);
return DEVICE_ERR;
}
/* 添加到管理器 */
manager->motors[manager->motor_count] = motor;
manager->motor_count++;
return DEVICE_OK;
}
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_DM_Update(MOTOR_DM_Param_t *param) {
if (param == NULL) {
return DEVICE_ERR_NULL;
}
MOTOR_DM_CANManager_t *manager = MOTOR_DM_GetCANManager(param->can);
if (manager == NULL) {
return DEVICE_ERR_NO_DEV;
}
/* 查找电机 */
MOTOR_DM_t *motor = NULL;
for (int i = 0; i < manager->motor_count; i++) {
if (manager->motors[i] && manager->motors[i]->param.master_id == param->master_id) {
motor = manager->motors[i];
break;
}
}
if (motor == NULL) {
return DEVICE_ERR_NO_DEV;
}
/* 主动接收CAN消息 */
uint16_t feedback_id = param->master_id;
BSP_CAN_Message_t rx_msg;
if (BSP_CAN_GetMessage(param->can, feedback_id, &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
uint64_t now_time = BSP_TIME_Get();
if (now_time - motor->motor.header.last_online_time > 100000) { // 100ms超时单位微秒
motor->motor.header.online = false;
}
return DEVICE_ERR;
}
motor->motor.header.online = true;
motor->motor.header.last_online_time = BSP_TIME_Get();
MOTOR_DM_ParseFeedbackFrame(motor, rx_msg.data);
return DEVICE_OK;
}
/**
* @brief
* @return
*/
int8_t MOTOR_DM_UpdateAll(void) {
int8_t ret = DEVICE_OK;
for (int can = 0; can < BSP_CAN_NUM; can++) {
MOTOR_DM_CANManager_t *manager = MOTOR_DM_GetCANManager((BSP_CAN_t)can);
if (manager == NULL) continue;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_DM_t *motor = manager->motors[i];
if (motor != NULL) {
if (MOTOR_DM_Update(&motor->param) != DEVICE_OK) {
ret = DEVICE_ERR;
}
}
}
}
return ret;
}
/**
* @brief MIT模式控制
* @param param
* @param output MIT控制参数
* @return
*/
int8_t MOTOR_DM_MITCtrl(MOTOR_DM_Param_t *param, MOTOR_MIT_Output_t *output) {
if (param == NULL || output == NULL) {
return DEVICE_ERR_NULL;
}
MOTOR_DM_t *motor = MOTOR_DM_GetMotor(param);
if (motor == NULL) {
return DEVICE_ERR_NO_DEV;
}
return MOTOR_DM_SendMITCmd(motor, output);
}
/**
* @brief
* @param param
* @param target_pos
* @param target_vel
* @return
*/
int8_t MOTOR_DM_PosVelCtrl(MOTOR_DM_Param_t *param, float target_pos, float target_vel) {
if (param == NULL) {
return DEVICE_ERR_NULL;
}
MOTOR_DM_t *motor = MOTOR_DM_GetMotor(param);
if (motor == NULL) {
return DEVICE_ERR_NO_DEV;
}
return MOTOR_DM_SendPosVelCmd(motor, target_pos, target_vel);
}
/**
* @brief
* @param param
* @param target_vel
* @return
*/
int8_t MOTOR_DM_VelCtrl(MOTOR_DM_Param_t *param, float target_vel) {
if (param == NULL) {
return DEVICE_ERR_NULL;
}
MOTOR_DM_t *motor = MOTOR_DM_GetMotor(param);
if (motor == NULL) {
return DEVICE_ERR_NO_DEV;
}
return MOTOR_DM_SendVelCmd(motor, target_vel);
}
/**
* @brief
* @param param
* @return
*/
MOTOR_DM_t* MOTOR_DM_GetMotor(MOTOR_DM_Param_t *param) {
if (param == NULL) {
return NULL;
}
MOTOR_DM_CANManager_t *manager = MOTOR_DM_GetCANManager(param->can);
if (manager == NULL) {
return NULL;
}
/* 查找对应的电机 */
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_DM_t *motor = manager->motors[i];
if (motor && motor->param.can == param->can &&
motor->param.master_id == param->master_id) {
return motor;
}
}
return NULL;
}
int8_t MOTOR_DM_Enable(MOTOR_DM_Param_t *param){
if (param == NULL) {
return DEVICE_ERR_NULL;
}
MOTOR_DM_t *motor = MOTOR_DM_GetMotor(param);
if (motor == NULL) {
return DEVICE_ERR_NO_DEV;
}
BSP_CAN_StdDataFrame_t frame;
frame.id = motor->param.can_id;
frame.dlc = 8;
frame.data[0] = 0XFF;
frame.data[1] = 0xFF;
frame.data[2] = 0xFF;
frame.data[3] = 0xFF;
frame.data[4] = 0xFF;
frame.data[5] = 0xFF;
frame.data[6] = 0xFF;
frame.data[7] = 0xFC;
return BSP_CAN_TransmitStdDataFrame(motor->param.can, &frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
/**
* @brief 使0
* @param param
* @return
*/
int8_t MOTOR_DM_Relax(MOTOR_DM_Param_t *param) {
if (param == NULL) {
return DEVICE_ERR_NULL;
}
MOTOR_MIT_Output_t output = {0};
return MOTOR_DM_MITCtrl(param, &output);
}
/**
* @brief 使线线false
* @param param
* @return
*/
int8_t MOTOR_DM_Offine(MOTOR_DM_Param_t *param) {
if (param == NULL) {
return DEVICE_ERR_NULL;
}
MOTOR_DM_t *motor = MOTOR_DM_GetMotor(param);
if (motor == NULL) {
return DEVICE_ERR_NO_DEV;
}
motor->motor.header.online = false;
return DEVICE_OK;
}

98
User/device/motor_dm.h Normal file
View File

@ -0,0 +1,98 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "device/device.h"
#include "device/motor.h"
#include "bsp/can.h"
/* Exported constants ------------------------------------------------------- */
#define MOTOR_DM_MAX_MOTORS 32
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef enum {
MOTOR_DM_J4310,
} MOTOR_DM_Module_t;
/*每个电机需要的参数*/
typedef struct {
BSP_CAN_t can;
uint16_t master_id; /* 主站ID用于发送控制命令 */
uint16_t can_id; /* 反馈ID用于接收电机反馈 */
MOTOR_DM_Module_t module;
bool reverse;
} MOTOR_DM_Param_t;
/*电机实例*/
typedef struct{
MOTOR_DM_Param_t param;
MOTOR_t motor;
} MOTOR_DM_t;
/*CAN管理器管理一个CAN总线上所有的电机*/
typedef struct {
BSP_CAN_t can;
MOTOR_DM_t *motors[MOTOR_DM_MAX_MOTORS];
uint8_t motor_count;
} MOTOR_DM_CANManager_t;
/* Exported functions prototypes -------------------------------------------- */
/**
* @brief LK电机
* @param param
* @return
*/
int8_t MOTOR_DM_Register(MOTOR_DM_Param_t *param);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_DM_Update(MOTOR_DM_Param_t *param);
/**
* @brief
* @return
*/
int8_t MOTOR_DM_UpdateAll(void);
int8_t MOTOR_DM_MITCtrl(MOTOR_DM_Param_t *param, MOTOR_MIT_Output_t *output);
int8_t MOTOR_DM_PosVelCtrl(MOTOR_DM_Param_t *param, float target_pos, float target_vel);
int8_t MOTOR_DM_VelCtrl(MOTOR_DM_Param_t *param, float target_vel);
/**
* @brief
* @param param
* @return
*/
MOTOR_DM_t* MOTOR_DM_GetMotor(MOTOR_DM_Param_t *param);
int8_t MOTOR_DM_Enable(MOTOR_DM_Param_t *param);
/**
* @brief 使0
* @param param
* @return
*/
int8_t MOTOR_DM_Relax(MOTOR_DM_Param_t *param);
/**
* @brief 使线线false
* @param param
* @return
*/
int8_t MOTOR_DM_Offine(MOTOR_DM_Param_t *param);
#ifdef __cplusplus
}
#endif

329
User/device/motor_lk.c Normal file
View File

@ -0,0 +1,329 @@
/*
LK电机驱动
*/
/* Includes ----------------------------------------------------------------- */
#include "motor_lk.h"
#include <stdbool.h>
#include <string.h>
#include "bsp/can.h"
#include "bsp/mm.h"
#include "bsp/time.h"
#include "component/user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
#define LK_CTRL_ID_BASE (0x140)
#define LK_FB_ID_BASE (0x240)
// LK电机命令字节定义
#define LK_CMD_FEEDBACK (0x9C) // 反馈命令字节
#define LK_CMD_MOTOR_OFF (0x80) // 电机关闭命令
#define LK_CMD_MOTOR_ON (0x88) // 电机运行命令
#define LK_CMD_TORQUE_CTRL (0xA1) // 转矩闭环控制命令
// LK电机参数定义
#define LK_CURR_LSB_MF (33.0f / 4096.0f) // MF电机转矩电流分辨率 A/LSB
#define LK_CURR_LSB_MG (66.0f / 4096.0f) // MG电机转矩电流分辨率 A/LSB
#define LK_POWER_RANGE_MS (1000) // MS电机功率范围 ±1000
#define LK_TORQUE_RANGE (2048) // 转矩控制值范围 ±2048
#define LK_TORQUE_CURRENT_MF (16.5f) // MF电机最大转矩电流 A
#define LK_TORQUE_CURRENT_MG (33.0f) // MG电机最大转矩电流 A
#define MOTOR_TX_BUF_SIZE (8)
#define MOTOR_RX_BUF_SIZE (8)
// 编码器分辨率定义
#define LK_ENC_14BIT_MAX (16383) // 14位编码器最大值
#define LK_ENC_15BIT_MAX (32767) // 15位编码器最大值
#define LK_ENC_16BIT_MAX (65535) // 16位编码器最大值
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
static MOTOR_LK_CANManager_t *can_managers[BSP_CAN_NUM] = {NULL};
/* Private functions -------------------------------------------------------- */
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
static float MOTOR_LK_GetCurrentLSB(MOTOR_LK_Module_t module) {
switch (module) {
case MOTOR_LK_MF9025:
case MOTOR_LK_MF9035:
return LK_CURR_LSB_MF;
default:
return LK_CURR_LSB_MG; // 默认使用MG的分辨率
}
}
static uint16_t MOTOR_LK_GetEncoderMax(MOTOR_LK_Module_t module) {
// 根据电机型号返回编码器最大值这里假设都使用16位编码器
// 实际使用时需要根据具体电机型号配置
return LK_ENC_16BIT_MAX;
}
static MOTOR_LK_CANManager_t* MOTOR_LK_GetCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) return NULL;
return can_managers[can];
}
static int8_t MOTOR_LK_CreateCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) return DEVICE_ERR;
if (can_managers[can] != NULL) return DEVICE_OK;
can_managers[can] = (MOTOR_LK_CANManager_t*)BSP_Malloc(sizeof(MOTOR_LK_CANManager_t));
if (can_managers[can] == NULL) return DEVICE_ERR;
memset(can_managers[can], 0, sizeof(MOTOR_LK_CANManager_t));
can_managers[can]->can = can;
return DEVICE_OK;
}
static void MOTOR_LK_Decode(MOTOR_LK_t *motor, BSP_CAN_Message_t *msg) {
// 检查命令字节是否为反馈命令
if (msg->data[0] != LK_CMD_FEEDBACK) {
// 如果不是标准反馈命令,可能是其他格式的数据
// 临时跳过命令字节检查,直接解析数据
// return;
}
// 解析温度 (DATA[1])
motor->motor.feedback.temp = (int8_t)msg->data[1];
// 解析转矩电流值或功率值 (DATA[2], DATA[3])
int16_t raw_current_or_power = (int16_t)((msg->data[3] << 8) | msg->data[2]);
// 根据电机类型解析电流或功率
switch (motor->param.module) {
case MOTOR_LK_MF9025:
case MOTOR_LK_MF9035:
motor->motor.feedback.torque_current = raw_current_or_power * MOTOR_LK_GetCurrentLSB(motor->param.module);
break;
default:
motor->motor.feedback.torque_current = (float)raw_current_or_power;
break;
}
// 解析转速 (DATA[4], DATA[5]) - 单位1dps/LSB
int16_t raw_speed = (int16_t)((msg->data[5] << 8) | msg->data[4]);
motor->motor.feedback.rotor_speed = motor->param.reverse ? -raw_speed : raw_speed;
// 解析编码器值 (DATA[6], DATA[7])
uint16_t raw_encoder = (uint16_t)((msg->data[7] << 8) | msg->data[6]);
uint16_t encoder_max = MOTOR_LK_GetEncoderMax(motor->param.module);
// 将编码器值转换为弧度 (0 ~ 2π)
float angle = (float)raw_encoder / (float)encoder_max * M_2PI;
motor->motor.feedback.rotor_abs_angle = motor->param.reverse ? (M_2PI - angle) : angle;
}
/* Exported functions ------------------------------------------------------- */
int8_t MOTOR_LK_Register(MOTOR_LK_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
if (MOTOR_LK_CreateCANManager(param->can) != DEVICE_OK) return DEVICE_ERR;
MOTOR_LK_CANManager_t *manager = MOTOR_LK_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR;
// 检查是否已注册
for (int i = 0; i < manager->motor_count; i++) {
if (manager->motors[i] && manager->motors[i]->param.id == param->id) {
return DEVICE_ERR_INITED;
}
}
// 检查数量
if (manager->motor_count >= MOTOR_LK_MAX_MOTORS) return DEVICE_ERR;
// 创建新电机实例
MOTOR_LK_t *new_motor = (MOTOR_LK_t*)BSP_Malloc(sizeof(MOTOR_LK_t));
if (new_motor == NULL) return DEVICE_ERR;
memcpy(&new_motor->param, param, sizeof(MOTOR_LK_Param_t));
memset(&new_motor->motor, 0, sizeof(MOTOR_t));
new_motor->motor.reverse = param->reverse;
// 对于某些LK电机反馈数据可能通过命令ID发送
// 根据实际测试使用命令ID接收反馈数据
uint16_t feedback_id = param->id; // 使用命令ID作为反馈ID
// 注册CAN接收ID
if (BSP_CAN_RegisterId(param->can, feedback_id, 3) != BSP_OK) {
BSP_Free(new_motor);
return DEVICE_ERR;
}
manager->motors[manager->motor_count] = new_motor;
manager->motor_count++;
return DEVICE_OK;
}
int8_t MOTOR_LK_Update(MOTOR_LK_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
MOTOR_LK_CANManager_t *manager = MOTOR_LK_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR_NO_DEV;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_LK_t *motor = manager->motors[i];
if (motor && motor->param.id == param->id) {
// 对于某些LK电机反馈数据通过命令ID发送
uint16_t feedback_id = param->id;
BSP_CAN_Message_t rx_msg;
if (BSP_CAN_GetMessage(param->can, feedback_id, &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
uint64_t now_time = BSP_TIME_Get();
if (now_time - motor->motor.header.last_online_time > 1000) {
motor->motor.header.online = false;
return DEVICE_ERR_NO_DEV;
}
return DEVICE_ERR;
}
motor->motor.header.online = true;
motor->motor.header.last_online_time = BSP_TIME_Get();
MOTOR_LK_Decode(motor, &rx_msg);
return DEVICE_OK;
}
}
return DEVICE_ERR_NO_DEV;
}
int8_t MOTOR_LK_UpdateAll(void) {
int8_t ret = DEVICE_OK;
for (int can = 0; can < BSP_CAN_NUM; can++) {
MOTOR_LK_CANManager_t *manager = MOTOR_LK_GetCANManager((BSP_CAN_t)can);
if (manager == NULL) continue;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_LK_t *motor = manager->motors[i];
if (motor != NULL) {
if (MOTOR_LK_Update(&motor->param) != DEVICE_OK) {
ret = DEVICE_ERR;
}
}
}
}
return ret;
}
int8_t MOTOR_LK_SetOutput(MOTOR_LK_Param_t *param, float value) {
if (param == NULL) return DEVICE_ERR_NULL;
MOTOR_LK_CANManager_t *manager = MOTOR_LK_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR_NO_DEV;
// 限制输出值范围
if (value > 1.0f) value = 1.0f;
if (value < -1.0f) value = -1.0f;
MOTOR_LK_t *motor = MOTOR_LK_GetMotor(param);
if (motor == NULL) return DEVICE_ERR_NO_DEV;
// 根据反转参数调整输出
float output = param->reverse ? -value : value;
// 转矩闭环控制命令 - 将输出值转换为转矩控制值
int16_t torque_control = (int16_t)(output * (float)LK_TORQUE_RANGE);
// 构建CAN帧
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = param->id;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
tx_frame.data[0] = LK_CMD_TORQUE_CTRL;
tx_frame.data[1] = 0x00;
tx_frame.data[2] = 0x00;
tx_frame.data[3] = 0x00;
tx_frame.data[4] = (uint8_t)(torque_control & 0xFF);
tx_frame.data[5] = (uint8_t)((torque_control >> 8) & 0xFF);
tx_frame.data[6] = 0x00;
tx_frame.data[7] = 0x00;
return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
int8_t MOTOR_LK_Ctrl(MOTOR_LK_Param_t *param) {
// 对于LK电机每次设置输出时就直接发送控制命令
// 这个函数可以用于发送其他控制命令,如电机开启/关闭
return DEVICE_OK;
}
int8_t MOTOR_LK_MotorOn(MOTOR_LK_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = param->id;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
// 电机运行命令
tx_frame.data[0] = LK_CMD_MOTOR_ON; // 命令字节
tx_frame.data[1] = 0x00;
tx_frame.data[2] = 0x00;
tx_frame.data[3] = 0x00;
tx_frame.data[4] = 0x00;
tx_frame.data[5] = 0x00;
tx_frame.data[6] = 0x00;
tx_frame.data[7] = 0x00;
return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
int8_t MOTOR_LK_MotorOff(MOTOR_LK_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = param->id;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
// 电机关闭命令
tx_frame.data[0] = LK_CMD_MOTOR_OFF; // 命令字节
tx_frame.data[1] = 0x00;
tx_frame.data[2] = 0x00;
tx_frame.data[3] = 0x00;
tx_frame.data[4] = 0x00;
tx_frame.data[5] = 0x00;
tx_frame.data[6] = 0x00;
tx_frame.data[7] = 0x00;
return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
MOTOR_LK_t* MOTOR_LK_GetMotor(MOTOR_LK_Param_t *param) {
if (param == NULL) return NULL;
MOTOR_LK_CANManager_t *manager = MOTOR_LK_GetCANManager(param->can);
if (manager == NULL) return NULL;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_LK_t *motor = manager->motors[i];
if (motor && motor->param.id == param->id) {
return motor;
}
}
return NULL;
}
int8_t MOTOR_LK_Relax(MOTOR_LK_Param_t *param) {
return MOTOR_LK_SetOutput(param, 0.0f);
}
int8_t MOTOR_LK_Offine(MOTOR_LK_Param_t *param) {
MOTOR_LK_t *motor = MOTOR_LK_GetMotor(param);
if (motor) {
motor->motor.header.online = false;
return DEVICE_OK;
}
return DEVICE_ERR_NO_DEV;
}

119
User/device/motor_lk.h Normal file
View File

@ -0,0 +1,119 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "device/device.h"
#include "device/motor.h"
#include "bsp/can.h"
/* Exported constants ------------------------------------------------------- */
#define MOTOR_LK_MAX_MOTORS 32
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef enum {
MOTOR_LK_MF9025,
MOTOR_LK_MF9035,
} MOTOR_LK_Module_t;
/*每个电机需要的参数*/
typedef struct {
BSP_CAN_t can;
uint16_t id;
MOTOR_LK_Module_t module;
bool reverse;
} MOTOR_LK_Param_t;
/*电机实例*/
typedef struct{
MOTOR_LK_Param_t param;
MOTOR_t motor;
} MOTOR_LK_t;
/*CAN管理器管理一个CAN总线上所有的电机*/
typedef struct {
BSP_CAN_t can;
MOTOR_LK_t *motors[MOTOR_LK_MAX_MOTORS];
uint8_t motor_count;
} MOTOR_LK_CANManager_t;
/* Exported functions prototypes -------------------------------------------- */
/**
* @brief LK电机
* @param param
* @return
*/
int8_t MOTOR_LK_Register(MOTOR_LK_Param_t *param);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_LK_Update(MOTOR_LK_Param_t *param);
/**
* @brief
* @param param
* @param value [-1.0, 1.0]
* @return
*/
int8_t MOTOR_LK_SetOutput(MOTOR_LK_Param_t *param, float value);
/**
* @brief CAN可以控制多个电机
* @param param
* @return
*/
int8_t MOTOR_LK_Ctrl(MOTOR_LK_Param_t *param);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_LK_MotorOn(MOTOR_LK_Param_t *param);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_LK_MotorOff(MOTOR_LK_Param_t *param);
/**
* @brief
* @param param
* @return
*/
MOTOR_LK_t* MOTOR_LK_GetMotor(MOTOR_LK_Param_t *param);
/**
* @brief 使0
* @param param
* @return
*/
int8_t MOTOR_LK_Relax(MOTOR_LK_Param_t *param);
/**
* @brief 使线线false
* @param param
* @return
*/
int8_t MOTOR_LK_Offine(MOTOR_LK_Param_t *param);
/**
* @brief
* @param
* @return
*/
int8_t MOTOR_LK_UpdateAll(void);
#ifdef __cplusplus
}
#endif

440
User/device/motor_lz.c Normal file
View File

@ -0,0 +1,440 @@
/*
- CAN 2.01Mbps
- (29ID)
- ID格式Bit28~24() + Bit23~8(2) + Bit7~0()
*/
/* Includes ----------------------------------------------------------------- */
#include "motor_lz.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "bsp/can.h"
#include "bsp/mm.h"
#include "bsp/time.h"
#include "component/user_math.h"
/* Private define ----------------------------------------------------------- */
// 灵足电机协议参数
#define LZ_ANGLE_RANGE_RAD (12.57f) /* 角度范围 ±12.57 rad */
#define LZ_VELOCITY_RANGE_RAD_S (20.0f) /* 角速度范围 ±20 rad/s */
#define LZ_TORQUE_RANGE_NM (60.0f) /* 力矩范围 ±60 Nm */
#define LZ_KP_MAX (5000.0f) /* Kp最大值 */
#define LZ_KD_MAX (100.0f) /* Kd最大值 */
#define LZ_RAW_VALUE_MAX (65535) /* 16位原始值最大值 */
#define LZ_TEMP_SCALE (10.0f) /* 温度缩放因子 */
#define LZ_MAX_RECOVER_DIFF_RAD (0.28f)
#define MOTOR_TX_BUF_SIZE (8)
#define MOTOR_RX_BUF_SIZE (8)
/* Private macro ------------------------------------------------------------ */
MOTOR_LZ_MotionParam_t lz_relax_param = {
.target_angle = 0.0f,
.target_velocity = 0.0f,
.kp = 0.0f,
.kd = 0.0f,
.torque = 0.0f,
};
/* Private typedef ---------------------------------------------------------- */
/* Private variables -------------------------------------------------------- */
static MOTOR_LZ_CANManager_t *can_managers[BSP_CAN_NUM] = {NULL};
/* Private function prototypes ---------------------------------------------- */
static MOTOR_LZ_CANManager_t* MOTOR_LZ_GetCANManager(BSP_CAN_t can);
static int8_t MOTOR_LZ_CreateCANManager(BSP_CAN_t can);
static void MOTOR_LZ_Decode(MOTOR_LZ_t *motor, BSP_CAN_Message_t *msg);
static uint32_t MOTOR_LZ_BuildExtID(MOTOR_LZ_CmdType_t cmd_type, uint16_t data2, uint8_t target_id);
static uint16_t MOTOR_LZ_FloatToRaw(float value, float max_value);
static float MOTOR_LZ_RawToFloat(uint16_t raw_value, float max_value);
static int8_t MOTOR_LZ_SendExtFrame(BSP_CAN_t can, uint32_t ext_id, uint8_t *data, uint8_t dlc);
static uint32_t MOTOR_LZ_IdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type);
/* Private functions -------------------------------------------------------- */
/**
* @brief CAN管理器
*/
static MOTOR_LZ_CANManager_t* MOTOR_LZ_GetCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) return NULL;
return can_managers[can];
}
/**
* @brief CAN管理器
*/
static int8_t MOTOR_LZ_CreateCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) return DEVICE_ERR;
if (can_managers[can] != NULL) return DEVICE_OK;
can_managers[can] = (MOTOR_LZ_CANManager_t*)BSP_Malloc(sizeof(MOTOR_LZ_CANManager_t));
if (can_managers[can] == NULL) return DEVICE_ERR;
memset(can_managers[can], 0, sizeof(MOTOR_LZ_CANManager_t));
can_managers[can]->can = can;
return DEVICE_OK;
}
/**
* @brief ID
*/
static uint32_t MOTOR_LZ_BuildExtID(MOTOR_LZ_CmdType_t cmd_type, uint16_t data2, uint8_t target_id) {
uint32_t ext_id = 0;
ext_id |= ((uint32_t)cmd_type & 0x1F) << 24; // Bit28~24: 通信类型
ext_id |= ((uint32_t)data2 & 0xFFFF) << 8; // Bit23~8: 数据区2
ext_id |= ((uint32_t)target_id & 0xFF); // Bit7~0: 目标地址
return ext_id;
}
/**
* @brief -max_value ~ +max_value
*/
static uint16_t MOTOR_LZ_FloatToRaw(float value, float max_value) {
// 限制范围
if (value > max_value) value = max_value;
if (value < -max_value) value = -max_value;
// 转换为0~65535范围对应-max_value~max_value
return (uint16_t)((value + max_value) / (2.0f * max_value) * (float)LZ_RAW_VALUE_MAX);
}
/**
* @brief 0 ~ +max_value
*/
static uint16_t MOTOR_LZ_FloatToRawPositive(float value, float max_value) {
// 限制范围
if (value > max_value) value = max_value;
if (value < 0.0f) value = 0.0f;
// 转换为0~65535范围对应0~max_value
return (uint16_t)(value / max_value * (float)LZ_RAW_VALUE_MAX);
}
/**
* @brief
*/
static float MOTOR_LZ_RawToFloat(uint16_t raw_value, float max_value) {
// 将0~65535范围转换为-max_value~max_value
return ((float)raw_value / (float)LZ_RAW_VALUE_MAX) * (2.0f * max_value) - max_value;
}
/**
* @brief
*/
static int8_t MOTOR_LZ_SendExtFrame(BSP_CAN_t can, uint32_t ext_id, uint8_t *data, uint8_t dlc) {
BSP_CAN_ExtDataFrame_t tx_frame;
tx_frame.id = ext_id;
tx_frame.dlc = dlc;
if (data != NULL) {
memcpy(tx_frame.data, data, dlc);
} else {
memset(tx_frame.data, 0, dlc);
}
return BSP_CAN_TransmitExtDataFrame(can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
/**
* @brief ID解析器
* @param original_id CAN ID29
* @param frame_type
* @return ID
*
* ID格式
* Bit28~24: (0x1=, 0x2=, 0x3=使, 0x4=, 0x6=)
* Bit23~8: 2 ()
* Bit7~0: (CAN ID)
*/
static uint32_t MOTOR_LZ_IdParser(uint32_t original_id, BSP_CAN_FrameType_t frame_type) {
// 只处理扩展数据帧
if (frame_type != BSP_CAN_FRAME_EXT_DATA) {
return original_id; // 非扩展帧直接返回原始ID
}
// 解析扩展ID各个字段
uint8_t cmd_type = (original_id >> 24) & 0x1F; // Bit28~24: 通信类型
uint16_t data2 = (original_id >> 8) & 0xFFFF; // Bit23~8: 数据区2
uint8_t host_id = (uint8_t)(original_id & 0xFF); // Bit7~0: 主机CAN ID
// 对于反馈数据帧,我们使用特殊的解析规则
if (cmd_type == MOTOR_LZ_CMD_FEEDBACK) {
// 反馈数据的data2字段包含
// Bit8~15: 当前电机CAN ID
// Bit16~21: 故障信息
// Bit22~23: 模式状态
uint8_t motor_can_id = data2 & 0xFF; // bit8~15: 当前电机CAN ID
// 返回格式化的ID便于匹配
// 格式0x02HHMMTT (02=反馈命令, HH=主机ID, MM=电机ID, TT=主机ID)
return (0x02000000) | (host_id << 16) | (motor_can_id << 8) | host_id;
}
// 对于其他命令类型直接返回原始ID
return original_id;
}
/**
* @brief
*/
static void MOTOR_LZ_Decode(MOTOR_LZ_t *motor, BSP_CAN_Message_t *msg) {
if (motor == NULL || msg == NULL) return;
uint8_t cmd_type = (msg->original_id >> 24) & 0x1F;
if (cmd_type != MOTOR_LZ_CMD_FEEDBACK) return;
uint16_t id_data2 = (msg->original_id >> 8) & 0xFFFF;
uint8_t motor_can_id = id_data2 & 0xFF;
uint8_t fault_info = (id_data2 >> 8) & 0x3F;
uint8_t mode_state = (id_data2 >> 14) & 0x03;
motor->lz_feedback.motor_can_id = motor_can_id;
motor->lz_feedback.fault.under_voltage = (fault_info & 0x01) != 0;
motor->lz_feedback.fault.driver_fault = (fault_info & 0x02) != 0;
motor->lz_feedback.fault.over_temp = (fault_info & 0x04) != 0;
motor->lz_feedback.fault.encoder_fault = (fault_info & 0x08) != 0;
motor->lz_feedback.fault.stall_overload = (fault_info & 0x10) != 0;
motor->lz_feedback.fault.uncalibrated = (fault_info & 0x20) != 0;
motor->lz_feedback.state = (MOTOR_LZ_State_t)mode_state;
// 反馈解码并自动反向
uint16_t raw_angle = (uint16_t)((msg->data[0] << 8) | msg->data[1]);
float angle = MOTOR_LZ_RawToFloat(raw_angle, LZ_ANGLE_RANGE_RAD);
uint16_t raw_velocity = (uint16_t)((msg->data[2] << 8) | msg->data[3]);
float velocity = MOTOR_LZ_RawToFloat(raw_velocity, LZ_VELOCITY_RANGE_RAD_S);
uint16_t raw_torque = (uint16_t)((msg->data[4] << 8) | msg->data[5]);
float torque = MOTOR_LZ_RawToFloat(raw_torque, LZ_TORQUE_RANGE_NM);
while (angle <0){
angle += M_2PI;
}
while (angle > M_2PI){
angle -= M_2PI;
}
// 自动反向
if (motor->param.reverse) {
angle = M_2PI - angle;
velocity = -velocity;
torque = -torque;
}
motor->lz_feedback.current_angle = angle;
motor->lz_feedback.current_velocity = velocity;
motor->lz_feedback.current_torque = torque;
uint16_t raw_temp = (uint16_t)((msg->data[6] << 8) | msg->data[7]);
motor->lz_feedback.temperature = (float)raw_temp / LZ_TEMP_SCALE;
motor->motor.feedback.rotor_abs_angle = angle;
motor->motor.feedback.rotor_speed = velocity;
motor->motor.feedback.torque_current = torque;
motor->motor.feedback.temp = (int8_t)motor->lz_feedback.temperature;
motor->motor.header.online = true;
motor->motor.header.last_online_time = BSP_TIME_Get();
}
/* Exported functions ------------------------------------------------------- */
/**
* @brief
* @return
*/
int8_t MOTOR_LZ_Init(void) {
// 注册灵足电机专用的ID解析器
return BSP_CAN_RegisterIdParser(MOTOR_LZ_IdParser) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
int8_t MOTOR_LZ_Register(MOTOR_LZ_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
if (MOTOR_LZ_CreateCANManager(param->can) != DEVICE_OK) return DEVICE_ERR;
MOTOR_LZ_CANManager_t *manager = MOTOR_LZ_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR;
// 检查是否已注册
for (int i = 0; i < manager->motor_count; i++) {
if (manager->motors[i] && manager->motors[i]->param.motor_id == param->motor_id) {
return DEVICE_ERR; // 已注册
}
}
// 检查数量
if (manager->motor_count >= MOTOR_LZ_MAX_MOTORS) return DEVICE_ERR;
// 创建新电机实例
MOTOR_LZ_t *new_motor = (MOTOR_LZ_t*)BSP_Malloc(sizeof(MOTOR_LZ_t));
if (new_motor == NULL) return DEVICE_ERR;
memcpy(&new_motor->param, param, sizeof(MOTOR_LZ_Param_t));
memset(&new_motor->motor, 0, sizeof(MOTOR_t));
memset(&new_motor->lz_feedback, 0, sizeof(MOTOR_LZ_Feedback_t));
memset(&new_motor->motion_param, 0, sizeof(MOTOR_LZ_MotionParam_t));
new_motor->motor.reverse = param->reverse;
// 注册CAN接收ID - 使用解析后的反馈数据ID
// 构建反馈数据的原始扩展ID
// 反馈数据data2包含电机ID(bit8~15)target_id是主机ID
uint32_t original_feedback_id = MOTOR_LZ_BuildExtID(MOTOR_LZ_CMD_FEEDBACK, param->motor_id, param->host_id);
// 通过ID解析器得到解析后的ID
uint32_t parsed_feedback_id = MOTOR_LZ_IdParser(original_feedback_id, BSP_CAN_FRAME_EXT_DATA);
if (BSP_CAN_RegisterId(param->can, parsed_feedback_id, 3) != BSP_OK) {
BSP_Free(new_motor);
return DEVICE_ERR;
}
manager->motors[manager->motor_count] = new_motor;
manager->motor_count++;
return DEVICE_OK;
}
int8_t MOTOR_LZ_Update(MOTOR_LZ_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
MOTOR_LZ_CANManager_t *manager = MOTOR_LZ_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR_NO_DEV;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_LZ_t *motor = manager->motors[i];
if (motor && motor->param.motor_id == param->motor_id) {
// 获取反馈数据 - 使用解析后的ID
uint32_t original_feedback_id = MOTOR_LZ_BuildExtID(MOTOR_LZ_CMD_FEEDBACK, param->motor_id, param->host_id);
uint32_t parsed_feedback_id = MOTOR_LZ_IdParser(original_feedback_id, BSP_CAN_FRAME_EXT_DATA);
BSP_CAN_Message_t msg;
while (BSP_CAN_GetMessage(param->can, parsed_feedback_id, &msg, 0) == BSP_OK) {
MOTOR_LZ_Decode(motor, &msg);
}
return DEVICE_OK;
}
}
return DEVICE_ERR_NO_DEV;
}
int8_t MOTOR_LZ_UpdateAll(void) {
int8_t ret = DEVICE_OK;
for (int can = 0; can < BSP_CAN_NUM; can++) {
MOTOR_LZ_CANManager_t *manager = MOTOR_LZ_GetCANManager((BSP_CAN_t)can);
if (manager == NULL) continue;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_LZ_t *motor = manager->motors[i];
if (motor) {
if (MOTOR_LZ_Update(&motor->param) != DEVICE_OK) {
ret = DEVICE_ERR;
}
}
}
}
return ret;
}
int8_t MOTOR_LZ_MotionControl(MOTOR_LZ_Param_t *param, MOTOR_LZ_MotionParam_t *motion_param) {
if (param == NULL || motion_param == NULL) return DEVICE_ERR_NULL;
MOTOR_LZ_t *motor = MOTOR_LZ_GetMotor(param);
if (motor == NULL) return DEVICE_ERR_NO_DEV;
// 自动反向控制
MOTOR_LZ_MotionParam_t send_param = *motion_param;
if (param->reverse) {
send_param.target_angle = -send_param.target_angle;
send_param.target_velocity = -send_param.target_velocity;
send_param.torque = -send_param.torque;
}
memcpy(&motor->motion_param, motion_param, sizeof(MOTOR_LZ_MotionParam_t));
uint16_t raw_torque = MOTOR_LZ_FloatToRaw(send_param.torque, LZ_TORQUE_RANGE_NM);
uint32_t ext_id = MOTOR_LZ_BuildExtID(MOTOR_LZ_CMD_MOTION, raw_torque, param->motor_id);
uint8_t data[8];
uint16_t raw_angle = MOTOR_LZ_FloatToRaw(send_param.target_angle, LZ_ANGLE_RANGE_RAD);
data[0] = (raw_angle >> 8) & 0xFF;
data[1] = raw_angle & 0xFF;
uint16_t raw_velocity = MOTOR_LZ_FloatToRaw(send_param.target_velocity, LZ_VELOCITY_RANGE_RAD_S);
data[2] = (raw_velocity >> 8) & 0xFF;
data[3] = raw_velocity & 0xFF;
uint16_t raw_kp = MOTOR_LZ_FloatToRawPositive(send_param.kp, LZ_KP_MAX);
data[4] = (raw_kp >> 8) & 0xFF;
data[5] = raw_kp & 0xFF;
uint16_t raw_kd = MOTOR_LZ_FloatToRawPositive(send_param.kd, LZ_KD_MAX);
data[6] = (raw_kd >> 8) & 0xFF;
data[7] = raw_kd & 0xFF;
return MOTOR_LZ_SendExtFrame(param->can, ext_id, data, 8);
}
int8_t MOTOR_LZ_Enable(MOTOR_LZ_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
// 构建扩展ID - 使能命令
uint32_t ext_id = MOTOR_LZ_BuildExtID(MOTOR_LZ_CMD_ENABLE, param->host_id, param->motor_id);
// 数据区清零
uint8_t data[8] = {0};
return MOTOR_LZ_SendExtFrame(param->can, ext_id, data, 8);
}
int8_t MOTOR_LZ_Disable(MOTOR_LZ_Param_t *param, bool clear_fault) {
if (param == NULL) return DEVICE_ERR_NULL;
// 构建扩展ID - 停止命令
uint32_t ext_id = MOTOR_LZ_BuildExtID(MOTOR_LZ_CMD_DISABLE, param->host_id, param->motor_id);
// 数据区
uint8_t data[8] = {0};
if (clear_fault) {
data[0] = 1; // Byte[0]=1时清故障
}
return MOTOR_LZ_SendExtFrame(param->can, ext_id, data, 8);
}
int8_t MOTOR_LZ_SetZero(MOTOR_LZ_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
// 构建扩展ID - 设置零位命令
uint32_t ext_id = MOTOR_LZ_BuildExtID(MOTOR_LZ_CMD_SET_ZERO, param->host_id, param->motor_id);
// 数据区 - Byte[0]=1
uint8_t data[8] = {1, 0, 0, 0, 0, 0, 0, 0};
return MOTOR_LZ_SendExtFrame(param->can, ext_id, data, 8);
}
MOTOR_LZ_t* MOTOR_LZ_GetMotor(MOTOR_LZ_Param_t *param) {
if (param == NULL) return NULL;
MOTOR_LZ_CANManager_t *manager = MOTOR_LZ_GetCANManager(param->can);
if (manager == NULL) return NULL;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_LZ_t *motor = manager->motors[i];
if (motor && motor->param.motor_id == param->motor_id) {
return motor;
}
}
return NULL;
}
int8_t MOTOR_LZ_Relax(MOTOR_LZ_Param_t *param) {
return MOTOR_LZ_MotionControl(param, &lz_relax_param);
}
int8_t MOTOR_LZ_Offline(MOTOR_LZ_Param_t *param) {
MOTOR_LZ_t *motor = MOTOR_LZ_GetMotor(param);
if (motor) {
motor->motor.header.online = false;
return DEVICE_OK;
}
return DEVICE_ERR_NO_DEV;
}
static MOTOR_LZ_Feedback_t* MOTOR_LZ_GetFeedback(MOTOR_LZ_Param_t *param) {
MOTOR_LZ_t *motor = MOTOR_LZ_GetMotor(param);
if (motor && motor->motor.header.online) {
return &motor->lz_feedback;
}
return NULL;
}

212
User/device/motor_lz.h Normal file
View File

@ -0,0 +1,212 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "device/device.h"
#include "device/motor.h"
#include "bsp/can.h"
/* Exported constants ------------------------------------------------------- */
#define MOTOR_LZ_MAX_MOTORS 32
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef enum {
MOTOR_LZ_RSO0,
MOTOR_LZ_RSO1,
MOTOR_LZ_RSO2,
MOTOR_LZ_RSO3,
MOTOR_LZ_RSO4,
MOTOR_LZ_RSO5,
MOTOR_LZ_RSO6,
} MOTOR_LZ_Module_t;
/* 灵足电机控制模式 */
typedef enum {
MOTOR_LZ_MODE_MOTION = 0x1, /* 运控模式 */
MOTOR_LZ_MODE_CURRENT = 0x2, /* 电流模式 */
MOTOR_LZ_MODE_VELOCITY = 0x3, /* 速度模式 */
MOTOR_LZ_MODE_POSITION = 0x4, /* 位置模式 */
} MOTOR_LZ_ControlMode_t;
/* 灵足电机通信类型 */
typedef enum {
MOTOR_LZ_CMD_MOTION = 0x1, /* 运控模式控制 */
MOTOR_LZ_CMD_FEEDBACK = 0x2, /* 电机反馈数据 */
MOTOR_LZ_CMD_ENABLE = 0x3, /* 电机使能运行 */
MOTOR_LZ_CMD_DISABLE = 0x4, /* 电机停止运行 */
MOTOR_LZ_CMD_SET_ZERO = 0x6, /* 设置电机机械零位 */
} MOTOR_LZ_CmdType_t;
/* 灵足电机运行状态 */
typedef enum {
MOTOR_LZ_STATE_RESET = 0, /* Reset模式[复位] */
MOTOR_LZ_STATE_CALI = 1, /* Cali模式[标定] */
MOTOR_LZ_STATE_MOTOR = 2, /* Motor模式[运行] */
} MOTOR_LZ_State_t;
/* 灵足电机故障信息 */
typedef struct {
bool uncalibrated; /* bit21: 未标定 */
bool stall_overload; /* bit20: 堵转过载故障 */
bool encoder_fault; /* bit19: 磁编码故障 */
bool over_temp; /* bit18: 过温 */
bool driver_fault; /* bit17: 驱动故障 */
bool under_voltage; /* bit16: 欠压故障 */
} MOTOR_LZ_Fault_t;
/* 灵足电机运控参数 */
typedef struct {
float target_angle; /* 目标角度 (-12.57f~12.57f rad) */
float target_velocity; /* 目标角速度 (-20~20 rad/s) */
float kp; /* 位置增益 (0.0~5000.0) */
float kd; /* 微分增益 (0.0~100.0) */
float torque; /* 力矩 (-60~60 Nm) */
} MOTOR_LZ_MotionParam_t;
/*每个电机需要的参数*/
typedef struct {
BSP_CAN_t can; /* CAN总线 */
uint8_t motor_id; /* 电机CAN ID */
uint8_t host_id; /* 主机CAN ID */
MOTOR_LZ_Module_t module; /* 电机型号 */
bool reverse; /* 是否反向 */
MOTOR_LZ_ControlMode_t mode; /* 控制模式 */
} MOTOR_LZ_Param_t;
/*电机反馈信息扩展*/
typedef struct {
float current_angle; /* 当前角度 (-12.57f~12.57f rad) */
float current_velocity; /* 当前角速度 (-20~20 rad/s) */
float current_torque; /* 当前力矩 (-60~60 Nm) */
float temperature; /* 当前温度 (摄氏度) */
MOTOR_LZ_State_t state; /* 运行状态 */
MOTOR_LZ_Fault_t fault; /* 故障信息 */
uint8_t motor_can_id; /* 当前电机CAN ID */
} MOTOR_LZ_Feedback_t;
/*电机实例*/
typedef struct {
MOTOR_LZ_Param_t param;
MOTOR_t motor;
MOTOR_LZ_Feedback_t lz_feedback; /* 灵足电机特有反馈信息 */
MOTOR_LZ_MotionParam_t motion_param; /* 运控模式参数 */
} MOTOR_LZ_t;
/*CAN管理器管理一个CAN总线上所有的电机*/
typedef struct {
BSP_CAN_t can;
MOTOR_LZ_t *motors[MOTOR_LZ_MAX_MOTORS];
uint8_t motor_count;
} MOTOR_LZ_CANManager_t;
/* Exported functions prototypes -------------------------------------------- */
/**
* @brief
* @return
*/
int8_t MOTOR_LZ_Init(void);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_LZ_Register(MOTOR_LZ_Param_t *param);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_LZ_Update(MOTOR_LZ_Param_t *param);
/**
* @brief
* @return
*/
int8_t MOTOR_LZ_UpdateAll(void);
/**
* @brief
* @param param
* @param motion_param
* @return
*/
int8_t MOTOR_LZ_MotionControl(MOTOR_LZ_Param_t *param, MOTOR_LZ_MotionParam_t *motion_param);
/**
* @brief ()
* @param param
* @param torque (-60~60 Nm)
* @return
*/
int8_t MOTOR_LZ_TorqueControl(MOTOR_LZ_Param_t *param, float torque);
/**
* @brief
* @param param
* @param target_angle (-12.57~12.57 rad)
* @param max_velocity (0~20 rad/s)
* @return
*/
int8_t MOTOR_LZ_PositionControl(MOTOR_LZ_Param_t *param, float target_angle, float max_velocity);
/**
* @brief
* @param param
* @param target_velocity (-20~20 rad/s)
* @return
*/
int8_t MOTOR_LZ_VelocityControl(MOTOR_LZ_Param_t *param, float target_velocity);
/**
* @brief 使
* @param param
* @return
*/
int8_t MOTOR_LZ_Enable(MOTOR_LZ_Param_t *param);
/**
* @brief
* @param param
* @param clear_fault
* @return
*/
int8_t MOTOR_LZ_Disable(MOTOR_LZ_Param_t *param, bool clear_fault);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_LZ_SetZero(MOTOR_LZ_Param_t *param);
/**
* @brief
* @param param
* @return NULL
*/
MOTOR_LZ_t* MOTOR_LZ_GetMotor(MOTOR_LZ_Param_t *param);
/**
* @brief 使
* @param param
* @return
*/
int8_t MOTOR_LZ_Relax(MOTOR_LZ_Param_t *param);
/**
* @brief 使线线false
* @param param
* @return
*/
int8_t MOTOR_LZ_Offline(MOTOR_LZ_Param_t *param);
#ifdef __cplusplus
}
#endif

321
User/device/motor_rm.c Normal file
View File

@ -0,0 +1,321 @@
/*
RM电机驱动
*/
/* Includes ----------------------------------------------------------------- */
#include "motor_rm.h"
#include <stdbool.h>
#include <string.h>
#include "bsp/can.h"
#include "bsp/mm.h"
#include "bsp/time.h"
#include "component/user_math.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private define ----------------------------------------------------------- */
#define GM6020_FB_ID_BASE (0x205)
#define GM6020_CTRL_ID_BASE (0x1ff)
#define GM6020_CTRL_ID_EXTAND (0x2ff)
#define M3508_M2006_FB_ID_BASE (0x201)
#define M3508_M2006_CTRL_ID_BASE (0x200)
#define M3508_M2006_CTRL_ID_EXTAND (0x1ff)
#define M3508_M2006_ID_SETTING_ID (0x700)
#define GM6020_MAX_ABS_LSB (30000)
#define M3508_MAX_ABS_LSB (16384)
#define M2006_MAX_ABS_LSB (10000)
#define MOTOR_TX_BUF_SIZE (8)
#define MOTOR_RX_BUF_SIZE (8)
#define MOTOR_ENC_RES (8192) /* 电机编码器分辨率 */
#define MOTOR_CUR_RES (16384) /* 电机转矩电流分辨率 */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Private macro ------------------------------------------------------------ */
/* Private typedef ---------------------------------------------------------- */
/* USER STRUCT BEGIN */
/* USER STRUCT END */
/* Private variables -------------------------------------------------------- */
static MOTOR_RM_CANManager_t *can_managers[BSP_CAN_NUM] = {NULL};
/* Private function -------------------------------------------------------- */
/* USER FUNCTION BEGIN */
/* USER FUNCTION END */
static int8_t MOTOR_RM_GetLogicalIndex(uint16_t can_id, MOTOR_RM_Module_t module) {
switch (module) {
case MOTOR_M2006:
case MOTOR_M3508:
if (can_id >= M3508_M2006_FB_ID_BASE && can_id <= M3508_M2006_FB_ID_BASE + 7) {
return can_id - M3508_M2006_FB_ID_BASE;
}
break;
case MOTOR_GM6020:
if (can_id >= GM6020_FB_ID_BASE && can_id <= GM6020_FB_ID_BASE + 6) {
return can_id - GM6020_FB_ID_BASE + 4;
}
break;
default:
break;
}
return DEVICE_ERR;
}
static float MOTOR_RM_GetRatio(MOTOR_RM_Module_t module) {
switch (module) {
case MOTOR_M2006: return 36.0f;
case MOTOR_M3508: return 3591.0f / 187.0f;
case MOTOR_GM6020: return 1.0f;
default: return 1.0f;
}
}
static int16_t MOTOR_RM_GetLSB(MOTOR_RM_Module_t module) {
switch (module) {
case MOTOR_M2006: return M2006_MAX_ABS_LSB;
case MOTOR_M3508: return M3508_MAX_ABS_LSB;
case MOTOR_GM6020: return GM6020_MAX_ABS_LSB;
default: return DEVICE_ERR;
}
}
static MOTOR_RM_CANManager_t* MOTOR_RM_GetCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) return NULL;
return can_managers[can];
}
static int8_t MOTOR_RM_CreateCANManager(BSP_CAN_t can) {
if (can >= BSP_CAN_NUM) return DEVICE_ERR;
if (can_managers[can] != NULL) return DEVICE_OK;
can_managers[can] = (MOTOR_RM_CANManager_t*)BSP_Malloc(sizeof(MOTOR_RM_CANManager_t));
if (can_managers[can] == NULL) return DEVICE_ERR;
memset(can_managers[can], 0, sizeof(MOTOR_RM_CANManager_t));
can_managers[can]->can = can;
return DEVICE_OK;
}
static void Motor_RM_Decode(MOTOR_RM_t *motor, BSP_CAN_Message_t *msg) {
uint16_t raw_angle = (uint16_t)((msg->data[0] << 8) | msg->data[1]);
int16_t raw_speed = (int16_t)((msg->data[2] << 8) | msg->data[3]);
int16_t raw_current = (int16_t)((msg->data[4] << 8) | msg->data[5]);
int16_t lsb = MOTOR_RM_GetLSB(motor->param.module);
float ratio = MOTOR_RM_GetRatio(motor->param.module);
float rotor_angle = raw_angle / (float)MOTOR_ENC_RES * M_2PI;
float rotor_speed = raw_speed;
float torque_current = raw_current * lsb / (float)MOTOR_CUR_RES;
if (motor->param.gear) {
// 多圈累加
int32_t delta = (int32_t)raw_angle - (int32_t)motor->last_raw_angle;
if (delta > (MOTOR_ENC_RES / 2)) {
motor->gearbox_round_count--;
} else if (delta < -(MOTOR_ENC_RES / 2)) {
motor->gearbox_round_count++;
}
motor->last_raw_angle = raw_angle;
float single_turn = rotor_angle;
motor->gearbox_total_angle = (motor->gearbox_round_count * M_2PI + single_turn) / ratio;
// 输出轴多圈绝对值
motor->feedback.rotor_abs_angle = motor->gearbox_total_angle;
motor->feedback.rotor_speed = rotor_speed / ratio;
motor->feedback.torque_current = torque_current * ratio;
} else {
// 非gear模式直接用转子单圈
motor->gearbox_round_count = 0;
motor->last_raw_angle = raw_angle;
motor->gearbox_total_angle = 0.0f;
motor->feedback.rotor_abs_angle = rotor_angle;
motor->feedback.rotor_speed = rotor_speed;
motor->feedback.torque_current = torque_current;
}
while (motor->feedback.rotor_abs_angle < 0) {
motor->feedback.rotor_abs_angle += M_2PI;
}
while (motor->feedback.rotor_abs_angle >= M_2PI) {
motor->feedback.rotor_abs_angle -= M_2PI;
}
if (motor->motor.reverse) {
motor->feedback.rotor_abs_angle = M_2PI - motor->feedback.rotor_abs_angle;
motor->feedback.rotor_speed = -motor->feedback.rotor_speed;
motor->feedback.torque_current = -motor->feedback.torque_current;
}
motor->feedback.temp = msg->data[6];
}
/* Exported functions ------------------------------------------------------- */
int8_t MOTOR_RM_Register(MOTOR_RM_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
if (MOTOR_RM_CreateCANManager(param->can) != DEVICE_OK) return DEVICE_ERR;
MOTOR_RM_CANManager_t *manager = MOTOR_RM_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR;
// 检查是否已注册
for (int i = 0; i < manager->motor_count; i++) {
if (manager->motors[i] && manager->motors[i]->param.id == param->id) {
return DEVICE_ERR_INITED;
}
}
// 检查数量
if (manager->motor_count >= MOTOR_RM_MAX_MOTORS) return DEVICE_ERR;
// 创建新电机实例
MOTOR_RM_t *new_motor = (MOTOR_RM_t*)BSP_Malloc(sizeof(MOTOR_RM_t));
if (new_motor == NULL) return DEVICE_ERR;
memcpy(&new_motor->param, param, sizeof(MOTOR_RM_Param_t));
memset(&new_motor->motor, 0, sizeof(MOTOR_t));
new_motor->motor.reverse = param->reverse;
// 注册CAN接收ID
if (BSP_CAN_RegisterId(param->can, param->id, 3) != BSP_OK) {
BSP_Free(new_motor);
return DEVICE_ERR;
}
manager->motors[manager->motor_count] = new_motor;
manager->motor_count++;
return DEVICE_OK;
}
int8_t MOTOR_RM_Update(MOTOR_RM_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
MOTOR_RM_CANManager_t *manager = MOTOR_RM_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR_NO_DEV;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_RM_t *motor = manager->motors[i];
if (motor && motor->param.id == param->id) {
BSP_CAN_Message_t rx_msg;
if (BSP_CAN_GetMessage(param->can, param->id, &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) != BSP_OK) {
uint64_t now_time = BSP_TIME_Get();
if (now_time - motor->motor.header.last_online_time > 1000) {
motor->motor.header.online = false;
return DEVICE_ERR_NO_DEV;
}
return DEVICE_ERR;
}
motor->motor.header.online = true;
motor->motor.header.last_online_time = BSP_TIME_Get();
Motor_RM_Decode(motor, &rx_msg);
motor->motor.feedback = motor->feedback;
return DEVICE_OK;
}
}
return DEVICE_ERR_NO_DEV;
}
int8_t MOTOR_RM_UpdateAll(void) {
int8_t ret = DEVICE_OK;
for (int can = 0; can < BSP_CAN_NUM; can++) {
MOTOR_RM_CANManager_t *manager = MOTOR_RM_GetCANManager((BSP_CAN_t)can);
if (manager == NULL) continue;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_RM_t *motor = manager->motors[i];
if (motor != NULL) {
if (MOTOR_RM_Update(&motor->param) != DEVICE_OK) {
ret = DEVICE_ERR;
}
}
}
}
return ret;
}
int8_t MOTOR_RM_SetOutput(MOTOR_RM_Param_t *param, float value) {
if (param == NULL) return DEVICE_ERR_NULL;
MOTOR_RM_CANManager_t *manager = MOTOR_RM_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR_NO_DEV;
if (value > 1.0f) value = 1.0f;
if (value < -1.0f) value = -1.0f;
if (param->reverse){
value = -value;
}
MOTOR_RM_t *motor = MOTOR_RM_GetMotor(param);
if (motor == NULL) return DEVICE_ERR_NO_DEV;
int8_t logical_index = MOTOR_RM_GetLogicalIndex(param->id, param->module);
if (logical_index < 0) return DEVICE_ERR;
MOTOR_RM_MsgOutput_t *output_msg = &manager->output_msg;
int16_t output_value = (int16_t)(value * (float)MOTOR_RM_GetLSB(param->module));
output_msg->output[logical_index] = output_value;
return DEVICE_OK;
}
int8_t MOTOR_RM_Ctrl(MOTOR_RM_Param_t *param) {
if (param == NULL) return DEVICE_ERR_NULL;
MOTOR_RM_CANManager_t *manager = MOTOR_RM_GetCANManager(param->can);
if (manager == NULL) return DEVICE_ERR_NO_DEV;
MOTOR_RM_MsgOutput_t *output_msg = &manager->output_msg;
BSP_CAN_StdDataFrame_t tx_frame;
uint16_t id = param->id;
switch (id) {
case M3508_M2006_FB_ID_BASE:
case M3508_M2006_FB_ID_BASE+1:
case M3508_M2006_FB_ID_BASE+2:
case M3508_M2006_FB_ID_BASE+3:
tx_frame.id = M3508_M2006_CTRL_ID_BASE;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
for (int i = 0; i < 4; i++) {
tx_frame.data[i*2] = (uint8_t)((output_msg->output[i] >> 8) & 0xFF);
tx_frame.data[i*2+1] = (uint8_t)(output_msg->output[i] & 0xFF);
}
break;
case M3508_M2006_FB_ID_BASE+4:
case M3508_M2006_FB_ID_BASE+5:
case M3508_M2006_FB_ID_BASE+6:
case M3508_M2006_FB_ID_BASE+7:
tx_frame.id = M3508_M2006_CTRL_ID_EXTAND;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
for (int i = 4; i < 8; i++) {
tx_frame.data[(i-4)*2] = (uint8_t)((output_msg->output[i] >> 8) & 0xFF);
tx_frame.data[(i-4)*2+1] = (uint8_t)(output_msg->output[i] & 0xFF);
}
break;
case GM6020_FB_ID_BASE+4:
case GM6020_FB_ID_BASE+5:
case GM6020_FB_ID_BASE+6:
tx_frame.id = GM6020_CTRL_ID_EXTAND;
tx_frame.dlc = MOTOR_TX_BUF_SIZE;
for (int i = 8; i < 11; i++) {
tx_frame.data[(i-8)*2] = (uint8_t)((output_msg->output[i] >> 8) & 0xFF);
tx_frame.data[(i-8)*2+1] = (uint8_t)(output_msg->output[i] & 0xFF);
}
tx_frame.data[6] = 0;
tx_frame.data[7] = 0;
break;
default:
return DEVICE_ERR;
}
return BSP_CAN_TransmitStdDataFrame(param->can, &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}
MOTOR_RM_t* MOTOR_RM_GetMotor(MOTOR_RM_Param_t *param) {
if (param == NULL) return NULL;
MOTOR_RM_CANManager_t *manager = MOTOR_RM_GetCANManager(param->can);
if (manager == NULL) return NULL;
for (int i = 0; i < manager->motor_count; i++) {
MOTOR_RM_t *motor = manager->motors[i];
if (motor && motor->param.id == param->id) {
return motor;
}
}
return NULL;
}
int8_t MOTOR_RM_Relax(MOTOR_RM_Param_t *param) {
return MOTOR_RM_SetOutput(param, 0.0f);
}
int8_t MOTOR_RM_Offine(MOTOR_RM_Param_t *param) {
MOTOR_RM_t *motor = MOTOR_RM_GetMotor(param);
if (motor) {
motor->motor.header.online = false;
return DEVICE_OK;
}
return DEVICE_ERR_NO_DEV;
}

132
User/device/motor_rm.h Normal file
View File

@ -0,0 +1,132 @@
#pragma once
#include "motor.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "device/device.h"
#include "device/motor.h"
#include "bsp/can.h"
/* Exported constants ------------------------------------------------------- */
#define MOTOR_RM_MAX_MOTORS 11
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
typedef enum {
MOTOR_M2006,
MOTOR_M3508,
MOTOR_GM6020,
} MOTOR_RM_Module_t;
/*一个can最多控制11个电机*/
typedef union {
int16_t output[MOTOR_RM_MAX_MOTORS];
struct {
int16_t m3508_m2006_id201;
int16_t m3508_m2006_id202;
int16_t m3508_m2006_id203;
int16_t m3508_m2006_id204;
int16_t m3508_m2006_gm6020_id205;
int16_t m3508_m2006_gm6020_id206;
int16_t m3508_m2006_gm6020_id207;
int16_t m3508_m2006_gm6020_id208;
int16_t gm6020_id209;
int16_t gm6020_id20A;
int16_t gm6020_id20B;
} named;
} MOTOR_RM_MsgOutput_t;
/*每个电机需要的参数*/
typedef struct {
BSP_CAN_t can;
uint16_t id;
MOTOR_RM_Module_t module;
bool reverse;
bool gear;
} MOTOR_RM_Param_t;
typedef MOTOR_Feedback_t MOTOR_RM_Feedback_t;
typedef struct {
MOTOR_RM_Param_t param;
MOTOR_RM_Feedback_t feedback;
MOTOR_t motor;
// 多圈相关变量仅gear模式下有效
uint16_t last_raw_angle;
int32_t gearbox_round_count;
float gearbox_total_angle;
} MOTOR_RM_t;
/*CAN管理器管理一个CAN总线上所有的电机*/
typedef struct {
BSP_CAN_t can;
MOTOR_RM_MsgOutput_t output_msg;
MOTOR_RM_t *motors[MOTOR_RM_MAX_MOTORS];
uint8_t motor_count;
} MOTOR_RM_CANManager_t;
/* Exported functions prototypes -------------------------------------------- */
/**
* @brief RM电机
* @param param
* @return
*/
int8_t MOTOR_RM_Register(MOTOR_RM_Param_t *param);
/**
* @brief
* @param param
* @return
*/
int8_t MOTOR_RM_Update(MOTOR_RM_Param_t *param);
/**
* @brief
* @param param
* @param value [-1.0, 1.0]
* @return
*/
int8_t MOTOR_RM_SetOutput(MOTOR_RM_Param_t *param, float value);
/**
* @brief CAN可以控制多个电机
* @param param
* @return
*/
int8_t MOTOR_RM_Ctrl(MOTOR_RM_Param_t *param);
/**
* @brief
* @param param
* @return
*/
MOTOR_RM_t* MOTOR_RM_GetMotor(MOTOR_RM_Param_t *param);
/**
* @brief 使0
* @param param
* @return
*/
int8_t MOTOR_RM_Relax(MOTOR_RM_Param_t *param);
/**
* @brief 使线线false
* @param param
* @return
*/
int8_t MOTOR_RM_Offine(MOTOR_RM_Param_t *param);
/**
* @brief
* @param
* @return
*/
int8_t MOTOR_RM_UpdateAll(void);
#ifdef __cplusplus
}
#endif

89
User/task/atti_esit.c Normal file
View File

@ -0,0 +1,89 @@
/*
atti_esit Task
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "bsp/gpio.h"
#include "bsp/mm.h"
#include "bsp/pwm.h"
#include "component/ahrs.h"
#include "component/pid.h"
#include "device/bmi088.h"
#include "task/user_task.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
BMI088_t bmi088;
AHRS_t gimbal_ahrs;
AHRS_Magn_t magn;
AHRS_Eulr_t eulr_to_send;
KPID_t imu_temp_ctrl_pid;
/*默认校准参数*/
BMI088_Cali_t cali_bmi088 = {
.gyro_offset = {-0.00147764047f, -0.00273479894f, 0.00154074503f},
};
static const KPID_Params_t imu_temp_ctrl_pid_param = {
.k = 0.1f,
.p = 0.15f,
.i = 0.01f,
.d = 0.02f,
.i_limit = 1.0f,
.out_limit = 1.0f,
};
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_atti_esit(void *argument) {
(void)argument; /* 未使用argument消除警告 */
osDelay(ATTI_ESIT_INIT_DELAY); /* 延时一段时间再开启任务 */
/* USER CODE INIT BEGIN */
BMI088_Init(&bmi088, &cali_bmi088);
AHRS_Init(&gimbal_ahrs, &magn, BMI088_GetUpdateFreq(&bmi088));
PID_Init(&imu_temp_ctrl_pid, KPID_MODE_NO_D,
1.0f / BMI088_GetUpdateFreq(&bmi088), &imu_temp_ctrl_pid_param);
BSP_PWM_Start(BSP_PWM_IMU_HEAT);
/* USER CODE INIT END */
while (1) {
/* USER CODE BEGIN */
BMI088_WaitNew();
BMI088_AcclStartDmaRecv();
BMI088_AcclWaitDmaCplt();
BMI088_GyroStartDmaRecv();
BMI088_GyroWaitDmaCplt();
/* 锁住RTOS内核防止数据解析过程中断造成错误 */
osKernelLock();
/* 接收完所有数据后,把数据从原始字节加工成方便计算的数据 */
BMI088_ParseAccl(&bmi088);
BMI088_ParseGyro(&bmi088);
// IST8310_Parse(&ist8310);
/* 根据设备接收到的数据进行姿态解析 */
AHRS_Update(&gimbal_ahrs, &bmi088.accl, &bmi088.gyro, &magn);
/* 根据解析出来的四元数计算欧拉角 */
AHRS_GetEulr(&eulr_to_send, &gimbal_ahrs);
BSP_PWM_SetComp(BSP_PWM_IMU_HEAT, PID_Calc(&imu_temp_ctrl_pid, 40.5f,
bmi088.temp, 0.0f, 0.0f));
osKernelUnlock();
/* USER CODE END */
}
}

13
User/task/config.yaml Normal file
View File

@ -0,0 +1,13 @@
- delay: 0
description: ''
freq_control: true
frequency: 500.0
function: Task_rc
name: rc
stack: 256
- delay: 0
description: ''
freq_control: false
function: Task_atti_esit
name: atti_esit
stack: 256

43
User/task/init.c Normal file
View File

@ -0,0 +1,43 @@
/*
Init Task
线
*/
/* Includes ----------------------------------------------------------------- */
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
/**
* \brief
*
* \param argument 使
*/
void Task_Init(void *argument) {
(void)argument; /* 未使用argument消除警告 */
/* USER CODE INIT BEGIN */
/* USER CODE INIT END */
osKernelLock(); /* 锁定内核,防止任务切换 */
/* 创建任务线程 */
task_runtime.thread.rc = osThreadNew(Task_rc, NULL, &attr_rc);
task_runtime.thread.atti_esit = osThreadNew(Task_atti_esit, NULL, &attr_atti_esit);
// 创建消息队列
/* USER MESSAGE BEGIN */
task_runtime.msgq.user_msg= osMessageQueueNew(2u, 10, NULL);
/* USER MESSAGE END */
osKernelUnlock(); // 解锁内核
osThreadTerminate(osThreadGetId()); // 任务完成后结束自身
}

50
User/task/rc.c Normal file
View File

@ -0,0 +1,50 @@
/*
rc Task
*/
/* Includes ----------------------------------------------------------------- */
#include "device/dr16.h"
#include "task/user_task.h"
/* USER INCLUDE BEGIN */
#include "device/dr16.h"
/* USER INCLUDE END */
/* Private typedef ---------------------------------------------------------- */
/* Private define ----------------------------------------------------------- */
/* Private macro ------------------------------------------------------------ */
/* Private variables -------------------------------------------------------- */
/* USER STRUCT BEGIN */
DR16_t dr16;
/* USER STRUCT END */
/* Private function --------------------------------------------------------- */
/* Exported functions ------------------------------------------------------- */
void Task_rc(void *argument) {
(void)argument; /* 未使用argument消除警告 */
/* 计算任务运行到指定频率需要等待的tick数 */
const uint32_t delay_tick = osKernelGetTickFreq() / RC_FREQ;
osDelay(RC_INIT_DELAY); /* 延时一段时间再开启任务 */
uint32_t tick = osKernelGetTickCount(); /* 控制任务运行频率的计时 */
/* USER CODE INIT BEGIN */
DR16_Init(&dr16);
/* USER CODE INIT END */
while (1) {
tick += delay_tick; /* 计算下一个唤醒时刻 */
/* USER CODE BEGIN */
DR16_StartDmaRecv(&dr16);
if (DR16_WaitDmaCplt(20)) {
DR16_ParseData(&dr16);
} else {
DR16_Offline(&dr16);
}
/* USER CODE END */
osDelayUntil(tick); /* 运行结束,等待下一次唤醒 */
}
}

21
User/task/user_task.c Normal file
View File

@ -0,0 +1,21 @@
#include "task/user_task.h"
Task_Runtime_t task_runtime;
const osThreadAttr_t attr_init = {
.name = "Task_Init",
.priority = osPriorityRealtime,
.stack_size = 256 * 4,
};
/* User_task */
const osThreadAttr_t attr_rc = {
.name = "rc",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
};
const osThreadAttr_t attr_atti_esit = {
.name = "atti_esit",
.priority = osPriorityNormal,
.stack_size = 256 * 4,
};

85
User/task/user_task.h Normal file
View File

@ -0,0 +1,85 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include <cmsis_os2.h>
#include "FreeRTOS.h"
#include "task.h"
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* Exported constants ------------------------------------------------------- */
/* 任务运行频率 */
#define RC_FREQ (500.0)
/* 任务初始化延时ms */
#define TASK_INIT_DELAY (100u)
#define RC_INIT_DELAY (0)
#define ATTI_ESIT_INIT_DELAY (0)
/* Exported defines --------------------------------------------------------- */
/* Exported macro ----------------------------------------------------------- */
/* Exported types ----------------------------------------------------------- */
/* 任务运行时结构体 */
typedef struct {
/* 各任务,也可以叫做线程 */
struct {
osThreadId_t rc;
osThreadId_t atti_esit;
} thread;
/* USER MESSAGE BEGIN */
struct {
osMessageQueueId_t user_msg; /* 用户自定义任务消息队列 */
} msgq;
/* USER MESSAGE END */
/* 机器人状态 */
struct {
float battery; /* 电池电量百分比 */
float vbat; /* 电池电压 */
float cpu_temp; /* CPU温度 */
} status;
/* USER CONFIG BEGIN */
/* USER CONFIG END */
/* 各任务的stack使用 */
struct {
UBaseType_t rc;
UBaseType_t atti_esit;
} stack_water_mark;
/* 各任务运行频率 */
struct {
float rc;
} freq;
/* 任务最近运行时间 */
struct {
float rc;
} last_up_time;
} Task_Runtime_t;
/* 任务运行时结构体 */
extern Task_Runtime_t task_runtime;
/* 初始化任务句柄 */
extern const osThreadAttr_t attr_init;
extern const osThreadAttr_t attr_rc;
extern const osThreadAttr_t attr_atti_esit;
/* 任务函数声明 */
void Task_Init(void *argument);
void Task_rc(void *argument);
void Task_atti_esit(void *argument);
#ifdef __cplusplus
}
#endif

View File

@ -1,902 +0,0 @@
#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_4
ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_19
ADC1.ClockPrescaler=ADC_CLOCK_ASYNC_DIV64
ADC1.ContinuousConvMode=ENABLE
ADC1.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,OffsetSignedSaturation-0\#ChannelRegularConversion,NbrOfConversionFlag,master,ClockPrescaler,ContinuousConvMode,ConversionDataManagement,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,OffsetNumber-1\#ChannelRegularConversion,OffsetSignedSaturation-1\#ChannelRegularConversion,NbrOfConversion
ADC1.NbrOfConversion=2
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetNumber-1\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetSignedSaturation-0\#ChannelRegularConversion=DISABLE
ADC1.OffsetSignedSaturation-1\#ChannelRegularConversion=DISABLE
ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.Rank-1\#ChannelRegularConversion=2
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_32CYCLES_5
ADC1.master=1
Bdma.Request0=SPI6_TX
Bdma.RequestsNb=1
Bdma.SPI6_TX.0.Direction=DMA_MEMORY_TO_PERIPH
Bdma.SPI6_TX.0.EventEnable=DISABLE
Bdma.SPI6_TX.0.Instance=BDMA_Channel0
Bdma.SPI6_TX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
Bdma.SPI6_TX.0.MemInc=DMA_MINC_ENABLE
Bdma.SPI6_TX.0.Mode=DMA_NORMAL
Bdma.SPI6_TX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Bdma.SPI6_TX.0.PeriphInc=DMA_PINC_DISABLE
Bdma.SPI6_TX.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Bdma.SPI6_TX.0.Priority=DMA_PRIORITY_LOW
Bdma.SPI6_TX.0.RequestNumber=1
Bdma.SPI6_TX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Bdma.SPI6_TX.0.SignalID=NONE
Bdma.SPI6_TX.0.SyncEnable=DISABLE
Bdma.SPI6_TX.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Bdma.SPI6_TX.0.SyncRequestNumber=1
Bdma.SPI6_TX.0.SyncSignalID=NONE
CAD.formats=
CAD.pinconfig=
CAD.provider=
CORTEX_M7.CPU_DCache=Enabled
CORTEX_M7.CPU_ICache=Enabled
CORTEX_M7.Enable-Cortex_Memory_Protection_Unit_Region0_Settings=MPU_REGION_ENABLE
CORTEX_M7.IPParameters=CPU_DCache,CPU_ICache,MPU_Control,Enable-Cortex_Memory_Protection_Unit_Region0_Settings,default_mode_Activation
CORTEX_M7.MPU_Control=__NULL
CORTEX_M7.default_mode_Activation=1
DAC1.DAC_Channel-DAC_OUT2_Int=DAC_CHANNEL_2
DAC1.IPParameters=DAC_Channel-DAC_OUT2_Int
Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.0.EventEnable=DISABLE
Dma.ADC1.0.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.ADC1.0.Instance=DMA1_Stream0
Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
Dma.ADC1.0.Mode=DMA_CIRCULAR
Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
Dma.ADC1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.ADC1.0.Priority=DMA_PRIORITY_LOW
Dma.ADC1.0.RequestNumber=1
Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.ADC1.0.SignalID=NONE
Dma.ADC1.0.SyncEnable=DISABLE
Dma.ADC1.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.ADC1.0.SyncRequestNumber=1
Dma.ADC1.0.SyncSignalID=NONE
Dma.Request0=ADC1
Dma.Request1=SPI2_RX
Dma.Request10=USART3_TX
Dma.Request11=USART10_RX
Dma.Request12=USART10_TX
Dma.Request13=UART5_RX
Dma.Request2=SPI2_TX
Dma.Request3=UART7_RX
Dma.Request4=UART7_TX
Dma.Request5=USART1_RX
Dma.Request6=USART1_TX
Dma.Request7=USART2_RX
Dma.Request8=USART2_TX
Dma.Request9=USART3_RX
Dma.RequestsNb=14
Dma.SPI2_RX.1.Direction=DMA_PERIPH_TO_MEMORY
Dma.SPI2_RX.1.EventEnable=DISABLE
Dma.SPI2_RX.1.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI2_RX.1.Instance=DMA1_Stream2
Dma.SPI2_RX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI2_RX.1.MemInc=DMA_MINC_ENABLE
Dma.SPI2_RX.1.Mode=DMA_NORMAL
Dma.SPI2_RX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI2_RX.1.PeriphInc=DMA_PINC_DISABLE
Dma.SPI2_RX.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SPI2_RX.1.Priority=DMA_PRIORITY_LOW
Dma.SPI2_RX.1.RequestNumber=1
Dma.SPI2_RX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SPI2_RX.1.SignalID=NONE
Dma.SPI2_RX.1.SyncEnable=DISABLE
Dma.SPI2_RX.1.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SPI2_RX.1.SyncRequestNumber=1
Dma.SPI2_RX.1.SyncSignalID=NONE
Dma.SPI2_TX.2.Direction=DMA_MEMORY_TO_PERIPH
Dma.SPI2_TX.2.EventEnable=DISABLE
Dma.SPI2_TX.2.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.SPI2_TX.2.Instance=DMA1_Stream3
Dma.SPI2_TX.2.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.SPI2_TX.2.MemInc=DMA_MINC_ENABLE
Dma.SPI2_TX.2.Mode=DMA_NORMAL
Dma.SPI2_TX.2.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.SPI2_TX.2.PeriphInc=DMA_PINC_DISABLE
Dma.SPI2_TX.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SPI2_TX.2.Priority=DMA_PRIORITY_LOW
Dma.SPI2_TX.2.RequestNumber=1
Dma.SPI2_TX.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SPI2_TX.2.SignalID=NONE
Dma.SPI2_TX.2.SyncEnable=DISABLE
Dma.SPI2_TX.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SPI2_TX.2.SyncRequestNumber=1
Dma.SPI2_TX.2.SyncSignalID=NONE
Dma.UART5_RX.13.Direction=DMA_PERIPH_TO_MEMORY
Dma.UART5_RX.13.EventEnable=DISABLE
Dma.UART5_RX.13.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART5_RX.13.Instance=DMA1_Stream1
Dma.UART5_RX.13.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.UART5_RX.13.MemInc=DMA_MINC_ENABLE
Dma.UART5_RX.13.Mode=DMA_NORMAL
Dma.UART5_RX.13.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.UART5_RX.13.PeriphInc=DMA_PINC_DISABLE
Dma.UART5_RX.13.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.UART5_RX.13.Priority=DMA_PRIORITY_LOW
Dma.UART5_RX.13.RequestNumber=1
Dma.UART5_RX.13.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.UART5_RX.13.SignalID=NONE
Dma.UART5_RX.13.SyncEnable=DISABLE
Dma.UART5_RX.13.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.UART5_RX.13.SyncRequestNumber=1
Dma.UART5_RX.13.SyncSignalID=NONE
Dma.UART7_RX.3.Direction=DMA_PERIPH_TO_MEMORY
Dma.UART7_RX.3.EventEnable=DISABLE
Dma.UART7_RX.3.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART7_RX.3.Instance=DMA1_Stream4
Dma.UART7_RX.3.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.UART7_RX.3.MemInc=DMA_MINC_ENABLE
Dma.UART7_RX.3.Mode=DMA_NORMAL
Dma.UART7_RX.3.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.UART7_RX.3.PeriphInc=DMA_PINC_DISABLE
Dma.UART7_RX.3.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.UART7_RX.3.Priority=DMA_PRIORITY_LOW
Dma.UART7_RX.3.RequestNumber=1
Dma.UART7_RX.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.UART7_RX.3.SignalID=NONE
Dma.UART7_RX.3.SyncEnable=DISABLE
Dma.UART7_RX.3.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.UART7_RX.3.SyncRequestNumber=1
Dma.UART7_RX.3.SyncSignalID=NONE
Dma.UART7_TX.4.Direction=DMA_MEMORY_TO_PERIPH
Dma.UART7_TX.4.EventEnable=DISABLE
Dma.UART7_TX.4.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.UART7_TX.4.Instance=DMA1_Stream5
Dma.UART7_TX.4.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.UART7_TX.4.MemInc=DMA_MINC_ENABLE
Dma.UART7_TX.4.Mode=DMA_NORMAL
Dma.UART7_TX.4.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.UART7_TX.4.PeriphInc=DMA_PINC_DISABLE
Dma.UART7_TX.4.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.UART7_TX.4.Priority=DMA_PRIORITY_LOW
Dma.UART7_TX.4.RequestNumber=1
Dma.UART7_TX.4.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.UART7_TX.4.SignalID=NONE
Dma.UART7_TX.4.SyncEnable=DISABLE
Dma.UART7_TX.4.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.UART7_TX.4.SyncRequestNumber=1
Dma.UART7_TX.4.SyncSignalID=NONE
Dma.USART10_RX.11.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART10_RX.11.EventEnable=DISABLE
Dma.USART10_RX.11.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART10_RX.11.Instance=DMA2_Stream4
Dma.USART10_RX.11.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART10_RX.11.MemInc=DMA_MINC_ENABLE
Dma.USART10_RX.11.Mode=DMA_NORMAL
Dma.USART10_RX.11.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART10_RX.11.PeriphInc=DMA_PINC_DISABLE
Dma.USART10_RX.11.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART10_RX.11.Priority=DMA_PRIORITY_LOW
Dma.USART10_RX.11.RequestNumber=1
Dma.USART10_RX.11.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART10_RX.11.SignalID=NONE
Dma.USART10_RX.11.SyncEnable=DISABLE
Dma.USART10_RX.11.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART10_RX.11.SyncRequestNumber=1
Dma.USART10_RX.11.SyncSignalID=NONE
Dma.USART10_TX.12.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART10_TX.12.EventEnable=DISABLE
Dma.USART10_TX.12.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART10_TX.12.Instance=DMA2_Stream5
Dma.USART10_TX.12.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART10_TX.12.MemInc=DMA_MINC_ENABLE
Dma.USART10_TX.12.Mode=DMA_NORMAL
Dma.USART10_TX.12.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART10_TX.12.PeriphInc=DMA_PINC_DISABLE
Dma.USART10_TX.12.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART10_TX.12.Priority=DMA_PRIORITY_LOW
Dma.USART10_TX.12.RequestNumber=1
Dma.USART10_TX.12.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART10_TX.12.SignalID=NONE
Dma.USART10_TX.12.SyncEnable=DISABLE
Dma.USART10_TX.12.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART10_TX.12.SyncRequestNumber=1
Dma.USART10_TX.12.SyncSignalID=NONE
Dma.USART1_RX.5.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART1_RX.5.EventEnable=DISABLE
Dma.USART1_RX.5.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_RX.5.Instance=DMA1_Stream6
Dma.USART1_RX.5.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_RX.5.MemInc=DMA_MINC_ENABLE
Dma.USART1_RX.5.Mode=DMA_NORMAL
Dma.USART1_RX.5.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_RX.5.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_RX.5.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART1_RX.5.Priority=DMA_PRIORITY_LOW
Dma.USART1_RX.5.RequestNumber=1
Dma.USART1_RX.5.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART1_RX.5.SignalID=NONE
Dma.USART1_RX.5.SyncEnable=DISABLE
Dma.USART1_RX.5.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART1_RX.5.SyncRequestNumber=1
Dma.USART1_RX.5.SyncSignalID=NONE
Dma.USART1_TX.6.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART1_TX.6.EventEnable=DISABLE
Dma.USART1_TX.6.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART1_TX.6.Instance=DMA1_Stream7
Dma.USART1_TX.6.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART1_TX.6.MemInc=DMA_MINC_ENABLE
Dma.USART1_TX.6.Mode=DMA_NORMAL
Dma.USART1_TX.6.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART1_TX.6.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_TX.6.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART1_TX.6.Priority=DMA_PRIORITY_LOW
Dma.USART1_TX.6.RequestNumber=1
Dma.USART1_TX.6.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART1_TX.6.SignalID=NONE
Dma.USART1_TX.6.SyncEnable=DISABLE
Dma.USART1_TX.6.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART1_TX.6.SyncRequestNumber=1
Dma.USART1_TX.6.SyncSignalID=NONE
Dma.USART2_RX.7.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART2_RX.7.EventEnable=DISABLE
Dma.USART2_RX.7.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_RX.7.Instance=DMA2_Stream0
Dma.USART2_RX.7.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_RX.7.MemInc=DMA_MINC_ENABLE
Dma.USART2_RX.7.Mode=DMA_NORMAL
Dma.USART2_RX.7.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_RX.7.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_RX.7.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART2_RX.7.Priority=DMA_PRIORITY_LOW
Dma.USART2_RX.7.RequestNumber=1
Dma.USART2_RX.7.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART2_RX.7.SignalID=NONE
Dma.USART2_RX.7.SyncEnable=DISABLE
Dma.USART2_RX.7.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART2_RX.7.SyncRequestNumber=1
Dma.USART2_RX.7.SyncSignalID=NONE
Dma.USART2_TX.8.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART2_TX.8.EventEnable=DISABLE
Dma.USART2_TX.8.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART2_TX.8.Instance=DMA2_Stream1
Dma.USART2_TX.8.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART2_TX.8.MemInc=DMA_MINC_ENABLE
Dma.USART2_TX.8.Mode=DMA_NORMAL
Dma.USART2_TX.8.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART2_TX.8.PeriphInc=DMA_PINC_DISABLE
Dma.USART2_TX.8.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART2_TX.8.Priority=DMA_PRIORITY_LOW
Dma.USART2_TX.8.RequestNumber=1
Dma.USART2_TX.8.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART2_TX.8.SignalID=NONE
Dma.USART2_TX.8.SyncEnable=DISABLE
Dma.USART2_TX.8.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART2_TX.8.SyncRequestNumber=1
Dma.USART2_TX.8.SyncSignalID=NONE
Dma.USART3_RX.9.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART3_RX.9.EventEnable=DISABLE
Dma.USART3_RX.9.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART3_RX.9.Instance=DMA2_Stream2
Dma.USART3_RX.9.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_RX.9.MemInc=DMA_MINC_ENABLE
Dma.USART3_RX.9.Mode=DMA_NORMAL
Dma.USART3_RX.9.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_RX.9.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_RX.9.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART3_RX.9.Priority=DMA_PRIORITY_LOW
Dma.USART3_RX.9.RequestNumber=1
Dma.USART3_RX.9.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART3_RX.9.SignalID=NONE
Dma.USART3_RX.9.SyncEnable=DISABLE
Dma.USART3_RX.9.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART3_RX.9.SyncRequestNumber=1
Dma.USART3_RX.9.SyncSignalID=NONE
Dma.USART3_TX.10.Direction=DMA_MEMORY_TO_PERIPH
Dma.USART3_TX.10.EventEnable=DISABLE
Dma.USART3_TX.10.FIFOMode=DMA_FIFOMODE_DISABLE
Dma.USART3_TX.10.Instance=DMA2_Stream3
Dma.USART3_TX.10.MemDataAlignment=DMA_MDATAALIGN_BYTE
Dma.USART3_TX.10.MemInc=DMA_MINC_ENABLE
Dma.USART3_TX.10.Mode=DMA_NORMAL
Dma.USART3_TX.10.PeriphDataAlignment=DMA_PDATAALIGN_BYTE
Dma.USART3_TX.10.PeriphInc=DMA_PINC_DISABLE
Dma.USART3_TX.10.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.USART3_TX.10.Priority=DMA_PRIORITY_LOW
Dma.USART3_TX.10.RequestNumber=1
Dma.USART3_TX.10.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.USART3_TX.10.SignalID=NONE
Dma.USART3_TX.10.SyncEnable=DISABLE
Dma.USART3_TX.10.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.USART3_TX.10.SyncRequestNumber=1
Dma.USART3_TX.10.SyncSignalID=NONE
FDCAN1.AutoRetransmission=ENABLE
FDCAN1.CalculateBaudRateNominal=999999
FDCAN1.CalculateTimeBitNominal=1000
FDCAN1.CalculateTimeQuantumNominal=90.90909090909092
FDCAN1.DataPrescaler=1
FDCAN1.DataSyncJumpWidth=10
FDCAN1.DataTimeSeg1=9
FDCAN1.DataTimeSeg2=1
FDCAN1.ExtFiltersNbr=1
FDCAN1.FrameFormat=FDCAN_FRAME_CLASSIC
FDCAN1.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,NominalTimeSeg1,FrameFormat,NominalSyncJumpWidth,DataSyncJumpWidth,DataTimeSeg1,DataTimeSeg2,MessageRAMOffset,ExtFiltersNbr,RxFifo0ElmtSize,RxFifo1ElmtsNbr,RxFifo1ElmtSize,RxBuffersNbr,RxBufferSize,TxElmtSize,NominalTimeSeg2,DataPrescaler,AutoRetransmission
FDCAN1.MessageRAMOffset=0
FDCAN1.NominalPrescaler=5
FDCAN1.NominalSyncJumpWidth=10
FDCAN1.NominalTimeSeg1=9
FDCAN1.NominalTimeSeg2=1
FDCAN1.RxBufferSize=FDCAN_DATA_BYTES_64
FDCAN1.RxBuffersNbr=0
FDCAN1.RxFifo0ElmtSize=FDCAN_DATA_BYTES_64
FDCAN1.RxFifo0ElmtsNbr=23
FDCAN1.RxFifo1ElmtSize=FDCAN_DATA_BYTES_64
FDCAN1.RxFifo1ElmtsNbr=0
FDCAN1.StdFiltersNbr=1
FDCAN1.TxElmtSize=FDCAN_DATA_BYTES_64
FDCAN1.TxFifoQueueElmtsNbr=23
FDCAN2.AutoRetransmission=ENABLE
FDCAN2.CalculateBaudRateNominal=999999
FDCAN2.CalculateTimeBitNominal=1000
FDCAN2.CalculateTimeQuantumNominal=90.90909090909092
FDCAN2.DataPrescaler=1
FDCAN2.DataSyncJumpWidth=10
FDCAN2.DataTimeSeg1=9
FDCAN2.DataTimeSeg2=1
FDCAN2.ExtFiltersNbr=1
FDCAN2.FrameFormat=FDCAN_FRAME_CLASSIC
FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,FrameFormat,NominalSyncJumpWidth,DataSyncJumpWidth,DataTimeSeg1,DataTimeSeg2,ExtFiltersNbr,RxFifo0ElmtSize,RxFifo1ElmtsNbr,RxFifo1ElmtSize,RxBuffersNbr,RxBufferSize,TxBuffersNbr,TxElmtSize,NominalTimeSeg1,NominalTimeSeg2,DataPrescaler,AutoRetransmission
FDCAN2.MessageRAMOffset=831
FDCAN2.NominalPrescaler=5
FDCAN2.NominalSyncJumpWidth=10
FDCAN2.NominalTimeSeg1=9
FDCAN2.NominalTimeSeg2=1
FDCAN2.RxBufferSize=FDCAN_DATA_BYTES_64
FDCAN2.RxBuffersNbr=0
FDCAN2.RxFifo0ElmtSize=FDCAN_DATA_BYTES_64
FDCAN2.RxFifo0ElmtsNbr=0
FDCAN2.RxFifo1ElmtSize=FDCAN_DATA_BYTES_64
FDCAN2.RxFifo1ElmtsNbr=23
FDCAN2.StdFiltersNbr=1
FDCAN2.TxBuffersNbr=0
FDCAN2.TxElmtSize=FDCAN_DATA_BYTES_64
FDCAN2.TxFifoQueueElmtsNbr=23
FDCAN3.AutoRetransmission=ENABLE
FDCAN3.CalculateBaudRateNominal=999999
FDCAN3.CalculateTimeBitNominal=1000
FDCAN3.CalculateTimeQuantumNominal=90.90909090909092
FDCAN3.DataPrescaler=1
FDCAN3.DataSyncJumpWidth=10
FDCAN3.DataTimeSeg1=9
FDCAN3.DataTimeSeg2=1
FDCAN3.ExtFiltersNbr=1
FDCAN3.FrameFormat=FDCAN_FRAME_CLASSIC
FDCAN3.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,MessageRAMOffset,RxFifo0ElmtsNbr,TxFifoQueueElmtsNbr,NominalPrescaler,StdFiltersNbr,FrameFormat,NominalSyncJumpWidth,DataSyncJumpWidth,DataTimeSeg1,DataTimeSeg2,ExtFiltersNbr,RxFifo0ElmtSize,RxFifo1ElmtsNbr,RxFifo1ElmtSize,RxBuffersNbr,RxBufferSize,TxBuffersNbr,TxElmtSize,NominalTimeSeg1,NominalTimeSeg2,DataPrescaler,Mode,AutoRetransmission
FDCAN3.MessageRAMOffset=1662
FDCAN3.Mode=FDCAN_MODE_NORMAL
FDCAN3.NominalPrescaler=5
FDCAN3.NominalSyncJumpWidth=10
FDCAN3.NominalTimeSeg1=9
FDCAN3.NominalTimeSeg2=1
FDCAN3.RxBufferSize=FDCAN_DATA_BYTES_64
FDCAN3.RxBuffersNbr=0
FDCAN3.RxFifo0ElmtSize=FDCAN_DATA_BYTES_64
FDCAN3.RxFifo0ElmtsNbr=0
FDCAN3.RxFifo1ElmtSize=FDCAN_DATA_BYTES_64
FDCAN3.RxFifo1ElmtsNbr=23
FDCAN3.StdFiltersNbr=1
FDCAN3.TxBuffersNbr=0
FDCAN3.TxElmtSize=FDCAN_DATA_BYTES_64
FDCAN3.TxFifoQueueElmtsNbr=23
FREERTOS.IPParameters=Tasks01
FREERTOS.Tasks01=defaultTask,24,128,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL
File.Version=6
GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false
MMTAppRegionsCount=0
MMTConfigApplied=false
Mcu.CPN=STM32H723VGT6
Mcu.Family=STM32H7
Mcu.IP0=ADC1
Mcu.IP1=BDMA
Mcu.IP10=MEMORYMAP
Mcu.IP11=NVIC
Mcu.IP12=RCC
Mcu.IP13=SPI2
Mcu.IP14=SPI6
Mcu.IP15=SYS
Mcu.IP16=TIM1
Mcu.IP17=TIM2
Mcu.IP18=TIM3
Mcu.IP19=TIM12
Mcu.IP2=CORTEX_M7
Mcu.IP20=UART5
Mcu.IP21=UART7
Mcu.IP22=USART1
Mcu.IP23=USART2
Mcu.IP24=USART3
Mcu.IP25=USART10
Mcu.IP26=USB_OTG_HS
Mcu.IP3=DAC1
Mcu.IP4=DEBUG
Mcu.IP5=DMA
Mcu.IP6=FDCAN1
Mcu.IP7=FDCAN2
Mcu.IP8=FDCAN3
Mcu.IP9=FREERTOS
Mcu.IPNb=27
Mcu.Name=STM32H723VGTx
Mcu.Package=LQFP100
Mcu.Pin0=PE2
Mcu.Pin1=PE3
Mcu.Pin10=PC3_C
Mcu.Pin11=PA0
Mcu.Pin12=PA2
Mcu.Pin13=PA5
Mcu.Pin14=PA7
Mcu.Pin15=PC4
Mcu.Pin16=PB1
Mcu.Pin17=PE7
Mcu.Pin18=PE8
Mcu.Pin19=PE9
Mcu.Pin2=PC13
Mcu.Pin20=PE10
Mcu.Pin21=PE11
Mcu.Pin22=PE12
Mcu.Pin23=PE13
Mcu.Pin24=PE15
Mcu.Pin25=PB10
Mcu.Pin26=PB11
Mcu.Pin27=PB13
Mcu.Pin28=PB14
Mcu.Pin29=PB15
Mcu.Pin3=PC14-OSC32_IN
Mcu.Pin30=PD8
Mcu.Pin31=PD9
Mcu.Pin32=PD12
Mcu.Pin33=PD13
Mcu.Pin34=PA9
Mcu.Pin35=PA10
Mcu.Pin36=PA11
Mcu.Pin37=PA12
Mcu.Pin38=PA13(JTMS/SWDIO)
Mcu.Pin39=PA14(JTCK/SWCLK)
Mcu.Pin4=PC15-OSC32_OUT
Mcu.Pin40=PA15(JTDI)
Mcu.Pin41=PC12
Mcu.Pin42=PD0
Mcu.Pin43=PD1
Mcu.Pin44=PD2
Mcu.Pin45=PD4
Mcu.Pin46=PD5
Mcu.Pin47=PD6
Mcu.Pin48=PB3(JTDO/TRACESWO)
Mcu.Pin49=PB5
Mcu.Pin5=PH0-OSC_IN
Mcu.Pin50=PB6
Mcu.Pin51=VP_DAC1_VS_DACI2
Mcu.Pin52=VP_FREERTOS_VS_CMSIS_V2
Mcu.Pin53=VP_SYS_VS_tim4
Mcu.Pin54=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin6=PH1-OSC_OUT
Mcu.Pin7=PC0
Mcu.Pin8=PC1
Mcu.Pin9=PC2_C
Mcu.PinsNb=55
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32H723VGTx
MxCube.Version=6.15.0
MxDb.Version=DB.6.0.150
NVIC.BDMA_Channel0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.DMA1_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream6_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA1_Stream7_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream0_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream1_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream3_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream4_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DMA2_Stream5_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.FDCAN1_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN1_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN2_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT0_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.FDCAN3_IT1_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
NVIC.OTG_HS_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.PendSV_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SPI2_IRQn=true\:5\:0\:false\:false\:true\:true\:false\:true\:true
NVIC.SPI6_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false\:false
NVIC.SavedPendsvIrqHandlerGenerated=true
NVIC.SavedSvcallIrqHandlerGenerated=true
NVIC.SavedSystickIrqHandlerGenerated=true
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true\:false
NVIC.TIM4_IRQn=true\:15\:0\:false\:false\:true\:false\:false\:true\:true
NVIC.TimeBase=TIM4_IRQn
NVIC.TimeBaseIP=TIM4
NVIC.UART5_IRQn=true\:5\:0\:false\:false\:true\:true\:true\:true\:true
NVIC.UART7_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART10_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART2_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.USART3_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false\:false
PA0.Locked=true
PA0.Signal=S_TIM2_CH1_ETR
PA10.Locked=true
PA10.Mode=Asynchronous
PA10.Signal=USART1_RX
PA11.Mode=Device_Only_FS
PA11.Signal=USB_OTG_HS_DM
PA12.Mode=Device_Only_FS
PA12.Signal=USB_OTG_HS_DP
PA13(JTMS/SWDIO).Locked=true
PA13(JTMS/SWDIO).Mode=Serial_Wire
PA13(JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO
PA14(JTCK/SWCLK).Locked=true
PA14(JTCK/SWCLK).Mode=Serial_Wire
PA14(JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK
PA15(JTDI).Locked=true
PA15(JTDI).Signal=GPIO_Input
PA2.Locked=true
PA2.Signal=S_TIM2_CH3
PA5.Locked=true
PA5.Signal=ADCx_INP19
PA7.Mode=TX_Only_Simplex_Unidirect_Master
PA7.Signal=SPI6_MOSI
PA9.Locked=true
PA9.Mode=Asynchronous
PA9.Signal=USART1_TX
PB1.Locked=true
PB1.Signal=S_TIM3_CH4
PB10.GPIOParameters=GPIO_Label
PB10.GPIO_Label=LCD_BLK
PB10.Locked=true
PB10.Signal=GPIO_Output
PB11.GPIOParameters=GPIO_Label
PB11.GPIO_Label=LCD_RES
PB11.Locked=true
PB11.Signal=GPIO_Output
PB13.GPIOParameters=GPIO_Speed
PB13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PB13.Locked=true
PB13.Mode=Full_Duplex_Master
PB13.Signal=SPI2_SCK
PB14.Mode=Hardware Flow Control (RS485)
PB14.Signal=USART3_DE
PB15.Locked=true
PB15.Signal=S_TIM12_CH2
PB3(JTDO/TRACESWO).Mode=TX_Only_Simplex_Unidirect_Master
PB3(JTDO/TRACESWO).Signal=SPI6_SCK
PB5.Locked=true
PB5.Mode=FDCAN_Activate
PB5.Signal=FDCAN2_RX
PB6.Locked=true
PB6.Mode=FDCAN_Activate
PB6.Signal=FDCAN2_TX
PC0.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PC0.GPIO_Label=ACC_CS
PC0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC0.Locked=true
PC0.PinState=GPIO_PIN_SET
PC0.Signal=GPIO_Output
PC1.GPIOParameters=GPIO_Speed
PC1.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC1.Mode=Full_Duplex_Master
PC1.Signal=SPI2_MOSI
PC12.Mode=Asynchronous
PC12.Signal=UART5_TX
PC13.GPIOParameters=PinState,GPIO_Label
PC13.GPIO_Label=POWER_24V_2
PC13.Locked=true
PC13.PinState=GPIO_PIN_SET
PC13.Signal=GPIO_Output
PC14-OSC32_IN.Locked=true
PC14-OSC32_IN.Signal=GPIO_Output
PC15-OSC32_OUT.GPIOParameters=PinState,GPIO_Label
PC15-OSC32_OUT.GPIO_Label=POWER_5V
PC15-OSC32_OUT.Locked=true
PC15-OSC32_OUT.PinState=GPIO_PIN_SET
PC15-OSC32_OUT.Signal=GPIO_Output
PC2_C.GPIOParameters=GPIO_Speed
PC2_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC2_C.Mode=Full_Duplex_Master
PC2_C.Signal=SPI2_MISO
PC3_C.GPIOParameters=GPIO_Speed,PinState,GPIO_Label
PC3_C.GPIO_Label=GYRO_CS
PC3_C.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PC3_C.Locked=true
PC3_C.PinState=GPIO_PIN_SET
PC3_C.Signal=GPIO_Output
PC4.Locked=true
PC4.Signal=ADCx_INP4
PD0.Mode=FDCAN_Activate
PD0.Signal=FDCAN1_RX
PD1.Locked=true
PD1.Mode=FDCAN_Activate
PD1.Signal=FDCAN1_TX
PD12.Mode=FDCAN_Activate
PD12.Signal=FDCAN3_RX
PD13.Locked=true
PD13.Mode=FDCAN_Activate
PD13.Signal=FDCAN3_TX
PD2.Mode=Asynchronous
PD2.Signal=UART5_RX
PD4.Locked=true
PD4.Mode=Hardware Flow Control (RS485)
PD4.Signal=USART2_DE
PD5.Locked=true
PD5.Mode=Asynchronous
PD5.Signal=USART2_TX
PD6.Locked=true
PD6.Mode=Asynchronous
PD6.Signal=USART2_RX
PD8.Mode=Asynchronous
PD8.Signal=USART3_TX
PD9.Mode=Asynchronous
PD9.Signal=USART3_RX
PE10.GPIOParameters=GPIO_PuPd,GPIO_Label
PE10.GPIO_Label=ACC_INT
PE10.GPIO_PuPd=GPIO_NOPULL
PE10.Locked=true
PE10.Signal=GPXTI10
PE11.GPIOParameters=GPIO_Label
PE11.GPIO_Label=W25Q64_CS
PE11.Locked=true
PE11.Signal=GPIO_Output
PE12.GPIOParameters=GPIO_Label
PE12.GPIO_Label=GYRO_INT
PE12.Locked=true
PE12.Signal=GPXTI12
PE13.Signal=S_TIM1_CH3
PE15.GPIOParameters=GPIO_Label
PE15.GPIO_Label=LCD_CS
PE15.Locked=true
PE15.Signal=GPIO_Output
PE2.Mode=Asynchronous
PE2.Signal=USART10_RX
PE3.Mode=Asynchronous
PE3.Signal=USART10_TX
PE7.Mode=Asynchronous
PE7.Signal=UART7_RX
PE8.Mode=Asynchronous
PE8.Signal=UART7_TX
PE9.Locked=true
PE9.Signal=S_TIM1_CH1
PH0-OSC_IN.Mode=HSE-External-Oscillator
PH0-OSC_IN.Signal=RCC_OSC_IN
PH1-OSC_OUT.Mode=HSE-External-Oscillator
PH1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerLinker=GCC
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32H723VGTx
ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.12.1
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=0
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=balance_infantry.ioc
ProjectManager.ProjectName=balance_infantry
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x800
ProjectManager.TargetToolchain=CMake
ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_BDMA_Init-BDMA-false-HAL-true,5-MX_ADC1_Init-ADC1-false-HAL-true,6-MX_TIM12_Init-TIM12-false-HAL-true,7-MX_SPI6_Init-SPI6-false-HAL-true,8-MX_SPI2_Init-SPI2-false-HAL-true,9-MX_TIM3_Init-TIM3-false-HAL-true,10-MX_USART1_UART_Init-USART1-false-HAL-true,11-MX_USART2_UART_Init-USART2-false-HAL-true,12-MX_USART3_UART_Init-USART3-false-HAL-true,13-MX_UART7_Init-UART7-false-HAL-true,14-MX_USART10_UART_Init-USART10-false-HAL-true,15-MX_FDCAN1_Init-FDCAN1-false-HAL-true,16-MX_FDCAN2_Init-FDCAN2-false-HAL-true,17-MX_FDCAN3_Init-FDCAN3-false-HAL-true,18-MX_TIM1_Init-TIM1-false-HAL-true,19-MX_TIM2_Init-TIM2-false-HAL-true,20-MX_DAC1_Init-DAC1-false-HAL-true,21-MX_USB_OTG_HS_PCD_Init-USB_OTG_HS-false-HAL-true,22-MX_UART5_Init-UART5-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
RCC.ADCFreq_Value=64000000
RCC.AHB12Freq_Value=275000000
RCC.AHB4Freq_Value=275000000
RCC.APB1Freq_Value=137500000
RCC.APB2Freq_Value=137500000
RCC.APB3Freq_Value=137500000
RCC.APB4Freq_Value=137500000
RCC.AXIClockFreq_Value=275000000
RCC.CECFreq_Value=32000
RCC.CKPERFreq_Value=64000000
RCC.CortexFreq_Value=550000000
RCC.CpuClockFreq_Value=550000000
RCC.D1CPREFreq_Value=550000000
RCC.D1PPRE=RCC_APB3_DIV2
RCC.D2PPRE1=RCC_APB1_DIV2
RCC.D2PPRE2=RCC_APB2_DIV2
RCC.D3PPRE=RCC_APB4_DIV2
RCC.DFSDMACLkFreq_Value=55000000
RCC.DFSDMFreq_Value=137500000
RCC.DIVM1=3
RCC.DIVM2=2
RCC.DIVN1=68
RCC.DIVN2=16
RCC.DIVN3=128
RCC.DIVP1=1
RCC.DIVP1Freq_Value=550000000
RCC.DIVP2=3
RCC.DIVP2Freq_Value=64000000
RCC.DIVP3=4
RCC.DIVP3Freq_Value=24000000
RCC.DIVQ1=10
RCC.DIVQ1Freq_Value=55000000
RCC.DIVQ2Freq_Value=96000000
RCC.DIVQ3Freq_Value=48000000
RCC.DIVR1Freq_Value=275000000
RCC.DIVR2Freq_Value=96000000
RCC.DIVR3Freq_Value=48000000
RCC.FDCANFreq_Value=55000000
RCC.FMCFreq_Value=275000000
RCC.FamilyName=M
RCC.HCLK3ClockFreq_Value=275000000
RCC.HCLKFreq_Value=275000000
RCC.HPRE=RCC_HCLK_DIV2
RCC.HSE_VALUE=24000000
RCC.I2C123Freq_Value=137500000
RCC.I2C4Freq_Value=137500000
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVN1,DIVN2,DIVN3,DIVP1,DIVP1Freq_Value,DIVP2,DIVP2Freq_Value,DIVP3,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HSE_VALUE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL2_VCI_Range-AdvancedSettings,PLL2_VCO_SEL-AdvancedSettings,PLL3FRACN,PLL3_VCO_SEL-AdvancedSettings,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123CLockSelection,SPI123Freq_Value,SPI45Freq_Value,SPI6CLockSelection,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
RCC.LPTIM1Freq_Value=137500000
RCC.LPTIM2Freq_Value=137500000
RCC.LPTIM345Freq_Value=137500000
RCC.LPUART1Freq_Value=137500000
RCC.LTDCFreq_Value=48000000
RCC.MCO1PinFreq_Value=64000000
RCC.MCO2PinFreq_Value=550000000
RCC.PLL2FRACN=0
RCC.PLL2_VCI_Range-AdvancedSettings=RCC_PLL2VCIRANGE_0
RCC.PLL2_VCO_SEL-AdvancedSettings=RCC_PLL2VCOWIDE
RCC.PLL3FRACN=0
RCC.PLL3_VCO_SEL-AdvancedSettings=RCC_PLL3VCOMEDIUM
RCC.PLLFRACN=6144
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.QSPIFreq_Value=275000000
RCC.RNGFreq_Value=48000000
RCC.RTCFreq_Value=32000
RCC.SAI1Freq_Value=55000000
RCC.SAI4AFreq_Value=55000000
RCC.SAI4BFreq_Value=55000000
RCC.SDMMCFreq_Value=55000000
RCC.SPDIFRXFreq_Value=55000000
RCC.SPI123CLockSelection=RCC_SPI123CLKSOURCE_PLL2
RCC.SPI123Freq_Value=64000000
RCC.SPI45Freq_Value=137500000
RCC.SPI6CLockSelection=RCC_SPI6CLKSOURCE_HSE
RCC.SPI6Freq_Value=24000000
RCC.SWPMI1Freq_Value=137500000
RCC.SYSCLKFreq_VALUE=550000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.Tim1OutputFreq_Value=275000000
RCC.Tim2OutputFreq_Value=275000000
RCC.TraceFreq_Value=275000000
RCC.USART16Freq_Value=137500000
RCC.USART234578Freq_Value=137500000
RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48
RCC.USBFreq_Value=48000000
RCC.VCO1OutputFreq_Value=550000000
RCC.VCO2OutputFreq_Value=192000000
RCC.VCO3OutputFreq_Value=96000000
RCC.VCOInput1Freq_Value=8000000
RCC.VCOInput2Freq_Value=12000000
RCC.VCOInput3Freq_Value=750000
SH.ADCx_INP19.0=ADC1_INP19,IN19-Single-Ended
SH.ADCx_INP19.ConfNb=1
SH.ADCx_INP4.0=ADC1_INP4,IN4-Single-Ended
SH.ADCx_INP4.ConfNb=1
SH.GPXTI10.0=GPIO_EXTI10
SH.GPXTI10.ConfNb=1
SH.GPXTI12.0=GPIO_EXTI12
SH.GPXTI12.ConfNb=1
SH.S_TIM12_CH2.0=TIM12_CH2,PWM Generation2 CH2
SH.S_TIM12_CH2.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
SH.S_TIM1_CH1.ConfNb=1
SH.S_TIM1_CH3.0=TIM1_CH3,PWM Generation3 CH3
SH.S_TIM1_CH3.ConfNb=1
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
SH.S_TIM2_CH1_ETR.ConfNb=1
SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
SH.S_TIM2_CH3.ConfNb=1
SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4
SH.S_TIM3_CH4.ConfNb=1
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32
SPI2.CLKPhase=SPI_PHASE_2EDGE
SPI2.CLKPolarity=SPI_POLARITY_HIGH
SPI2.CalculateBaudRate=2.0 MBits/s
SPI2.DataSize=SPI_DATASIZE_8BIT
SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPolarity,CLKPhase
SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
SPI6.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_4
SPI6.CLKPhase=SPI_PHASE_2EDGE
SPI6.CalculateBaudRate=6.0 MBits/s
SPI6.DataSize=SPI_DATASIZE_8BIT
SPI6.Direction=SPI_DIRECTION_2LINES_TXONLY
SPI6.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPhase
SPI6.Mode=SPI_MODE_MASTER
SPI6.VirtualType=VM_MASTER
TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM1.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM1.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation1 CH1,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
TIM1.Period=10000
TIM1.Prescaler=24
TIM1.Pulse-PWM\ Generation1\ CH1=5000
TIM1.Pulse-PWM\ Generation3\ CH3=5000
TIM12.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
TIM12.IPParameters=Channel-PWM Generation2 CH2,Prescaler,Period
TIM12.Period=2000-1
TIM12.Prescaler=24-1
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM2.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation3 CH3,Period,Pulse-PWM Generation1 CH1,Pulse-PWM Generation3 CH3,Prescaler
TIM2.Period=10000
TIM2.Prescaler=24
TIM2.Pulse-PWM\ Generation1\ CH1=5000
TIM2.Pulse-PWM\ Generation3\ CH3=5000
TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
TIM3.IPParameters=Channel-PWM Generation4 CH4,Prescaler,Period,AutoReloadPreload
TIM3.Period=10000-1
TIM3.Prescaler=24-1
UART5.BaudRate=100000
UART5.IPParameters=BaudRate,WordLength,Parity,Mode
UART5.Mode=MODE_RX
UART5.Parity=PARITY_EVEN
UART5.WordLength=WORDLENGTH_9B
UART7.BaudRate=921600
UART7.IPParameters=BaudRate
USART1.BaudRate=921600
USART1.IPParameters=VirtualMode-Asynchronous,BaudRate
USART1.VirtualMode-Asynchronous=VM_ASYNC
USART10.BaudRate=921600
USART10.IPParameters=VirtualMode,BaudRate
USART10.VirtualMode=VM_ASYNC
USART2.BaudRate=921600
USART2.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
USART2.VirtualMode-Asynchronous=VM_ASYNC
USART2.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
USART3.BaudRate=921600
USART3.IPParameters=VirtualMode-Asynchronous,VirtualMode-Hardware Flow Control (RS485),BaudRate
USART3.VirtualMode-Asynchronous=VM_ASYNC
USART3.VirtualMode-Hardware\ Flow\ Control\ (RS485)=VM_ASYNC
USB_OTG_HS.IPParameters=VirtualMode-Device_Only_FS,dma_enable-Device_Only_FS
USB_OTG_HS.VirtualMode-Device_Only_FS=Device_Only_FS
USB_OTG_HS.dma_enable-Device_Only_FS=ENABLE
VP_DAC1_VS_DACI2.Mode=DAC_OUT2_Int
VP_DAC1_VS_DACI2.Signal=DAC1_VS_DACI2
VP_FREERTOS_VS_CMSIS_V2.Mode=CMSIS_V2
VP_FREERTOS_VS_CMSIS_V2.Signal=FREERTOS_VS_CMSIS_V2
VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
VP_SYS_VS_tim4.Mode=TIM4
VP_SYS_VS_tim4.Signal=SYS_VS_tim4
board=custom

View File

@ -27,10 +27,9 @@ set(MX_Application_Src
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/gpio.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/gpio.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/freertos.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/freertos.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/adc.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/adc.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/bdma.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/dac.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/dma.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/dma.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/fdcan.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/fdcan.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/octospi.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/spi.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/spi.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/tim.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/tim.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/usart.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Core/Src/usart.c
@ -66,9 +65,8 @@ set(STM32_Drivers_Src
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dac.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dac_ex.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_fdcan.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_ospi.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c
${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c