diff --git a/.vscode/launch.json b/.vscode/launch.json index 2a0845dc..cdb5115c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -223,7 +223,7 @@ { "cwd": "${workspaceFolder}", "executable": "${command:cmake.buildDirectory}/G4ADCTESTING.elf", - "name": "G4ADCTESTING", + "name": "G4CANTESTING", "request": "launch", "type": "cortex-debug", "servertype": "openocd", @@ -234,7 +234,7 @@ "searchDir": [], "preLaunchTask": "CMake: configure and build G4ADCTESTING", "showDevDebugOutput": "raw", - "svdPath": "${workspaceFolder}/Lib/Vendor/CMSIS_5/SVD/STM32G474.svd", + "svdPath": "${workspaceFolder}/Lib/Platform/STM32G474xE/CompileDependencies/STM32G474.svd", "swoConfig": { "enabled": true, "cpuFrequency": 170000000, @@ -250,6 +250,37 @@ } ] } + }, + { + "cwd": "${workspaceFolder}", + "executable": "${command:cmake.buildDirectory}/G4CANTESTING.elf", + "name": "G4CANTESTING", + "request": "launch", + "type": "cortex-debug", + "servertype": "openocd", + "configFiles": [ + "interface/stlink.cfg", + "target/stm32g4x.cfg" + ], + "searchDir": [], + "preLaunchTask": "CMake: configure and build G4CANTESTING", + "showDevDebugOutput": "raw", + "svdPath": "${workspaceFolder}/Lib/Platform/STM32G474xE/CompileDependencies/STM32G474.svd", + "swoConfig": { + "enabled": true, + "cpuFrequency": 160000000, + "swoFrequency": 2000000, + "source": "probe", + "decoders": [ + { + "type": "console", + "label": "ITM", + "showOnStartup": true, + "port": 0, + "encoding": "ascii" + } + ] + } } ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f06bd93c..0e2fd381 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -28,13 +28,13 @@ "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target CCU" }, { - "label": "CMake: configure and build G4HELLO", + "label": "CMake: configure and build G4ADCTESTING", "type": "shell", "dependsOrder": "sequence", "dependsOn": [ "CMake: configure" ], - "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4HELLO" + "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4ADCTESTING" }, { "label": "CMake: configure and build G4PERTESTING", @@ -46,13 +46,22 @@ "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4PERTESTING" }, { - "label": "CMake: configure and build G4ADCTESTING", + "label": "CMake: configure and build G4CANTESTING", "type": "shell", "dependsOrder": "sequence", "dependsOn": [ "CMake: configure" ], - "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4ADCTESTING" + "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4CANTESTING" + }, + { + "label": "CMake: configure and build G4HELLO", + "type": "shell", + "dependsOrder": "sequence", + "dependsOn": [ + "CMake: configure" + ], + "command": "cmake --build build/${command:cmake.activeBuildPresetName} --target G4HELLO" }, { "label": "CMake: configure and build G4BLINKY", diff --git a/CMakeLists.txt b/CMakeLists.txt index 999f4464..bb3126aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ include("${lib_path}/Utils/BitManipulations/bit-utils.cmake") # Peripherals include("${lib_path}/Peripherals/USART/common.cmake") +include("${lib_path}/Peripherals/CAN/common.cmake") include("${lib_path}/FancyLayers-RENAME/ADC/adc.cmake") # FIXME Temporary holdover for CAN messages until URCA is ready for merge @@ -67,6 +68,7 @@ add_gr_project(STM32G474xE CCU) # Development add_gr_project(STM32G474xE G4ADCTESTING) add_gr_project(STM32G474xE G4PERTESTING) +add_gr_project(STM32G474xE G4CANTESTING) # BLINKY Demos add_gr_project(STM32G474xE BLINKY G4HELLO) diff --git a/G4CANTESTING/CMakeLists.txt b/G4CANTESTING/CMakeLists.txt new file mode 100644 index 00000000..0c52f1d1 --- /dev/null +++ b/G4CANTESTING/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.25) + +# Setup compiler settings +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) + +# Define the build type +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug") +endif() + +# Enable compile command to ease indexing with e.g. clangd +set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE) + +# Enable CMake support for ASM and C languages +enable_language( + C + ASM +) + +# Core project settings +project(${CMAKE_PROJECT_NAME}) + +# what, does in fact not get the filename of somthing but rather the name of the project from the path +get_filename_component(PROJECT_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME) + +add_library(${PROJECT_NAME}_USER_CODE INTERFACE) + +target_sources( + ${PROJECT_NAME}_USER_CODE + INTERFACE + Core/Src/adc.c + Core/Src/crc.c + Core/Src/dma.c + Core/Src/gpio.c + Core/Src/i2c.c + Core/Src/main.c + Core/Src/spi.c + Core/Src/stm32g4xx_hal_msp.c + Core/Src/stm32g4xx_it.c + Core/Src/syscalls.c + Core/Src/sysmem.c + Core/Src/system_stm32g4xx.c + Core/Src/tim.c + Core/Src/usart.c +) + +target_link_libraries(${PROJECT_NAME}_USER_CODE INTERFACE PERIPHERAL_CAN_LIB) +target_link_libraries( + ${PROJECT_NAME}_USER_CODE + INTERFACE + PERIPHERAL_CAN_TEST_LIB +) + +target_include_directories(${PROJECT_NAME}_USER_CODE INTERFACE Core/Inc) diff --git a/G4CANTESTING/Core/Inc/adc.h b/G4CANTESTING/Core/Inc/adc.h new file mode 100644 index 00000000..41154538 --- /dev/null +++ b/G4CANTESTING/Core/Inc/adc.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ADC_H__ +#define __ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_ADC1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_H__ */ diff --git a/G4CANTESTING/Core/Inc/crc.h b/G4CANTESTING/Core/Inc/crc.h new file mode 100644 index 00000000..133957e9 --- /dev/null +++ b/G4CANTESTING/Core/Inc/crc.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.h + * @brief This file contains all the function prototypes for + * the crc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __CRC_H__ +#define __CRC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern CRC_HandleTypeDef hcrc; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_CRC_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CRC_H__ */ diff --git a/G4CANTESTING/Core/Inc/dma.h b/G4CANTESTING/Core/Inc/dma.h new file mode 100644 index 00000000..ae819cab --- /dev/null +++ b/G4CANTESTING/Core/Inc/dma.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.h + * @brief This file contains all the function prototypes for + * the dma.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __DMA_H__ +#define __DMA_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* DMA memory to memory transfer handles -------------------------------------*/ + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_DMA_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __DMA_H__ */ diff --git a/G4CANTESTING/Core/Inc/fdcan.h b/G4CANTESTING/Core/Inc/fdcan.h new file mode 100644 index 00000000..56c4a8ad --- /dev/null +++ b/G4CANTESTING/Core/Inc/fdcan.h @@ -0,0 +1,51 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file fdcan.h + * @brief This file contains all the function prototypes for + * the fdcan.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __FDCAN_H__ +#define __FDCAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern FDCAN_HandleTypeDef hfdcan2; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_FDCAN2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __FDCAN_H__ */ diff --git a/G4CANTESTING/Core/Inc/gpio.h b/G4CANTESTING/Core/Inc/gpio.h new file mode 100644 index 00000000..843d4e9e --- /dev/null +++ b/G4CANTESTING/Core/Inc/gpio.h @@ -0,0 +1,48 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_GPIO_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif +#endif /*__ GPIO_H__ */ diff --git a/G4CANTESTING/Core/Inc/i2c.h b/G4CANTESTING/Core/Inc/i2c.h new file mode 100644 index 00000000..0a0a5080 --- /dev/null +++ b/G4CANTESTING/Core/Inc/i2c.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.h + * @brief This file contains all the function prototypes for + * the i2c.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __I2C_H__ +#define __I2C_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_I2C2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __I2C_H__ */ diff --git a/G4CANTESTING/Core/Inc/main.h b/G4CANTESTING/Core/Inc/main.h new file mode 100644 index 00000000..23d7ffce --- /dev/null +++ b/G4CANTESTING/Core/Inc/main.h @@ -0,0 +1,115 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32g4xx_hal.h" +#include "stm32g4xx_ll_adc.h" +#include "stm32g4xx_ll_bus.h" +#include "stm32g4xx_ll_cortex.h" +#include "stm32g4xx_ll_crs.h" +#include "stm32g4xx_ll_dma.h" +#include "stm32g4xx_ll_exti.h" +#include "stm32g4xx_ll_gpio.h" +#include "stm32g4xx_ll_i2c.h" +#include "stm32g4xx_ll_lpuart.h" +#include "stm32g4xx_ll_pwr.h" +#include "stm32g4xx_ll_rcc.h" +#include "stm32g4xx_ll_spi.h" +#include "stm32g4xx_ll_system.h" +#include "stm32g4xx_ll_tim.h" +#include "stm32g4xx_ll_usart.h" +#include "stm32g4xx_ll_utils.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define BSPD_SIGNAL_Pin LL_GPIO_PIN_1 +#define BSPD_SIGNAL_GPIO_Port GPIOC +#define APPS1_SIGNAL_Pin LL_GPIO_PIN_2 +#define APPS1_SIGNAL_GPIO_Port GPIOC +#define APPS2_SIGNAL_Pin LL_GPIO_PIN_3 +#define APPS2_SIGNAL_GPIO_Port GPIOC +#define BLINKY_Pin LL_GPIO_PIN_5 +#define BLINKY_GPIO_Port GPIOA +#define IMD_SENSE_Pin LL_GPIO_PIN_6 +#define IMD_SENSE_GPIO_Port GPIOA +#define AMS_SENSE_Pin LL_GPIO_PIN_7 +#define AMS_SENSE_GPIO_Port GPIOA +#define BRAKE_F_SIGNAL_Pin LL_GPIO_PIN_0 +#define BRAKE_F_SIGNAL_GPIO_Port GPIOB +#define BRAKE_R_SIGNAL_Pin LL_GPIO_PIN_1 +#define BRAKE_R_SIGNAL_GPIO_Port GPIOB +#define LED_TEST_Pin LL_GPIO_PIN_11 +#define LED_TEST_GPIO_Port GPIOB +#define AUX_SIGNAL_Pin LL_GPIO_PIN_14 +#define AUX_SIGNAL_GPIO_Port GPIOB +#define STEERING_ANGLE_Pin LL_GPIO_PIN_15 +#define STEERING_ANGLE_GPIO_Port GPIOB +#define BRAKE_LIGHT_Pin LL_GPIO_PIN_4 +#define BRAKE_LIGHT_GPIO_Port GPIOB +#define TSSI_G_CONTROL_Pin LL_GPIO_PIN_5 +#define TSSI_G_CONTROL_GPIO_Port GPIOB +#define AUX_CONTROL_Pin LL_GPIO_PIN_8 +#define AUX_CONTROL_GPIO_Port GPIOB +#define SOFTWARE_OK_CONTROL_Pin LL_GPIO_PIN_9 +#define SOFTWARE_OK_CONTROL_GPIO_Port GPIOB + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/G4CANTESTING/Core/Inc/spi.h b/G4CANTESTING/Core/Inc/spi.h new file mode 100644 index 00000000..74bed003 --- /dev/null +++ b/G4CANTESTING/Core/Inc/spi.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.h + * @brief This file contains all the function prototypes for + * the spi.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SPI_H__ +#define __SPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_SPI3_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __SPI_H__ */ diff --git a/G4CANTESTING/Core/Inc/stm32_assert.h b/G4CANTESTING/Core/Inc/stm32_assert.h new file mode 100644 index 00000000..92460620 --- /dev/null +++ b/G4CANTESTING/Core/Inc/stm32_assert.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32_assert.h + * @author MCD Application Team + * @brief STM32 assert file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32_ASSERT_H +#define __STM32_ASSERT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_ASSERT_H */ diff --git a/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h b/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h new file mode 100644 index 00000000..3e1fcb01 --- /dev/null +++ b/G4CANTESTING/Core/Inc/stm32g4xx_hal_conf.h @@ -0,0 +1,390 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32G4xx_HAL_CONF_H +#define STM32G4xx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED + +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CORDIC_MODULE_ENABLED */ +#define HAL_CRC_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +#define HAL_FDCAN_MODULE_ENABLED +/*#define HAL_FMAC_MODULE_ENABLED */ +/*#define HAL_HRTIM_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_I2C_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_UART_MODULE_ENABLED */ +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Register Callbacks selection + * ############################## */ +/** + * @brief This is the list of modules where register callback can be used + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_EXTI_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FMAC_REGISTER_CALLBACKS 0U +#define USE_HAL_HRTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U +#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U + +/* ########################## Oscillator Values adaptation + * ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your + * application. This value is used by the RCC HAL module to compute the system + * frequency (when HSE is used as system clock source, directly or through the + * PLL). + */ +#if !defined(HSE_VALUE) +#define HSE_VALUE (16000000UL) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system + * frequency (when HSI is used as system clock source, directly or through the + * PLL). + */ +#if !defined(HSI_VALUE) +#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS and RNG. + * This internal oscillator is mainly dedicated to provide a high + * precision clock to the USB peripheral by means of a special Clock Recovery + * System (CRS) circuitry. When the CRS is not used, the HSI48 RC oscillator + * runs on it default frequency which is subject to manufacturing process + * variations. + */ +#if !defined(HSI48_VALUE) +#define HSI48_VALUE \ + (48000000UL) /*!< Value of the Internal High Speed oscillator for USB \ + FS/RNG in Hz. The real value my vary depending on \ + manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined(LSI_VALUE) +/*!< Value of the Internal Low Speed oscillator in Hz +The real value may vary depending on the variations in voltage and +temperature.*/ +#define LSI_VALUE (32000UL) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system + * frequency + */ +#if !defined(LSE_VALUE) +#define LSE_VALUE (32768UL) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined(LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S and SAI peripherals + * This value is used by the I2S and SAI HAL modules to compute the I2S + * and SAI clock source frequency, this source is inserted directly through + * I2S_CKIN pad. + */ +#if !defined(EXTERNAL_CLOCK_VALUE) +#define EXTERNAL_CLOCK_VALUE (12288000UL) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32g4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32g4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32g4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32g4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32g4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32g4xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORDIC_MODULE_ENABLED +#include "stm32g4xx_hal_cordic.h" +#endif /* HAL_CORDIC_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32g4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32g4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED +#include "stm32g4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32g4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FDCAN_MODULE_ENABLED +#include "stm32g4xx_hal_fdcan.h" +#endif /* HAL_FDCAN_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32g4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_FMAC_MODULE_ENABLED +#include "stm32g4xx_hal_fmac.h" +#endif /* HAL_FMAC_MODULE_ENABLED */ + +#ifdef HAL_HRTIM_MODULE_ENABLED +#include "stm32g4xx_hal_hrtim.h" +#endif /* HAL_HRTIM_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32g4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32g4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32g4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED +#include "stm32g4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32g4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED +#include "stm32g4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED +#include "stm32g4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED +#include "stm32g4xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32g4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32g4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED +#include "stm32g4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32g4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32g4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32g4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32g4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32g4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32g4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED +#include "stm32g4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32g4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32g4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32g4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32g4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32G4xx_HAL_CONF_H */ diff --git a/G4CANTESTING/Core/Inc/stm32g4xx_it.h b/G4CANTESTING/Core/Inc/stm32g4xx_it.h new file mode 100644 index 00000000..b6c3b2f7 --- /dev/null +++ b/G4CANTESTING/Core/Inc/stm32g4xx_it.h @@ -0,0 +1,67 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32G4xx_IT_H +#define __STM32G4xx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void FDCAN2_IT0_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32G4xx_IT_H */ diff --git a/G4CANTESTING/Core/Inc/tim.h b/G4CANTESTING/Core/Inc/tim.h new file mode 100644 index 00000000..c19e6cc7 --- /dev/null +++ b/G4CANTESTING/Core/Inc/tim.h @@ -0,0 +1,49 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TIM_H__ +#define __TIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_TIM2_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_H__ */ diff --git a/G4CANTESTING/Core/Inc/usart.h b/G4CANTESTING/Core/Inc/usart.h new file mode 100644 index 00000000..daefd73e --- /dev/null +++ b/G4CANTESTING/Core/Inc/usart.h @@ -0,0 +1,50 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.h + * @brief This file contains all the function prototypes for + * the usart.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USART_H__ +#define __USART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_LPUART1_UART_Init(void); +void MX_USART1_UART_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USART_H__ */ diff --git a/G4CANTESTING/Core/Src/adc.c b/G4CANTESTING/Core/Src/adc.c new file mode 100644 index 00000000..f3dbff8e --- /dev/null +++ b/G4CANTESTING/Core/Src/adc.c @@ -0,0 +1,186 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "adc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + LL_ADC_InitTypeDef ADC_InitStruct = {0}; + LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0}; + LL_ADC_CommonInitTypeDef ADC_CommonInitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetADCClockSource(LL_RCC_ADC12_CLKSOURCE_SYSCLK); + + /* Peripheral clock enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**ADC1 GPIO Configuration + PC1 ------> ADC1_IN7 + PC2 ------> ADC1_IN8 + PC3 ------> ADC1_IN9 + PB0 ------> ADC1_IN15 + PB1 ------> ADC1_IN12 + PB14 ------> ADC1_IN5 + */ + GPIO_InitStruct.Pin = BSPD_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BSPD_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = APPS1_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(APPS1_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = APPS2_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(APPS2_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = BRAKE_F_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_F_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = BRAKE_R_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_R_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = AUX_SIGNAL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AUX_SIGNAL_GPIO_Port, &GPIO_InitStruct); + + /* ADC1 DMA Init */ + + /* ADC1 Init */ + LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1); + + LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_1, LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + + LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PRIORITY_LOW); + + LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MODE_CIRCULAR); + + LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PERIPH_NOINCREMENT); + + LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MEMORY_INCREMENT); + + LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_PDATAALIGN_HALFWORD); + + LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_1, LL_DMA_MDATAALIGN_HALFWORD); + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Common config + */ + ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B; + ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT; + ADC_InitStruct.LowPowerMode = LL_ADC_LP_MODE_NONE; + LL_ADC_Init(ADC1, &ADC_InitStruct); + ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE; + ADC_REG_InitStruct.SequencerLength = LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS; + ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE; + ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_CONTINUOUS; + ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_UNLIMITED; + ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED; + LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct); + LL_ADC_SetGainCompensation(ADC1, 0); + LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE); + ADC_CommonInitStruct.CommonClock = LL_ADC_CLOCK_ASYNC_DIV256; + ADC_CommonInitStruct.Multimode = LL_ADC_MULTI_INDEPENDENT; + LL_ADC_CommonInit(__LL_ADC_COMMON_INSTANCE(ADC1), &ADC_CommonInitStruct); + + /* Disable ADC deep power down (enabled by default after reset state) */ + LL_ADC_DisableDeepPowerDown(ADC1); + /* Enable ADC internal voltage regulator */ + LL_ADC_EnableInternalRegulator(ADC1); + /* Delay for ADC internal voltage regulator stabilization. */ + /* Compute number of CPU cycles to wait for, from delay in us. */ + /* Note: Variable divided by 2 to compensate partially */ + /* CPU processing cycles (depends on compilation optimization). */ + /* Note: If system core clock frequency is below 200kHz, wait time */ + /* is only a few CPU processing cycles. */ + uint32_t wait_loop_index; + wait_loop_index = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * (SystemCoreClock / (100000 * 2))) / 10); + while (wait_loop_index != 0) { + wait_loop_index--; + } + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_5); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_5, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_7); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_7, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_8); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_8, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_9); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_9, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_5, LL_ADC_CHANNEL_12); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_12, LL_ADC_SINGLE_ENDED); + + /** Configure Regular Channel + */ + LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_6, LL_ADC_CHANNEL_15); + LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SAMPLINGTIME_92CYCLES_5); + LL_ADC_SetChannelSingleDiff(ADC1, LL_ADC_CHANNEL_15, LL_ADC_SINGLE_ENDED); + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/crc.c b/G4CANTESTING/Core/Src/crc.c new file mode 100644 index 00000000..213510a5 --- /dev/null +++ b/G4CANTESTING/Core/Src/crc.c @@ -0,0 +1,86 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file crc.c + * @brief This file provides code for the configuration + * of the CRC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "crc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +CRC_HandleTypeDef hcrc; + +/* CRC init function */ +void MX_CRC_Init(void) +{ + + /* USER CODE BEGIN CRC_Init 0 */ + + /* USER CODE END CRC_Init 0 */ + + /* USER CODE BEGIN CRC_Init 1 */ + + /* USER CODE END CRC_Init 1 */ + hcrc.Instance = CRC; + hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; + hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; + hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; + hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; + hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; + if (HAL_CRC_Init(&hcrc) != HAL_OK) { + Error_Handler(); + } + /* USER CODE BEGIN CRC_Init 2 */ + + /* USER CODE END CRC_Init 2 */ +} + +void HAL_CRC_MspInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspInit 0 */ + + /* USER CODE END CRC_MspInit 0 */ + /* CRC clock enable */ + __HAL_RCC_CRC_CLK_ENABLE(); + /* USER CODE BEGIN CRC_MspInit 1 */ + + /* USER CODE END CRC_MspInit 1 */ + } +} + +void HAL_CRC_MspDeInit(CRC_HandleTypeDef *crcHandle) +{ + + if (crcHandle->Instance == CRC) { + /* USER CODE BEGIN CRC_MspDeInit 0 */ + + /* USER CODE END CRC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_CRC_CLK_DISABLE(); + /* USER CODE BEGIN CRC_MspDeInit 1 */ + + /* USER CODE END CRC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/dma.c b/G4CANTESTING/Core/Src/dma.c new file mode 100644 index 00000000..491e3889 --- /dev/null +++ b/G4CANTESTING/Core/Src/dma.c @@ -0,0 +1,50 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file dma.c + * @brief This file provides code for the configuration + * of all the requested memory to memory DMA transfers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "dma.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure DMA */ +/*----------------------------------------------------------------------------*/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Enable DMA controller clock + */ +void MX_DMA_Init(void) +{ + + /* Init with LL driver */ + /* DMA controller clock enable */ + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1); + LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/G4CANTESTING/Core/Src/fdcan.c b/G4CANTESTING/Core/Src/fdcan.c new file mode 100644 index 00000000..5373c38c --- /dev/null +++ b/G4CANTESTING/Core/Src/fdcan.c @@ -0,0 +1,135 @@ +// #include "unused.h" +// /* USER CODE BEGIN Header */ +// /** +// ****************************************************************************** +// * @file fdcan.c +// * @brief This file provides code for the configuration +// * of the FDCAN instances. +// ****************************************************************************** +// * @attention +// * +// * Copyright (c) 2024 STMicroelectronics. +// * All rights reserved. +// * +// * This software is licensed under terms that can be found in the LICENSE file +// * in the root directory of this software component. +// * If no LICENSE file comes with this software, it is provided AS-IS. +// * +// ****************************************************************************** +// */ +// /* USER CODE END Header */ +// /* Includes ------------------------------------------------------------------*/ +// #include "fdcan.h" + +// /* USER CODE BEGIN 0 */ + +// /* USER CODE END 0 */ + +// FDCAN_HandleTypeDef hfdcan2; + +// /* FDCAN2 init function */ +// void MX_FDCAN2_Init(void) +// { + +// /* USER CODE BEGIN FDCAN2_Init 0 */ + +// /* USER CODE END FDCAN2_Init 0 */ + +// /* USER CODE BEGIN FDCAN2_Init 1 */ + +// /* USER CODE END FDCAN2_Init 1 */ +// hfdcan2.Instance = FDCAN2; +// hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV1; +// hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; +// hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; +// hfdcan2.Init.AutoRetransmission = ENABLE; +// hfdcan2.Init.TransmitPause = DISABLE; +// hfdcan2.Init.ProtocolException = ENABLE; +// hfdcan2.Init.NominalPrescaler = 1; +// hfdcan2.Init.NominalSyncJumpWidth = 16; +// hfdcan2.Init.NominalTimeSeg1 = 119; +// hfdcan2.Init.NominalTimeSeg2 = 40; +// hfdcan2.Init.DataPrescaler = 8; +// hfdcan2.Init.DataSyncJumpWidth = 16; +// hfdcan2.Init.DataTimeSeg1 = 14; +// hfdcan2.Init.DataTimeSeg2 = 5; +// hfdcan2.Init.StdFiltersNbr = 0; +// hfdcan2.Init.ExtFiltersNbr = 2; +// hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; +// if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { +// Error_Handler(); +// } +// /* USER CODE BEGIN FDCAN2_Init 2 */ + +// /* USER CODE END FDCAN2_Init 2 */ +// } + +// void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// GPIO_InitTypeDef GPIO_InitStruct = {0}; +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspInit 0 */ + +// /* USER CODE END FDCAN2_MspInit 0 */ +// LL_RCC_SetFDCANClockSource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + +// /* FDCAN2 clock enable */ +// __HAL_RCC_FDCAN_CLK_ENABLE(); + +// __HAL_RCC_GPIOB_CLK_ENABLE(); +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// GPIO_InitStruct.Pin = GPIO_PIN_12; +// GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; +// GPIO_InitStruct.Pull = GPIO_PULLUP; +// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; +// GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// GPIO_InitStruct.Pin = GPIO_PIN_13; +// 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_FDCAN2; +// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +// /* FDCAN2 interrupt Init */ +// HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn, 0, 0); +// HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspInit 1 */ + +// /* USER CODE END FDCAN2_MspInit 1 */ +// } +// } + +// /*void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *fdcanHandle) +// { + +// if (fdcanHandle->Instance == FDCAN2) { +// /* USER CODE BEGIN FDCAN2_MspDeInit 0 */ + +// /* USER CODE END FDCAN2_MspDeInit 0 */ +// /* Peripheral clock disable */ +// __HAL_RCC_FDCAN_CLK_DISABLE(); + +// /**FDCAN2 GPIO Configuration +// PB12 ------> FDCAN2_RX +// PB13 ------> FDCAN2_TX +// */ +// HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13); + +// /* FDCAN2 interrupt Deinit */ +// HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); +// /* USER CODE BEGIN FDCAN2_MspDeInit 1 */ + +// /* USER CODE END FDCAN2_MspDeInit 1 */ +// } +// } + +// /* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +// UNUSED(5); \ No newline at end of file diff --git a/G4CANTESTING/Core/Src/gpio.c b/G4CANTESTING/Core/Src/gpio.c new file mode 100644 index 00000000..d36e6eca --- /dev/null +++ b/G4CANTESTING/Core/Src/gpio.c @@ -0,0 +1,260 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "gpio.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI + * Free pins are configured automatically as Analog (this feature is + enabled through + * the Code Generation settings) + PA6 ------> ADC2_IN3 + PA7 ------> ADC2_IN4 + PB15 ------> ADC2_IN15 + PB7 ------> UART4_CTS +*/ +void MX_GPIO_Init(void) +{ + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOF); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOG); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD); + + /**/ + LL_GPIO_ResetOutputPin(BLINKY_GPIO_Port, BLINKY_Pin); + + /**/ + LL_GPIO_ResetOutputPin(LED_TEST_GPIO_Port, LED_TEST_Pin); + + /**/ + LL_GPIO_ResetOutputPin(BRAKE_LIGHT_GPIO_Port, BRAKE_LIGHT_Pin); + + /**/ + LL_GPIO_ResetOutputPin(TSSI_G_CONTROL_GPIO_Port, TSSI_G_CONTROL_Pin); + + /**/ + LL_GPIO_ResetOutputPin(AUX_CONTROL_GPIO_Port, AUX_CONTROL_Pin); + + /**/ + LL_GPIO_ResetOutputPin(SOFTWARE_OK_CONTROL_GPIO_Port, SOFTWARE_OK_CONTROL_Pin); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_13; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_14; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_1; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = BLINKY_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BLINKY_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = IMD_SENSE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(IMD_SENSE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = AMS_SENSE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AMS_SENSE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LED_TEST_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(LED_TEST_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = STEERING_ANGLE_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(STEERING_ANGLE_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_9; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_15; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = BRAKE_LIGHT_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(BRAKE_LIGHT_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = TSSI_G_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(TSSI_G_CONTROL_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = LL_GPIO_PIN_7; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_14; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = AUX_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(AUX_CONTROL_GPIO_Port, &GPIO_InitStruct); + + /**/ + GPIO_InitStruct.Pin = SOFTWARE_OK_CONTROL_Pin; + GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + LL_GPIO_Init(SOFTWARE_OK_CONTROL_GPIO_Port, &GPIO_InitStruct); +} + +/* USER CODE BEGIN 2 */ + +/* USER CODE END 2 */ diff --git a/G4CANTESTING/Core/Src/i2c.c b/G4CANTESTING/Core/Src/i2c.c new file mode 100644 index 00000000..bfb4e015 --- /dev/null +++ b/G4CANTESTING/Core/Src/i2c.c @@ -0,0 +1,92 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file i2c.c + * @brief This file provides code for the configuration + * of the I2C instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "i2c.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* I2C2 init function */ +void MX_I2C2_Init(void) +{ + + /* USER CODE BEGIN I2C2_Init 0 */ + + /* USER CODE END I2C2_Init 0 */ + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetI2CClockSource(LL_RCC_I2C2_CLKSOURCE_PCLK1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**I2C2 GPIO Configuration + PC4 ------> I2C2_SCL + PA8 ------> I2C2_SDA + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_4; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_8; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_4; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2); + + /* USER CODE BEGIN I2C2_Init 1 */ + + /* USER CODE END I2C2_Init 1 */ + + /** I2C Initialization + */ + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.Timing = 0x30D29DE4; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + LL_I2C_Init(I2C2, &I2C_InitStruct); + LL_I2C_EnableAutoEndMode(I2C2); + LL_I2C_SetOwnAddress2(I2C2, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(I2C2); + LL_I2C_DisableGeneralCall(I2C2); + LL_I2C_EnableClockStretching(I2C2); + /* USER CODE BEGIN I2C2_Init 2 */ + + /* USER CODE END I2C2_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/main.c b/G4CANTESTING/Core/Src/main.c new file mode 100644 index 00000000..b5850c37 --- /dev/null +++ b/G4CANTESTING/Core/Src/main.c @@ -0,0 +1,278 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +#include "adc.h" +#include "can.h" // Assume this works +#include "can_tests.h" +#include "dma.h" +#include "fdcan.h" +#include "gpio.h" +#include "i2c.h" +#include "spi.h" +#include "tim.h" +#include "usart.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "Logomatic.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ +/* Enable ITM for SWO output */ +static void ITM_Enable(void) +{ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_0; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + DBGMCU->CR |= DBGMCU_CR_TRACE_IOEN; + + /* Enable TRC (Trace) */ + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + + /* Configure TPI for SWO output (set prescaler for 2MHz SWO clock) */ + TPI->SPPR = 2U; /* 2 = Manchester/async UART mode */ + TPI->ACPR = 84U; /* Prescaler: (170 MHz / (84+1) / 2) ≈ 1MHz SWO */ + + ITM->TER |= (1UL << 0); + ITM->TCR |= (ITM_TCR_ITMENA_Msk | ITM_TCR_SWOENA_Msk); +} +// static int toggleze = 0; +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU + * Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the + * Systick. */ + HAL_Init(); + /* USER CODE BEGIN Init */ + ITM_Enable(); + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_DMA_Init(); + // MX_FDCAN2_Init(); + MX_ADC1_Init(); + MX_LPUART1_UART_Init(); + MX_I2C2_Init(); + MX_USART1_UART_Init(); + MX_SPI3_Init(); + MX_TIM2_Init(); + + /* USER CODE BEGIN 2 */ + + LOGOMATIC("Booted!\n"); + + can_test(); + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + while (1) { + /* USER CODE END WHILE */ + LOGOMATIC("Main Loop\n"); + LL_mDelay(1000); + + // Receive on GPIOs + // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, toggleze ? GPIO_PIN_SET + // : GPIO_PIN_RESET); HAL_Delay(1000); msg.data[0] = toggleze ? + // 0x00 : 0x80; can_send(can2Handle, &msg); + + // RCC->CFGR |= RCC_CFGR_SW; + /* USER CODE BEGIN 3 */ + } +} + +/** + * @brief System Clock Configuration + * @retval None + */ + +// void SystemClock_Config(void) +// { +// LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); +// while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { +// } +// LL_PWR_EnableRange1BoostMode(); +// LL_RCC_HSE_Enable(); + +// /* Wait till HSE is ready */ +// while (LL_RCC_HSE_IsReady() != 1) { +// } + +// LL_RCC_HSE_EnableCSS(); +// LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_1, 20, +// LL_RCC_PLLR_DIV_2); +// //LL_RCC_PLL_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSE, ); +// LL_RCC_PLL_EnableDomain_SYS(); +// LL_RCC_PLL_Enable(); +// /* Wait till PLL is ready */ +// while (LL_RCC_PLL_IsReady() != 1) { +// } + +// LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); +// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); +// /* Wait till System clock is ready */ +// while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { +// } + +// /* Insure 1us transition state at intermediate medium speed clock*/ +// for (__IO uint32_t i = (170 >> 1); i != 0; i--) +// ; + +// /* Set AHB prescaler*/ +// LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); +// LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); +// LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); +// LL_SetSystemCoreClock(160000000); + +// /* Update the time base */ +// if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { +// Error_Handler(); +// } +// }*/ +void SystemClock_Config(void) +{ + LL_FLASH_SetLatency(LL_FLASH_LATENCY_4); + while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4) { + } + LL_PWR_EnableRange1BoostMode(); + LL_RCC_HSI_Enable(); + /* Wait till HSI is ready */ + while (LL_RCC_HSI_IsReady() != 1) { + } + + LL_RCC_HSI_SetCalibTrimming(64); + LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, LL_RCC_PLLR_DIV_2); + LL_RCC_PLL_EnableDomain_SYS(); + LL_RCC_PLL_Enable(); + /* Wait till PLL is ready */ + while (LL_RCC_PLL_IsReady() != 1) { + } + + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); + // LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + /* Wait till System clock is ready */ + while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { + } + + /* Insure 1us transition state at intermediate medium speed clock*/ + for (__IO uint32_t i = (170 >> 1); i != 0; i--) + ; + + /* Set AHB prescaler*/ + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); + LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1); + LL_SetSystemCoreClock(170000000); + + /* Update the time base */ + if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return + * state */ + __disable_irq(); + while (1) { + } + /* USER CODE END Error_Handler_Debug */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line + number, ex: printf("Wrong parameters value: file %s on line %d\r\n", + file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/G4CANTESTING/Core/Src/spi.c b/G4CANTESTING/Core/Src/spi.c new file mode 100644 index 00000000..66459f2e --- /dev/null +++ b/G4CANTESTING/Core/Src/spi.c @@ -0,0 +1,95 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file spi.c + * @brief This file provides code for the configuration + * of the SPI instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "spi.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* SPI3 init function */ +void MX_SPI3_Init(void) +{ + + /* USER CODE BEGIN SPI3_Init 0 */ + + /* USER CODE END SPI3_Init 0 */ + + LL_SPI_InitTypeDef SPI_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI3); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + /**SPI3 GPIO Configuration + PC10 ------> SPI3_SCK + PC11 ------> SPI3_MISO + PC12 ------> SPI3_MOSI + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_10; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_6; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI3_Init 1 */ + + /* USER CODE END SPI3_Init 1 */ + SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; + SPI_InitStruct.Mode = LL_SPI_MODE_MASTER; + SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_4BIT; + SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; + SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; + SPI_InitStruct.NSS = LL_SPI_NSS_SOFT; + SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32; + SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST; + SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE; + SPI_InitStruct.CRCPoly = 7; + LL_SPI_Init(SPI3, &SPI_InitStruct); + LL_SPI_SetStandard(SPI3, LL_SPI_PROTOCOL_MOTOROLA); + LL_SPI_EnableNSSPulseMgt(SPI3); + /* USER CODE BEGIN SPI3_Init 2 */ + + /* USER CODE END SPI3_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c b/G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c new file mode 100644 index 00000000..69189ef4 --- /dev/null +++ b/G4CANTESTING/Core/Src/stm32g4xx_hal_msp.c @@ -0,0 +1,86 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + /* System interrupt init*/ + + /** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral + */ + HAL_PWREx_DisableUCPDDeadBattery(); + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/stm32g4xx_it.c b/G4CANTESTING/Core/Src/stm32g4xx_it.c new file mode 100644 index 00000000..51eefbe0 --- /dev/null +++ b/G4CANTESTING/Core/Src/stm32g4xx_it.c @@ -0,0 +1,195 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32g4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32g4xx_it.h" + +#include "main.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +// extern FDCAN_HandleTypeDef hfdcan2; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32G4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32g4xx.s). */ +/******************************************************************************/ diff --git a/G4CANTESTING/Core/Src/syscalls.c b/G4CANTESTING/Core/Src/syscalls.c new file mode 100644 index 00000000..a2412b22 --- /dev/null +++ b/G4CANTESTING/Core/Src/syscalls.c @@ -0,0 +1,166 @@ +/** + ****************************************************************************** + * @file syscalls.c + * @author Auto-generated by STM32CubeMX + * @brief Minimal System calls file + * + * For more information about which c-functions + * need which of these lowlevel functions + * please consult the Newlib libc-manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2020-2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* Variables */ +extern int __io_putchar(int ch) __attribute__((weak)); +extern int __io_getchar(void) __attribute__((weak)); + +char *__env[1] = {0}; +char **environ = __env; + +/* Functions */ +void initialise_monitor_handles() {} + +int _getpid(void) { return 1; } + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + errno = EINVAL; + return -1; +} + +void _exit(int status) +{ + _kill(status, -1); + while (1) { + } /* Make sure we hang here */ +} + +__attribute__((weak)) int _read(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) { + *ptr++ = __io_getchar(); + } + + return len; +} + +__attribute__((weak)) int _write(int file, char *ptr, int len) +{ + (void)file; + int DataIdx; + + for (DataIdx = 0; DataIdx < len; DataIdx++) { + __io_putchar(*ptr++); + } + return len; +} + +int _close(int file) +{ + (void)file; + return -1; +} + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _open(char *path, int flags, ...) +{ + (void)path; + (void)flags; + /* Pretend like we always fail */ + return -1; +} + +int _wait(int *status) +{ + (void)status; + errno = ECHILD; + return -1; +} + +int _unlink(char *name) +{ + (void)name; + errno = ENOENT; + return -1; +} + +int _times(struct tms *buf) +{ + (void)buf; + return -1; +} + +int _stat(char *file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _link(char *old, char *new) +{ + (void)old; + (void)new; + errno = EMLINK; + return -1; +} + +int _fork(void) +{ + errno = EAGAIN; + return -1; +} + +int _execve(char *name, char **argv, char **env) +{ + (void)name; + (void)argv; + (void)env; + errno = ENOMEM; + return -1; +} diff --git a/G4CANTESTING/Core/Src/sysmem.c b/G4CANTESTING/Core/Src/sysmem.c new file mode 100644 index 00000000..00c39793 --- /dev/null +++ b/G4CANTESTING/Core/Src/sysmem.c @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file sysmem.c + * @author Generated by STM32CubeMX + * @brief System Memory calls file + * + * For more information about which C functions + * need which of these lowlevel functions + * please consult the newlib libc manual + ****************************************************************************** + * @attention + * + * Copyright (c) 2024 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes */ +#include +#include + +/** + * Pointer to the current high watermark of the heap usage + */ +static uint8_t *__sbrk_heap_end = NULL; + +/** + * @brief _sbrk() allocates memory to the newlib heap and is used by malloc + * and others from the C library + * + * @verbatim + * ############################################################################ + * # .data # .bss # newlib heap # MSP stack # + * # # # # Reserved by _Min_Stack_Size # + * ############################################################################ + * ^-- RAM start ^-- _end _estack, RAM end --^ + * @endverbatim + * + * This implementation starts allocating at the '_end' linker symbol + * The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack + * The implementation considers '_estack' linker symbol to be RAM end + * NOTE: If the MSP stack, at any point during execution, grows larger than the + * reserved size, please increase the '_Min_Stack_Size'. + * + * @param incr Memory size + * @return Pointer to allocated memory + */ +void *_sbrk(ptrdiff_t incr) +{ + extern uint8_t _end; /* Symbol defined in the linker script */ + extern uint8_t _estack; /* Symbol defined in the linker script */ + extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */ + const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size; + const uint8_t *max_heap = (uint8_t *)stack_limit; + uint8_t *prev_heap_end; + + /* Initialize heap end at first call */ + if (NULL == __sbrk_heap_end) { + __sbrk_heap_end = &_end; + } + + /* Protect heap from growing into the reserved MSP stack */ + if (__sbrk_heap_end + incr > max_heap) { + errno = ENOMEM; + return (void *)-1; + } + + prev_heap_end = __sbrk_heap_end; + __sbrk_heap_end += incr; + + return (void *)prev_heap_end; +} diff --git a/G4CANTESTING/Core/Src/system_stm32g4xx.c b/G4CANTESTING/Core/Src/system_stm32g4xx.c new file mode 100644 index 00000000..990865b8 --- /dev/null +++ b/G4CANTESTING/Core/Src/system_stm32g4xx.c @@ -0,0 +1,289 @@ +/** + ****************************************************************************** + * @file system_stm32g4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32g4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be + *used by the user application to setup the SysTick timer or configure other + *parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the HSI (16 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32g4xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 16 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * Require 48MHz for RNG | Disabled + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + * Copyright (c) 2019 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32g4xx_system + * @{ + */ + +/** @addtogroup STM32G4xx_System_Private_Includes + * @{ + */ + +#include "stm32g4xx.h" + +#if !defined(HSE_VALUE) +#define HSE_VALUE 24000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined(HSI_VALUE) +#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate the vector table + anywhere in Flash or Sram, else the vector table is kept at the automatic + remap of boot address selected */ +/* #define USER_VECT_TAB_ADDRESS */ + +#if defined(USER_VECT_TAB_ADDRESS) +/*!< Uncomment the following line if you need to relocate your vector Table + in Sram else user remap will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS \ + SRAM_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#endif /* VECT_TAB_SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Variables + * @{ + */ +/* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock + frequency Note: If you use this function to configure the system clock; then + there is no need to call the 2 first functions listed above, since + SystemCoreClock variable is updated automatically. +*/ +uint32_t SystemCoreClock = HSI_VALUE; + +const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; +const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32G4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ +/* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << (10 * 2)) | (3UL << (11 * 2))); /* set CP10 and CP11 Full Access */ +#endif + + /* Configure the Vector Table location add offset address + * ------------------*/ +#if defined(USER_VECT_TAB_ADDRESS) + SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#endif /* USER_VECT_TAB_ADDRESS */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or + * configure other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any + * configuration based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the + * HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the + * HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the + * HSE_VALUE(***) or HSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (**) HSI_VALUE is a constant defined in stm32g4xx_hal.h file (default + * value 16 MHz) but the real value may vary depending on the variations in + * voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32g4xx_hal.h file + * (default value 24 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using + * fractional value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp, pllvco, pllr, pllsource, pllm; + + /* Get SYSCLK source + * -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) { + case 0x04: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4) + 1U; + if (pllsource == 0x02UL) /* HSI used as PLL clock source */ + { + pllvco = (HSI_VALUE / pllm); + } else /* HSE used as PLL clock source */ + { + pllvco = (HSE_VALUE / pllm); + } + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25) + 1U) * 2U; + SystemCoreClock = pllvco / pllr; + break; + + default: + break; + } + /* Compute HCLK clock frequency + * --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/G4CANTESTING/Core/Src/tim.c b/G4CANTESTING/Core/Src/tim.c new file mode 100644 index 00000000..7f521c3b --- /dev/null +++ b/G4CANTESTING/Core/Src/tim.c @@ -0,0 +1,79 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "tim.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* TIM2 init function */ +void MX_TIM2_Init(void) +{ + + /* USER CODE BEGIN TIM2_Init 0 */ + + /* USER CODE END TIM2_Init 0 */ + + LL_TIM_InitTypeDef TIM_InitStruct = {0}; + LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* Peripheral clock enable */ + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + + /* USER CODE BEGIN TIM2_Init 1 */ + + /* USER CODE END TIM2_Init 1 */ + TIM_InitStruct.Prescaler = 0; + TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; + TIM_InitStruct.Autoreload = 4294967295; + TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; + LL_TIM_Init(TIM2, &TIM_InitStruct); + LL_TIM_DisableARRPreload(TIM2); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_FORCED_ACTIVE; + TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE; + TIM_OC_InitStruct.CompareValue = 0; + TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + LL_TIM_OC_Init(TIM2, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct); + LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH1); + LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET); + LL_TIM_DisableMasterSlaveMode(TIM2); + /* USER CODE BEGIN TIM2_Init 2 */ + + /* USER CODE END TIM2_Init 2 */ + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**TIM2 GPIO Configuration + PA0 ------> TIM2_CH1 + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_0; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_1; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/Core/Src/usart.c b/G4CANTESTING/Core/Src/usart.c new file mode 100644 index 00000000..45c8c7ad --- /dev/null +++ b/G4CANTESTING/Core/Src/usart.c @@ -0,0 +1,186 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.c + * @brief This file provides code for the configuration + * of the USART instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "usart.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* LPUART1 init function */ + +void MX_LPUART1_UART_Init(void) +{ + + /* USER CODE BEGIN LPUART1_Init 0 */ + + /* USER CODE END LPUART1_Init 0 */ + + LL_LPUART_InitTypeDef LPUART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_HSI); + + /* Peripheral clock enable */ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + /**LPUART1 GPIO Configuration + PA2 ------> LPUART1_TX + PA3 ------> LPUART1_RX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_2; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_3; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_12; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN LPUART1_Init 1 */ + + /* USER CODE END LPUART1_Init 1 */ + LPUART_InitStruct.PrescalerValue = LL_LPUART_PRESCALER_DIV1; + LPUART_InitStruct.BaudRate = 115200; + LPUART_InitStruct.DataWidth = LL_LPUART_DATAWIDTH_8B; + LPUART_InitStruct.StopBits = LL_LPUART_STOPBITS_1; + LPUART_InitStruct.Parity = LL_LPUART_PARITY_NONE; + LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; + LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; + LL_LPUART_Init(LPUART1, &LPUART_InitStruct); + LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); + LL_LPUART_DisableFIFO(LPUART1); + + /* USER CODE BEGIN WKUPType LPUART1 */ + + /* USER CODE END WKUPType LPUART1 */ + + LL_LPUART_Enable(LPUART1); + + /* Polling LPUART1 initialisation */ + while ((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) { + } + /* USER CODE BEGIN LPUART1_Init 2 */ + + /* USER CODE END LPUART1_Init 2 */ +} +/* USART1 init function */ + +void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + LL_USART_InitTypeDef USART_InitStruct = {0}; + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + + LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); + + /* Peripheral clock enable */ + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1); + + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB); + /**USART1 GPIO Configuration + PC5 ------> USART1_RX + PA11 ------> USART1_CTS + PA12 ------> USART1_RTS + PB6 ------> USART1_TX + */ + GPIO_InitStruct.Pin = LL_GPIO_PIN_5; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_6; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_7; + LL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + USART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; + USART_InitStruct.BaudRate = 115200; + USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; + USART_InitStruct.StopBits = LL_USART_STOPBITS_1; + USART_InitStruct.Parity = LL_USART_PARITY_NONE; + USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; + USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_RTS_CTS; + USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; + LL_USART_Init(USART1, &USART_InitStruct); + LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_SetRXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_8); + LL_USART_DisableFIFO(USART1); + LL_USART_ConfigAsyncMode(USART1); + + /* USER CODE BEGIN WKUPType USART1 */ + + /* USER CODE END WKUPType USART1 */ + + LL_USART_Enable(USART1); + + /* Polling USART1 initialisation */ + while ((!(LL_USART_IsActiveFlag_TEACK(USART1))) || (!(LL_USART_IsActiveFlag_REACK(USART1)))) { + } + /* USER CODE BEGIN USART1_Init 2 */ + + /* USER CODE END USART1_Init 2 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/G4CANTESTING/G4PERTESTING.ioc b/G4CANTESTING/G4PERTESTING.ioc new file mode 100644 index 00000000..8cf1860b --- /dev/null +++ b/G4CANTESTING/G4PERTESTING.ioc @@ -0,0 +1,382 @@ +#MicroXplorer Configuration settings - do not modify +ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_5 +ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_7 +ADC1.Channel-4\#ChannelRegularConversion=ADC_CHANNEL_8 +ADC1.Channel-5\#ChannelRegularConversion=ADC_CHANNEL_9 +ADC1.Channel-6\#ChannelRegularConversion=ADC_CHANNEL_12 +ADC1.Channel-7\#ChannelRegularConversion=ADC_CHANNEL_15 +ADC1.ClockPrescaler=ADC_CLOCK_ASYNC_DIV256 +ADC1.CommonPathInternal=null|null|null|null +ADC1.ContinuousConvMode=ENABLE +ADC1.DMAContinuousRequests=ENABLE +ADC1.EOCSelection=ADC_EOC_SEQ_CONV +ADC1.ExternalTrigConv=ADC_SOFTWARE_START +ADC1.IPParameters=Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,OffsetNumber-2\#ChannelRegularConversion,NbrOfConversionFlag,master,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,OffsetNumber-3\#ChannelRegularConversion,Rank-4\#ChannelRegularConversion,Channel-4\#ChannelRegularConversion,SamplingTime-4\#ChannelRegularConversion,OffsetNumber-4\#ChannelRegularConversion,Rank-5\#ChannelRegularConversion,Channel-5\#ChannelRegularConversion,SamplingTime-5\#ChannelRegularConversion,OffsetNumber-5\#ChannelRegularConversion,Rank-6\#ChannelRegularConversion,Channel-6\#ChannelRegularConversion,SamplingTime-6\#ChannelRegularConversion,OffsetNumber-6\#ChannelRegularConversion,Rank-7\#ChannelRegularConversion,Channel-7\#ChannelRegularConversion,SamplingTime-7\#ChannelRegularConversion,OffsetNumber-7\#ChannelRegularConversion,NbrOfConversion,ContinuousConvMode,DMAContinuousRequests,ClockPrescaler,EOCSelection,ExternalTrigConv,CommonPathInternal +ADC1.NbrOfConversion=6 +ADC1.NbrOfConversionFlag=1 +ADC1.OffsetNumber-2\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-3\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-4\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-5\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-6\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.OffsetNumber-7\#ChannelRegularConversion=ADC_OFFSET_NONE +ADC1.Rank-2\#ChannelRegularConversion=1 +ADC1.Rank-3\#ChannelRegularConversion=2 +ADC1.Rank-4\#ChannelRegularConversion=3 +ADC1.Rank-5\#ChannelRegularConversion=4 +ADC1.Rank-6\#ChannelRegularConversion=5 +ADC1.Rank-7\#ChannelRegularConversion=6 +ADC1.SamplingTime-2\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-4\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-5\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-6\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.SamplingTime-7\#ChannelRegularConversion=ADC_SAMPLETIME_92CYCLES_5 +ADC1.master=1 +CAD.formats=[] +CAD.pinconfig=Dual +CAD.provider= +Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY +Dma.ADC1.0.EventEnable=DISABLE +Dma.ADC1.0.Instance=DMA1_Channel1 +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,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.RequestsNb=1 +FDCAN2.AutoRetransmission=ENABLE +FDCAN2.CalculateBaudRateNominal=1000000 +FDCAN2.CalculateTimeBitNominal=1000 +FDCAN2.CalculateTimeQuantumNominal=6.25 +FDCAN2.DataPrescaler=8 +FDCAN2.DataSyncJumpWidth=16 +FDCAN2.DataTimeSeg1=14 +FDCAN2.DataTimeSeg2=5 +FDCAN2.ExtFiltersNbr=2 +FDCAN2.FrameFormat=FDCAN_FRAME_CLASSIC +FDCAN2.IPParameters=CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,FrameFormat,NominalTimeSeg1,NominalTimeSeg2,NominalPrescaler,AutoRetransmission,StdFiltersNbr,TransmitPause,NominalSyncJumpWidth,DataTimeSeg1,DataTimeSeg2,DataPrescaler,DataSyncJumpWidth,ExtFiltersNbr,ProtocolException +FDCAN2.NominalPrescaler=1 +FDCAN2.NominalSyncJumpWidth=16 +FDCAN2.NominalTimeSeg1=119 +FDCAN2.NominalTimeSeg2=40 +FDCAN2.ProtocolException=ENABLE +FDCAN2.StdFiltersNbr=0 +FDCAN2.TransmitPause=DISABLE +File.Version=6 +GPIO.groupedBy=Group By Peripherals +I2C2.IPParameters=Timing +I2C2.Timing=0x30D29DE4 +KeepUserPlacement=false +LPUART1.BaudRate=115200 +LPUART1.IPParameters=BaudRate +Mcu.CPN=STM32G474RET6 +Mcu.Family=STM32G4 +Mcu.IP0=ADC1 +Mcu.IP1=DMA +Mcu.IP10=USART1 +Mcu.IP2=FDCAN2 +Mcu.IP3=I2C2 +Mcu.IP4=LPUART1 +Mcu.IP5=NVIC +Mcu.IP6=RCC +Mcu.IP7=SPI3 +Mcu.IP8=SYS +Mcu.IP9=TIM2 +Mcu.IPNb=11 +Mcu.Name=STM32G474R(B-C-E)Tx +Mcu.Package=LQFP64 +Mcu.Pin0=PF0-OSC_IN +Mcu.Pin1=PF1-OSC_OUT +Mcu.Pin10=PA7 +Mcu.Pin11=PC4 +Mcu.Pin12=PC5 +Mcu.Pin13=PB0 +Mcu.Pin14=PB1 +Mcu.Pin15=PB11 +Mcu.Pin16=PB12 +Mcu.Pin17=PB13 +Mcu.Pin18=PB14 +Mcu.Pin19=PB15 +Mcu.Pin2=PC1 +Mcu.Pin20=PA8 +Mcu.Pin21=PA11 +Mcu.Pin22=PA12 +Mcu.Pin23=PA13 +Mcu.Pin24=PA14 +Mcu.Pin25=PC10 +Mcu.Pin26=PC11 +Mcu.Pin27=PC12 +Mcu.Pin28=PB3 +Mcu.Pin29=PB4 +Mcu.Pin3=PC2 +Mcu.Pin30=PB5 +Mcu.Pin31=PB6 +Mcu.Pin32=PB7 +Mcu.Pin33=PB8-BOOT0 +Mcu.Pin34=PB9 +Mcu.Pin35=VP_SYS_VS_Systick +Mcu.Pin36=VP_SYS_VS_DBSignals +Mcu.Pin37=VP_TIM2_VS_ClockSourceINT +Mcu.Pin4=PC3 +Mcu.Pin5=PA0 +Mcu.Pin6=PA2 +Mcu.Pin7=PA3 +Mcu.Pin8=PA5 +Mcu.Pin9=PA6 +Mcu.PinsNb=38 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32G474RETx +MxCube.Version=6.15.0 +MxDb.Version=DB.6.0.150 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.FDCAN2_IT0_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.ForceEnableDMAVector=false +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA0.Signal=S_TIM2_CH1 +PA11.Locked=true +PA11.Mode=CTS_RTS +PA11.Signal=USART1_CTS +PA12.Locked=true +PA12.Mode=CTS_RTS +PA12.Signal=USART1_RTS +PA13.Locked=true +PA13.Mode=Trace_Asynchronous_SW +PA13.Signal=SYS_JTMS-SWDIO +PA14.Locked=true +PA14.Mode=Trace_Asynchronous_SW +PA14.Signal=SYS_JTCK-SWCLK +PA2.GPIOParameters=GPIO_Speed +PA2.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA2.Locked=true +PA2.Mode=Asynchronous +PA2.Signal=LPUART1_TX +PA3.GPIOParameters=GPIO_Speed +PA3.GPIO_Speed=GPIO_SPEED_FREQ_HIGH +PA3.Locked=true +PA3.Mode=Asynchronous +PA3.Signal=LPUART1_RX +PA5.GPIOParameters=GPIO_Label +PA5.GPIO_Label=BLINKY +PA5.Locked=true +PA5.Signal=GPIO_Output +PA6.GPIOParameters=GPIO_Label +PA6.GPIO_Label=IMD_SENSE +PA6.Locked=true +PA6.Signal=ADC2_IN3 +PA7.GPIOParameters=GPIO_Label +PA7.GPIO_Label=AMS_SENSE +PA7.Locked=true +PA7.Signal=ADC2_IN4 +PA8.Mode=I2C +PA8.Signal=I2C2_SDA +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=BRAKE_F_SIGNAL +PB0.Locked=true +PB0.Mode=IN15-Single-Ended +PB0.Signal=ADC1_IN15 +PB1.GPIOParameters=GPIO_Label +PB1.GPIO_Label=BRAKE_R_SIGNAL +PB1.Locked=true +PB1.Mode=IN12-Single-Ended +PB1.Signal=ADC1_IN12 +PB11.GPIOParameters=GPIO_Label +PB11.GPIO_Label=LED_TEST +PB11.Locked=true +PB11.Signal=GPIO_Output +PB12.GPIOParameters=GPIO_Speed,GPIO_PuPd +PB12.GPIO_PuPd=GPIO_PULLUP +PB12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PB12.Locked=true +PB12.Mode=FDCAN_Activate +PB12.Signal=FDCAN2_RX +PB13.GPIOParameters=GPIO_Speed +PB13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PB13.Locked=true +PB13.Mode=FDCAN_Activate +PB13.Signal=FDCAN2_TX +PB14.GPIOParameters=GPIO_Label +PB14.GPIO_Label=AUX_SIGNAL +PB14.Locked=true +PB14.Mode=IN5-Single-Ended +PB14.Signal=ADC1_IN5 +PB15.GPIOParameters=GPIO_Label +PB15.GPIO_Label=STEERING_ANGLE +PB15.Locked=true +PB15.Signal=ADC2_IN15 +PB3.Locked=true +PB3.Mode=Trace_Asynchronous_SW +PB3.Signal=SYS_JTDO-SWO +PB4.GPIOParameters=GPIO_Label +PB4.GPIO_Label=BRAKE_LIGHT +PB4.Locked=true +PB4.Signal=GPIO_Output +PB5.GPIOParameters=GPIO_Label +PB5.GPIO_Label=TSSI_G_CONTROL +PB5.Locked=true +PB5.Signal=GPIO_Output +PB6.Locked=true +PB6.Mode=Asynchronous +PB6.Signal=USART1_TX +PB7.Locked=true +PB7.Signal=UART4_CTS +PB8-BOOT0.GPIOParameters=GPIO_Label +PB8-BOOT0.GPIO_Label=AUX_CONTROL +PB8-BOOT0.Locked=true +PB8-BOOT0.Signal=GPIO_Output +PB9.GPIOParameters=GPIO_Label +PB9.GPIO_Label=SOFTWARE_OK_CONTROL +PB9.Locked=true +PB9.Signal=GPIO_Output +PC1.GPIOParameters=GPIO_Label +PC1.GPIO_Label=BSPD_SIGNAL +PC1.Locked=true +PC1.Mode=IN7-Single-Ended +PC1.Signal=ADC1_IN7 +PC10.Mode=Full_Duplex_Master +PC10.Signal=SPI3_SCK +PC11.Mode=Full_Duplex_Master +PC11.Signal=SPI3_MISO +PC12.Mode=Full_Duplex_Master +PC12.Signal=SPI3_MOSI +PC2.GPIOParameters=GPIO_Label +PC2.GPIO_Label=APPS1_SIGNAL +PC2.Locked=true +PC2.Mode=IN8-Single-Ended +PC2.Signal=ADC1_IN8 +PC3.GPIOParameters=GPIO_Label +PC3.GPIO_Label=APPS2_SIGNAL +PC3.Locked=true +PC3.Mode=IN9-Single-Ended +PC3.Signal=ADC1_IN9 +PC4.Mode=I2C +PC4.Signal=I2C2_SCL +PC5.Mode=Asynchronous +PC5.Signal=USART1_RX +PF0-OSC_IN.Locked=true +PF0-OSC_IN.Mode=HSE-External-Oscillator +PF0-OSC_IN.Signal=RCC_OSC_IN +PF1-OSC_OUT.Locked=true +PF1-OSC_OUT.Mode=HSE-External-Oscillator +PF1-OSC_OUT.Signal=RCC_OSC_OUT +PinOutPanel.RotationAngle=180 +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=STM32G474RETx +ProjectManager.FirmwarePackage=STM32Cube FW_G4 V1.6.1 +ProjectManager.FreePins=true +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=G4PERTESTING.ioc +ProjectManager.ProjectName=G4PERTESTING +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=CMake +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-LL-false,2-MX_GPIO_Init-GPIO-false-LL-true,3-MX_DMA_Init-DMA-false-LL-true,4-MX_FDCAN2_Init-FDCAN2-false-HAL-true,5-MX_ADC1_Init-ADC1-false-LL-true,6-MX_LPUART1_UART_Init-LPUART1-false-LL-true,7-MX_I2C2_Init-I2C2-false-LL-true,8-MX_USART1_UART_Init-USART1-false-LL-true,9-MX_SPI3_Init-SPI3-false-LL-true,10-MX_TIM2_Init-TIM2-false-LL-true +RCC.ADC12Freq_Value=160000000 +RCC.ADC345Freq_Value=160000000 +RCC.AHBFreq_Value=160000000 +RCC.APB1Freq_Value=160000000 +RCC.APB1TimFreq_Value=160000000 +RCC.APB2Freq_Value=160000000 +RCC.APB2TimFreq_Value=160000000 +RCC.CRSFreq_Value=48000000 +RCC.CortexFreq_Value=160000000 +RCC.EXTERNAL_CLOCK_VALUE=12288000 +RCC.EnbaleCSS=true +RCC.FCLKCortexFreq_Value=160000000 +RCC.FDCANFreq_Value=160000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=160000000 +RCC.HRTIM1Freq_Value=160000000 +RCC.HSE_VALUE=16000000 +RCC.HSI48_VALUE=48000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=160000000 +RCC.I2C2Freq_Value=160000000 +RCC.I2C3Freq_Value=160000000 +RCC.I2C4Freq_Value=160000000 +RCC.I2SFreq_Value=160000000 +RCC.IPParameters=ADC12Freq_Value,ADC345Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CRSFreq_Value,CortexFreq_Value,EXTERNAL_CLOCK_VALUE,EnbaleCSS,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HRTIM1Freq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2SFreq_Value,LPTIM1Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSI_VALUE,MCO1PinFreq_Value,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSourceVirtual,PWRFreq_Value,QSPIFreq_Value,RNGFreq_Value,SAI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value +RCC.LPTIM1Freq_Value=160000000 +RCC.LPUART1Freq_Value=160000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSE_VALUE=32768 +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=16000000 +RCC.PLLN=20 +RCC.PLLPoutputFreq_Value=160000000 +RCC.PLLQoutputFreq_Value=160000000 +RCC.PLLRCLKFreq_Value=160000000 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.PWRFreq_Value=160000000 +RCC.QSPIFreq_Value=160000000 +RCC.RNGFreq_Value=160000000 +RCC.SAI1Freq_Value=160000000 +RCC.SYSCLKFreq_VALUE=160000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.UART4Freq_Value=160000000 +RCC.UART5Freq_Value=160000000 +RCC.USART1Freq_Value=160000000 +RCC.USART2Freq_Value=160000000 +RCC.USART3Freq_Value=160000000 +RCC.USBFreq_Value=160000000 +RCC.VCOInputFreq_Value=16000000 +RCC.VCOOutputFreq_Value=320000000 +SH.S_TIM2_CH1.0=TIM2_CH1,Forced Output1 CH1 +SH.S_TIM2_CH1.ConfNb=1 +SPI3.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_32 +SPI3.CalculateBaudRate=5.0 MBits/s +SPI3.Direction=SPI_DIRECTION_2LINES +SPI3.IPParameters=VirtualType,Mode,Direction,BaudRatePrescaler,CalculateBaudRate +SPI3.Mode=SPI_MODE_MASTER +SPI3.VirtualType=VM_MASTER +TIM2.Channel-Forced\ Output1\ CH1=TIM_CHANNEL_1 +TIM2.IPParameters=Channel-Forced Output1 CH1 +USART1.IPParameters=VirtualMode-Asynchronous +USART1.VirtualMode-Asynchronous=VM_ASYNC +VP_SYS_VS_DBSignals.Mode=DisableDeadBatterySignals +VP_SYS_VS_DBSignals.Signal=SYS_VS_DBSignals +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM2_VS_ClockSourceINT.Mode=Internal +VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT +board=custom diff --git a/G4CANTESTING/README.md b/G4CANTESTING/README.md new file mode 100644 index 00000000..558f1c12 --- /dev/null +++ b/G4CANTESTING/README.md @@ -0,0 +1,5 @@ +# STM32G474 CAN +Nucleo-G474RE-C04 + +Plug in the board following ST-LINK pinout +Compile and flash G4CANTESTING.elf diff --git a/Lib/Peripherals/CAN/Inc/can.h b/Lib/Peripherals/CAN/Inc/can.h new file mode 100644 index 00000000..d37d614d --- /dev/null +++ b/Lib/Peripherals/CAN/Inc/can.h @@ -0,0 +1,80 @@ +#ifndef CAN_H +#define CAN_H + +// Supported STM32 Families +#ifdef STM32G4 +#elif defined(STM32L4) +#elif defined(STM32U5) +#error "Unsupported STM32 Family" +#endif + +#include "can_platform_deps.h" +#include "circularBuffer.h" + +// RX Callback must perform a deep copy of the data +// +typedef void (*CAN_RXCallback)(void *data, uint32_t size); +typedef struct { + // can baud rate is set by fdcan prescaler and RCC clock configurations + FDCAN_GlobalTypeDef *fdcan_instance; // Base address of FDCAN peripheral in memory (FDCAN1, FDCAN2, FDCAN3 macros) + + FDCAN_InitTypeDef hal_fdcan_init; + CAN_RXCallback rx_callback; + uint32_t rx_interrupt_priority; + uint32_t tx_interrupt_priority; + + // Circular Buffer + uint32_t tx_buffer_length; + + GPIO_TypeDef *rx_gpio; // Instance name, like GPIOA, GPIOB, etc. + GPIO_InitTypeDef init_rx_gpio; // GPIO Parameters - set correct Alternate Function, no pullup/pulldown, high/very_high frequency + GPIO_TypeDef *tx_gpio; + GPIO_InitTypeDef init_tx_gpio; + + // additional parameters +} CANConfig; + +// FDCAN peripheral for STM32G4 +typedef struct { + FDCAN_HandleTypeDef *hal_fdcanP; + CircularBuffer *tx_buffer; + uint32_t tx_buffer_length; + + CAN_RXCallback rx_callback; + + // for release + GPIO_TypeDef *rx_gpio; + GPIO_TypeDef *tx_gpio; + uint32_t Clock_Source; + + // state + bool init; + bool started; + + // error states +} CANHandle; + +#define FDCAN_MAX_DATA_BYTES 64 +typedef struct { + FDCAN_TxHeaderTypeDef tx_header; + uint8_t data[FDCAN_MAX_DATA_BYTES]; +} FDCANTxMessage; +typedef struct { + FDCAN_RxHeaderTypeDef rx_header; + uint8_t data[FDCAN_MAX_DATA_BYTES]; +} FDCANRxMessage; + +CANHandle *can_init(const CANConfig *config); // user must supply an rx callback function +int can_start(CANHandle *handle); +int can_stop(CANHandle *handle); +int can_send(CANHandle *handle, FDCANTxMessage *buffer); +int can_release(CANHandle *handle); // deinit circular buffer and turn off can peripheral and gpios +int can_add_filter(CANHandle *handle, FDCAN_FilterTypeDef *filter); +// alternatively use +// HAL_FDCAN_ConfigGlobalFilter() //important to accept nonmatching frames into +// HAL_FDCAN_ConfigFilter() + +// doesn't need a handle, CAN cores share peripheral clock +void can_set_clksource(uint32_t clksource); // ex. LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE + +#endif // End Header Guard diff --git a/Lib/Peripherals/CAN/Inc/can_platform_deps.h b/Lib/Peripherals/CAN/Inc/can_platform_deps.h new file mode 100644 index 00000000..3958adbc --- /dev/null +++ b/Lib/Peripherals/CAN/Inc/can_platform_deps.h @@ -0,0 +1,18 @@ +#ifndef CAN_PLATFORM_DEPS_H +#define CAN_PLATFORM_DEPS_H + +#if defined(STM32G4) +#include "stm32g4xx_hal.h" +#include "stm32g4xx_hal_fdcan.h" +#include "stm32g4xx_hal_gpio.h" +#include "stm32g4xx_hal_gpio_ex.h" +#include "stm32g4xx_hal_rcc.h" +#include "stm32g4xx_ll_gpio.h" +#include "stm32g4xx_ll_rcc.h" +// #elif defined(STM32L4) +// #elif defined(STM32U5) +#else +#error "Unsupported STM32 family" +#endif + +#endif // end header guard diff --git a/Lib/Peripherals/CAN/README.md b/Lib/Peripherals/CAN/README.md new file mode 100644 index 00000000..43d257b0 --- /dev/null +++ b/Lib/Peripherals/CAN/README.md @@ -0,0 +1,83 @@ +- USAGE: + +CANHandle* can_init(CANConfig *config); //user must supply an rx callback function + +void can_set_clksource(uint32_t LL_RCC_FDCAN_CLKSOURCE); //ex LL_RCC_FDCAN_CLKSOURCE_PCLK1 for STM32G474RE + +int can_start(CANHandle*handle); +int can_stop(CANHandle*handle); +int can_send(CANHandle*handle, FDCANMessage* buffer, size_t send); +int can_release(CANHandle* handle); //deinit circular buffer and turn off can peripheral and gpios +int can_add_filter(CANHandle* handle, HAL_FDCAN_FilterTypeDef * filter); +int can_add_global_filter(CANHandle* handle, HAL_FDCAN_FilterTypeDef* filter); + +//alternatively instead use the HAL filter functions +//HAL_FDCAN_ConfigGlobalFilter(canHandle->hal_fdcanP, filterTypeDef) +//HAL_FDCAN_ConfigFilter(ca) + +If no filters are set, the default behaviour is to accept all standard and extended frames into the RXFIFO0 + + + + + +PROBLEMS: +Verify ISR safety, no race conditions, atomic read/writes + - Interrupts keep firing while trying to can_release() + - Could try to set the NVIC register to selectively disable interrupts (preferably using a bitmask) +- Need to discuss expected behaviour of API + - particularly can_start, can_stop + - can_release +- Freeing within ISRs whenever popping from CircularBuffer (yes its faster, than stack copies, but heap is getting fragmented) +- ISRS might take too long to resolve because popping and freeing circular buffer. + +- HARDCODE Platform Usage Flag for compiler definitions +- CAN.H expects #STM32G4 to be defined, + + +- RX Callback must perform deep copy of data supplied to it - could also malloc, but not safe to do inside ISRs +- + + +-Shouldn't disable GPIOs in the MSP layers when releasing, might affect other peripherals + + +IDEAS for other features: +- abstract to different STM families besides STM32G4 +- Rx Buffering +- TX Buffering policy, do we spread them out over multiple TX buffers +- DMA support for copying from circular buffer, circular buffer could then be stack allocated +- Smaller can headers for tx and rx (right now its just use the TXHeaderTypeDef) +- TX FIFO vs Queue policy (only allow FIFOS) +- Add support for RXFifo1 + + +TESTING- ---------------------------------------------- +USE LOGOMATIC for return status - +either returns through semihosting or debug cores +LOGOMATIC is defined platform by platform + +Testing framework +- Can operate on API states and behaviours, but API should work across platforms +- All API tests are defined in can_test.c +- All tests are run from the top level function in can_test.c + +- can_test.c should initialize everything properly. +- May have to create platform specific asserts when testing state +- use LOGOMATIC to return errors or throw asserts + +- Platform testing, such as in G4PERTESTING just needs include "can_test.h" and call top level function +in main. + +Two approaches: +Platform centric +- In G4PERTesting, include "can_tests.h" and call the top level function in can_test.c +- This approach is better because we can abstract the logging and debug method + +Library Centric Testing: +- Test the implementation in each library. + +HAL_Rewrite: +- Alternatively, rewrite without using HAL, just use CMSIS definitions. +- PROS: Would look good on your Github. +- CONS: takes too long \ No newline at end of file diff --git a/Lib/Peripherals/CAN/Src/can.c b/Lib/Peripherals/CAN/Src/can.c new file mode 100644 index 00000000..1bea5c95 --- /dev/null +++ b/Lib/Peripherals/CAN/Src/can.c @@ -0,0 +1,617 @@ +#include "can.h" + +#include +#include +#include +#include + +#include "Logomatic.h" + +// HAL handles +// #ifdef USECAN1 +static FDCAN_HandleTypeDef hal_fdcan1 = {.Instance = FDCAN1}; +static CANHandle CAN1 = {.hal_fdcanP = &hal_fdcan1}; +// #endif + +// #ifdef USECAN2 +static FDCAN_HandleTypeDef hal_fdcan2 = {.Instance = FDCAN2}; +static CANHandle CAN2 = {.hal_fdcanP = &hal_fdcan2}; +// #endif + +// #ifdef USECAN3 +static FDCAN_HandleTypeDef hal_fdcan3 = {.Instance = FDCAN3}; +static CANHandle CAN3 = {.hal_fdcanP = &hal_fdcan3}; +// #endif + +// macro lore +/* +#define CAT(a,b) a##b +#define CAT3(a, b, c) a##b##c +#define CAT4(a, b,c,d) a##b##c##d +#define CAT5(a, b,c,d,e) a##b##c##d##e + +#define ACTIVATE_FDCAN_HELPER(FDCANX, ITY, preirq, subirq) \ + do { \ + HAL_NVIC_SetPriority( CAT4(FDCANX##,_,ITY, _IRQn ) , preirq, subirq ); \ + HAL_NVIC_EnableIRQ( CAT4(FDCANX##,_,ITY, _IRQn ) ); \ + } while(0) + +#define HAL_NVIC_ACTIVATE_FDCAN(FDCANX, ITY, preirq, subirq) \ + do { \ + if (FDCANX == ##FDCAN1 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN1 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN1, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN2 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN2, IT1, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 0) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT0, preirq, subirq); } \ + else if (FDCANX == FDCAN3 && ITY == 1) { ACTIVATE_FDCAN_HELPER(FDCAN3, IT1, preirq, subirq); } \ + else { LOGOMATIC("Unrecognized FDCAN and Interrupt Line combination"); } \ + } while(0) + +*/ + +#define GPIOx_CLK_ENABLE(GPIOX) \ + do { \ + if (GPIOX == GPIOA) \ + __HAL_RCC_GPIOA_CLK_ENABLE(); \ + else if (GPIOX == GPIOB) \ + __HAL_RCC_GPIOB_CLK_ENABLE(); \ + else if (GPIOX == GPIOD) \ + __HAL_RCC_GPIOD_CLK_ENABLE(); \ + else \ + LOGOMATIC("BAD FDCAN GPIO Port"); \ + } while (0) + +#define GPIOx_CLK_DISABLE(GPIOX) \ + do { \ + if (GPIOX == GPIOA) \ + __HAL_RCC_GPIOA_CLK_DISABLE(); \ + else if (GPIOX == GPIOB) \ + __HAL_RCC_GPIOB_CLK_DISABLE(); \ + else if (GPIOX == GPIOD) \ + __HAL_RCC_GPIOD_CLK_DISABLE(); \ + else \ + LOGOMATIC("BAD FDCAN GPIO Port"); \ + } while (0) + +static int fdcan_shared_clock_ref = 0; +static inline void fdcan_enable_shared_clock(void) +{ + uint32_t primask = __get_PRIMASK(); + __disable_irq(); + + if (fdcan_shared_clock_ref == 0) { + __HAL_RCC_FDCAN_CLK_ENABLE(); + } + fdcan_shared_clock_ref++; + + __set_PRIMASK(primask); +} + +static inline void fdcan_disable_shared_clock(void) +{ + uint32_t primask = __get_PRIMASK(); + __disable_irq(); + + if (fdcan_shared_clock_ref > 0) { + fdcan_shared_clock_ref--; + if (fdcan_shared_clock_ref == 0) { + __HAL_RCC_FDCAN_CLK_DISABLE(); + } + } + __set_PRIMASK(primask); +} + +static inline void gpio_clk_enable(GPIO_TypeDef *gpio) +{ + if (gpio == GPIOA) { + __HAL_RCC_GPIOA_CLK_ENABLE(); + } else if (gpio == GPIOB) { + __HAL_RCC_GPIOB_CLK_ENABLE(); + } else if (gpio == GPIOD) { + __HAL_RCC_GPIOD_CLK_ENABLE(); + } +} + +static inline void gpio_clk_disable(GPIO_TypeDef *gpio) +{ + if (gpio == GPIOA) { + __HAL_RCC_GPIOA_CLK_DISABLE(); + } else if (gpio == GPIOB) { + __HAL_RCC_GPIOB_CLK_DISABLE(); + } else if (gpio == GPIOD) { + __HAL_RCC_GPIOD_CLK_DISABLE(); + } +} + +static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1); + +static int can_msp_init(CANHandle *handle, CANConfig *config); +CANHandle *can_init(const CANConfig *config) +{ + // config validation? + // assert(config != 0) + + // #ifdef STM32G474xx + CANHandle *canHandle = 0; + // #ifdef USECAN1 + if (config->fdcan_instance == FDCAN1) { + if (CAN1.init) { + LOGOMATIC("CAN: CAN1 is already initialized\n"); + return 0; + } else { + canHandle = &CAN1; + } + } + // #endif + // #ifdef USECAN2 + else if (config->fdcan_instance == FDCAN2) { + if (CAN2.init) { + LOGOMATIC("CAN: CAN2 is already initialized\n"); + return 0; + } else { + canHandle = &CAN2; + } + } + // #ifdef USECAN3 + else if (config->fdcan_instance == FDCAN3) { + if (CAN3.init) { + LOGOMATIC("CAN: CAN3 is already initialized\n"); + return 0; + } else { + canHandle = &CAN3; + } + } + // #endif + // #elif defined(STM32L476xx) + // #else + // #error "Unsupported STM32 family" + // #endif + else { + LOGOMATIC("CAN: Unrecognized FDCAN instance"); + return 0; + } + canHandle->init = false; + canHandle->started = false; + + // Initialize handle + assert(config->hal_fdcan_init.TxFifoQueueMode == FDCAN_TX_FIFO_OPERATION); + + canHandle->hal_fdcanP->Init = config->hal_fdcan_init; // copy FDCAN parameters from user + // canHandle->hal_fdcanP->Instance = config->fdcan_instance //handles initialized with correct base instance addresses + + canHandle->rx_gpio = config->rx_gpio; + canHandle->tx_gpio = config->tx_gpio; + canHandle->rx_callback = config->rx_callback; + canHandle->tx_buffer_length = config->tx_buffer_length; + + // alternately -> have can_msp_init setup state for HAL_FDCAN_MspInit to work correctly + // have can_msp_deinit setup state for HAL_FDCAN_MspDeInit to work correctly + // Then call HAL_FDCAN_Init() and HAL_FDCAN_DeInit() + + // Current idea, redefine HAL_FDCAN_MspInit and MspDeInit do nothing at all, do all the work in can_msp_init() + if (can_msp_init(canHandle, (CANConfig *)config)) { + LOGOMATIC("CAN_init: could not initialize MSP resources"); + can_release(canHandle); + } + + // PROBLEM: HAL_FDCAN_Init expects HAL_FDCAN_MspInit() to be defined + if (HAL_FDCAN_Init(canHandle->hal_fdcanP) != HAL_OK) { + LOGOMATIC("CAN: HAL Could not initialize FDCAN peripheral"); + return NULL; + // Error_Handler(); + } + + // Active FDCAN callbacks - rxcalback uses line0, txcallback uses line1 + // uint32_t rxevents = FDCAN_IT_RX_FIFO0_NEW_MESSAGE; + uint32_t status = 0; + uint32_t rx_events = FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_FULL; + status |= HAL_FDCAN_ActivateNotification(canHandle->hal_fdcanP, rx_events, 0); + status |= HAL_FDCAN_ConfigInterruptLines(canHandle->hal_fdcanP, rx_events, FDCAN_INTERRUPT_LINE0); + + // uint32_t txevents = FDCAN_IT_TX_COMPLETE; + uint32_t destinations = FDCAN_TX_BUFFER0; + uint32_t tx_events = FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY; + status |= HAL_FDCAN_ActivateNotification(canHandle->hal_fdcanP, tx_events, destinations); + status |= HAL_FDCAN_ConfigInterruptLines(canHandle->hal_fdcanP, tx_events, FDCAN_INTERRUPT_LINE1); + // Callbacks redefined later + + if (status & HAL_ERROR) { + LOGOMATIC("CAN: Could not activate rx and tx interrupts\n"); + return NULL; + } + + // Circular Buffer + canHandle->tx_buffer = GR_CircularBuffer_Create(config->tx_buffer_length); + if (!canHandle->tx_buffer) { + LOGOMATIC("CAN: Could not allocate circular buffer\n"); + return 0; + } + + canHandle->init = true; + canHandle->started = false; + + return canHandle; +} + +inline void can_set_clksource(uint32_t clksource) { LL_RCC_SetFDCANClockSource(clksource); } + +// only valid for #STM32G474x, must redefine for each family +static int can_msp_init(CANHandle *canHandle, CANConfig *config) +{ + // MSP Init ------- This could be inside HAL_FDCAN_MspInit() instead + // FDCAN Clock Select + + fdcan_enable_shared_clock(); + // Clock speed for FDCAN determined by APB1 clock speed and FDCAN prescaler + + // GPIOs init + GPIOx_CLK_ENABLE(config->rx_gpio); + GPIOx_CLK_ENABLE(config->tx_gpio); + + HAL_GPIO_Init(config->rx_gpio, &(config->init_rx_gpio)); + HAL_GPIO_Init(config->tx_gpio, &(config->init_tx_gpio)); + + IRQn_Type rxit = -1; + IRQn_Type txit = -1; + can_get_irqs(canHandle->hal_fdcanP->Instance, &rxit, &txit); + + // rxfifo0 + HAL_NVIC_SetPriority(rxit, config->rx_interrupt_priority, 0); + HAL_NVIC_EnableIRQ(rxit); + + // tx + HAL_NVIC_SetPriority(txit, config->tx_interrupt_priority, 0); + HAL_NVIC_EnableIRQ(txit); + // End MSP Init -------------- + + return 0; +} + +// valid only for STM32G4 +static int can_get_irqs(FDCAN_GlobalTypeDef *instance, IRQn_Type *it0, IRQn_Type *it1) +{ + if (instance == FDCAN1) { + *it0 = FDCAN1_IT0_IRQn; + *it1 = FDCAN1_IT1_IRQn; + return 0; + } + if (instance == FDCAN2) { + *it0 = FDCAN2_IT0_IRQn; + *it1 = FDCAN2_IT1_IRQn; + return 0; + } + if (instance == FDCAN3) { + *it0 = FDCAN3_IT0_IRQn; + *it1 = FDCAN3_IT1_IRQn; + return 0; + } + + return -1; // invalid instance +} + +// valid only for STM32G4 +// static const char *can_get_instance_name(FDCAN_GlobalTypeDef *instance) +// { +// if (instance == FDCAN1) { +// return "FDCAN1"; +// } else if (instance == FDCAN2) { +// return "FDCAN2"; +// } else if (instance == FDCAN3) { +// return "FDCAN3"; +// } +// return "UNKNOWN"; +// } + +// valid only for STM32G4 +static CANHandle *can_get_buffer_handle(FDCAN_HandleTypeDef *hfdcan) +{ + // #ifdef STM32G474xx + if (hfdcan->Instance == FDCAN1) { + return &CAN1; + } else if (hfdcan->Instance == FDCAN2) { + return &CAN2; + } else if (hfdcan->Instance == FDCAN3) { + return &CAN3; + } else { + LOGOMATIC("CAN_get_buffer_handle: was given invalid FDCAN instance\n"); + return 0; + } +} + +static void can_tx_buffer_helper(CANHandle *handle) +{ + while (HAL_FDCAN_GetTxFifoFreeLevel(handle->hal_fdcanP) && !GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { + FDCANTxMessage *msg = GR_CircularBuffer_Pop(handle->tx_buffer); + + if (!msg) { + break; + } + + HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ(handle->hal_fdcanP, &msg->tx_header, msg->data); + + if (status != HAL_OK) { + LOGOMATIC("CAN_tx_helper: failed to add message to FIFO\n"); + free(msg); // Free the message we couldn't send + break; // Stop trying to send more + } + + free(msg); // Successfully sent, free the memory + } +} + +void FDCAN1_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } +void FDCAN1_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan1); } + +void FDCAN2_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } +void FDCAN2_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan2); } + +void FDCAN3_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } +void FDCAN3_IT1_IRQHandler(void) { HAL_FDCAN_IRQHandler(&hal_fdcan3); } + +void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes) +{ + UNUSED(BufferIndexes); + // If circular buffer has elements, send to queue + // Otherwise do nothing + // #ifdef USECAN1 + CANHandle *handle = can_get_buffer_handle(hfdcan); + + if (!handle || !handle->tx_buffer) { + return; + } + + if (GR_CircularBuffer_IsEmpty(handle->tx_buffer)) { + return; + } + + // see if you can pop any more from the buffer + can_tx_buffer_helper(handle); +} +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) +{ + CANHandle *handle = can_get_buffer_handle(hfdcan); + + if (!handle || !handle->init || !handle->rx_callback) { + return; + } + + /*if (!handle->rx_buffer) { + LOGOMATIC("CAN: RX Complete, but %s Buffer was released\n", can_get_instance_name(hfdcan->Instance)); + return; + } */ // no rx buffer at the moment + + /*if (RxFifo0ITs & FDCAN_IT_RX_FIFO0_MESSAGE_LOST) { + lost_rx++; + }*/ + + if (!(RxFifo0ITs & ~FDCAN_IT_RX_FIFO0_MESSAGE_LOST)) { + return; + } + + // if (GR_CircularBuffer_IsFull(handle->rx_buffer)) return; + + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; + + while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) > 0) { + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, rx_data); + + // stack allocation should be fine? Callback needs to terminate first before stack is popped + // should switch this over to malloc at some point to avoid double copies? + handle->rx_callback(rx_data, rx_header.DataLength); + } + + /* whoopsie, don't need the rx buffer yet + while (HAL_FDCAN_GetRxFifoFillLevel(hfdcan, FDCAN_RX_FIFO0) & !GR_CircularBuffer_IsFull(handle->rx_buffer)) { + FDCAN_RxHeaderTypeDef rx_header; + uint8_t rx_data[64] = {0}; + HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &rx_header, &rx_data); + + if (GR_CircularBuffer_IsEmpty(handle->rx_buffer)) handle->rx_callback(rx_data, rx_header.DataLength); + else { + GR_CircularBuffer_Push(handle->rx_buffer, rx_data, rx_header.DataLength); + } + }*/ +} + +/* +void can_read_rx_buffer(CANHandle* canHandle) { + //User can call this at their leisure to pop the rx_buffer + + //read rx_buffer one element at a time? + //or read until empty +}*/ + +/*void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef * hfdcan, uint32_t RxFifo0ITs) { + +}*/ + +// Just alternatively just use the HAL_FDCAN_ConfigFilter directly with the canHandle->hal_fdcan +int can_add_filter(CANHandle *canHandle, FDCAN_FilterTypeDef *filter) +{ + if (!canHandle) { + LOGOMATIC("CAN_add_filter: handle is null"); + return -1; + } + + if (!canHandle->init || canHandle->started) { + LOGOMATIC("CAN_add_filter: can instance is not initialized or already started"); + return -1; + } + + if (HAL_FDCAN_ConfigFilter(canHandle->hal_fdcanP, filter) != HAL_OK) { + LOGOMATIC("CAN_add_filter: failed to configure filter"); + return -1; + } + return 0; + // check that # of filters isn't exceeding max value +} + +// Need to +int can_start(CANHandle *canHandle) +{ + if (!canHandle || !canHandle->init) { + return -1; + } + + GPIOx_CLK_ENABLE(canHandle->rx_gpio); + GPIOx_CLK_ENABLE(canHandle->tx_gpio); + + HAL_FDCAN_Start(canHandle->hal_fdcanP); + canHandle->started = true; + + return 0; +} + +int can_stop(CANHandle *canHandle) +{ + if (!canHandle || !canHandle->init) { + return -1; + } + if (!canHandle->started) { + return 0; + } + + HAL_FDCAN_Stop(canHandle->hal_fdcanP); + + GPIOx_CLK_DISABLE(canHandle->rx_gpio); + GPIOx_CLK_DISABLE(canHandle->tx_gpio); + + canHandle->started = false; + + return 0; +} + +// Valid only for STM32G474xE +/*int can_msp_deinit(CANHandle* canHandle) { + //MSP DeInit + //turn off gpio clocks - can only turn off GPIOs if no other instances are using them + + + return 0; +}*/ + +static void FDCAN_InstanceDeInit(FDCAN_HandleTypeDef *hfdcan) +{ + // Enter INIT mode + hfdcan->Instance->CCCR |= FDCAN_CCCR_INIT; + while (!(hfdcan->Instance->CCCR & FDCAN_CCCR_INIT)) + ; + + // Clear filters + // TODO: fix magic numbers + memset((void *)hfdcan->msgRam.StandardFilterSA, 0, 0x0070); + memset((void *)hfdcan->msgRam.ExtendedFilterSA, 0, 0x0050); + + // Optionally reset FIFOs / buffers + + // Disable interrupts + __HAL_FDCAN_DISABLE_IT(hfdcan, FDCAN_IT_LIST_RX_FIFO0 | FDCAN_IT_LIST_RX_FIFO1 | FDCAN_IT_LIST_SMSG | FDCAN_IT_LIST_TX_FIFO_ERROR | FDCAN_IT_LIST_MISC | FDCAN_IT_LIST_BIT_LINE_ERROR | + FDCAN_IT_LIST_PROTOCOL_ERROR); + + // Exit INIT mode + hfdcan->Instance->CCCR &= ~FDCAN_CCCR_INIT; + while (hfdcan->Instance->CCCR & FDCAN_CCCR_INIT) + ; + + // Update handle state + hfdcan->State = HAL_FDCAN_STATE_RESET; +} + +int can_release(CANHandle *canHandle) +{ + if (!canHandle) { + LOGOMATIC("CAN: Tried to release a null handle"); + return -1; + } + + if (!canHandle->init) { + LOGOMATIC("CAN_release: can instance is already deinitialized"); + return -1; + } + can_stop(canHandle); // try to prevent more interrupts from firing + + // must disable NVIC IRQs before freeing circular buffer + + // turn off NVIC resources + IRQn_Type rx0it = -1; + IRQn_Type txit = -1; + can_get_irqs(canHandle->hal_fdcanP->Instance, &rx0it, &txit); + HAL_NVIC_DisableIRQ(rx0it); + HAL_NVIC_DisableIRQ(txit); + + // need to check if other pins are using before disabling - do this after mvp + // GPIOx_CLK_DISABLE(canHandle->rx_gpio); + // GPIOx_CLK_DISABLE(canHandle->tx_gpio); + + // reset FDCANx instance and message RAM and filters, clear interrupts + // HAL_FDCAN_DeInit(canHandle->hal_fdcanP); resets a little too hard + FDCAN_InstanceDeInit(canHandle->hal_fdcanP); + + __DSB(); // Data Synchronization Barrier + __ISB(); // Instruction Synchronization Barrier + + // free circular buffer contents + GR_CircularBuffer_Free(&(canHandle->tx_buffer)); + + // reset can instance + FDCAN_HandleTypeDef *temp = canHandle->hal_fdcanP; + memset(canHandle, 0, sizeof(*canHandle)); + canHandle->hal_fdcanP = temp; + + fdcan_disable_shared_clock(); // only turns off clock if no other instances are running. + + return 0; +} + +int can_send(CANHandle *canHandle, FDCANTxMessage *message) +{ + if (!canHandle || !message) { + LOGOMATIC("CAN_send: received null pointer\n"); + return -1; + } + + if (!canHandle->init || !canHandle->started) { + LOGOMATIC("CAN_send: CAN not initialized or started\n"); + return -1; + } + + uint32_t primask = __get_PRIMASK(); + __disable_irq(); + // IF TX Fifos are not full, send directly to them + // If TX Fifos are full, append to circular buffer + // If circular buffer is full, return an error code + uint32_t free = HAL_FDCAN_GetTxFifoFreeLevel(canHandle->hal_fdcanP); + + if (free > 0) { + HAL_StatusTypeDef status = HAL_FDCAN_AddMessageToTxFifoQ(canHandle->hal_fdcanP, &(message->tx_header), + message->data // Not &message->data if data is array + ); + + __set_PRIMASK(primask); + + if (status != HAL_OK) { + LOGOMATIC("CAN_send: failed to add to HW FIFO\n"); + return -1; + } + return 0; + } + + // Hardware FIFO full, try software buffer + if (!GR_CircularBuffer_IsFull(canHandle->tx_buffer)) { + int result = GR_CircularBuffer_Push(canHandle->tx_buffer, message, sizeof(FDCANTxMessage)); + + __set_PRIMASK(primask); + + if (result != 0) { + LOGOMATIC("CAN_send: buffer push failed\n"); + return -1; + } + return 0; + } + + // Both buffers full + __set_PRIMASK(primask); + LOGOMATIC("CAN_send: all buffers full\n"); + return -1; +} diff --git a/Lib/Peripherals/CAN/Test/can_tests.c b/Lib/Peripherals/CAN/Test/can_tests.c new file mode 100644 index 00000000..6e436cc4 --- /dev/null +++ b/Lib/Peripherals/CAN/Test/can_tests.c @@ -0,0 +1,170 @@ +#include "can_tests.h" + +#include + +#include "can.h" + +// each family has a constant number of CAN peripherals + +int can_test_instance(FDCAN_HandleTypeDef fdcan_handle) +{ + UNUSED(fdcan_handle); + return 0; +} + +void can_test_rx_callback2(void *data, uint32_t size) +{ + LOGOMATIC("CAN2 Got data! Size %ld, data[0] = 0x%x\n", size, *(char *)data); + // Is within an ISR, so needs to exit quickly + return; +} + +void can_test_rx_callback1(void *data, uint32_t size) +{ + LOGOMATIC("CAN1 Got data! Size %ld, data[0] = 0x%x\n", size, *(char *)data); + + // Is within an ISR, so needs to exit quickly + return; +} + +int can_test(void) +{ + + CANConfig canCfg; + // canCfg.fdcan_instance = FDCAN2; + + canCfg.hal_fdcan_init.ClockDivider = FDCAN_CLOCK_DIV1; + canCfg.hal_fdcan_init.FrameFormat = FDCAN_FRAME_FD_NO_BRS; + canCfg.hal_fdcan_init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; + canCfg.hal_fdcan_init.Mode = FDCAN_MODE_NORMAL; + canCfg.hal_fdcan_init.AutoRetransmission = ENABLE; + canCfg.hal_fdcan_init.TransmitPause = DISABLE; + canCfg.hal_fdcan_init.ProtocolException = ENABLE; + canCfg.hal_fdcan_init.NominalPrescaler = 1; + canCfg.hal_fdcan_init.NominalSyncJumpWidth = 16; + canCfg.hal_fdcan_init.NominalTimeSeg1 = 127; // Updated for 170MHz: (1+127+42)*1 = 170 ticks -> 1 Mbps + canCfg.hal_fdcan_init.NominalTimeSeg2 = 42; + canCfg.hal_fdcan_init.DataPrescaler = 8; + canCfg.hal_fdcan_init.DataSyncJumpWidth = 16; + canCfg.hal_fdcan_init.DataTimeSeg1 = 15; // Updated for 170MHz: (1+15+5)*8 = 168 ticks -> ~5 Mbps + canCfg.hal_fdcan_init.DataTimeSeg2 = 5; + canCfg.hal_fdcan_init.StdFiltersNbr = 1; + canCfg.hal_fdcan_init.ExtFiltersNbr = 0; + + canCfg.rx_callback = NULL; // PLEASE SET + canCfg.rx_interrupt_priority = 0; // PLEASE SET + canCfg.tx_interrupt_priority = 0; // PLEASE SET + canCfg.tx_buffer_length = 3; // PLEASE SET + + // canCfg.rx_gpio = GPIOB; + // canCfg.init_rx_gpio.Pin = GPIO_PIN_12; + canCfg.init_rx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_rx_gpio.Pull = GPIO_PULLUP; + canCfg.init_rx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + // canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + // canCfg.tx_gpio = GPIOB; + // canCfg.init_tx_gpio.Pin = GPIO_PIN_13; + canCfg.init_tx_gpio.Mode = GPIO_MODE_AF_PP; + canCfg.init_tx_gpio.Pull = GPIO_NOPULL; + canCfg.init_tx_gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + // canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + + // Not testing filters at the moment + // FDCAN_FilterTypeDef filter; + + // can_add_filter(can2Handle, &filter); + /* USER CODE END 2 */ + + FDCAN_TxHeaderTypeDef TxHeader = { + .Identifier = 1, + + .IdType = FDCAN_STANDARD_ID, + .TxFrameType = FDCAN_DATA_FRAME, + .ErrorStateIndicator = FDCAN_ESI_ACTIVE, // honestly this might be a value you have to read from a node + // FDCAN_ESI_ACTIVE is just a state that assumes there are minimal errors + .DataLength = 1, + .BitRateSwitch = FDCAN_BRS_OFF, + .TxEventFifoControl = FDCAN_NO_TX_EVENTS, // change to FDCAN_STORE_TX_EVENTS if you need to store info regarding transmitted messages + .MessageMarker = 0 // also change this to a real address if you change fifo control + }; + + FDCANTxMessage msg; + msg.data[0] = 0x80; + memset(&(msg.data), 0, sizeof(msg.data)); + msg.tx_header = TxHeader; + + can_set_clksource(LL_RCC_FDCAN_CLKSOURCE_PCLK1); + +#ifdef FDCAN1 + + canCfg.fdcan_instance = FDCAN1; + canCfg.rx_gpio = GPIOA; + canCfg.init_rx_gpio.Pin = GPIO_PIN_11; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN1; + + canCfg.tx_gpio = GPIOA; + canCfg.init_tx_gpio.Pin = GPIO_PIN_12; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN1; + + canCfg.rx_callback = can_test_rx_callback1; // PLEASE SET + + CANHandle *can1Handle = can_init(&canCfg); + HAL_FDCAN_ConfigGlobalFilter(can1Handle->hal_fdcanP, 0, 0, 0, 0); + + can_start(can1Handle); + +#endif +#ifdef FDCAN2 + + canCfg.fdcan_instance = FDCAN2; + canCfg.rx_gpio = GPIOB; + canCfg.init_rx_gpio.Pin = GPIO_PIN_12; + canCfg.init_rx_gpio.Alternate = GPIO_AF9_FDCAN2; + + canCfg.tx_gpio = GPIOB; + canCfg.init_tx_gpio.Pin = GPIO_PIN_13; + canCfg.init_tx_gpio.Alternate = GPIO_AF9_FDCAN2; + + canCfg.rx_callback = can_test_rx_callback2; + + // FDCAN_FilterTypeDef filter; + // filter.IdType = FDCAN_STANDARD_ID; + // filter.FilterIndex = 0; + // filter.FilterType = FDCAN_FILTER_RANGE, + // filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; + // filter.FilterID1 = 0x00; + // filter.FilterID2 = 0x02; + + CANHandle *can2Handle = can_init(&canCfg); + + // accept unmatched standard and extended frames into RXFIFO0 - default behaviour + HAL_FDCAN_ConfigGlobalFilter(can2Handle->hal_fdcanP, 0, 0, 0, 0); + + // not accepting filters + // can_add_filter(can2Handle, &filter); + + // API Testing + // can_init(&canCfg); + + can_start(can2Handle); + + can_send(can2Handle, &msg); + // can_release(can2Handle); + +#endif +#ifdef FDCAN3 + +#endif + + while (1) { + HAL_Delay(1000); + msg.data[0] = 0x2; + can_send(can1Handle, &msg); + HAL_Delay(1000); + msg.data[0] = 0x10; + can_send(can2Handle, &msg); + } + + return 0; +} diff --git a/Lib/Peripherals/CAN/Test/can_tests.h b/Lib/Peripherals/CAN/Test/can_tests.h new file mode 100644 index 00000000..39cdec72 --- /dev/null +++ b/Lib/Peripherals/CAN/Test/can_tests.h @@ -0,0 +1,19 @@ +#ifndef CAN_TESTS_H +#define CAN_TESTS_H + +#include "Logomatic.h" +#include "can.h" +#include "can_platform_deps.h" + +// Tested STM32 Families +#ifdef STM32G4 +// #elif defined(STM32L4) +// #elif defined(STM32U5) +#else +#error "Untested STM32 Family" +#endif + +// Assume the LOGOMATIC is setup correctly +int can_test(void); // top-level function, just call this and check if the return status is correct + +#endif \ No newline at end of file diff --git a/Lib/Peripherals/CAN/Test/readme.md b/Lib/Peripherals/CAN/Test/readme.md new file mode 100644 index 00000000..aba2e133 --- /dev/null +++ b/Lib/Peripherals/CAN/Test/readme.md @@ -0,0 +1,21 @@ +# Tests +1. Initialize FDCAN1, then try to initialize the same instance (should error) +2. Initialize, then release immediately. Check state of GPIOs and FDCAN. Then initialize the same peripheral again +3. Initialize, add some filters until you add too many (should do something interesting) +4. Send some data, but try to release buffer halfway through and see if it gets logged by the TX complete callback + + +after releasing: +- State of FDCANx peripheral registers are back to reset. +- State of GPIOx ports registers are back to reset. +- turn off RCC clock if there are no other FDCAN peripherals. + +- can_send_helper, free a circular buffer + +- discuss freeing within ISR, how to avoid. + +- Critical Section when releasing: +- + + +- Add MACRO support to detect if FDCAN is a supported peripheral on the defined STM32 family \ No newline at end of file diff --git a/Lib/Peripherals/CAN/common.cmake b/Lib/Peripherals/CAN/common.cmake new file mode 100644 index 00000000..120a4dcb --- /dev/null +++ b/Lib/Peripherals/CAN/common.cmake @@ -0,0 +1,42 @@ +add_library(PERIPHERAL_CAN_LIB INTERFACE) + +target_link_libraries(PERIPHERAL_CAN_LIB INTERFACE CircularBuffer_Lib) + +target_sources(PERIPHERAL_CAN_LIB INTERFACE ${CMAKE_CURRENT_LIST_DIR}/Src/can.c) + +# Make headers accessible as #include "Peripherals/CAN/can.h" +target_include_directories( + PERIPHERAL_CAN_LIB + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/Inc +) + +#tests +add_library(PERIPHERAL_CAN_TEST_LIB INTERFACE) +target_sources( + PERIPHERAL_CAN_TEST_LIB + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/Test/can_tests.c +) +target_include_directories( + PERIPHERAL_CAN_TEST_LIB + INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/Test +) + +# link test to this library +#if(CMAKE_BUILD_TYPE STREQUAL "Test") +# Initialization +# add_executable( +# PERIPHERAL_CAN_LIB_init_test +# ${CMAKE_CURRENT_LIST_DIR}/Test/can_test_init.c +# ) +# target_link_libraries( +# PERIPHERAL_CAN_LIB_init_test +# PERIPHERAL_CAN_LIB +# ) +# add_test( +# PERIPHERAL_CAN_LIB_init +# PERIPHERAL_CAN_LIB_init_test +# ) +#endif()