From 7283164018f5f5cf099424c302d7287ecbb4d7b3 Mon Sep 17 00:00:00 2001 From: JoshLafleur Date: Mon, 17 Feb 2025 16:40:01 -0500 Subject: [PATCH] VC(PDU/FRONT/REAR) Initial Bringup Added BL and BLU support for nodes Added yamcan base support for nodes --- SConstruct | 2 +- components/bootloaders/STM/stm32f1/STM32F1.ld | 6 + .../STM/stm32f1/include/HW/HW_specific.h | 28 +- .../bootloaders/STM/stm32f1/variants.yaml | 90 ++++ .../FeatureDefs/Application_FeatureDefs.yaml | 3 + .../shared/code/RTOS/FreeRTOSResources.c | 395 +++++++++++++++ components/shared/code/RTOS/FreeRTOS_SWI.c | 209 ++++++++ components/shared/code/RTOS/FreeRTOS_SWI.h | 63 +++ components/shared/code/RTOS/FreeRTOS_types.h | 42 ++ components/shared/code/RTOS/Module.c | 140 +++++ components/shared/code/RTOS/Module.h | 54 ++ components/shared/code/RTOS/ModuleDesc.h | 25 + components/shared/code/app/CAN/CanTypes.h | 2 +- components/shared/code/libs/LIB_FloatTypes.h | 13 + components/shared/code/libs/LIB_Types.h | 18 + components/vc/SConscript | 19 + components/vc/front/FeatureDefs.yaml | 6 + components/vc/front/FeatureSels.yaml | 6 + components/vc/front/SConscript | 448 ++++++++++++++++ .../front/include/CANIO_componentSpecific.h | 39 ++ components/vc/front/include/FreeRTOSConfig.h | 162 ++++++ components/vc/front/include/HW/BuildDefines.h | 20 + components/vc/front/include/HW/HW.h | 36 ++ components/vc/front/include/HW/HW_adc.h | 58 +++ .../include/HW/HW_can_componentSpecific.h | 25 + components/vc/front/include/HW/HW_clock.h | 67 +++ components/vc/front/include/HW/HW_dma.h | 20 + .../include/HW/HW_gpio_componentSpecific.h | 20 + components/vc/front/include/HW/HW_intc.h | 35 ++ components/vc/front/include/HW/HW_tim.h | 25 + components/vc/front/include/HW/SystemConfig.h | 31 ++ components/vc/front/include/HW/stm32f105.yaml | 24 + .../vc/front/include/HW/stm32f1xx_hal_conf.h | 259 ++++++++++ components/vc/front/include/IO.h | 45 ++ .../front/include/Module_componentSpecific.h | 36 ++ components/vc/front/include/UDS.h | 19 + components/vc/front/include/Utility.h | 477 ++++++++++++++++++ .../vc/front/include/uds_componentSpecific.h | 27 + .../renderers/BuildDefines_generated.h.mako | 8 + .../vc/front/src/CANIO_componentSpecific.c | 32 ++ components/vc/front/src/HW/HW.c | 91 ++++ components/vc/front/src/HW/HW_adc.c | 203 ++++++++ .../front/src/HW/HW_can_componentSpecific.c | 410 +++++++++++++++ components/vc/front/src/HW/HW_dma.c | 29 ++ .../front/src/HW/HW_gpio_componentSpecific.c | 54 ++ components/vc/front/src/HW/HW_intc.c | 172 +++++++ components/vc/front/src/HW/HW_msp.c | 30 ++ components/vc/front/src/HW/HW_tim.c | 264 ++++++++++ components/vc/front/src/IO.c | 161 ++++++ .../vc/front/src/Module_componentSpecific.c | 27 + components/vc/front/src/SystemManager.c | 107 ++++ components/vc/front/src/UDS.c | 291 +++++++++++ components/vc/front/src/Utility.c | 26 + components/vc/front/variants.yaml | 11 + components/vc/pdu/FeatureDefs.yaml | 6 + components/vc/pdu/FeatureSels.yaml | 6 + components/vc/pdu/SConscript | 448 ++++++++++++++++ .../vc/pdu/include/CANIO_componentSpecific.h | 39 ++ components/vc/pdu/include/FreeRTOSConfig.h | 162 ++++++ components/vc/pdu/include/HW/BuildDefines.h | 20 + components/vc/pdu/include/HW/HW.h | 36 ++ components/vc/pdu/include/HW/HW_adc.h | 58 +++ .../pdu/include/HW/HW_can_componentSpecific.h | 25 + components/vc/pdu/include/HW/HW_clock.h | 67 +++ components/vc/pdu/include/HW/HW_dma.h | 20 + .../include/HW/HW_gpio_componentSpecific.h | 20 + components/vc/pdu/include/HW/HW_intc.h | 35 ++ components/vc/pdu/include/HW/HW_tim.h | 25 + components/vc/pdu/include/HW/SystemConfig.h | 31 ++ components/vc/pdu/include/HW/stm32f105.yaml | 24 + .../vc/pdu/include/HW/stm32f1xx_hal_conf.h | 259 ++++++++++ components/vc/pdu/include/IO.h | 45 ++ .../vc/pdu/include/Module_componentSpecific.h | 36 ++ components/vc/pdu/include/UDS.h | 19 + components/vc/pdu/include/Utility.h | 477 ++++++++++++++++++ .../vc/pdu/include/uds_componentSpecific.h | 27 + .../renderers/BuildDefines_generated.h.mako | 8 + .../vc/pdu/src/CANIO_componentSpecific.c | 32 ++ components/vc/pdu/src/HW/HW.c | 91 ++++ components/vc/pdu/src/HW/HW_adc.c | 203 ++++++++ .../vc/pdu/src/HW/HW_can_componentSpecific.c | 410 +++++++++++++++ components/vc/pdu/src/HW/HW_dma.c | 29 ++ .../vc/pdu/src/HW/HW_gpio_componentSpecific.c | 54 ++ components/vc/pdu/src/HW/HW_intc.c | 172 +++++++ components/vc/pdu/src/HW/HW_msp.c | 30 ++ components/vc/pdu/src/HW/HW_tim.c | 264 ++++++++++ components/vc/pdu/src/IO.c | 161 ++++++ .../vc/pdu/src/Module_componentSpecific.c | 27 + components/vc/pdu/src/SystemManager.c | 107 ++++ components/vc/pdu/src/UDS.c | 291 +++++++++++ components/vc/pdu/src/Utility.c | 26 + components/vc/pdu/variants.yaml | 11 + components/vc/rear/FeatureDefs.yaml | 6 + components/vc/rear/FeatureSels.yaml | 6 + components/vc/rear/SConscript | 448 ++++++++++++++++ .../vc/rear/include/CANIO_componentSpecific.h | 39 ++ components/vc/rear/include/FreeRTOSConfig.h | 162 ++++++ components/vc/rear/include/HW/BuildDefines.h | 20 + components/vc/rear/include/HW/HW.h | 36 ++ components/vc/rear/include/HW/HW_adc.h | 58 +++ .../include/HW/HW_can_componentSpecific.h | 25 + components/vc/rear/include/HW/HW_clock.h | 67 +++ components/vc/rear/include/HW/HW_dma.h | 20 + .../include/HW/HW_gpio_componentSpecific.h | 20 + components/vc/rear/include/HW/HW_intc.h | 35 ++ components/vc/rear/include/HW/HW_tim.h | 25 + components/vc/rear/include/HW/SystemConfig.h | 31 ++ components/vc/rear/include/HW/stm32f105.yaml | 24 + .../vc/rear/include/HW/stm32f1xx_hal_conf.h | 259 ++++++++++ components/vc/rear/include/IO.h | 45 ++ .../rear/include/Module_componentSpecific.h | 36 ++ components/vc/rear/include/UDS.h | 19 + components/vc/rear/include/Utility.h | 477 ++++++++++++++++++ .../vc/rear/include/uds_componentSpecific.h | 27 + .../renderers/BuildDefines_generated.h.mako | 8 + .../vc/rear/src/CANIO_componentSpecific.c | 32 ++ components/vc/rear/src/HW/HW.c | 91 ++++ components/vc/rear/src/HW/HW_adc.c | 203 ++++++++ .../vc/rear/src/HW/HW_can_componentSpecific.c | 410 +++++++++++++++ components/vc/rear/src/HW/HW_dma.c | 29 ++ .../rear/src/HW/HW_gpio_componentSpecific.c | 54 ++ components/vc/rear/src/HW/HW_intc.c | 172 +++++++ components/vc/rear/src/HW/HW_msp.c | 30 ++ components/vc/rear/src/HW/HW_tim.c | 264 ++++++++++ components/vc/rear/src/IO.c | 161 ++++++ .../vc/rear/src/Module_componentSpecific.c | 27 + components/vc/rear/src/SystemManager.c | 107 ++++ components/vc/rear/src/UDS.c | 291 +++++++++++ components/vc/rear/src/Utility.c | 26 + components/vc/rear/variants.yaml | 11 + .../templates/CANTypes_generated.h.mako | 8 - .../templates/MessagePack_generated.h.mako | 2 +- network/NetworkGen/templates/SigRx.h.mako | 5 +- network/definition/buses/ass.yaml | 4 + network/definition/buses/body.yaml | 4 + network/definition/buses/nose.yaml | 4 + .../udsClient/udsClient-message.yaml | 18 + .../components/vcfront/vcfront-message.yaml | 13 + .../data/components/vcfront/vcfront-rx.yaml | 5 + .../components/vcfront/vcfront-signals.yaml | 1 + .../data/components/vcfront/vcfront.yaml | 4 + .../data/components/vcpdu/vcpdu-message.yaml | 12 + .../data/components/vcpdu/vcpdu-rx.yaml | 5 + .../data/components/vcpdu/vcpdu-signals.yaml | 1 + .../data/components/vcpdu/vcpdu.yaml | 4 + .../components/vcrear/vcrear-message.yaml | 13 + .../data/components/vcrear/vcrear-rx.yaml | 5 + .../components/vcrear/vcrear-signals.yaml | 1 + .../data/components/vcrear/vcrear.yaml | 4 + site_scons/components.yaml | 6 + site_scons/platforms.yaml | 9 + site_scons/site_tools/network.py | 3 +- 152 files changed, 12620 insertions(+), 23 deletions(-) create mode 100644 components/shared/code/RTOS/FreeRTOSResources.c create mode 100644 components/shared/code/RTOS/FreeRTOS_SWI.c create mode 100644 components/shared/code/RTOS/FreeRTOS_SWI.h create mode 100644 components/shared/code/RTOS/FreeRTOS_types.h create mode 100644 components/shared/code/RTOS/Module.c create mode 100644 components/shared/code/RTOS/Module.h create mode 100644 components/shared/code/RTOS/ModuleDesc.h create mode 100644 components/shared/code/libs/LIB_FloatTypes.h create mode 100644 components/shared/code/libs/LIB_Types.h create mode 100644 components/vc/SConscript create mode 100644 components/vc/front/FeatureDefs.yaml create mode 100644 components/vc/front/FeatureSels.yaml create mode 100644 components/vc/front/SConscript create mode 100644 components/vc/front/include/CANIO_componentSpecific.h create mode 100644 components/vc/front/include/FreeRTOSConfig.h create mode 100644 components/vc/front/include/HW/BuildDefines.h create mode 100644 components/vc/front/include/HW/HW.h create mode 100644 components/vc/front/include/HW/HW_adc.h create mode 100644 components/vc/front/include/HW/HW_can_componentSpecific.h create mode 100644 components/vc/front/include/HW/HW_clock.h create mode 100644 components/vc/front/include/HW/HW_dma.h create mode 100644 components/vc/front/include/HW/HW_gpio_componentSpecific.h create mode 100644 components/vc/front/include/HW/HW_intc.h create mode 100644 components/vc/front/include/HW/HW_tim.h create mode 100644 components/vc/front/include/HW/SystemConfig.h create mode 100644 components/vc/front/include/HW/stm32f105.yaml create mode 100644 components/vc/front/include/HW/stm32f1xx_hal_conf.h create mode 100644 components/vc/front/include/IO.h create mode 100644 components/vc/front/include/Module_componentSpecific.h create mode 100644 components/vc/front/include/UDS.h create mode 100644 components/vc/front/include/Utility.h create mode 100644 components/vc/front/include/uds_componentSpecific.h create mode 100644 components/vc/front/renderers/BuildDefines_generated.h.mako create mode 100644 components/vc/front/src/CANIO_componentSpecific.c create mode 100644 components/vc/front/src/HW/HW.c create mode 100644 components/vc/front/src/HW/HW_adc.c create mode 100644 components/vc/front/src/HW/HW_can_componentSpecific.c create mode 100644 components/vc/front/src/HW/HW_dma.c create mode 100644 components/vc/front/src/HW/HW_gpio_componentSpecific.c create mode 100644 components/vc/front/src/HW/HW_intc.c create mode 100644 components/vc/front/src/HW/HW_msp.c create mode 100644 components/vc/front/src/HW/HW_tim.c create mode 100644 components/vc/front/src/IO.c create mode 100644 components/vc/front/src/Module_componentSpecific.c create mode 100644 components/vc/front/src/SystemManager.c create mode 100644 components/vc/front/src/UDS.c create mode 100644 components/vc/front/src/Utility.c create mode 100644 components/vc/front/variants.yaml create mode 100644 components/vc/pdu/FeatureDefs.yaml create mode 100644 components/vc/pdu/FeatureSels.yaml create mode 100644 components/vc/pdu/SConscript create mode 100644 components/vc/pdu/include/CANIO_componentSpecific.h create mode 100644 components/vc/pdu/include/FreeRTOSConfig.h create mode 100644 components/vc/pdu/include/HW/BuildDefines.h create mode 100644 components/vc/pdu/include/HW/HW.h create mode 100644 components/vc/pdu/include/HW/HW_adc.h create mode 100644 components/vc/pdu/include/HW/HW_can_componentSpecific.h create mode 100644 components/vc/pdu/include/HW/HW_clock.h create mode 100644 components/vc/pdu/include/HW/HW_dma.h create mode 100644 components/vc/pdu/include/HW/HW_gpio_componentSpecific.h create mode 100644 components/vc/pdu/include/HW/HW_intc.h create mode 100644 components/vc/pdu/include/HW/HW_tim.h create mode 100644 components/vc/pdu/include/HW/SystemConfig.h create mode 100644 components/vc/pdu/include/HW/stm32f105.yaml create mode 100644 components/vc/pdu/include/HW/stm32f1xx_hal_conf.h create mode 100644 components/vc/pdu/include/IO.h create mode 100644 components/vc/pdu/include/Module_componentSpecific.h create mode 100644 components/vc/pdu/include/UDS.h create mode 100644 components/vc/pdu/include/Utility.h create mode 100644 components/vc/pdu/include/uds_componentSpecific.h create mode 100644 components/vc/pdu/renderers/BuildDefines_generated.h.mako create mode 100644 components/vc/pdu/src/CANIO_componentSpecific.c create mode 100644 components/vc/pdu/src/HW/HW.c create mode 100644 components/vc/pdu/src/HW/HW_adc.c create mode 100644 components/vc/pdu/src/HW/HW_can_componentSpecific.c create mode 100644 components/vc/pdu/src/HW/HW_dma.c create mode 100644 components/vc/pdu/src/HW/HW_gpio_componentSpecific.c create mode 100644 components/vc/pdu/src/HW/HW_intc.c create mode 100644 components/vc/pdu/src/HW/HW_msp.c create mode 100644 components/vc/pdu/src/HW/HW_tim.c create mode 100644 components/vc/pdu/src/IO.c create mode 100644 components/vc/pdu/src/Module_componentSpecific.c create mode 100644 components/vc/pdu/src/SystemManager.c create mode 100644 components/vc/pdu/src/UDS.c create mode 100644 components/vc/pdu/src/Utility.c create mode 100644 components/vc/pdu/variants.yaml create mode 100644 components/vc/rear/FeatureDefs.yaml create mode 100644 components/vc/rear/FeatureSels.yaml create mode 100644 components/vc/rear/SConscript create mode 100644 components/vc/rear/include/CANIO_componentSpecific.h create mode 100644 components/vc/rear/include/FreeRTOSConfig.h create mode 100644 components/vc/rear/include/HW/BuildDefines.h create mode 100644 components/vc/rear/include/HW/HW.h create mode 100644 components/vc/rear/include/HW/HW_adc.h create mode 100644 components/vc/rear/include/HW/HW_can_componentSpecific.h create mode 100644 components/vc/rear/include/HW/HW_clock.h create mode 100644 components/vc/rear/include/HW/HW_dma.h create mode 100644 components/vc/rear/include/HW/HW_gpio_componentSpecific.h create mode 100644 components/vc/rear/include/HW/HW_intc.h create mode 100644 components/vc/rear/include/HW/HW_tim.h create mode 100644 components/vc/rear/include/HW/SystemConfig.h create mode 100644 components/vc/rear/include/HW/stm32f105.yaml create mode 100644 components/vc/rear/include/HW/stm32f1xx_hal_conf.h create mode 100644 components/vc/rear/include/IO.h create mode 100644 components/vc/rear/include/Module_componentSpecific.h create mode 100644 components/vc/rear/include/UDS.h create mode 100644 components/vc/rear/include/Utility.h create mode 100644 components/vc/rear/include/uds_componentSpecific.h create mode 100644 components/vc/rear/renderers/BuildDefines_generated.h.mako create mode 100644 components/vc/rear/src/CANIO_componentSpecific.c create mode 100644 components/vc/rear/src/HW/HW.c create mode 100644 components/vc/rear/src/HW/HW_adc.c create mode 100644 components/vc/rear/src/HW/HW_can_componentSpecific.c create mode 100644 components/vc/rear/src/HW/HW_dma.c create mode 100644 components/vc/rear/src/HW/HW_gpio_componentSpecific.c create mode 100644 components/vc/rear/src/HW/HW_intc.c create mode 100644 components/vc/rear/src/HW/HW_msp.c create mode 100644 components/vc/rear/src/HW/HW_tim.c create mode 100644 components/vc/rear/src/IO.c create mode 100644 components/vc/rear/src/Module_componentSpecific.c create mode 100644 components/vc/rear/src/SystemManager.c create mode 100644 components/vc/rear/src/UDS.c create mode 100644 components/vc/rear/src/Utility.c create mode 100644 components/vc/rear/variants.yaml create mode 100644 network/definition/buses/ass.yaml create mode 100644 network/definition/buses/body.yaml create mode 100644 network/definition/buses/nose.yaml create mode 100644 network/definition/data/components/vcfront/vcfront-message.yaml create mode 100644 network/definition/data/components/vcfront/vcfront-rx.yaml create mode 100644 network/definition/data/components/vcfront/vcfront-signals.yaml create mode 100644 network/definition/data/components/vcfront/vcfront.yaml create mode 100644 network/definition/data/components/vcpdu/vcpdu-message.yaml create mode 100644 network/definition/data/components/vcpdu/vcpdu-rx.yaml create mode 100644 network/definition/data/components/vcpdu/vcpdu-signals.yaml create mode 100644 network/definition/data/components/vcpdu/vcpdu.yaml create mode 100644 network/definition/data/components/vcrear/vcrear-message.yaml create mode 100644 network/definition/data/components/vcrear/vcrear-rx.yaml create mode 100644 network/definition/data/components/vcrear/vcrear-signals.yaml create mode 100644 network/definition/data/components/vcrear/vcrear.yaml diff --git a/SConstruct b/SConstruct index 16fee3e4..e2a9c10a 100644 --- a/SConstruct +++ b/SConstruct @@ -119,7 +119,7 @@ for target in target_dict: config_ids = [int(id) for id in findall(CONFIG_ID_REGEX, target)] target_sconscript = f"{components[component["component"]]['path']}SConscript" - PlatformEnv["ARTIFACTS"][f"{target.upper()}"] = SConscript(target_sconscript, exports={"CONFIG_IDS": config_ids, "PLATFORM_ENV": PlatformEnv, "NETWORK_ENV": NetworkEnv }) + PlatformEnv["ARTIFACTS"][f"{target.upper()}"] = SConscript(target_sconscript, exports={"TARGET": target, "CONFIG_IDS": config_ids, "PLATFORM_ENV": PlatformEnv, "NETWORK_ENV": NetworkEnv }) if PlatformEnv["ARTIFACTS"]: AddOption("--upload", dest="upload", action="store_true") diff --git a/components/bootloaders/STM/stm32f1/STM32F1.ld b/components/bootloaders/STM/stm32f1/STM32F1.ld index f63d5629..a3ac1dbe 100644 --- a/components/bootloaders/STM/stm32f1/STM32F1.ld +++ b/components/bootloaders/STM/stm32f1/STM32F1.ld @@ -57,7 +57,13 @@ SECTIONS #error "Function not supported" #endif +#if MCU_STM32_PN == FDEFS_STM32_PN_STM32F103XB .isr_vector : ALIGN(0x100) +#elif MCU_STM32_PN == FDEFS_STM32_PN_STM32F105 + .isr_vector : ALIGN(0x400) +#else +#error "Chipset not supported" +#endif { __app_start_addr = .; KEEP(*(.isr_vector)) /* interrupt vector table */ diff --git a/components/bootloaders/STM/stm32f1/include/HW/HW_specific.h b/components/bootloaders/STM/stm32f1/include/HW/HW_specific.h index 5fed2930..2d935084 100644 --- a/components/bootloaders/STM/stm32f1/include/HW/HW_specific.h +++ b/components/bootloaders/STM/stm32f1/include/HW/HW_specific.h @@ -31,7 +31,11 @@ # define CAN_TX_PORT GPIOB # define CAN_TX_PIN 9U -#elif ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_BMSB) && (APP_PCBA_ID == 1U)) || (APP_PCBA_ID == 10U) +#elif ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_BMSB) && (APP_PCBA_ID == 1U)) || \ + ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_VCPDU) && (APP_PCBA_ID == 0U)) || \ + ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_VCFRONT) && (APP_PCBA_ID == 0U)) || \ + ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_VCREAR) && (APP_PCBA_ID == 0U)) || \ + (APP_PCBA_ID == 10U) # define CAN_AFIO_REMAP false # define CAN_RX_PORT GPIOA @@ -49,13 +53,23 @@ #define BUTTON_PIN 2U #define BUTTON_PRESSED_STATE 1U -#define LED_PORT GPIOC -#define LED_PIN 13U -#define LED_ON_STATE 0U // this can probably be refactored -#if APP_PCBA_ID == 0 -# define LED_MODE GPIO_CFG_OUTPUT_OPEN_DRAIN -#elif ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_BMSB) && (APP_PCBA_ID == 1U)) || (APP_PCBA_ID == 10U) +#if ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_VCPDU) && (APP_PCBA_ID == 0U)) +# define LED_PORT GPIOB +# define LED_PIN 8U +#else +# define LED_PORT GPIOC +# define LED_PIN 13U +#endif +# define LED_ON_STATE 0U // this can probably be refactored + +#if ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_BMSB) && (APP_PCBA_ID == 1U)) || \ + ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_VCPDU) && (APP_PCBA_ID == 0U)) || \ + ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_VCFRONT) && (APP_PCBA_ID == 0U)) || \ + ((APP_COMPONENT_ID == FDEFS_COMPONENT_ID_VCREAR) && (APP_PCBA_ID == 0U)) || \ + (APP_PCBA_ID == 10U) # define LED_MODE GPIO_CFG_OUTPUT_PUSH_PULL +#elif APP_PCBA_ID == 0 +# define LED_MODE GPIO_CFG_OUTPUT_OPEN_DRAIN #else #error "Invalid configuration" #endif diff --git a/components/bootloaders/STM/stm32f1/variants.yaml b/components/bootloaders/STM/stm32f1/variants.yaml index 56f7efcf..b682977b 100644 --- a/components/bootloaders/STM/stm32f1/variants.yaml +++ b/components/bootloaders/STM/stm32f1/variants.yaml @@ -289,3 +289,93 @@ configs: overrides: app_pcba_id: 10 app_component_id: debug + 30: + description: VCFRONT Bootloader + options: + udsRequestId: 0x630 + udsResponseId: 0x670 + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/BOOT_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 + app_component_id: vcpdu + app_validation_enabled: true + feature_erase_invalid_app: false + 1030: + description: VCFRONT Bootloader Updater + options: + udsRequestId: 0x630 + udsResponseId: 0x670 + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/BOOTUPDATER_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 + app_component_id: vcpdu + app_validation_enabled: true + feature_erase_invalid_app: false + 31: + description: VCREAR Bootloader + options: + udsRequestId: 0x631 + udsResponseId: 0x671 + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/BOOT_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 + app_component_id: vcpdu + app_validation_enabled: true + feature_erase_invalid_app: false + 1031: + description: VCREAR Bootloader Updater + options: + udsRequestId: 0x631 + udsResponseId: 0x671 + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/BOOTUPDATER_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 + app_component_id: vcpdu + app_validation_enabled: true + feature_erase_invalid_app: false + 32: + description: VCPDU Bootloader + options: + udsRequestId: 0x632 + udsResponseId: 0x672 + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/BOOT_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 + app_component_id: vcpdu + app_validation_enabled: true + feature_erase_invalid_app: false + 1032: + description: VCPDU Bootloader Updater + options: + udsRequestId: 0x632 + udsResponseId: 0x672 + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/BOOTUPDATER_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 + app_component_id: vcpdu + app_validation_enabled: true + feature_erase_invalid_app: false diff --git a/components/shared/FeatureDefs/Application_FeatureDefs.yaml b/components/shared/FeatureDefs/Application_FeatureDefs.yaml index 95aefc71..2313bf28 100644 --- a/components/shared/FeatureDefs/Application_FeatureDefs.yaml +++ b/components/shared/FeatureDefs/Application_FeatureDefs.yaml @@ -39,6 +39,9 @@ discreteValues: - bmsw - bmsb - stw + - vcpdu + - vcfront + - vcrear function_id: - bl - app diff --git a/components/shared/code/RTOS/FreeRTOSResources.c b/components/shared/code/RTOS/FreeRTOSResources.c new file mode 100644 index 00000000..fcef74c2 --- /dev/null +++ b/components/shared/code/RTOS/FreeRTOSResources.c @@ -0,0 +1,395 @@ +/** + * @file FreeRTOSResources.c + * @brief Source code for FreeRTOS Implementation + * @author Joshua Lafleur (josh.lafleur@outlook.com) + * @version + * @date 2024-01-30 + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "FreeRTOS_types.h" +#include "SystemConfig.h" +#include + +// FreeRTOS includes +#include "FreeRTOS.h" +#include "FreeRTOS_SWI.h" +#include "task.h" +#include "timers.h" + +// Other Includes +#include "CAN/CAN.h" +#include "Utility.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// which bit in the event group corresponds to each task +#define PERIODIC_TASK_1kHz (1U) << (0U) +#define PERIODIC_TASK_100Hz (1U) << (1U) +#define PERIODIC_TASK_10Hz (1U) << (2U) +#define PERIODIC_TASK_1Hz (1U) << (3U) + + +/****************************************************************************** + * M A C R O S + ******************************************************************************/ + +#define NUM_TASKS (sizeof(ModuleTasks) / sizeof(RTOS_taskDesc_t)) // number of tasks in this module + + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +// periodic event group. each bit in the group signifies that the +// respective periodic task is ready to run +EventGroupHandle_t PeriodicEvent; + +// timer which will run all of the periodic tasks +TimerHandle_t rtos_tick_timer; + +// task handle and stack definitions +static StaticTask_t Task1kHz; +static StackType_t task1kHzStack[configMINIMAL_STACK_SIZE]; +static StaticTask_t Task100Hz; +static StackType_t task100HzStack[configMINIMAL_STACK_SIZE]; +static StaticTask_t Task10Hz; +static StackType_t task10HzStack[configMINIMAL_STACK_SIZE]; +static StaticTask_t Task1Hz; +static StackType_t task1HzStack[configMINIMAL_STACK_SIZE]; + +// module periodic tasks, defined in Module.h +extern void Module_1kHz_TSK(void); +extern void Module_100Hz_TSK(void); +extern void Module_10Hz_TSK(void); +extern void Module_1Hz_TSK(void); +extern void Module_ApplicationIdleHook(void); + +// SWIs +RTOS_swiHandle_T* CANRX_swi; +RTOS_swiHandle_T* CANTX_swi; + +// task definitions +RTOS_taskDesc_t ModuleTasks[] = { + { + .function = &Module_1kHz_TSK, + .name = "Task 1kHz", + .priority = 4U, + .parameters = NULL, + .stack = task1kHzStack, + .stackSize = sizeof(task1kHzStack) / sizeof(StackType_t), + .stateBuffer = &Task1kHz, + .event = { + .group = &PeriodicEvent, + .bit = PERIODIC_TASK_1kHz, + }, + .periodMs = pdMS_TO_TICKS(1U), + }, + { + .function = &Module_100Hz_TSK, + .name = "Task 100Hz", + .priority = 3U, + .parameters = NULL, + .stack = task100HzStack, + .stackSize = sizeof(task100HzStack) / sizeof(StackType_t), + .stateBuffer = &Task100Hz, + .event = { + .group = &PeriodicEvent, + .bit = PERIODIC_TASK_100Hz, + }, + .periodMs = pdMS_TO_TICKS(10U), + }, + { + .function = &Module_10Hz_TSK, + .name = "Task 10Hz", + .priority = 2U, + .stack = task10HzStack, + .stackSize = sizeof(task10HzStack) / sizeof(StackType_t), + .stateBuffer = &Task10Hz, + .parameters = NULL, + .event = { + .group = &PeriodicEvent, + .bit = PERIODIC_TASK_10Hz, + }, + .periodMs = pdMS_TO_TICKS(100U), + }, + { + .function = &Module_1Hz_TSK, + .name = "Task 1Hz", + .priority = 1U, + .stack = task1HzStack, + .stackSize = sizeof(task1HzStack) / sizeof(StackType_t), + .stateBuffer = &Task1Hz, + .parameters = NULL, + .event = { + .group = &PeriodicEvent, + .bit = PERIODIC_TASK_1Hz, + }, + .periodMs = pdMS_TO_TICKS(1000U), + }, +}; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void vApplicationIdleHook(void); +void vApplicationTickHook(void); + + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +static void rtosTickTimer(TimerHandle_t xTimer) +{ + if (xTimer == rtos_tick_timer) + { + for (uint16_t i = 0U; i < NUM_TASKS; i++) + { + RTOS_taskDesc_t* const task = &ModuleTasks[i]; + + if (task->periodMs == 0U) + { + // aperiodic task + continue; + } + + // check if it is time to execute the task + if (++task->timeSinceLastTickMs == task->periodMs) + { + task->timeSinceLastTickMs = 0U; + // if it is, set the event bit for this task in the event group + xEventGroupSetBits(*task->event.group, task->event.bit); + } + } + } +} + +/* + * Task Function + * This function is called by FreeRTOS for each task. Each task will then, + * in turn, check to see if it is time to execute based on its period and + * time since last execution. If it's time to execute, this function will call + * the function pointer associated with the task + */ +static void taskFxn(void* parameters) +{ + RTOS_taskDesc_t* task = (RTOS_taskDesc_t*)parameters; // convert the parameter back into a task description + + void (*const function)(void) = task->function; // get the function that will be called for this task + EventGroupHandle_t* event_group = task->event.group; // get the shared event group + EventBits_t event_bit = task->event.bit; // get the event bit for this task + + // if the processor has a floating point unit, uncomment the following line + // portTASK_USES_FLOATING_POINT(); + + for (;;) + { + // check if the event bit for this task has been set. If it has, call the function + // for this task. If not, non-blocking wait. + xEventGroupWaitBits(*event_group, event_bit, pdTRUE, pdFALSE, portMAX_DELAY); + + (*function)(); + } +} + +/** + * vApplicationIdleHook + * @brief function that runs when the scheduler is idle + */ +void vApplicationIdleHook(void) +{ + /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + * to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + * task. It is essential that code added to this hook function never attempts + * to block in any way (for example, call xQueueReceive() with a block time + * specified, or call vTaskDelay()). If the application makes use of the + * vTaskDelete() API function (as this demo application does) then it is also + * important that vApplicationIdleHook() is permitted to return to its calling + * function, because it is the responsibility of the idle task to clean up + * memory allocated by the kernel to any task that has since been deleted. */ + Module_ApplicationIdleHook(); +} + +void vApplicationTickHook(void) +{ +} + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * RTOS_createResources + * @brief create resources that are required by FreeRTOS + * namely, all of the tasks, timers, and SWIs + */ +void RTOS_createResources(void) +{ + /* + * create SWI handles + */ +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + CANRX_swi = SWI_create(RTOS_SWI_PRI_0, &CANRX_SWI); +#endif // FEATURE_CANRX_SWI +#if FEATURE_IS_ENABLED(FEATURE_CANTX_SWI) + CANTX_swi = SWI_create(RTOS_SWI_PRI_0, &CANTX_SWI); +#endif // FEATURE_CANTX_SWI + + /* + * Create tasks + */ + for (uint16_t i = 0U; i < NUM_TASKS; i++) + { + RTOS_taskDesc_t* const task = &ModuleTasks[i]; + + task->handle = xTaskCreateStatic(&taskFxn, + task->name, + task->stackSize, + task, + task->priority, + task->stack, + task->stateBuffer); + } + + /* + * Create timers + */ + static StaticTimer_t rtosTickTimerState; + + // 1kHz timer drives all tasks + // TODO: should this be faster and/or interrupt (i.e. hardware timer) driven? + rtos_tick_timer = xTimerCreateStatic("Timer 10kHz", + pdMS_TO_TICKS(1U), + pdTRUE, + NULL, + &rtosTickTimer, + &rtosTickTimerState); + + // start the timer (it will only start once the scheduler starts) + (void)xTimerStart(rtos_tick_timer, 0U); + + /* + * Create event groups + */ + static StaticEventGroup_t PeriodicTickEventGroup; + + PeriodicEvent = xEventGroupCreateStatic(&PeriodicTickEventGroup); +} + + +/****************************************************************************** + * O S H O O K S + ******************************************************************************/ +extern void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, + StackType_t** ppxIdleTaskStackBuffer, + uint32_t* pusIdleTaskStackSize); + +/** + * vApplicationGetIdleTaskMemory + * @brief allocate memory for the idle task + * @param ppxIdleTaskTCBBuffer TODO + * @param ppxIdleTaskStackBuffer TODO + * @param pusIdleTaskStackSize TODO + */ +void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer, + StackType_t** ppxIdleTaskStackBuffer, + uint32_t* pusIdleTaskStackSize) +{ + static StaticTask_t idleTask; + static StackType_t idleTaskStack[configIDLE_TASK_STACK_DEPTH]; + + *ppxIdleTaskTCBBuffer = &idleTask; + *ppxIdleTaskStackBuffer = idleTaskStack; + *pusIdleTaskStackSize = sizeof(idleTaskStack) / sizeof(StackType_t); +} + +extern void vApplicationGetTimerTaskMemory(StaticTask_t** ppxTimerTaskTCBBuffer, + StackType_t** ppxTimerTaskStackBuffer, + uint32_t* pusTimerTaskStackSize); + + +/** + * vApplicationGetTimerTaskMemory + * @brief allocate memory for the timer task + * @param ppxTimerTaskTCBBuffer TODO + * @param ppxTimerTaskStackBuffer TODO + * @param pusTimerTaskStackSize TODO + */ +void vApplicationGetTimerTaskMemory(StaticTask_t** ppxTimerTaskTCBBuffer, + StackType_t** ppxTimerTaskStackBuffer, + uint32_t* pusTimerTaskStackSize) +{ + static StaticTask_t timerTask; + static StackType_t timerTaskStack[configTIMER_TASK_STACK_DEPTH]; + + *ppxTimerTaskTCBBuffer = &timerTask; + *ppxTimerTaskStackBuffer = timerTaskStack; + *pusTimerTaskStackSize = sizeof(timerTaskStack) / sizeof(StackType_t); +} + + +/** + * RTOS_getSwiTaskMemory + * @brief allocate memory for the SWI tasks + * @param swiPriority priority of the SWI task this is being called for + * @param ppxSwiTaskTCBBuffer pointer to resultant task memory for this SWI priority + * @param ppxSwiTaskStackBuffer pointer to the resultant stack for this SWI priority + * @param pusSwiTaskStackSize pointer to the stack size var for this SWI priority + */ +void RTOS_getSwiTaskMemory(RTOS_swiPri_E swiPriority, + StaticTask_t** ppxSwiTaskTCBBuffer, + StackType_t** ppxSwiTaskStackBuffer, + uint32_t* pusSwiTaskStackSize) +{ + switch (swiPriority) + { + case RTOS_SWI_PRI_0: + { + // create task memory and stack + static StaticTask_t swiPri0Task; + static StackType_t swiPri0TaskStack[configMINIMAL_STACK_SIZE] __attribute__((aligned(portBYTE_ALIGNMENT))); + // link to relevant pointers + *ppxSwiTaskTCBBuffer = &swiPri0Task; + *ppxSwiTaskStackBuffer = swiPri0TaskStack; + *pusSwiTaskStackSize = COUNTOF(swiPri0TaskStack); + break; + } + + case RTOS_SWI_PRI_1: + { + static StaticTask_t swiPri1Task; + static StackType_t swiPri1TaskStack[configMINIMAL_STACK_SIZE] __attribute__((aligned(portBYTE_ALIGNMENT))); + *ppxSwiTaskTCBBuffer = &swiPri1Task; + *ppxSwiTaskStackBuffer = swiPri1TaskStack; + *pusSwiTaskStackSize = COUNTOF(swiPri1TaskStack); + break; + } + + case RTOS_SWI_PRI_2: + { + static StaticTask_t swiPri2Task; + static StackType_t swiPri2TaskStack[configMINIMAL_STACK_SIZE] __attribute__((aligned(portBYTE_ALIGNMENT))); + *ppxSwiTaskTCBBuffer = &swiPri2Task; + *ppxSwiTaskStackBuffer = swiPri2TaskStack; + *pusSwiTaskStackSize = COUNTOF(swiPri2TaskStack); + break; + } + + default: + // should never get here + *ppxSwiTaskTCBBuffer = NULL; + *ppxSwiTaskStackBuffer = NULL; + *pusSwiTaskStackSize = 0UL; + break; + } +} diff --git a/components/shared/code/RTOS/FreeRTOS_SWI.c b/components/shared/code/RTOS/FreeRTOS_SWI.c new file mode 100644 index 00000000..01272492 --- /dev/null +++ b/components/shared/code/RTOS/FreeRTOS_SWI.c @@ -0,0 +1,209 @@ +/** + * @file FreeRTOS_SWI.c + * @brief FreeRTOS SWI Implementation + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "FreeRTOS_types.h" +#include "SystemConfig.h" +#include +#include + +// FreeRTOS includes +#include "FreeRTOS.h" +#include "FreeRTOS_SWI.h" +#include "task.h" +#include "timers.h" + +// Other Includes +#include "Utility.h" + + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +// module struct +typedef struct +{ + RTOS_swiHandle_T swiTable[RTOS_SWI_PRI_COUNT][RTOS_SWI_MAX_PER_PRI]; // table containing all SWIs + RTOS_taskDesc_t swiTasks[RTOS_SWI_PRI_COUNT]; // task descriptions + EventGroupHandle_t swiEvents[RTOS_SWI_PRI_COUNT]; // event group per priority + uint8_t swiCountPerPri[RTOS_SWI_PRI_COUNT]; // count of SWIs defined in each priority +} rtos_S; + + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +static rtos_S rtos; +static const char* taskNames[RTOS_SWI_PRI_COUNT] = { + "SWI_PRI_0", + "SWI_PRI_1", + "SWI_PRI_2", +}; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +/** + * swiTaskFxn + * @brief function that each SWI task sits in while waiting for a SWI to fire. + * fires the corresponding SWI based on which event bit is set + * @param pvParameters void pointer to the priority, passed in by task creation + */ +static void swiTaskFxn(void* pvParameters) +{ + // convert void pointer to priority + const RTOS_swiPri_E priority = (RTOS_swiPri_E)(uint32_t)pvParameters; + + // sit in this loop forever + for (;;) + { + // wait forever for an event bit to get set. Yields back to scheduler + EventBits_t events = RTOS_EVENT_ALL & xEventGroupWaitBits(rtos.swiEvents[priority], RTOS_EVENT_ALL, pdTRUE, pdFALSE, portMAX_DELAY); + + // once event bit has set, fire all SWIs that have their bits set + while (events != 0U) + { + // find index of first event bit that is set + uint32_t index = 31UL - u32CountLeadingZeroes(events); + // clear that bit + events &= ~(1UL << index); + + // get the corresponding SWI handle from the table at this priority + const volatile RTOS_swiHandle_T* swi = &rtos.swiTable[priority][index]; + if (*swi->handler != NULL) + { + // call the SWI handler + (*swi->handler)(); + } + } + } +} + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * RTOS_SWI_Init + * @brief Initialize the SWI module + */ +void RTOS_SWI_Init(void) +{ + memset(&rtos, 0x00, sizeof(rtos)); + + // create the event groups for each priority + static StaticEventGroup_t eventGroups[RTOS_SWI_PRI_COUNT]; + + // intialize the task for each SWI priority + for (uint32_t pri = 0UL; pri < (uint32_t)RTOS_SWI_PRI_COUNT; pri++) + { + // create event group for this priority + rtos.swiEvents[pri] = xEventGroupCreateStatic(&eventGroups[pri]); + + StaticTask_t* swiTask; + StackType_t* swiTaskStack; + uint32_t swiTaskStackSize; + // allocate memory for this task + RTOS_getSwiTaskMemory((RTOS_swiPri_E)pri, &swiTask, &swiTaskStack, &swiTaskStackSize); + + // create the task + rtos.swiTasks[pri].handle = xTaskCreateStatic(&swiTaskFxn, // handler function + taskNames[pri], // task name + swiTaskStackSize, + (void*)pri, // void pointer to task priority (passed as argument to the handler function) + RTOS_SWI_PRI_OFFSET + pri, // task priority + swiTaskStack, + swiTask); + } +} + +/** + * SWI_create + * @brief create a SWI with a given priority and handler function + * @param priority priority of this SWI + * @param handler handler function for this SWI + * @return pointer to the created handler + */ +RTOS_swiHandle_T* SWI_create(RTOS_swiPri_E priority, RTOS_swiFn_t handler) +{ + // confirm that there is space in this priority level for another SWI + if (rtos.swiCountPerPri[priority] >= RTOS_SWI_MAX_PER_PRI) + { + // no more space in the table for this priority + return NULL; + } + else + { + uint8_t index = rtos.swiCountPerPri[priority]++; // index in the table where this SWI will be placed + RTOS_swiHandle_T* swi = &rtos.swiTable[priority][index]; // handle entry from the SWI table + + // create the SWI + swi->handler = handler; // link to SWI handler + swi->priority = priority; // link SWI priority + swi->event = 1UL << (uint32_t)index; // set event bit mask + + return swi; + } +} + +/** + * SWI_invoke + * @brief invoke the given SWI + * @param handle SWI handle to invoke + */ +void SWI_invoke(RTOS_swiHandle_T* handle) +{ + // set the event bit for the given SWI + (void)xEventGroupSetBits(rtos.swiEvents[handle->priority], handle->event); +} + +/** + * SWI_invokeFromISR + * @brief invoke the given SWI from ISR context + * used to invoke a SWI when already running from an interrupt handler + * @param handle SWI handle to invoke + * @return return whether the message was successfully sent to the daemon + */ +bool SWI_invokeFromISR(RTOS_swiHandle_T* handle) +{ + // whether the daemon task (which is used to set the bit, since this is called from an ISR) was woken in order to set the bit + // (i.e. the daemon task is a higher priority than the interrupt which is invoking the SWI) + BaseType_t higherPrioTaskWoken = pdFALSE; + BaseType_t result = xEventGroupSetBitsFromISR(rtos.swiEvents[handle->priority], + handle->event, + &higherPrioTaskWoken); + + // required in order to switch contexts when the ISR returns + portYIELD_FROM_ISR(higherPrioTaskWoken); + + return (result == pdPASS); +} + +/** + * SWI_disable + * @brief enter critical section, don't let SWIs interrupt + */ +void SWI_disable(void) +{ + taskENTER_CRITICAL(); +} + +/** + * SWI_enable + * @brief exit critical section, allow SWIs to interrupt again + */ +void SWI_enable(void) +{ + taskEXIT_CRITICAL(); +} diff --git a/components/shared/code/RTOS/FreeRTOS_SWI.h b/components/shared/code/RTOS/FreeRTOS_SWI.h new file mode 100644 index 00000000..01c6be83 --- /dev/null +++ b/components/shared/code/RTOS/FreeRTOS_SWI.h @@ -0,0 +1,63 @@ +/** + * @file FreeRTOS_SWI.h + * @brief FreeRTOS file for FreeRTOS SWI Implementation + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "FreeRTOSConfig.h" +#include "FreeRTOS_types.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define RTOS_SWI_PRI_OFFSET 12U // SWI priority offset from other interrupts +#define RTOS_SWI_MAX_PER_PRI RTOS_EVENT_COUNT // number of SWIs allowed per priority level + + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + RTOS_SWI_PRI_0 = 0U, + RTOS_SWI_PRI_1, + RTOS_SWI_PRI_2, + RTOS_SWI_PRI_COUNT, +} RTOS_swiPri_E; + +// function pointer type +typedef void (*RTOS_swiFn_t)(void); + +typedef struct +{ + RTOS_swiFn_t handler; // function to be called when SWI runs + uint32_t priority: 2; // priority of this SWI + uint32_t event : RTOS_EVENT_COUNT; // bitmask for the event bit for this SWI +} RTOS_swiHandle_T; + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void RTOS_SWI_Init(void); + +RTOS_swiHandle_T* SWI_create(RTOS_swiPri_E priority, RTOS_swiFn_t handler); + +void SWI_invoke(RTOS_swiHandle_T* handle); +bool SWI_invokeFromISR(RTOS_swiHandle_T* handle); +void SWI_disable(void); +void SWI_enable(void); + +void RTOS_getSwiTaskMemory(RTOS_swiPri_E swiPriority, + StaticTask_t** ppxSwiTaskTCBBuffer, + StackType_t** ppxSwiTaskStackBuffer, + uint32_t* pusSwiTaskStackSize); diff --git a/components/shared/code/RTOS/FreeRTOS_types.h b/components/shared/code/RTOS/FreeRTOS_types.h new file mode 100644 index 00000000..a08f6ea8 --- /dev/null +++ b/components/shared/code/RTOS/FreeRTOS_types.h @@ -0,0 +1,42 @@ +/** + * @file FreeRTOS_types.h + * @brief Types relating to FreeRTOS + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "stdbool.h" + +// FreeRTOS Includes +#include "FreeRTOS.h" +// #include "cmsis_os.h" +#include "event_groups.h" + + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef struct +{ + void (*function)(void); // function to be executed for task + const char* const name; + StackType_t* const stack; + const uint32_t stackSize; + void* const parameters; + const UBaseType_t priority; + StaticTask_t* const stateBuffer; + TaskHandle_t handle; + const uint32_t periodMs; + uint32_t timeSinceLastTickMs; + struct + { + EventGroupHandle_t* const group; + const EventBits_t bit; + } event; +} RTOS_taskDesc_t; diff --git a/components/shared/code/RTOS/Module.c b/components/shared/code/RTOS/Module.c new file mode 100644 index 00000000..9ce93541 --- /dev/null +++ b/components/shared/code/RTOS/Module.c @@ -0,0 +1,140 @@ +/** + * @file Module.c + * @brief Source code for Module Manager + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Module Header */ +#include "Module.h" + +/**< System Includes*/ +#include "SystemConfig.h" +#include "stddef.h" +#include "stdint.h" + +// FreeRTOS Includes +#include "FreeRTOS.h" +#include "task.h" + +/**< Other Includes */ +#include "Utility.h" +#include "FeatureDefines_generated.h" + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +/** + * @brief Modules run by the Module Manager. Order will apply to execution. + */ +extern const ModuleDesc_S* modules[MODULE_CNT]; + +static Module_taskStats_S stats[MODULE_TASK_CNT] = { 0 }; + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Module Init function + */ +void Module_Init(void) +{ + /**< Run each of the modules Init function in order */ + for (uint8_t i = 0U; i < COUNTOF(modules); i++) + { + if (modules[i]->moduleInit != NULL) + { + (*modules[i]->moduleInit)(); + } + } +} + +/** + * @brief 1kHz periodic function + */ +void Module_1kHz_TSK(void) +{ + /**< Run each of the modules 1kHz function in order */ + for (uint8_t i = 0U; i < COUNTOF(modules); i++) + { + if (modules[i]->periodic1kHz_CLK != NULL) + { + (*modules[i]->periodic1kHz_CLK)(); + } + } + + stats[MODULE_1kHz_TASK].total_percentage = (uint8_t)ulTaskGetRunTimePercent(NULL); +} + +/** + * @brief 100Hz periodic function + */ +void Module_100Hz_TSK(void) +{ + /**< Run each of the modules 100Hz function in order */ + for (uint8_t i = 0U; i < COUNTOF(modules); i++) + { + if (modules[i]->periodic100Hz_CLK != NULL) + { + (*modules[i]->periodic100Hz_CLK)(); + } + } + + stats[MODULE_100Hz_TASK].total_percentage = (uint8_t)ulTaskGetRunTimePercent(NULL); +} + +/** + * @brief 10Hz periodic function + */ +void Module_10Hz_TSK(void) +{ + /**< Run each of the modules 10Hz function in order */ + for (uint8_t i = 0U; i < COUNTOF(modules); i++) + { + if (modules[i]->periodic10Hz_CLK != NULL) + { + (*modules[i]->periodic10Hz_CLK)(); + } + } + + stats[MODULE_10Hz_TASK].total_percentage = (uint8_t)ulTaskGetRunTimePercent(NULL); +} + +/** + * @brief 1Hz periodic function + */ +void Module_1Hz_TSK(void) +{ + /**< Run each of the modules 1Hz function in order */ + for (uint8_t i = 0U; i < COUNTOF(modules); i++) + { + if (modules[i]->periodic1Hz_CLK != NULL) + { + (*modules[i]->periodic1Hz_CLK)(); + } + } + + stats[MODULE_1Hz_TASK].total_percentage = (uint8_t)ulTaskGetRunTimePercent(NULL); +} + +/** + * @brief Idle task used by FreeRTOS + */ +void Module_ApplicationIdleHook() +{ + stats[MODULE_IDLE_TASK].total_percentage = (uint8_t)ulTaskGetRunTimePercent(NULL); +} + +/** + * @brief Returns the total cpu usage of a task in percentage + * @param task Task to get the total runtime percentage of + * @returns The total runtime percentage of the task + */ +float32_t Module_getTotalRuntimePercentage(Module_taskSpeeds_E task) +{ + return stats[task].total_percentage; +} diff --git a/components/shared/code/RTOS/Module.h b/components/shared/code/RTOS/Module.h new file mode 100644 index 00000000..8d17d3fb --- /dev/null +++ b/components/shared/code/RTOS/Module.h @@ -0,0 +1,54 @@ +/** + * @file Module.h + * @brief Header file for Module Manager + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" + +// Other Includes +#include "Module_componentSpecific.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +/**< Module tasks to get called by the RTOS */ +extern void Module_Init(void); +extern void Module_1kHz_TSK(void); +extern void Module_100Hz_TSK(void); +extern void Module_10Hz_TSK(void); +extern void Module_1Hz_TSK(void); + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + MODULE_1Hz_TASK = 0x00, + MODULE_10Hz_TASK, + MODULE_100Hz_TASK, + MODULE_1kHz_TASK, + MODULE_IDLE_TASK, + MODULE_TASK_CNT +} Module_taskSpeeds_E; + +typedef struct +{ + uint8_t total_percentage; +} Module_taskStats_S; + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +float32_t Module_getTotalRuntimePercentage(Module_taskSpeeds_E task); +void Module_ApplicationIdleHook(void); diff --git a/components/shared/code/RTOS/ModuleDesc.h b/components/shared/code/RTOS/ModuleDesc.h new file mode 100644 index 00000000..ec61bce4 --- /dev/null +++ b/components/shared/code/RTOS/ModuleDesc.h @@ -0,0 +1,25 @@ +/** + * @file ModuleDesc.h + * @brief Header file for Modules Descriptor table + * @author Joshua Lafleur (josh.lafleur@outlook.com) + * @version + * @date 2024-01-30 + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +/** + * @brief Module Descriptor + */ +typedef struct +{ + void (*moduleInit)(void); // Pointer to module init function + void (*periodic1kHz_CLK)(void); // Pointer to module 1kHz periodic function + void (*periodic100Hz_CLK)(void); // Pointer to module 100Hz periodic function + void (*periodic10Hz_CLK)(void); // Pointer to module 10Hz periodic function + void (*periodic1Hz_CLK)(void); // Pointer to module 1Hz periodic function +} ModuleDesc_S; diff --git a/components/shared/code/app/CAN/CanTypes.h b/components/shared/code/app/CAN/CanTypes.h index fa6b03e6..a497b149 100644 --- a/components/shared/code/app/CAN/CanTypes.h +++ b/components/shared/code/app/CAN/CanTypes.h @@ -9,7 +9,7 @@ * I N C L U D E S ******************************************************************************/ -#include "Types.h" +#include "LIB_Types.h" /****************************************************************************** * T Y P E D E F S diff --git a/components/shared/code/libs/LIB_FloatTypes.h b/components/shared/code/libs/LIB_FloatTypes.h new file mode 100644 index 00000000..ad792994 --- /dev/null +++ b/components/shared/code/libs/LIB_FloatTypes.h @@ -0,0 +1,13 @@ +/** + * @file FloatTypes.h + * @brief Definition of float types + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef double float64_t; +typedef float float32_t; diff --git a/components/shared/code/libs/LIB_Types.h b/components/shared/code/libs/LIB_Types.h new file mode 100644 index 00000000..d045ea28 --- /dev/null +++ b/components/shared/code/libs/LIB_Types.h @@ -0,0 +1,18 @@ +/** + * Types.h + * General Typedefs + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include +#include +#include "LIB_FloatTypes.h" + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ diff --git a/components/vc/SConscript b/components/vc/SConscript new file mode 100644 index 00000000..114dd2f1 --- /dev/null +++ b/components/vc/SConscript @@ -0,0 +1,19 @@ +#!/usr/bin/python +from SCons.Script import Import, Return + +Import("*") + +target_sconscript = None + +match(TARGET): + case "vcpdu": + target_sconscript = "pdu/SConscript" + case "vcfront": + target_sconscript = "front/SConscript" + case "vcrear": + target_sconscript = "rear/SConscript" + case _: + raise Exception(f"Controller '{TARGET}' is not supported") + +artifacts = SConscript(target_sconscript, exports=["CONFIG_IDS", "PLATFORM_ENV", "NETWORK_ENV"]) +Return('artifacts') diff --git a/components/vc/front/FeatureDefs.yaml b/components/vc/front/FeatureDefs.yaml new file mode 100644 index 00000000..9a3acabb --- /dev/null +++ b/components/vc/front/FeatureDefs.yaml @@ -0,0 +1,6 @@ +config: + prefix: feature + description: Feature definitions for the BMS Boss +defs: + canrx_swi: + cantx_swi: diff --git a/components/vc/front/FeatureSels.yaml b/components/vc/front/FeatureSels.yaml new file mode 100644 index 00000000..3fe9dd3d --- /dev/null +++ b/components/vc/front/FeatureSels.yaml @@ -0,0 +1,6 @@ +featureDefs: "#/components/bms_boss/FeatureDefs.yaml" +features: + feature_cantx_swi: true + feature_canrx_swi: true + app_component_id: vcfront + app_uds: true diff --git a/components/vc/front/SConscript b/components/vc/front/SConscript new file mode 100644 index 00000000..3a3bf29f --- /dev/null +++ b/components/vc/front/SConscript @@ -0,0 +1,448 @@ +#!/usr/bin/python3 + +from os import makedirs +from typing import List, Optional, Tuple, Union + +from mako.template import Template +from SCons.Node import FS +from SCons.Script import Clean, Default, Depends, Dir, GetOption, Import, Return + +from site_scons.site_tools.variants import generate + +Import("PLATFORM_ENV", "NETWORK_ENV", "CONFIG_IDS") + +SRC_DIR = Dir("src") +HW_DIR= Dir("src/HW") +LIBS_DIR = Dir("#/embedded/libs") +FREERTOS_DIR = LIBS_DIR.Dir("FreeRTOS") +CMSIS_DIR = LIBS_DIR.Dir("CMSIS") + +ARTIFACT_NAME = "vcfront" +BUILDS_DIR = Dir(f"build") +UDS_DIR = LIBS_DIR.Dir("uds") +ISOTP_DIR = LIBS_DIR.Dir("isotp") +SHARED_CODE = Dir("#/components/shared/code") +SHARED_LIBS = SHARED_CODE.Dir("libs") +SHARED_APP = SHARED_CODE.Dir("app") +SHARED_HW = SHARED_CODE.Dir("HW") +SHARED_RTOS = SHARED_CODE.Dir("RTOS") + +env = PLATFORM_ENV.Clone( + tools=[ + "gcc-arm-none-eabi", + "chip_config", + "st-flash", + "openocd", + "compilation_db", + "variants", + # "doxygen", + ] +) +rtos_env = PLATFORM_ENV.Clone(tools=["gcc-arm-none-eabi"]) + +env["OPENOCD_INTERFACE"] = "stlink" +env["OPENOCD_MCU"] = "stm32f103c8" + +common_flags = [ + "-mthumb", + "-mcpu=cortex-m3", +] + +debug_flags = [ + "-ggdb3", + "-g3", + "-Og", +] + +release_flags = [ + "-O2", +] + +if GetOption("release"): + common_flags += release_flags +else: + common_flags += debug_flags + +link_flags = [ + "-Wl,--gc-sections", + "-Wl,--relax", + "-Wl,--print-memory-usage", + # "-Wl,--print-gc-sections", + "--specs=nano.specs", + "-Icomponents/vc/pdu/include/HW" +] + +as_flags = ["-xassembler-with-cpp"] + +c_flags = [ + "-std=c11", + "-ffunction-sections", + "-fdata-sections", + "-fshort-enums", + "-funsigned-char", + "-fstack-usage", + "-nostdlib", + "-msoft-float", + "-Wall", + "-Wextra", + "-Werror", + "-Wfloat-equal", + "-Wcast-align", + "-Wlogical-op", + "-Winline", + "-Wshadow", + "-Winit-self", + "-Wmissing-prototypes", + "-Wunused-function", + "-Wpointer-arith", + "-Wno-type-limits", + "-Wno-unused-local-typedefs", + "-Wundef", + "-Wconversion", + # FIXME: When in single quotes outputs to cmdline with "" + "-include", "BuildDefines.h", # Executed one after eachother +] + +free_rtos_flags = [ + "-Wno-missing-prototypes", + "-Wno-cast-align", + "-Wno-conversion", +] + + +RTOS_INCLUDE_DIRS = [ + SHARED_RTOS, + FREERTOS_DIR.Dir("Source/include/"), + FREERTOS_DIR.Dir("Source/portable/GCC/ARM_CM3/"), + CMSIS_DIR.Dir("CMSIS/Core/Include/"), +] + +LIBS_INCLUDE_DIRS = [ + LIBS_DIR.Dir("printf"), + LIBS_DIR.Dir("atomic"), + LIBS_DIR.Dir("pack"), + UDS_DIR.Dir("include"), + ISOTP_DIR.Dir("include"), + SHARED_LIBS, + SHARED_APP, + SHARED_HW, + SHARED_RTOS, +] + +PROJECT_INCLUDE_DIRS = [ + "include/", + "include/HW/", +] +# List of component C files + +project_source_files = [ + SRC_DIR.File("SystemManager.c"), + SRC_DIR.File("Module_componentSpecific.c"), + SHARED_RTOS.File("Module.c"), + SRC_DIR.File("CANIO_componentSpecific.c"), + SHARED_APP.File("CAN/CANIO-tx.c"), + SHARED_APP.File("CAN/CANIO-rx.c"), + SRC_DIR.File("IO.c"), + SRC_DIR.File("Utility.c"), + SRC_DIR.File("UDS.c"), + SHARED_LIBS.File("LIB_app.c"), +] + +project_hw_files = [ + HW_DIR.File("HW.c"), + HW_DIR.File("HW_adc.c"), + HW_DIR.File("HW_can_componentSpecific.c"), + HW_DIR.File("HW_gpio_componentSpecific.c"), + HW_DIR.File("HW_dma.c"), + HW_DIR.File("HW_intc.c"), + HW_DIR.File("HW_msp.c"), + HW_DIR.File("HW_tim.c"), + SHARED_HW.File("HW_can.c"), + SHARED_HW.File("HW_gpio.c"), +] + +project_source_files += project_hw_files + +rtos_source_files = [ + SHARED_RTOS.File("FreeRTOSResources.c"), + SHARED_RTOS.File("FreeRTOS_SWI.c"), + FREERTOS_DIR.File("Source/croutine.c"), + FREERTOS_DIR.File("Source/event_groups.c"), + FREERTOS_DIR.File("Source/list.c"), + FREERTOS_DIR.File("Source/queue.c"), + FREERTOS_DIR.File("Source/tasks.c"), + FREERTOS_DIR.File("Source/timers.c"), + FREERTOS_DIR.File("Source/portable/GCC/ARM_CM3/port.c"), + # FREERTOS_DIR.File("Source/stream_buffer.c"), + # FREERTOS_DIR.File("Source/portable/MemMang/heap_4.c"), +] + +uds_srcs = [ + ISOTP_DIR.File("isotp.c"), + UDS_DIR.File("src/udsServer.c"), +] + +def render_generated_files(options, renderer, output_dir): + targets = [] + if options is None: + return + + for template in renderer: + renderer = Template(filename=template.abspath) + rendered = renderer.render(**options) + if not isinstance(rendered, str): + raise Exception("Mako rendering didn't produce a str to write to the file") + + file = ( + output_dir.File(template.name) + .target_from_source(prefix="", suffix="") + .abspath + ) + + with open(file, "w") as out_fd: + out_fd.write(rendered) + + targets.append(file) + return targets + +def create_output_file_path( + variant_dir: FS.Dir, + file: FS.File, + new_ext: str, + target_dir: Optional[str] = None, +) -> str: + fn = file.target_from_source(prefix="", suffix=new_ext).name + + if target_dir: + return variant_dir.Dir(target_dir).File(fn) + + return variant_dir.Dir("/".join(file.path.split("/")[2:-1]) + "/").File(fn) + + +def compile_objects( + env, + files: List[Union[FS.File, Tuple[FS.File, List[str]]]], + variant_dir: FS.Dir, + target_dir: Optional[str] = None, + **kwargs, +) -> List[FS.File]: + objs = [] + flags = env["CCFLAGS"] + for src in files: + if isinstance(src, tuple): + src_file = src[0] + these_flags = flags + src[1] + elif isinstance(src, FS.File): + src_file = src + these_flags = flags + else: + raise Exception( + "Source file should either be a 'File' \ + object or a tuple of a 'File' and a list of extra flags to compile with" + ) + + target = create_output_file_path(variant_dir, src_file, ".obj", target_dir) + objs.append( + env.Object(target=target, source=src_file, CCFLAGS=these_flags, **kwargs) + ) + return objs + +renderers = { + "buildDefs": [File("renderers/BuildDefines_generated.h.mako")], + "featureDefs": [File("#/shared/renderers/mako/FeatureDefines_generated.h.mako")], +} + +chip_config = env.ChipConfig(config_file="include/HW/stm32f105.yaml") +configs = env.GenerateVariants(File("variants.yaml"), CONFIG_IDS) +elfs = [] +binaries = [] +binaries_crced = [] +asms = [] + +for config_id, config in configs.items(): + config_env = env.Clone() + c_flags.extend(chip_config.get("defines", [])) + DRIVERS_INCLUDE_DIRS = [ + chip_config["cmsis_includes"], + chip_config["hal_includes"], + ] + platform_source_files = [] + # add driver source files + platform_source_files.extend( + [(src[0], src[1] + ["-Wno-inline"]) for src in chip_config["sources"]] + ) + feature_selections = [] + feature_selections += config["features"]["selections"] + feature_selections_files = [] + for file in feature_selections: + feature_selections_files += [ File(file) ] + + variant_dir = BUILDS_DIR.Dir( + "_".join(config["description"].split(" ")) + f"_{config_id}" + ) + generated_dir = variant_dir.Dir("generated") + config_env.Append( + LINKFLAGS=f"-I{generated_dir.abspath}", + ) + makedirs(generated_dir.abspath, exist_ok=True) + + generated_sources = NETWORK_ENV.GenerateNodes({ f"{ARTIFACT_NAME}": generated_dir, }) + + features = {"features": config_env.GenerateFeatures(feature_selections_files, config["features"]["overrides"]) } + generated_features = render_generated_files(features, renderers["featureDefs"], generated_dir) + + build_options = {} + build_options["config"] = config["options"] + build_options["configId"] = config_id + generated_defs = render_generated_files(build_options, renderers["buildDefs"], generated_dir) + + ## actually compile stuff + proj_include_dirs = PROJECT_INCLUDE_DIRS + [generated_dir] + + paths = ( + RTOS_INCLUDE_DIRS + DRIVERS_INCLUDE_DIRS + proj_include_dirs + LIBS_INCLUDE_DIRS + ) + + config_env.Append( + ASFLAGS=as_flags, + CPPPATH=paths, + CCFLAGS=common_flags + c_flags, + LINKSCRIPT=chip_config["linker_file"], + LINKFLAGS=c_flags + link_flags + common_flags, + ) + + uds_env = config_env.Clone() + uds_env.Append( + CCFLAGS=[ + "-Wno-missing-prototypes", + "-Wno-unused-parameter", + "-DBYTE_ORDER=_BYTE_ORDER", + "-DLITTLE_ENDIAN=_LITTLE_ENDIAN", + "-Wno-inline", + "-Wno-conversion", + "-Wno-undef", + ] + ) + + rtos_env.Append( + CPPPATH=paths, + CCFLAGS=common_flags + c_flags + free_rtos_flags, + ) + + objs = [] # store objects here + + # compile platform files + objs.extend( + compile_objects( + config_env, + platform_source_files, + variant_dir=variant_dir, + target_dir="embedded/", + CPPPATH=paths + [generated_dir], + ) + ) + + # compile rtos source files + objs.extend( + compile_objects( + rtos_env, + rtos_source_files, + variant_dir=variant_dir, + target_dir="FreeRTOS/", + CPPPATH=paths + [generated_dir], + ) + ) + + # compile project source files + objs.extend( + compile_objects( + config_env, + project_source_files, + variant_dir=variant_dir, + CPPPATH=paths + [generated_dir] + ) + ) + + # compile UDS source files + objs.extend(compile_objects(uds_env, uds_srcs, variant_dir=variant_dir, target_dir="uds/")) + + gen_env = config_env.Clone() + gen_env.Append( + CCFLAGS=[ + "-Wno-inline", + "-Wno-conversion", + ] + ) + gen_srcs = [] + for generated_source in generated_sources: + gen_srcs += [generated_dir.File(generated_source)] + objs.extend( + compile_objects( + gen_env, + gen_srcs, + variant_dir=variant_dir, + target_dir=variant_dir.Dir("generated/obj"), + CPPPATH=paths + [generated_dir], + ) + ) + + # link all the compiled objects into an elf + elf, map = config_env.Program( + variant_dir.File(ARTIFACT_NAME + ".elf"), + objs, + MAPFILE=variant_dir.File(ARTIFACT_NAME + ".map"), + ) + elfs.append(elf) + Depends(elf, config_env["LINKSCRIPT"]) + Clean(elf, generated_defs) + + # generate a binary for flashing + binary = config_env.Bin(source=elf) + binaries.append(binary) + + crc_env = PLATFORM_ENV.Clone(tools=["hextools"]) + + # generate the CRCd binary + if "app_start_addr" not in env: + env["app_start_addr"] = features["features"]["defs"]["app_start_addr"] + binaries_crced.append( + crc_env.InjectMpeg2CRC(source=binary, start_addr=env["app_start_addr"]) + ) + + # Generate compile_commands.json + config_env["COMPILATIONDB_PATH_FILTER"] = "*/" + variant_dir.name + "/*" + compile_db = config_env.CompilationDatabase(variant_dir.File("compile_commands.json")) + Depends(compile_db, objs) + # generate it by default + Default(compile_db) + # add an alias to _only_ generate the compilation database + config_env.Alias("compiledb", compile_db) + +Default(binaries_crced) + +# build doxygen files for this component +#env.Alias("docs", env.Doxygen("doxygen_stw.conf")) +#env.Depends("docs", project_source_files) +#env.Clean("docs", Dir("docs")) + +# Return artifacts to the caller +artifacts = {} +if len(binaries) == 1: + artifacts["FLASHABLE_ARTIFACT"] = { + "artifact": binaries_crced[0], + "addr": env["app_start_addr"], + "tools": ["st-flash"], + } + +if len(elfs) == 1: + artifacts["DEBUG_ARTIFACT"] = { + "artifact": elfs[0], + "args": [], + "tools": ["gcc-arm-none-eabi", "openocd"], + "env": { + "OPENOCD_INTERFACE": "stlink", + "OPENOCD_MCU": "stm32f103c8", + }, + } + +Return("artifacts") diff --git a/components/vc/front/include/CANIO_componentSpecific.h b/components/vc/front/include/CANIO_componentSpecific.h new file mode 100644 index 00000000..27a54844 --- /dev/null +++ b/components/vc/front/include/CANIO_componentSpecific.h @@ -0,0 +1,39 @@ +/** + RX_config* CAN.h + * Header file for CANRX configuration + */ + +#pragma once + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// imports for timebase +#include "HW_tim.h" + +// imports for CAN generated types +#include "CANTypes_generated.h" + +// imports for data access +#include "Module.h" + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define CANIO_UDS_BUFFER_LENGTH 8U +#define CANIO_getTimeMs() (HW_TIM_getTimeMS()) + +#define set_taskUsage1kHz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1kHz_TASK)); +#define set_taskUsage100Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_100Hz_TASK)); +#define set_taskUsage10Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_10Hz_TASK)); +#define set_taskUsage1Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1Hz_TASK)); +#define set_taskUsageIdle(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_IDLE_TASK)); + +#include "TemporaryStubbing.h" diff --git a/components/vc/front/include/FreeRTOSConfig.h b/components/vc/front/include/FreeRTOSConfig.h new file mode 100644 index 00000000..3975aab6 --- /dev/null +++ b/components/vc/front/include/FreeRTOSConfig.h @@ -0,0 +1,162 @@ +/* + * FreeRTOS Kernel V10.0.1 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * These parameters and more are described within the 'configuration' section of the + * FreeRTOS API documentation available on the FreeRTOS.org web site. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +// Section where include file can be added + +// #if (defined(__ARMCC_VERSION) || defined(GNUC) || defined(ICCARM)) +// # include "RTE_Components.h" +// # include CMSIS_device_header +// #endif + +// Ensure definitions are only used by the compiler, and not by the assembler. +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) +# include +extern uint32_t SystemCoreClock; +#endif +#define configUSE_PREEMPTION (1) +#define configSUPPORT_STATIC_ALLOCATION (1) +#define configSUPPORT_DYNAMIC_ALLOCATION (0) +#define configUSE_IDLE_HOOK (0) +#define configUSE_TICK_HOOK (0) +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES (16) +#define configMAX_TASK_NAME_LEN (16) +#define configUSE_16_BIT_TICKS (0) +#define configUSE_MUTEXES (1) +#define configQUEUE_REGISTRY_SIZE (0) +#define configUSE_RECURSIVE_MUTEXES (1) +#define configUSE_COUNTING_SEMAPHORES (1) +#define configENABLE_BACKWARD_COMPATIBILITY (0) +#define configUSE_PORT_OPTIMISED_TASK_SELECTION (1) +#define configGENERATE_RUN_TIME_STATS (1) +#define configUSE_TRACE_FACILITY (1) + +/**< Used for RTOS profiling */ +extern void HW_TIM_configureRunTimeStatsTimer(void); +extern uint64_t HW_TIM_getBaseTick(void); +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() HW_TIM_configureRunTimeStatsTimer() +#define portGET_RUN_TIME_COUNTER_VALUE() (uint32_t)HW_TIM_getBaseTick() + +#define configSTACK_DEPTH_TYPE UBaseType_t +#define configMINIMAL_STACK_SIZE (256) +#define configIDLE_TASK_STACK_DEPTH (128) + +// heap is not used because dynamic allocation disabled +#define configAPPLICATION_ALLOCATED_HEAP (0) +#define configTOTAL_HEAP_SIZE ((size_t)3072) + +// Co-routine definitions. +#define configUSE_CO_ROUTINES (0) +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +// Software timer definitions. +#define configUSE_TIMERS (1) +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#define configTIMER_QUEUE_LENGTH (10) +#define configTIMER_TASK_STACK_DEPTH (128) + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet (1) +#define INCLUDE_uxTaskPriorityGet (1) +#define INCLUDE_vTaskDelete (1) +#define INCLUDE_vTaskCleanUpResources (0) +#define INCLUDE_vTaskSuspend (1) +#define INCLUDE_vTaskDelayUntil (1) +#define INCLUDE_vTaskDelay (1) +#define INCLUDE_xTaskGetSchedulerState (1) +#define INCLUDE_xTaskGetCurrentTaskHandle (1) +#define INCLUDE_xTimerPendFunctionCall (1) +#define INCLUDE_xQueueGetMutexHolder (1) +#define INCLUDE_uxTaskGetStackHighWaterMark (1) +#define INCLUDE_eTaskGetState (1) + +// Cortex-M specific definitions. +#ifdef __NVIC_PRIO_BITS +// __BVIC_PRIO_BITS will be specified when CMSIS is being used. +# define configPRIO_BITS __NVIC_PRIO_BITS +#else +# define configPRIO_BITS 4 +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" + * function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY (15) + +/* The highest interrupt priority that can be used by any interrupt service + * routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + * INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + * PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (5) + +/* Interrupt priorities used by the kernel port layer itself. These are generic + * to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/**< Define conversion from us to ticks */ +#define pdMS_TO_TICKS(xTime) (((xTime) * configTICK_RATE_HZ) / 1000U) + +/* Normal assert() semantics without relying on the provision of an assert.h + * header file. */ +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + taskDISABLE_INTERRUPTS(); \ + for (;;) \ + ; \ + } + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS + * standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + +// Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) + +#define RTOS_EVENT_ALL 0x00000FFF +#define RTOS_EVENT_COUNT 12U + +#endif /* FREERTOS_CONFIG_H */ diff --git a/components/vc/front/include/HW/BuildDefines.h b/components/vc/front/include/HW/BuildDefines.h new file mode 100644 index 00000000..4e0672dc --- /dev/null +++ b/components/vc/front/include/HW/BuildDefines.h @@ -0,0 +1,20 @@ +/* + * BuildDefines.h + * + */ + +#pragma once + +#include "FeatureDefines_generated.h" +#include "BuildDefines_generated.h" + +#if (MCU_STM32_PN == FDEFS_STM32_PN_STM32F105) +#define STM32F1 +#define STM32F105xC +#else +#error "Chipset not supported" +#endif + +#if FEATURE_IS_ENABLED(MCU_STM32_USE_HAL) +#define USE_HAL_DRIVER +#endif // MCU_STM32_USE_HAL diff --git a/components/vc/front/include/HW/HW.h b/components/vc/front/include/HW/HW.h new file mode 100644 index 00000000..3b6b05b2 --- /dev/null +++ b/components/vc/front/include/HW/HW.h @@ -0,0 +1,36 @@ +/** + * @file HW.h + * @brief Header file for generic firmware functions + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "stm32f1xx.h" + +// System Includes +#include "LIB_Types.h" + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + HW_OK = 0x00U, + HW_ERROR = 0x01U +} HW_StatusTypeDef_E; + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +bool HW_init(void); +uint32_t HW_getTick(void); +void HW_delay(uint32_t delay); +void HW_usDelay(uint8_t us); +void HW_systemHardReset(void); +void Error_Handler(void); diff --git a/components/vc/front/include/HW/HW_adc.h b/components/vc/front/include/HW/HW_adc.h new file mode 100644 index 00000000..ccb41fd7 --- /dev/null +++ b/components/vc/front/include/HW/HW_adc.h @@ -0,0 +1,58 @@ +/** + * @file HW_adc.h + * @brief Header file for ADC firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" +#include "stdbool.h" +#include "LIB_Types.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define ADC_MAX_VAL 4095U // Max integer value of ADC reading (2^12 for this chip) +#define ADC_REF_VOLTAGE 3.0F + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + BUFFER_HALF_LOWER = 0U, + BUFFER_HALF_UPPER, +} bufferHalf_E; + +typedef struct +{ + uint32_t raw; + float32_t value; + uint16_t count; +} simpleFilter_S; + + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern ADC_HandleTypeDef hadc1; +extern ADC_HandleTypeDef hadc2; +extern DMA_HandleTypeDef hdma_adc1; + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_ADC_init(void); +bool HW_ADC_calibrate(ADC_HandleTypeDef* hadc); +bool HW_ADC_startDMA(ADC_HandleTypeDef* hadc, uint32_t* data, uint32_t size); +uint16_t HW_ADC_getVFromCount(uint16_t cnt); diff --git a/components/vc/front/include/HW/HW_can_componentSpecific.h b/components/vc/front/include/HW/HW_can_componentSpecific.h new file mode 100644 index 00000000..d3012b3e --- /dev/null +++ b/components/vc/front/include/HW/HW_can_componentSpecific.h @@ -0,0 +1,25 @@ +/** + * @file HW_can_componentSpecific.h + * @brief Header file for component specific CAN firmware + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + CAN_TX_MAILBOX_0 = 0U, + CAN_TX_MAILBOX_1, + CAN_TX_MAILBOX_2, + CAN_TX_MAILBOX_COUNT, +} CAN_TxMailbox_E; + +typedef enum +{ + CAN_RX_FIFO_0 = 0U, + CAN_RX_FIFO_1, + CAN_RX_FIFO_COUNT, +} CAN_RxFifo_E; diff --git a/components/vc/front/include/HW/HW_clock.h b/components/vc/front/include/HW/HW_clock.h new file mode 100644 index 00000000..773727c5 --- /dev/null +++ b/components/vc/front/include/HW/HW_clock.h @@ -0,0 +1,67 @@ +/** + * @file HW_clock.h + * @brief Header file for clock configuration + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW.h" + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_systemClockConfig(void); + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief System Clock Configuration + */ +void HW_systemClockConfig(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; + + // Initializes the RCC Oscillators according to the specified parameters + // in the RCC_OscInitTypeDef structure. + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; /**< HSE is 8MHz */ + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; /**< PLL is 8Mhz */ + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; /**< PLL output is 64MHz */ + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + // Initializes the CPU, AHB and APB buses clocks + + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /**< SYSCLK is 64MHz */ + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /**< SYSCLK output is 64MHz */ + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; /**< APB1 is 32MHz */ + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; /**< APB2 is 64MHz */ + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8; /**< ADC is 8MHz from APB2 */ + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } +} diff --git a/components/vc/front/include/HW/HW_dma.h b/components/vc/front/include/HW/HW_dma.h new file mode 100644 index 00000000..f51bb7a7 --- /dev/null +++ b/components/vc/front/include/HW/HW_dma.h @@ -0,0 +1,20 @@ +/** + * @file HW_dma.h + * @brief Header file for DMA firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_DMA_init(void); diff --git a/components/vc/front/include/HW/HW_gpio_componentSpecific.h b/components/vc/front/include/HW/HW_gpio_componentSpecific.h new file mode 100644 index 00000000..3e1f27fa --- /dev/null +++ b/components/vc/front/include/HW/HW_gpio_componentSpecific.h @@ -0,0 +1,20 @@ +/** + * @file HW_gpio_componentSpecific.h + * @brief Header file for GPIO firmware component specific + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + HW_GPIO_CAN1_RX = 0U, + HW_GPIO_CAN1_TX, + HW_GPIO_CAN2_RX, + HW_GPIO_CAN2_TX, + HW_GPIO_LED, + HW_GPIO_COUNT, +} HW_GPIO_pinmux_E; diff --git a/components/vc/front/include/HW/HW_intc.h b/components/vc/front/include/HW/HW_intc.h new file mode 100644 index 00000000..3dc99f02 --- /dev/null +++ b/components/vc/front/include/HW/HW_intc.h @@ -0,0 +1,35 @@ +/** + * @file HW_intc.h + * @brief Header file for STM32F1xx Cortex M3 Interrupts + */ + +#pragma once + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +#include "stm32f1xx.h" + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void DebugMon_Handler(void); + +void DMA1_Channel1_IRQHandler(void); +void ADC1_2_IRQHandler(void); +void TIM1_TRG_COM_IRQHandler(void); +void TIM2_IRQHandler(void); +void TIM1_CC_IRQHandler(void); + +void CAN1_SCE_IRQHandler(void); +void CAN1_TX_IRQHandler(void); +void CAN1_RX0_IRQHandler(void); +void CAN1_RX1_IRQHandler(void); + +void CAN2_SCE_IRQHandler(void); +void CAN2_TX_IRQHandler(void); +void CAN2_RX0_IRQHandler(void); +void CAN2_RX1_IRQHandler(void); diff --git a/components/vc/front/include/HW/HW_tim.h b/components/vc/front/include/HW/HW_tim.h new file mode 100644 index 00000000..22e450a2 --- /dev/null +++ b/components/vc/front/include/HW/HW_tim.h @@ -0,0 +1,25 @@ +/** + * @file HW_tim.h + * @brief Header file for TIM firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "stm32f1xx_hal.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +HAL_StatusTypeDef HW_TIM_init(void); +void HW_TIM_configureRunTimeStatsTimer(void); +uint32_t HW_TIM_getTick(void); +uint32_t HW_TIM_getTimeMS(void); +void HW_TIM_incBaseTick(void); +uint64_t HW_TIM_getBaseTick(void); diff --git a/components/vc/front/include/HW/SystemConfig.h b/components/vc/front/include/HW/SystemConfig.h new file mode 100644 index 00000000..f389823a --- /dev/null +++ b/components/vc/front/include/HW/SystemConfig.h @@ -0,0 +1,31 @@ +/** + * @file SystemConfig.h + * @brief Define System Configuration + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW.h" + +// FreeRTOS Includes +#include "FreeRTOSConfig.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// System altering defines +#define USE_FULL_LL_DRIVER + +// NVIC interrupt priorities, lower number is higher priority +// tick interrupt is highest priority +#define DMA_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 4U +#define ADC_IRQ_PRIO DMA_IRQ_PRIO + 1U +#define CAN_RX_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 6U +#define CAN_TX_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 8U +#define EXTI_IRQ_PRIO ADC_IRQ_PRIO diff --git a/components/vc/front/include/HW/stm32f105.yaml b/components/vc/front/include/HW/stm32f105.yaml new file mode 100644 index 00000000..0f366998 --- /dev/null +++ b/components/vc/front/include/HW/stm32f105.yaml @@ -0,0 +1,24 @@ +mcu: STM32F105 +features: + controller: + definition: "#/shared/FeatureDefs/Controller_FeatureDefs.yaml" + selection: "" +linker: + useDefault: true +drivers: + hal: # required + adc: + adc_ex: + can: + cortex: # required + dma: + flash: + gpio: + i2c: + pwr: + rcc: + rcc_ex: # required + spi: + use_ll: true + tim: + tim_ex: # required with tim diff --git a/components/vc/front/include/HW/stm32f1xx_hal_conf.h b/components/vc/front/include/HW/stm32f1xx_hal_conf.h new file mode 100644 index 00000000..67bfe0aa --- /dev/null +++ b/components/vc/front/include/HW/stm32f1xx_hal_conf.h @@ -0,0 +1,259 @@ +/** + * @file stm32f1xx_hal_conf.h + * @brief Header file for STM32F1xx Configuration + */ + +#pragma once + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// Enable HAL modules here +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +// #define HAL_CRYP_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +// #define HAL_CAN_LEGACY_MODULE_ENABLED +// #define HAL_CEC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +// #define HAL_CRC_MODULE_ENABLED +// #define HAL_DAC_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +// #define HAL_ETH_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +// #define HAL_I2S_MODULE_ENABLED +// #define HAL_IRDA_MODULE_ENABLED +// #define HAL_IWDG_MODULE_ENABLED +// #define HAL_NOR_MODULE_ENABLED +// #define HAL_NAND_MODULE_ENABLED +// #define HAL_PCCARD_MODULE_ENABLED +// #define HAL_PCD_MODULE_ENABLED +// #define HAL_HCD_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +// #define HAL_RTC_MODULE_ENABLED +// #define HAL_SD_MODULE_ENABLED +// #define HAL_MMC_MODULE_ENABLED +// #define HAL_SDRAM_MODULE_ENABLED +// #define HAL_SMARTCARD_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 + +// Adjust Oscillator settings + +#if !defined(HSE_VALUE) +# define HSE_VALUE 8000000U // Value of the External oscillator in Hz +#endif + +#if !defined(HSE_STARTUP_TIMEOUT) +# define HSE_STARTUP_TIMEOUT 100U // Time out for HSE start up, in ms +#endif + +#if !defined(HSI_VALUE) +# define HSI_VALUE 8000000U // Value of the Internal oscillator in Hz +#endif + +#if !defined(LSI_VALUE) +# define LSI_VALUE 40000U // LSI Typical Value in Hz +#endif + +#if !defined(LSE_VALUE) +# define LSE_VALUE 32768U // Value of the External oscillator in Hz +#endif + +#if !defined(LSE_STARTUP_TIMEOUT) +# define LSE_STARTUP_TIMEOUT 5000U // Time out for LSE start up, in ms +#endif + +// ########################### System Configuration ######################### +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3000U // Value of VDD in mv +#define TICK_INT_PRIORITY 0U // tick interrupt priority (lowest by default) +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U // ADC register callback disabled +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U // CAN register callback disabled +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U // CEC register callback disabled +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U // DAC register callback disabled +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U // ETH register callback disabled +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U // HCD register callback disabled +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U // I2C register callback disabled +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U // I2S register callback disabled +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U // MMC register callback disabled +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U // NAND register callback disabled +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U // NOR register callback disabled +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U // PCCARD register callback disabled +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U // PCD register callback disabled +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U // RTC register callback disabled +#define USE_HAL_SD_REGISTER_CALLBACKS 0U // SD register callback disabled +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U // SMARTCARD register callback disabled +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U // IRDA register callback disabled +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U // SRAM register callback disabled +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U // SPI register callback disabled +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U // TIM register callback disabled +#define USE_HAL_UART_REGISTER_CALLBACKS 0U // UART register callback disabled +#define USE_HAL_USART_REGISTER_CALLBACKS 0U // USART register callback disabled +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U // WWDG register callback disabled + + +// Uncomment the line below to expanse the "assert_param" macro in the +// HAL drivers code +// #define USE_FULL_ASSERT +#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__)) + +void assert_failed(uint8_t* file, uint32_t line); +#else +# define assert_param(expr) ((void)0U) +#endif // ifdef USE_FULL_ASSERT + + +// 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 + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Include headers for enabled HAL modules + +#ifdef HAL_RCC_MODULE_ENABLED +# include "stm32f1xx_hal_rcc.h" +#endif + +#ifdef HAL_GPIO_MODULE_ENABLED +# include "stm32f1xx_hal_gpio.h" +#endif + +#ifdef HAL_EXTI_MODULE_ENABLED +# include "stm32f1xx_hal_exti.h" +#endif + +#ifdef HAL_DMA_MODULE_ENABLED +# include "stm32f1xx_hal_dma.h" +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +# include "stm32f1xx_hal_can.h" +#endif + +#ifdef HAL_CEC_MODULE_ENABLED +# include "stm32f1xx_hal_cec.h" +#endif + +#ifdef HAL_CORTEX_MODULE_ENABLED +# include "stm32f1xx_hal_cortex.h" +#endif + +#ifdef HAL_ADC_MODULE_ENABLED +# include "stm32f1xx_hal_adc.h" +#endif + +#ifdef HAL_CRC_MODULE_ENABLED +# include "stm32f1xx_hal_crc.h" +#endif + +#ifdef HAL_DAC_MODULE_ENABLED +# include "stm32f1xx_hal_dac.h" +#endif + +#ifdef HAL_FLASH_MODULE_ENABLED +# include "stm32f1xx_hal_flash.h" +#endif + +#ifdef HAL_SRAM_MODULE_ENABLED +# include "stm32f1xx_hal_sram.h" +#endif + +#ifdef HAL_NOR_MODULE_ENABLED +# include "stm32f1xx_hal_nor.h" +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +# include "stm32f1xx_hal_i2c.h" +#endif + +#ifdef HAL_IWDG_MODULE_ENABLED +# include "stm32f1xx_hal_iwdg.h" +#endif + +#ifdef HAL_PWR_MODULE_ENABLED +# include "stm32f1xx_hal_pwr.h" +#endif + +#ifdef HAL_RTC_MODULE_ENABLED +# include "stm32f1xx_hal_rtc.h" +#endif + +#ifdef HAL_PCCARD_MODULE_ENABLED +# include "stm32f1xx_hal_pccard.h" +#endif + +#ifdef HAL_SD_MODULE_ENABLED +# include "stm32f1xx_hal_sd.h" +#endif + +#ifdef HAL_NAND_MODULE_ENABLED +# include "stm32f1xx_hal_nand.h" +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +# include "stm32f1xx_hal_spi.h" +#endif + +#ifdef HAL_TIM_MODULE_ENABLED +# include "stm32f1xx_hal_tim.h" +#endif + +#ifdef HAL_UART_MODULE_ENABLED +# include "stm32f1xx_hal_uart.h" +#endif + +#ifdef HAL_USART_MODULE_ENABLED +# include "stm32f1xx_hal_usart.h" +#endif + +#ifdef HAL_IRDA_MODULE_ENABLED +# include "stm32f1xx_hal_irda.h" +#endif + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +# include "stm32f1xx_hal_smartcard.h" +#endif + +#ifdef HAL_WWDG_MODULE_ENABLED +# include "stm32f1xx_hal_wwdg.h" +#endif + +#ifdef HAL_PCD_MODULE_ENABLED +# include "stm32f1xx_hal_pcd.h" +#endif + +#ifdef HAL_HCD_MODULE_ENABLED +# include "stm32f1xx_hal_hcd.h" +#endif + +#ifdef HAL_MMC_MODULE_ENABLED +# include "stm32f1xx_hal_mmc.h" +#endif diff --git a/components/vc/front/include/IO.h b/components/vc/front/include/IO.h new file mode 100644 index 00000000..c2dae852 --- /dev/null +++ b/components/vc/front/include/IO.h @@ -0,0 +1,45 @@ +/** + * @file IO.h + * @brief Header file for IO Module + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" + +// Firmware Includes +#include "HW_adc.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define VREF ADC_REF_VOLTAGE /**< Shunt Diode reference voltage */ + +#define IO_ADC_BUF_LEN 192U /**< To fit the number of measurements into a time less than 100us \ + the buffer length must be less than 100us / (ADC clock freq * \ + cycles per conversion). For this firmware, there is 14 cycles \ + per conversion. Therefore the max samples per 100us is 57, which \ + rounded down to the nearest multiple of 12 is 48 */ + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef struct +{ + float32_t mcu_temp; +} IO_S; + + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern IO_S IO; diff --git a/components/vc/front/include/Module_componentSpecific.h b/components/vc/front/include/Module_componentSpecific.h new file mode 100644 index 00000000..e1ed821b --- /dev/null +++ b/components/vc/front/include/Module_componentSpecific.h @@ -0,0 +1,36 @@ +/** + * @file Module_componentSpecific.h + * @brief Header file for Module Manager for the component specific modules + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "ModuleDesc.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +/**< Modules */ +extern const ModuleDesc_S IO_desc; +extern const ModuleDesc_S UDS_desc; +extern const ModuleDesc_S CANIO_rx; +extern const ModuleDesc_S CANIO_tx; + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + MODULE_IO = 0x00, + MODULE_UDS, + MODULE_CANIO_tx, + MODULE_CANIO_rx, + MODULE_CNT +} Module_tasks_E; diff --git a/components/vc/front/include/UDS.h b/components/vc/front/include/UDS.h new file mode 100644 index 00000000..437dd32e --- /dev/null +++ b/components/vc/front/include/UDS.h @@ -0,0 +1,19 @@ +/* + * UDS.h + * UDS module header file + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "FeatureDefines_generated.h" +#if APP_UDS +// component-specific UDS configuration +#include "uds_componentSpecific.h" + +// other includes +#include "LIB_Types.h" +#endif // FEATURE_UDS diff --git a/components/vc/front/include/Utility.h b/components/vc/front/include/Utility.h new file mode 100644 index 00000000..a3edc42d --- /dev/null +++ b/components/vc/front/include/Utility.h @@ -0,0 +1,477 @@ +/** + * @file Utility.h + * @brief Header file for Utlity functions + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" +#include "stddef.h" +#include "string.h" + +/****************************************************************************** + * M A C R O S + ******************************************************************************/ + +// Count number of items in array +#define COUNTOF(x) ((uint16_t)(sizeof(x) / sizeof(x[0]))) // return size of an array as uint16 +// Count leading zeroes +static inline uint16_t u32CountLeadingZeroes(uint32_t x) +{ + uint16_t c = 0U; + while (((x & 0x80000000UL) == 0UL) && (c < 32U)) + { + c++; + x <<= 1UL; + } + + return c; +} + +#define VAR_IN_SECTION(s) __attribute__((section(s))) // place a given variable in the specified linker section + +#ifndef UNUSED +# define UNUSED(x) (void)x +#endif + +#define zero() (0U) + +// Join macros +// Convert token to string (doesn't expand) +#define STR(x) #x + +// Expand and convert token to string +#define XSTR(x) STR(x) + +// Join two tokens (doesn't expand) +#define DO_JOIN(x, y) x##y + +// Expand and join tokens +#define JOIN(x, y) DO_JOIN(x, y) +#define JOIN3(x, y, z) JOIN(x, JOIN(y, z)) + +// Expand and join with `_` separating tokens +#define SNAKE(x, y) JOIN3(x, _, y) +#define SNAKE3(x, y, z) SNAKE(x, SNAKE(y, z)) +#define SNAKE4(x, y, z, a) SNAKE3(x, y, SNAKE(z, a)) + +// atomic bit stuff +// FIXME: check if these compile down to one instruction +// If not, make this atomic +#define setBitAtomic(bit) ((bit) = true) +#define clearBitAtomic(bit) ((bit) = false) +#define assignBitAtomic(bit, condition) \ + do { \ + if (condition) \ + { \ + (bit) = true; \ + } \ + else \ + { \ + (bit) = false; \ + } \ + } while (zero()) + + +// FLAGS +// This should get moved elsewhere at some point +#define FLAG_bits_each 16 +#define WORDS_FROM_COUNT(count) (uint16_t)((count + (FLAG_bits_each - 1)) / FLAG_bits_each) +#define FLAG_GET_WORD(name, flag) (name[(uint16_t)flag / FLAG_bits_each]) +#define FLAG_GET_MASK(flag) (1U << ((uint16_t)flag % FLAG_bits_each)) + +#define FLAG_create(name, size) uint16_t(name)[WORDS_FROM_COUNT(size)] +#define FLAG_set(name, pos) FLAG_GET_WORD(name, pos) |= (uint16_t)FLAG_GET_MASK(pos) +#define FLAG_clear(name, pos) FLAG_GET_WORD(name, pos) &= (uint16_t)~FLAG_GET_MASK(pos) +#define FLAG_get(name, pos) ((bool)((FLAG_GET_WORD(name, pos) & FLAG_GET_MASK(pos)) == FLAG_GET_MASK(pos))) +#define FLAG_assign(name, pos, value) \ + do { \ + if (value) \ + { \ + FLAG_set(name, pos); \ + } \ + else \ + { \ + FLAG_clear(name, pos); \ + } \ + } while (zero()) + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/* + * FLAG_setAll + * @brief Sets all of the flags in the given flag word + * @param name Flag word name + * @param count Number of flags in the given flag + */ +static inline void FLAG_setAll(uint16_t* name, uint16_t count) +{ + uint16_t numWords = WORDS_FROM_COUNT(count); + uint16_t extraBits = count % FLAG_bits_each; + + if (numWords > 1U) + { + memset(name, 0xFF, (uint16_t)(numWords * FLAG_bits_each)); + } + if (extraBits > 0U) + { + name[numWords] |= (0xFF >> (FLAG_bits_each - extraBits)); + } +} + + +/* + * FLAG_clearAll + * @brief clears all of the bits in the given flag + * @param name Flag word name + * @param count Number of bits in the given flag + */ +static inline void FLAG_clearAll(uint16_t* name, uint16_t count) +{ + memset(name, 0x00, (uint16_t)(WORDS_FROM_COUNT(count) * FLAG_bits_each)); +} + + +/* + * FLAG_any + * @brief check if any of the flags in the flag word is set + * @param name Flag word name + * @param count Number of flags in the given flag + */ +static inline bool FLAG_any(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0U) + { + return true; + } + } + return false; +} + + +/* + * FLAG_all + * @brief checks if all flags in the flag word are set + * @param name Flag word name + * @param count Number of bits in the given flag word + */ +static inline bool FLAG_all(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0xFF) + { + return false; + } + } + return true; +} + + +/* + * FLAG_none + * @brief checks if none of the flags in the flag word are set + * @param name Flag word name + * @param count Number of bits in the given flag word + */ +static inline bool FLAG_none(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0U) + { + return false; + } + } + return true; +} + +static inline uint8_t reverse_byte(uint8_t x) +{ + static const uint8_t table[] = { + 0x00, + 0x80, + 0x40, + 0xc0, + 0x20, + 0xa0, + 0x60, + 0xe0, + 0x10, + 0x90, + 0x50, + 0xd0, + 0x30, + 0xb0, + 0x70, + 0xf0, + 0x08, + 0x88, + 0x48, + 0xc8, + 0x28, + 0xa8, + 0x68, + 0xe8, + 0x18, + 0x98, + 0x58, + 0xd8, + 0x38, + 0xb8, + 0x78, + 0xf8, + 0x04, + 0x84, + 0x44, + 0xc4, + 0x24, + 0xa4, + 0x64, + 0xe4, + 0x14, + 0x94, + 0x54, + 0xd4, + 0x34, + 0xb4, + 0x74, + 0xf4, + 0x0c, + 0x8c, + 0x4c, + 0xcc, + 0x2c, + 0xac, + 0x6c, + 0xec, + 0x1c, + 0x9c, + 0x5c, + 0xdc, + 0x3c, + 0xbc, + 0x7c, + 0xfc, + 0x02, + 0x82, + 0x42, + 0xc2, + 0x22, + 0xa2, + 0x62, + 0xe2, + 0x12, + 0x92, + 0x52, + 0xd2, + 0x32, + 0xb2, + 0x72, + 0xf2, + 0x0a, + 0x8a, + 0x4a, + 0xca, + 0x2a, + 0xaa, + 0x6a, + 0xea, + 0x1a, + 0x9a, + 0x5a, + 0xda, + 0x3a, + 0xba, + 0x7a, + 0xfa, + 0x06, + 0x86, + 0x46, + 0xc6, + 0x26, + 0xa6, + 0x66, + 0xe6, + 0x16, + 0x96, + 0x56, + 0xd6, + 0x36, + 0xb6, + 0x76, + 0xf6, + 0x0e, + 0x8e, + 0x4e, + 0xce, + 0x2e, + 0xae, + 0x6e, + 0xee, + 0x1e, + 0x9e, + 0x5e, + 0xde, + 0x3e, + 0xbe, + 0x7e, + 0xfe, + 0x01, + 0x81, + 0x41, + 0xc1, + 0x21, + 0xa1, + 0x61, + 0xe1, + 0x11, + 0x91, + 0x51, + 0xd1, + 0x31, + 0xb1, + 0x71, + 0xf1, + 0x09, + 0x89, + 0x49, + 0xc9, + 0x29, + 0xa9, + 0x69, + 0xe9, + 0x19, + 0x99, + 0x59, + 0xd9, + 0x39, + 0xb9, + 0x79, + 0xf9, + 0x05, + 0x85, + 0x45, + 0xc5, + 0x25, + 0xa5, + 0x65, + 0xe5, + 0x15, + 0x95, + 0x55, + 0xd5, + 0x35, + 0xb5, + 0x75, + 0xf5, + 0x0d, + 0x8d, + 0x4d, + 0xcd, + 0x2d, + 0xad, + 0x6d, + 0xed, + 0x1d, + 0x9d, + 0x5d, + 0xdd, + 0x3d, + 0xbd, + 0x7d, + 0xfd, + 0x03, + 0x83, + 0x43, + 0xc3, + 0x23, + 0xa3, + 0x63, + 0xe3, + 0x13, + 0x93, + 0x53, + 0xd3, + 0x33, + 0xb3, + 0x73, + 0xf3, + 0x0b, + 0x8b, + 0x4b, + 0xcb, + 0x2b, + 0xab, + 0x6b, + 0xeb, + 0x1b, + 0x9b, + 0x5b, + 0xdb, + 0x3b, + 0xbb, + 0x7b, + 0xfb, + 0x07, + 0x87, + 0x47, + 0xc7, + 0x27, + 0xa7, + 0x67, + 0xe7, + 0x17, + 0x97, + 0x57, + 0xd7, + 0x37, + 0xb7, + 0x77, + 0xf7, + 0x0f, + 0x8f, + 0x4f, + 0xcf, + 0x2f, + 0xaf, + 0x6f, + 0xef, + 0x1f, + 0x9f, + 0x5f, + 0xdf, + 0x3f, + 0xbf, + 0x7f, + 0xff, + }; + return table[x]; +} + +uint8_t* reverse_bytes(uint8_t* in, uint8_t len); + +/** + * @brief Simple fast accurate natural log approximation + * + * @note Lingdong Huang, 2020, Public Domain + * @note Floating point bit hacking + * Remez Algorithm + * x=m*2^p => ln(x)=ln(m)+ln(2)p* + * + * @param x Number to calculate ln of + * + * @retval result of ln(x) + */ +float ln(float x); diff --git a/components/vc/front/include/uds_componentSpecific.h b/components/vc/front/include/uds_componentSpecific.h new file mode 100644 index 00000000..e15a8849 --- /dev/null +++ b/components/vc/front/include/uds_componentSpecific.h @@ -0,0 +1,27 @@ +/* + * uds_componentSpecific.h + * Component-specific defines for the UDS library + */ +#pragma once + +#include "NetworkDefines_generated.h" +#include "FeatureDefines_generated.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#if APP_UDS +#define UDS_ENABLE_LIB APP_UDS + +#define UDS_REQUEST_ID CAN_VEH_UDSCLIENT_vcfrontUdsRequest_ID +#define UDS_RESPONSE_ID CAN_VEH_VCFRONT_udsResponse_ID + +#define ISOTP_TX_BUF_SIZE 128U // [bytes] mostly arbitrary +#define ISOTP_RX_BUF_SIZE 128U // [bytes] maximum size of a multi-frame ISOTP transaction (mostly arbitrary, increase if necessary) + +// supported UDS services +#define UDS_SERVICE_SUPPORTED_ECU_RESET true +#define UDS_SERVICE_SUPPORTED_ROUTINE_CONTROL true +#define UDS_SERVICE_SUPPORTED_DID_READ true +#endif // FEATURE_UDS diff --git a/components/vc/front/renderers/BuildDefines_generated.h.mako b/components/vc/front/renderers/BuildDefines_generated.h.mako new file mode 100644 index 00000000..38a1d744 --- /dev/null +++ b/components/vc/front/renderers/BuildDefines_generated.h.mako @@ -0,0 +1,8 @@ +/* + * BuildDefines_generated.h + * + */ + +#pragma once + +#define VCPDU_CONFIG_ID ${configId}U diff --git a/components/vc/front/src/CANIO_componentSpecific.c b/components/vc/front/src/CANIO_componentSpecific.c new file mode 100644 index 00000000..6b6d940a --- /dev/null +++ b/components/vc/front/src/CANIO_componentSpecific.c @@ -0,0 +1,32 @@ +/** + RX_config* CAN.h + * Header file for CANRX configuration + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "CAN/CAN.h" +#include "CANIO_componentSpecific.h" +#include "Utility.h" +#include "MessageUnpack_generated.h" + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +void CANRX_unpackMessage(CAN_bus_E bus, uint32_t id, CAN_data_T *data) +{ + switch (bus) + { + case CAN_BUS_NOSE: + CANRX_NOSE_unpackMessage(id, data); + break; + case CAN_BUS_VEH: + CANRX_VEH_unpackMessage(id, data); + break; + default: + break; + } +} diff --git a/components/vc/front/src/HW/HW.c b/components/vc/front/src/HW/HW.c new file mode 100644 index 00000000..dff17f3d --- /dev/null +++ b/components/vc/front/src/HW/HW.c @@ -0,0 +1,91 @@ +/** + * @file HW.c + * @brief Source code for generic firmware functions + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Header file +#include "HW.h" + +// System Includes +#include "stdbool.h" + +// Firmware Includes +#include "stm32f1xx.h" +#include "HW_tim.h" + +typedef struct +{ + volatile uint32_t const CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint32_t SHPR[3]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; +} SCB_regMap; +#define pSCB ((SCB_regMap*)SCB_BASE) + +#define AIRCR_RESET (0x05FA0000UL) +#define AIRCR_RESET_REQ (AIRCR_RESET | 0x04UL) + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +/** + * @brief Initializes the generic low-level firmware + * + * @retval Always true + */ +bool HW_init(void) +{ + return HAL_Init() == HAL_OK; +} + +/** + * @brief Get the number of ticks since clock start + * + * @retval Number of ticks + */ +uint32_t HW_getTick(void) +{ + return HAL_GetTick(); +} + +/** + * @brief Delay the execution in blocking mode for amount of ticks + * + * @param delay Number of ticks to delay in blocking mode + */ +void HW_delay(uint32_t delay) +{ + HAL_Delay(delay); +} + +/** + * @brief This function is blocking and should be avoided + * + * @param us Microsecond blocking delay + */ +void HW_usDelay(uint8_t us) +{ + uint64_t us_start = HW_TIM_getBaseTick(); + + while (HW_TIM_getBaseTick() < us_start + us); +} + +void HW_systemHardReset(void) +{ + pSCB->AIRCR = AIRCR_RESET_REQ; +} diff --git a/components/vc/front/src/HW/HW_adc.c b/components/vc/front/src/HW/HW_adc.c new file mode 100644 index 00000000..73c7785a --- /dev/null +++ b/components/vc/front/src/HW/HW_adc.c @@ -0,0 +1,203 @@ +/** + * @file HW_adc.c + * @brief Source code for ADC firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// FreeRTOS Includes +#include "FreeRTOS.h" +#include "task.h" + +// System Inlcudes +#include "string.h" + +// Firmware Includes +#include "HW_adc.h" + +// Other Includes +#include "IO.h" +#include "SystemConfig.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES 2U +#define ADC_CALIBRATION_TIMEOUT 10U + +#define ADC_MAX_COUNT 4095 + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +ADC_HandleTypeDef hadc1; +ADC_HandleTypeDef hadc2; +DMA_HandleTypeDef hdma_adc1; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_ADC_unpackBuffer(bufferHalf_E half); + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Init function for ADC firmware + */ +void HW_ADC_init(void) +{ + ADC_MultiModeTypeDef multimode = { 0 }; + ADC_ChannelConfTypeDef sConfig = { 0 }; + + // Cell Measurement config + hadc1.Instance = ADC1; + hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc1.Init.ContinuousConvMode = ENABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + multimode.Mode = ADC_DUALMODE_REGSIMULT; + if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) + { + Error_Handler(); + } + + // Configure Regular Channels + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + hadc2.Instance = ADC2; + hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc2.Init.ContinuousConvMode = ENABLE; + hadc2.Init.DiscontinuousConvMode = DISABLE; + hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc2.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc2) != HAL_OK) + { + Error_Handler(); + } + + // Configure Regular Channels + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5; + if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + HAL_ADC_Start(&hadc2); +} + +/** + * @brief Callback for STM32 HAL once ADC initialization is complete + * + * @param adcHandle pointer to ADC peripheral + */ +void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) +{ + if (adcHandle->Instance == ADC1) + { + // ADC1 clock enable + __HAL_RCC_ADC1_CLK_ENABLE(); + + // ADC1 DMA Init + // ADC1 Init + hdma_adc1.Instance = DMA1_Channel1; + hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + hdma_adc1.Init.Mode = DMA_CIRCULAR; + hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM; + if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(adcHandle, DMA_Handle, hdma_adc1); + + HAL_NVIC_SetPriority(ADC1_2_IRQn, ADC_IRQ_PRIO, 0U); + HAL_NVIC_EnableIRQ(ADC1_2_IRQn); + } + else if (adcHandle->Instance == ADC2) + { + // ADC1 clock enable + __HAL_RCC_ADC2_CLK_ENABLE(); + } +} + +/** + * @brief STM32 HAL callback. Called once de-init is complete + * + * @param adcHandle Pointer to ADC peripheral + */ +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) +{ + if (adcHandle->Instance == ADC1) + { + __HAL_RCC_ADC1_CLK_DISABLE(); + + // ADC1 DMA DeInit + HAL_DMA_DeInit(adcHandle->DMA_Handle); + } + if (adcHandle->Instance == ADC2) + { + // Peripheral clock disable + __HAL_RCC_ADC2_CLK_DISABLE(); + } +} + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Firmware function to initiate ADC calibration. + * + * @param hadc Pointer to ADC peripheral + * + * @retval true = Success, false = Failure + */ +bool HW_ADC_calibrate(ADC_HandleTypeDef* hadc) +{ + return HAL_ADCEx_Calibration_Start(hadc) == HAL_OK; +} + +/** + * @brief Firmware function to start DMA transfer + * + * @param hadc Pointer to ADC peripheral + * @param data Pointer to memory start address + * @param size Size of buffer + * + * @retval true = Success, false = Failure + */ +bool HW_ADC_startDMA(ADC_HandleTypeDef* hadc, uint32_t* data, uint32_t size) +{ + return HAL_ADCEx_MultiModeStart_DMA(hadc, data, size) == HAL_OK; +} diff --git a/components/vc/front/src/HW/HW_can_componentSpecific.c b/components/vc/front/src/HW/HW_can_componentSpecific.c new file mode 100644 index 00000000..bdf00eba --- /dev/null +++ b/components/vc/front/src/HW/HW_can_componentSpecific.c @@ -0,0 +1,410 @@ +/** + * @file HW_can.c + * @brief Source code for CAN firmware + */ + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "HW_can.h" + +#include "HW.h" +#include "stdint.h" +#include "SystemConfig.h" + +#include "CAN/CAN.h" +#include "CAN/CanTypes.h" + +#include "NetworkDefines_generated.h" +#include "MessageUnpack_generated.h" +#include "uds.h" +#include "uds_componentSpecific.h" +#include "LIB_app.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// which CAN interrupts we want to enable +// stm32f1xx_hal_can.h from ST drivers for description of each one +// Description of interrupts: +// CAN_IER_TMEIE Transmit Mailbox Empty +// CAN_IER_FMPIEx FIFO x Message Pending (RX FIFO) +// CAN_IER_FFIEx FIFO x Full +// CAN_IER_FOVIEx FIFO x Overrun +// CAN_IER_WKUIE Wakeup Interrupt +// CAN_IER_SLKIE Sleep Interrupt +// CAN_IER_EWGIE Error Warning Interrupt +// CAN_IER_EPVIE Error Passive Interrupt +// CAN_IER_BOFIE Bus Off Interrupt +// CAN_IER_LECIE Last Error Code Interrupt +// CAN_IER_ERRIE Error Interrupt +#define CAN_ENABLED_INTERRUPTS (CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_FFIE0 | \ + CAN_IER_FFIE1 | CAN_IER_FOVIE0 | CAN_IER_FOVIE1 | CAN_IER_EWGIE | \ + CAN_IER_EPVIE | CAN_IER_BOFIE | CAN_IER_LECIE | CAN_IER_ERRIE) + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +CAN_HandleTypeDef hcan[CAN_BUS_COUNT]; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +static inline CAN_bus_E HW_CAN_getBusFromPeripheral(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = 0U; + + for (CAN_bus_E i = 0U; i < CAN_BUS_COUNT; i++) + { + if (&hcan[i] == canHandle) + { + bus = i; + i = CAN_BUS_COUNT; + } + } + + return bus; +} + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * HW_CAN_sendMsgBus0 + * @param priority TODO + * @param data TODO + * @param id TODO + * @param len TODO + * @return TODO + */ +bool HW_CAN_sendMsg(CAN_bus_E bus, CAN_data_T data, uint32_t id, uint8_t len) +{ + CAN_TxMessage_T msg = {0}; + + msg.id = id; + msg.data = data; + msg.lengthBytes = len; + msg.IDE = (id <= 0x7ff) ? CAN_IDENTIFIER_STD : CAN_IDENTIFIER_EXT; + + return HW_CAN_sendMsgOnPeripheral(bus, msg) == HW_OK; +} + +/** + * HW_CAN_Init + * initialize the CAN peripheral + */ +HW_StatusTypeDef_E HW_CAN_init(void) +{ + hcan[CAN_BUS_VEH].Instance = CAN1; + hcan[CAN_BUS_NOSE].Instance = CAN2; + for (CAN_bus_E bus = 0U; bus < CAN_BUS_COUNT; bus++) + { + hcan[bus].Init.Mode = CAN_MODE_NORMAL; + hcan[bus].Init.TimeTriggeredMode = DISABLE; + hcan[bus].Init.AutoBusOff = ENABLE; + hcan[bus].Init.AutoWakeUp = DISABLE; + hcan[bus].Init.AutoRetransmission = ENABLE; + hcan[bus].Init.ReceiveFifoLocked = DISABLE; + hcan[bus].Init.TransmitFifoPriority = DISABLE; + + switch(CAN_busConfig[bus].baudrate) + { + case CAN_BAUDRATE_1MBIT: + hcan[bus].Init.Prescaler = 4; + hcan[bus].Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan[bus].Init.TimeSeg1 = CAN_BS1_6TQ; + hcan[bus].Init.TimeSeg2 = CAN_BS2_1TQ; + break; + case CAN_BAUDRATE_500KBIT: + hcan[bus].Init.Prescaler = 4; + hcan[bus].Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan[bus].Init.TimeSeg1 = CAN_BS1_12TQ; + hcan[bus].Init.TimeSeg2 = CAN_BS2_3TQ; + break; + default: + return HW_ERROR; + } + + if (HAL_CAN_Init(&hcan[bus]) != HAL_OK) + { + Error_Handler(); + } + } + + _Static_assert(((COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4) + (COUNTOF(CANRX_VEH_unpackListExtID) / 2U) + + ((COUNTOF(CANRX_NOSE_unpackList) + ((4U - COUNTOF(CANRX_NOSE_unpackList) % 4U) % 4U)) / 4) + (COUNTOF(CANRX_NOSE_unpackListExtID) / 2U) + <= CAN_FILTERBANK_LENGTH, "Too many CAN filter bank's used"); + uint8_t filterBank = 0U; + for (uint32_t i = 0U; i < COUNTOF(CANRX_VEH_unpackList); i += 4U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_16BIT; + // All filters are shifted left 5 bits + filt.FilterIdHigh = CANRX_VEH_unpackList[i + 0U] << 5U; + if ((i + 1U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterIdLow = CANRX_VEH_unpackList[i + 1U] << 5U; } + if ((i + 2U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterMaskIdHigh = CANRX_VEH_unpackList[i + 2U] << 5U; } + if ((i + 3U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterMaskIdLow = CANRX_VEH_unpackList[i + 3U] << 5U; } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_VEH], &filt); + } + for (uint32_t i = 0U; i < COUNTOF(CANRX_VEH_unpackListExtID); i+= 2U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_32BIT; + // All filters are fucky - lookup RM0008 information + filt.FilterIdHigh = (uint16_t)(CANRX_VEH_unpackListExtID[i + 0U] >> 13U); + filt.FilterIdLow = (uint16_t)(CANRX_VEH_unpackListExtID[i + 0U] << 3U) | (0x01 << 2U); + if ((i + 1U) < COUNTOF(CANRX_VEH_unpackListExtID)) { + filt.FilterMaskIdHigh = (uint16_t)(CANRX_VEH_unpackListExtID[i + 1U] >> 13U); + filt.FilterMaskIdLow = (uint16_t)(CANRX_VEH_unpackListExtID[i + 1U] << 3U) | (0x01 << 2U); + } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_VEH], &filt); + } + HAL_CAN_ActivateNotification(&hcan[CAN_BUS_VEH], CAN_ENABLED_INTERRUPTS); + + for (uint32_t i = 0U; i < COUNTOF(CANRX_NOSE_unpackList); i += 4U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_16BIT; + // All filters are shifted left 5 bits + filt.FilterIdHigh = CANRX_NOSE_unpackList[i + 0U] << 5U; + if ((i + 1U) < COUNTOF(CANRX_NOSE_unpackList)) { filt.FilterIdLow = CANRX_NOSE_unpackList[i + 1U] << 5U; } + if ((i + 2U) < COUNTOF(CANRX_NOSE_unpackList)) { filt.FilterMaskIdHigh = CANRX_NOSE_unpackList[i + 2U] << 5U; } + if ((i + 3U) < COUNTOF(CANRX_NOSE_unpackList)) { filt.FilterMaskIdLow = CANRX_NOSE_unpackList[i + 3U] << 5U; } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_NOSE], &filt); + } + for (uint32_t i = 0U; i < COUNTOF(CANRX_NOSE_unpackListExtID); i+= 2U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_32BIT; + // All filters are fucky - lookup RM0008 information + filt.FilterIdHigh = (uint16_t)(CANRX_NOSE_unpackListExtID[i + 0U] >> 13U); + filt.FilterIdLow = (uint16_t)(CANRX_NOSE_unpackListExtID[i + 0U] << 3U) | (0x01 << 2U); + if ((i + 1U) < COUNTOF(CANRX_NOSE_unpackListExtID)) { + filt.FilterMaskIdHigh = (uint16_t)(CANRX_NOSE_unpackListExtID[i + 1U] >> 13U); + filt.FilterMaskIdLow = (uint16_t)(CANRX_NOSE_unpackListExtID[i + 1U] << 3U) | (0x01 << 2U); + } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_NOSE], &filt); + } + HAL_CAN_ActivateNotification(&hcan[CAN_BUS_NOSE], CAN_ENABLED_INTERRUPTS); + + return HW_OK; +} + +/** + * HAL_CAN_MspInit + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) +{ + if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // CAN1 clock enable + __HAL_RCC_CAN1_CLK_ENABLE(); + + HAL_NVIC_SetPriority(CAN1_SCE_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_TX_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_RX0_IRQn, CAN_RX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_RX1_IRQn, CAN_RX_IRQ_PRIO, 0U); + + HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn); + HAL_NVIC_EnableIRQ(CAN1_TX_IRQn); + HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); + HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn); + + } + else if (canHandle->Instance == hcan[CAN_BUS_NOSE].Instance) + { + __HAL_RCC_CAN2_CLK_ENABLE(); + + HAL_NVIC_SetPriority(CAN2_SCE_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_TX_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_RX0_IRQn, CAN_RX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_RX1_IRQn, CAN_RX_IRQ_PRIO, 0U); + + HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn); + HAL_NVIC_EnableIRQ(CAN2_TX_IRQn); + HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn); + } +} + +/** + * HAL_CAN_MspDeInit + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle) +{ + if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // Peripheral clock disable + __HAL_RCC_CAN1_CLK_DISABLE(); + + HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn); + HAL_NVIC_DisableIRQ(CAN1_TX_IRQn); + HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn); + HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn); + } + else if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // Peripheral clock disable + __HAL_RCC_CAN2_CLK_DISABLE(); + + HAL_NVIC_DisableIRQ(CAN2_SCE_IRQn); + HAL_NVIC_DisableIRQ(CAN2_TX_IRQn); + HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn); + } +} + +// overload default interrupt callback functions provided by HAL +/** + * HAL_CAN_TxMailbox0CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_0); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox1CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_1); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox2CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_2); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox0AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_0); +} + +/** + * HAL_CAN_TxMailbox1AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_1); +} + +/** + * HAL_CAN_TxMailbox2AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_2); +} + +/** + * HAL_CAN_RxFifo0MsgPendingCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FMPIE0); +#endif // FEATURE_CANRX_SWI + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_0); +} + +/** + * HAL_CAN_RxFifo1MsgPendingCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FMPIE1); +#endif // FEATURE_CANRX_SWI + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_1); +} + +/** + * HAL_CAN_RxFifo0FullCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_0); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FFIE0); + SWI_invokeFromISR(CANRX_swi); +#endif // FEATURE_CANRX_SWI +} + +/** + * HAL_CAN_RxFifo1FullCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_1); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FFIE1); + SWI_invokeFromISR(CANRX_swi); +#endif // FEATURE_CANRX_SWI +} + +/** + * HAL_CAN_ErrorCallback + * @param canHandle TODO + */ +void HAL_CAN_ErrorCallback(CAN_HandleTypeDef* canHandle) +{ + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_ERRIE); +} diff --git a/components/vc/front/src/HW/HW_dma.c b/components/vc/front/src/HW/HW_dma.c new file mode 100644 index 00000000..f4c5bba0 --- /dev/null +++ b/components/vc/front/src/HW/HW_dma.c @@ -0,0 +1,29 @@ +/** + * @file HW_dma.c + * @brief Source code for DMA firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "HW_dma.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Firmware DMA Initialization function + */ +void HW_DMA_init(void) +{ + // DMA controller clock enable + __HAL_RCC_DMA1_CLK_ENABLE(); + + // DMA interrupt init + // DMA1_Channel1_IRQn interrupt configuration + HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, DMA_IRQ_PRIO, 0U); + HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); +} diff --git a/components/vc/front/src/HW/HW_gpio_componentSpecific.c b/components/vc/front/src/HW/HW_gpio_componentSpecific.c new file mode 100644 index 00000000..b892719f --- /dev/null +++ b/components/vc/front/src/HW/HW_gpio_componentSpecific.c @@ -0,0 +1,54 @@ +/** + * @file HW_gpio_componentSpecific.c + * @brief Source code for GPIO firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW_gpio.h" + +const HW_GPIO_S HW_GPIO_pinmux[HW_GPIO_COUNT] = { + [HW_GPIO_CAN1_RX] = { + .port = GPIOB, + .pin = GPIO_PIN_8, + .mode = GPIO_MODE_INPUT, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_NOSET, + }, + [HW_GPIO_CAN1_TX] = { + .port = GPIOB, + .pin = GPIO_PIN_9, + .mode = GPIO_MODE_AF_PP, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINSET, + }, + [HW_GPIO_CAN2_RX] = { + .port = GPIOB, + .pin = GPIO_PIN_12, + .mode = GPIO_MODE_INPUT, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_NOSET, + }, + [HW_GPIO_CAN2_TX] = { + .port = GPIOB, + .pin = GPIO_PIN_13, + .mode = GPIO_MODE_AF_PP, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINSET, + }, + [HW_GPIO_LED] = { + .port = GPIOC, + .pin = GPIO_PIN_13, + .mode = GPIO_MODE_OUTPUT_PP, + .speed = GPIO_SPEED_FREQ_LOW, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINRESET, + }, +}; diff --git a/components/vc/front/src/HW/HW_intc.c b/components/vc/front/src/HW/HW_intc.c new file mode 100644 index 00000000..e019c1bb --- /dev/null +++ b/components/vc/front/src/HW/HW_intc.c @@ -0,0 +1,172 @@ +/** + * @file HW_intc.c + * @brief Source code for STM32F1xx Cortex M3 Interrupts + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW_intc.h" +#include "NetworkDefines_generated.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern ADC_HandleTypeDef hadc1; +extern ADC_HandleTypeDef hadc2; +extern DMA_HandleTypeDef hdma_adc1; +extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim4; +extern TIM_HandleTypeDef htim2; +extern CAN_HandleTypeDef hcan[CAN_BUS_COUNT]; + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + volatile uint8_t c = 0; + + while (c == 0) + { + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ +} + +// Peripheral Interrupt Handlers + +/** + * @brief This function handles DMA1 channel1 global interrupt. + */ +void DMA1_Channel1_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_adc1); +} + +void ADC1_2_IRQHandler(void) +{ + HAL_ADC_IRQHandler(&hadc1); + // HAL_ADC_IRQHandler(&hadc2); +} + +void TIM2_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim2); +} + +void TIM1_TRG_COM_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim1); +} + +void TIM1_CC_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim1); +} + +// CAN interrupts +void CAN1_SCE_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_TX_IRQHandler + * + */ +void CAN1_TX_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_RX0_IRQHandler + * + */ +void CAN1_RX0_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_RX1_IRQHandler + * + */ +void CAN1_RX1_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +void CAN2_SCE_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_NOSE]); +} + +void CAN2_TX_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_NOSE]); +} + +void CAN2_RX0_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_NOSE]); +} + +void CAN2_RX1_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_NOSE]); +} diff --git a/components/vc/front/src/HW/HW_msp.c b/components/vc/front/src/HW/HW_msp.c new file mode 100644 index 00000000..e43824a5 --- /dev/null +++ b/components/vc/front/src/HW/HW_msp.c @@ -0,0 +1,30 @@ +/** + * @file HW_msp.c + * @brief Source code for generic Msp firmware calls + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" + + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Overrides weak HAL Link for our implementation + */ +void HAL_MspInit(void) +{ + __HAL_RCC_AFIO_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); + + // Enable SWD, disable JTAG + __HAL_AFIO_REMAP_SWJ_NOJTAG(); +} diff --git a/components/vc/front/src/HW/HW_tim.c b/components/vc/front/src/HW/HW_tim.c new file mode 100644 index 00000000..9deec4eb --- /dev/null +++ b/components/vc/front/src/HW/HW_tim.c @@ -0,0 +1,264 @@ +/** + * @file HW_tim.c + * @brief Source code for TIM firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" +#include "LIB_Types.h" + +// Firmware Includes +#include "HW_tim.h" + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim2; + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called TIMx interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) +{ + if (htim->Instance == TIM2) + { + HAL_IncTick(); + } +} + +/** + * @brief Initializes TIM peripherals + * + * @retval true = Success, false = Failure + */ +HAL_StatusTypeDef HW_TIM_init(void) +{ + TIM_ClockConfigTypeDef sClockSourceConfig = { 0 }; + TIM_SlaveConfigTypeDef sSlaveConfig = { 0 }; + TIM_IC_InitTypeDef sConfigIC = { 0 }; + TIM_MasterConfigTypeDef sMasterConfig = { 0 }; + + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock = 0; + uint32_t uwPrescalerValue = 0; + uint32_t pFLatency; + + // Get clock configuration + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + // Compute TIM4 clock + uwTimclock = 2 * HAL_RCC_GetPCLK2Freq(); + // Compute the prescaler value to have TIM4 counter clock equal to 1MHz + uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U); + + htim1.Instance = TIM1; + htim1.Init.Prescaler = uwPrescalerValue; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 1000000000; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_IC_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; + sSlaveConfig.InputTrigger = TIM_TS_TI2FP2; + sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; + sSlaveConfig.TriggerFilter = 0; + if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; + sConfigIC.ICFilter = 0; + if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; + sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; + if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + // Configure the TIM4 IRQ priority + HAL_NVIC_SetPriority(TIM1_CC_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_BRK_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_UP_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, TICK_INT_PRIORITY, 0); + + // Enable the TIM4 global Interrupt + HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + HAL_NVIC_EnableIRQ(TIM1_BRK_IRQn); + HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); + HAL_NVIC_EnableIRQ(TIM1_TRG_COM_IRQn); + + HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2); // main channel + HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1); // indirect channel + + return HAL_OK; +} + +/** + * @brief HAL callback once Initialization is complete. Used for GPIO/INTERRUPT configuration + * + * @param htim_base TIM peripheral + */ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim) +{ + if (tim->Instance == TIM1) + { + __HAL_RCC_TIM1_CLK_ENABLE(); + } +} + +/** + * @brief HAL callback called once an input capture has triggered + * + * @param htim TIM peripheral + */ +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) +{ + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) // If the interrupt is triggered by channel 1 + { + } +} + +/** + * @brief RTOS callback to configure a more precise timebase for cpu profiling + */ +void HW_TIM_configureRunTimeStatsTimer(void) +{ +} + +/** + * @brief RTOS Profiling has a ~1us accuracy by using the OS CLK and internal counter + * + * @retval Elapsed time in us from clock start + */ +uint64_t HW_TIM_getBaseTick() +{ + // return fast_clk; + + return ((uint64_t)HW_getTick() * 1000) + htim2.Instance->CNT; +} + +/** + * @brief Get the number of ticks since clock start + * + * @retval Number of ticks + */ +uint32_t HW_TIM_getTick(void) +{ + return HAL_GetTick(); +} + +uint32_t HW_TIM_getTimeMS() +{ + return HW_TIM_getTick(); +} + +/** + * HAL_InitTick + * This function configures the TIM4 as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority Tick interrupt priority. + * @return exit status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock = 0; + uint32_t uwPrescalerValue = 0; + uint32_t pFLatency; + + // Configure the TIM4 IRQ priority + HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority, 0); + + // Enable the TIM4 global Interrupt + HAL_NVIC_EnableIRQ(TIM2_IRQn); + + // Enable TIM4 clock + __HAL_RCC_TIM2_CLK_ENABLE(); + + // Get clock configuration + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + + // Compute TIM2 clock + uwTimclock = 1 * HAL_RCC_GetPCLK2Freq(); + // Compute the prescaler value to have TIM4 counter clock equal to 1MHz + uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U); + + // Initialize TIM4 + htim2.Instance = TIM2; + + // Initialize TIMx peripheral as follow: + // Period = [(TIM4CLK/1000) - 1]. to have a (1/1000) s time base. + // Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. + // ClockDivision = 0 + // Counter direction = Up + htim2.Init.Period = (1000000U / 1000) - 1U; + htim2.Init.Prescaler = uwPrescalerValue; + htim2.Init.ClockDivision = 0; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + + if (HAL_TIM_Base_Init(&htim2) == HAL_OK) + { + // Start the TIM time Base generation in interrupt mode + return HAL_TIM_Base_Start_IT(&htim2); + } + + return HAL_ERROR; +} + +/** + * @brief Suspends the tick interrupt + */ +void HAL_SuspendTick(void) +{ + __HAL_TIM_DISABLE_IT(&htim2, TIM_IT_UPDATE); +} + + +/** + * @brief Resumes tick interrupt + */ +void HAL_ResumeTick(void) +{ + __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE); +} diff --git a/components/vc/front/src/IO.c b/components/vc/front/src/IO.c new file mode 100644 index 00000000..c875dc70 --- /dev/null +++ b/components/vc/front/src/IO.c @@ -0,0 +1,161 @@ +/** + * @file IO.c + * @brief Source code for IO Module + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Module Header */ +#include "IO.h" + +/**< System Includes*/ +#include "LIB_Types.h" +#include + +/**< Firmware Includes */ +#include "HW.h" +#include "HW_adc.h" +#include "HW_dma.h" +#include "HW_gpio.h" + +/**< Other Includes */ +#include "ModuleDesc.h" +#include "Utility.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + ADC_STATE_INIT = 0, + ADC_STATE_CALIBRATION, + ADC_STATE_RUNNING, + ADC_STATE_CALIBRATION_FAILED, + ADC_STATE_COUNT, +} adcState_E; + +typedef enum +{ + ADC_MCU_TEMP, + ADC_MCU_TEMP_temporary, + ADC_CHANNEL_COUNT, +} adcChannels_E; +_Static_assert(IO_ADC_BUF_LEN % ADC_CHANNEL_COUNT == 0, "ADC Buffer Length should be a multiple of the number of ADC channels"); +_Static_assert((IO_ADC_BUF_LEN / 2) % ADC_CHANNEL_COUNT == 0, "ADC Buffer Length divided by two should be a multiple of the number of ADC channels"); + +typedef struct +{ + adcState_E adcState; + uint32_t adcBuffer[IO_ADC_BUF_LEN]; + simpleFilter_S adcData[ADC_CHANNEL_COUNT]; +} io_S; + + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +static io_S io; + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +/** + * @brief Stores the public IO struct + */ +IO_S IO; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void IO_unpackADCBuffer(void); + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief IO Module Init function + */ +static void IO_init(void) +{ + memset(&io, 0x00, sizeof(io)); + memset(&IO, 0x00, sizeof(IO)); +} + +static void IO10Hz_PRD(void) +{ + if (io.adcState == ADC_STATE_INIT) + { + io.adcState = ADC_STATE_CALIBRATION; + if (HW_ADC_calibrate(&hadc1) && HW_ADC_calibrate(&hadc2)) + { + HW_ADC_startDMA(&hadc1, (uint32_t*)&io.adcBuffer, IO_ADC_BUF_LEN); + io.adcState = ADC_STATE_RUNNING; + } + else + { + io.adcState = ADC_STATE_CALIBRATION_FAILED; + } + } + else if (io.adcState == ADC_STATE_CALIBRATION_FAILED) + { + // adc calibration failed + // what do now? + } + else if (io.adcState == ADC_STATE_RUNNING) + { + IO_unpackADCBuffer(); + IO.mcu_temp = (io.adcData[ADC_MCU_TEMP].value / ADC_MAX_VAL) * VREF; + } +} + +/** + * @brief IO Module descriptor + */ +const ModuleDesc_S IO_desc = { + .moduleInit = &IO_init, + .periodic10Hz_CLK = &IO10Hz_PRD, +}; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Unpack ADC buffer + */ +void IO_unpackADCBuffer(void) +{ + for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) + { + io.adcData[i].raw = 0; + io.adcData[i].count = 0; + } + + for (uint16_t i = 0; i < IO_ADC_BUF_LEN; i++) + { + if (i % 2 == 0) + { + } + else + { + io.adcData[ADC_MCU_TEMP].raw += io.adcBuffer[i] & 0xffff; + io.adcData[ADC_MCU_TEMP].count++; + } + } + + io.adcData[ADC_MCU_TEMP].value = (float32_t)io.adcData[ADC_MCU_TEMP].raw / io.adcData[ADC_MCU_TEMP].count; +} diff --git a/components/vc/front/src/Module_componentSpecific.c b/components/vc/front/src/Module_componentSpecific.c new file mode 100644 index 00000000..6f25f4c0 --- /dev/null +++ b/components/vc/front/src/Module_componentSpecific.c @@ -0,0 +1,27 @@ +/** + * @file Module.c + * @brief Source code for Module Manager + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Module Header */ +#include "Module.h" + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +/** + * @brief Modules run by the Module Manager. Order will apply to execution. + */ +const ModuleDesc_S* modules[] = { + &IO_desc, +#if APP_UDS + &UDS_desc, +#endif + &CANIO_rx, + &CANIO_tx, +}; diff --git a/components/vc/front/src/SystemManager.c b/components/vc/front/src/SystemManager.c new file mode 100644 index 00000000..29aa1c1c --- /dev/null +++ b/components/vc/front/src/SystemManager.c @@ -0,0 +1,107 @@ +/** + * @file SystemManager.c + * @brief Runs the Embedded System. Contains main called by the startup assembly. + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Firmware Includes */ +#include "HW.h" +#include "HW_adc.h" +#include "HW_can.h" +#include "HW_clock.h" +#include "HW_dma.h" +#include "HW_gpio.h" +#include "HW_tim.h" + +/**< FreeRTOS Includes */ +#include "FreeRTOS.h" +#include "FreeRTOS_SWI.h" +#include "task.h" + +/**< Other Includes */ +#include "Module.h" + +#include "LIB_app.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern void RTOS_createResources(void); + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +// defined by linker +extern const uint32_t __app_start_addr; +extern const uint32_t __app_end_addr; +extern const uint32_t __app_crc_addr; + +__attribute__((section(".appDescriptor"))) +const lib_app_appDesc_S appDesc = { + .appStart = (const uint32_t)&__app_start_addr, + .appEnd = (const uint32_t)&__app_end_addr, + // .appCrcLocation = (const uint32_t)&__app_crc_addr, + .appCrcLocation = (const uint32_t)&__app_end_addr, + .appComponentId = APP_COMPONENT_ID, + .appPcbaId = APP_PCBA_ID, +}; + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Main function called by the bootloader + * + * @retval none + */ +int main(void) +{ + /**< Setup HAL Reset all peripherals. Initializes the Flash interface and the Systick. */ + HW_init(); + + /**< Configure system clocks */ + HW_systemClockConfig(); + + /**< Initiate Firmware */ + /**< Order is important, don't change without checking */ + HW_TIM_init(); + HW_CAN_init(); + HW_DMA_init(); + HW_ADC_init(); + HW_GPIO_init(); + + ///**< Create RTOS Tasks, Timers, etc... */ + RTOS_SWI_Init(); + RTOS_createResources(); + + ///**< Initialize Modules */ + Module_Init(); + + ///**< Start RTOS task scheduler. Should never return */ + vTaskStartScheduler(); + + return 0; +} + +/** + * @brief This function is executed in case of error occurrence. + */ +void Error_Handler(void) +{ + __disable_irq(); + + /**< Fast Toggle LED */ + while (1) + { + uint32_t cnt = 6400000; + HW_GPIO_togglePin(HW_GPIO_LED); + while (cnt--) + ; + } +} diff --git a/components/vc/front/src/UDS.c b/components/vc/front/src/UDS.c new file mode 100644 index 00000000..d7241e08 --- /dev/null +++ b/components/vc/front/src/UDS.c @@ -0,0 +1,291 @@ +/* + * UDS.c + * UDS module implementation + */ + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "FeatureDefines_generated.h" +#if APP_UDS + +#ifndef ISO_TP_USER_DEBUG_ENABLED +#define ISO_TP_USER_DEBUG_ENABLED 0U +#endif + +// module include +#include "UDS.h" + +// other includes +#include "CAN/CanTypes.h" +#include "FreeRTOS.h" +#include "HW.h" +#include "HW_can.h" +#include "ModuleDesc.h" +#include "task.h" +#include "uds.h" +#include "LIB_app.h" +#include "Utility.h" + +// system includes +#include + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern uint16_t isotp_user_send_can(const uint32_t id, const uint8_t data[], const uint8_t len); +extern uint32_t isotp_user_get_ms(void); +#if ISO_TP_USER_DEBUG_ENABLED +extern void isotp_user_debug(const char* message, ...); +#endif + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +// typedef struct +// { +// } uds_S; + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +// static uds_S uds; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/* + * UDS_init + * @brief initialize the UDS module + */ +static void UDS_init(void) +{ + udsSrv_init(); // initialize the UDS library +} + +/* + * UDS_periodic + * @brief periodic UDS function. Needs to be called at 1kHz + */ +static void UDS_periodic_1kHz(void) +{ + udsSrv_periodic(); +} + + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +// module description +// TODO: right now there are no UDS operations that will really block for anything. +// If ever that changes, UDS should probably get its own dedicated task +const ModuleDesc_S UDS_desc = { + .moduleInit = &UDS_init, + .periodic1kHz_CLK = &UDS_periodic_1kHz, +}; + + +/****************************************************************************** + * U D S L I B R A R Y C A L L B A C K S + ******************************************************************************/ + +/* + * uds_cb_ecuReset + * @brief callback for uds ecu reset service + */ +void uds_cb_ecuReset(udsResetType_E resetType) +{ + switch (resetType) + { + case UDS_RESET_TYPE_HARD: + // have to send positive response from here since this function + // won't return in this case + uds_sendPositiveResponse(UDS_SID_ECU_RESET, resetType, NULL, 0U); + + // one day we can have an actual check here to see if the ecu is ready to reset + // i.e. check eeprom writes finished, etc. + vTaskDelay(pdMS_TO_TICKS(10U)); + + // Reset + // FIXME: move this to a function somewhere + { + HW_systemHardReset(); + + // loop while we wait for the reset to happen + while (1) + { + __asm__ volatile ("nop"); + } + } + break; + + case UDS_RESET_TYPE_KEY: + case UDS_RESET_TYPE_SOFT: + case UDS_RESET_RAPID_SHUTDOWN_ENABLE: + case UDS_RESET_RAPID_SHUTDOWN_DISABLE: + // not implemented + uds_sendNegativeResponse(UDS_SID_ECU_RESET, UDS_NRC_SUB_FUNCTION_NOT_SUPPORTED); + break; + + default: + uds_sendNegativeResponse(UDS_SID_ECU_RESET, UDS_NRC_GENERAL_REJECT); + break; + } +} + + +/* + * uds_cb_routineControl + * @brief callback for uds routine control service + */ +void uds_cb_routineControl(udsRoutineControlType_E routineControlType, uint8_t *payload, uint8_t payloadLengthBytes) +{ + UNUSED(routineControlType); + if (payloadLengthBytes < 2U) + { + uds_sendNegativeResponse(UDS_SID_ROUTINE_CONTROL, UDS_NRC_INVALID_LEN_FORMAT); + return; + } + + union + { + uint8_t u8[2U]; + uint16_t u16; + } routineId; + + memcpy(routineId.u8, payload, 2); + + switch (routineId.u16) + { + default: + uds_sendNegativeResponse(UDS_SID_ROUTINE_CONTROL, UDS_NRC_SERVICE_NOT_SUPPORTED); + break; + } +} + + +/* + * uds_cb_DIDRead + * @brief callback for a data ID read + */ +void uds_cb_DIDRead(uint8_t *payload, uint8_t payloadLengthBytes) +{ + if (payloadLengthBytes != 2U) + { + uds_sendNegativeResponse(UDS_SID_READ_DID, UDS_NRC_INVALID_LEN_FORMAT); + return; + } + + union + { + uint8_t u8[2U]; + uint16_t u16; + } did; + + memcpy(did.u8, payload, 2); + + switch (did.u16) + { + case 0x00: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appStart, sizeof(appDesc.appStart)); + break; + } + case 0x01: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appEnd, sizeof(appDesc.appEnd)); + break; + } + case 0x02: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appCrcLocation, sizeof(appDesc.appCrcLocation)); + break; + } + case 0x03: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&(*((uint32_t*)appDesc.appCrcLocation)), sizeof(*((uint32_t*)appDesc.appCrcLocation))); + break; + } + case 0x04: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appComponentId, sizeof(appDesc.appComponentId)); + break; + } + case 0x05: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appPcbaId, sizeof(appDesc.appPcbaId)); + break; + } + case 0x101: + { + // always respond with 0x01 since we're in the app + uint8_t data = 0x01; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, &data, 1); + break; + } + + default: + uds_sendNegativeResponse(UDS_SID_READ_DID, UDS_NRC_GENERAL_REJECT); + break; + } +} + + +/****************************************************************************** + * U D S L I B R A R Y F U N C T I O N S + ******************************************************************************/ +// define functions required for isotp library + +uint16_t isotp_user_send_can(const uint32_t id, const uint8_t data[], const uint8_t len) +{ + CAN_data_T d; + bool sent = false; + + memcpy(&d, data, len); + + if (HW_CAN_sendMsg(CAN_BUS_VEH, d, id, len)) + { + sent = true; + } + return sent; +} + + +uint32_t isotp_user_get_ms(void) +{ + return xTaskGetTickCount(); +} + + +#if ISO_TP_USER_DEBUG_ENABLED +extern void isotp_user_debug(const char* message, ...); +void isotp_user_debug(const char* message, ...) +{ + UNUSED(message); +} +#endif // ISO_TP_USER_DEBUG_ENABLED +#endif // FEATURE_UDS diff --git a/components/vc/front/src/Utility.c b/components/vc/front/src/Utility.c new file mode 100644 index 00000000..fcc03a54 --- /dev/null +++ b/components/vc/front/src/Utility.c @@ -0,0 +1,26 @@ +#include "Utility.h" + +float32_t ln(float32_t x) +{ + uint32_t bx = *(uint32_t*)(&x); + uint32_t ex = bx >> 23; + int32_t t = (int32_t)ex - (int32_t)127; + + // unsigned int s = (t < 0) ? (-t) : t; + bx = 1065353216 | (bx & 8388607); + x = *(float32_t*)(&bx); + return (float32_t)(-1.49278f + (2.11263f + (-0.729104f + 0.10969f * x) * x) * x + 0.6931471806f * (float32_t)t); +} + +uint8_t* reverse_bytes(uint8_t* in, uint8_t len) +{ + for (uint8_t i = 0; i < (len / 2); i++) + { + uint8_t tmp = in[i]; + + in[i] = in[len - i - 1]; + in[len - i - 1] = tmp; + } + + return in; +} diff --git a/components/vc/front/variants.yaml b/components/vc/front/variants.yaml new file mode 100644 index 00000000..c7ed6dc8 --- /dev/null +++ b/components/vc/front/variants.yaml @@ -0,0 +1,11 @@ +configs: + 0: + description: Front Vehicle Control Unit + options: + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/APP_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 diff --git a/components/vc/pdu/FeatureDefs.yaml b/components/vc/pdu/FeatureDefs.yaml new file mode 100644 index 00000000..9a3acabb --- /dev/null +++ b/components/vc/pdu/FeatureDefs.yaml @@ -0,0 +1,6 @@ +config: + prefix: feature + description: Feature definitions for the BMS Boss +defs: + canrx_swi: + cantx_swi: diff --git a/components/vc/pdu/FeatureSels.yaml b/components/vc/pdu/FeatureSels.yaml new file mode 100644 index 00000000..6403d5d3 --- /dev/null +++ b/components/vc/pdu/FeatureSels.yaml @@ -0,0 +1,6 @@ +featureDefs: "#/components/bms_boss/FeatureDefs.yaml" +features: + feature_cantx_swi: true + feature_canrx_swi: true + app_component_id: vcpdu + app_uds: true diff --git a/components/vc/pdu/SConscript b/components/vc/pdu/SConscript new file mode 100644 index 00000000..eb1f677e --- /dev/null +++ b/components/vc/pdu/SConscript @@ -0,0 +1,448 @@ +#!/usr/bin/python3 + +from os import makedirs +from typing import List, Optional, Tuple, Union + +from mako.template import Template +from SCons.Node import FS +from SCons.Script import Clean, Default, Depends, Dir, GetOption, Import, Return + +from site_scons.site_tools.variants import generate + +Import("PLATFORM_ENV", "NETWORK_ENV", "CONFIG_IDS") + +SRC_DIR = Dir("src") +HW_DIR= Dir("src/HW") +LIBS_DIR = Dir("#/embedded/libs") +FREERTOS_DIR = LIBS_DIR.Dir("FreeRTOS") +CMSIS_DIR = LIBS_DIR.Dir("CMSIS") + +ARTIFACT_NAME = "vcpdu" +BUILDS_DIR = Dir(f"build") +UDS_DIR = LIBS_DIR.Dir("uds") +ISOTP_DIR = LIBS_DIR.Dir("isotp") +SHARED_CODE = Dir("#/components/shared/code") +SHARED_LIBS = SHARED_CODE.Dir("libs") +SHARED_APP = SHARED_CODE.Dir("app") +SHARED_HW = SHARED_CODE.Dir("HW") +SHARED_RTOS = SHARED_CODE.Dir("RTOS") + +env = PLATFORM_ENV.Clone( + tools=[ + "gcc-arm-none-eabi", + "chip_config", + "st-flash", + "openocd", + "compilation_db", + "variants", + # "doxygen", + ] +) +rtos_env = PLATFORM_ENV.Clone(tools=["gcc-arm-none-eabi"]) + +env["OPENOCD_INTERFACE"] = "stlink" +env["OPENOCD_MCU"] = "stm32f103c8" + +common_flags = [ + "-mthumb", + "-mcpu=cortex-m3", +] + +debug_flags = [ + "-ggdb3", + "-g3", + "-Og", +] + +release_flags = [ + "-O2", +] + +if GetOption("release"): + common_flags += release_flags +else: + common_flags += debug_flags + +link_flags = [ + "-Wl,--gc-sections", + "-Wl,--relax", + "-Wl,--print-memory-usage", + # "-Wl,--print-gc-sections", + "--specs=nano.specs", + "-Icomponents/vc/pdu/include/HW" +] + +as_flags = ["-xassembler-with-cpp"] + +c_flags = [ + "-std=c11", + "-ffunction-sections", + "-fdata-sections", + "-fshort-enums", + "-funsigned-char", + "-fstack-usage", + "-nostdlib", + "-msoft-float", + "-Wall", + "-Wextra", + "-Werror", + "-Wfloat-equal", + "-Wcast-align", + "-Wlogical-op", + "-Winline", + "-Wshadow", + "-Winit-self", + "-Wmissing-prototypes", + "-Wunused-function", + "-Wpointer-arith", + "-Wno-type-limits", + "-Wno-unused-local-typedefs", + "-Wundef", + "-Wconversion", + # FIXME: When in single quotes outputs to cmdline with "" + "-include", "BuildDefines.h", # Executed one after eachother +] + +free_rtos_flags = [ + "-Wno-missing-prototypes", + "-Wno-cast-align", + "-Wno-conversion", +] + + +RTOS_INCLUDE_DIRS = [ + SHARED_RTOS, + FREERTOS_DIR.Dir("Source/include/"), + FREERTOS_DIR.Dir("Source/portable/GCC/ARM_CM3/"), + CMSIS_DIR.Dir("CMSIS/Core/Include/"), +] + +LIBS_INCLUDE_DIRS = [ + LIBS_DIR.Dir("printf"), + LIBS_DIR.Dir("atomic"), + LIBS_DIR.Dir("pack"), + UDS_DIR.Dir("include"), + ISOTP_DIR.Dir("include"), + SHARED_LIBS, + SHARED_APP, + SHARED_HW, + SHARED_RTOS, +] + +PROJECT_INCLUDE_DIRS = [ + "include/", + "include/HW/", +] +# List of component C files + +project_source_files = [ + SRC_DIR.File("SystemManager.c"), + SRC_DIR.File("Module_componentSpecific.c"), + SHARED_RTOS.File("Module.c"), + SRC_DIR.File("CANIO_componentSpecific.c"), + SHARED_APP.File("CAN/CANIO-tx.c"), + SHARED_APP.File("CAN/CANIO-rx.c"), + SRC_DIR.File("IO.c"), + SRC_DIR.File("Utility.c"), + SRC_DIR.File("UDS.c"), + SHARED_LIBS.File("LIB_app.c"), +] + +project_hw_files = [ + HW_DIR.File("HW.c"), + HW_DIR.File("HW_adc.c"), + HW_DIR.File("HW_can_componentSpecific.c"), + HW_DIR.File("HW_gpio_componentSpecific.c"), + HW_DIR.File("HW_dma.c"), + HW_DIR.File("HW_intc.c"), + HW_DIR.File("HW_msp.c"), + HW_DIR.File("HW_tim.c"), + SHARED_HW.File("HW_can.c"), + SHARED_HW.File("HW_gpio.c"), +] + +project_source_files += project_hw_files + +rtos_source_files = [ + SHARED_RTOS.File("FreeRTOSResources.c"), + SHARED_RTOS.File("FreeRTOS_SWI.c"), + FREERTOS_DIR.File("Source/croutine.c"), + FREERTOS_DIR.File("Source/event_groups.c"), + FREERTOS_DIR.File("Source/list.c"), + FREERTOS_DIR.File("Source/queue.c"), + FREERTOS_DIR.File("Source/tasks.c"), + FREERTOS_DIR.File("Source/timers.c"), + FREERTOS_DIR.File("Source/portable/GCC/ARM_CM3/port.c"), + # FREERTOS_DIR.File("Source/stream_buffer.c"), + # FREERTOS_DIR.File("Source/portable/MemMang/heap_4.c"), +] + +uds_srcs = [ + ISOTP_DIR.File("isotp.c"), + UDS_DIR.File("src/udsServer.c"), +] + +def render_generated_files(options, renderer, output_dir): + targets = [] + if options is None: + return + + for template in renderer: + renderer = Template(filename=template.abspath) + rendered = renderer.render(**options) + if not isinstance(rendered, str): + raise Exception("Mako rendering didn't produce a str to write to the file") + + file = ( + output_dir.File(template.name) + .target_from_source(prefix="", suffix="") + .abspath + ) + + with open(file, "w") as out_fd: + out_fd.write(rendered) + + targets.append(file) + return targets + +def create_output_file_path( + variant_dir: FS.Dir, + file: FS.File, + new_ext: str, + target_dir: Optional[str] = None, +) -> str: + fn = file.target_from_source(prefix="", suffix=new_ext).name + + if target_dir: + return variant_dir.Dir(target_dir).File(fn) + + return variant_dir.Dir("/".join(file.path.split("/")[2:-1]) + "/").File(fn) + + +def compile_objects( + env, + files: List[Union[FS.File, Tuple[FS.File, List[str]]]], + variant_dir: FS.Dir, + target_dir: Optional[str] = None, + **kwargs, +) -> List[FS.File]: + objs = [] + flags = env["CCFLAGS"] + for src in files: + if isinstance(src, tuple): + src_file = src[0] + these_flags = flags + src[1] + elif isinstance(src, FS.File): + src_file = src + these_flags = flags + else: + raise Exception( + "Source file should either be a 'File' \ + object or a tuple of a 'File' and a list of extra flags to compile with" + ) + + target = create_output_file_path(variant_dir, src_file, ".obj", target_dir) + objs.append( + env.Object(target=target, source=src_file, CCFLAGS=these_flags, **kwargs) + ) + return objs + +renderers = { + "buildDefs": [File("renderers/BuildDefines_generated.h.mako")], + "featureDefs": [File("#/shared/renderers/mako/FeatureDefines_generated.h.mako")], +} + +chip_config = env.ChipConfig(config_file="include/HW/stm32f105.yaml") +configs = env.GenerateVariants(File("variants.yaml"), CONFIG_IDS) +elfs = [] +binaries = [] +binaries_crced = [] +asms = [] + +for config_id, config in configs.items(): + config_env = env.Clone() + c_flags.extend(chip_config.get("defines", [])) + DRIVERS_INCLUDE_DIRS = [ + chip_config["cmsis_includes"], + chip_config["hal_includes"], + ] + platform_source_files = [] + # add driver source files + platform_source_files.extend( + [(src[0], src[1] + ["-Wno-inline"]) for src in chip_config["sources"]] + ) + feature_selections = [] + feature_selections += config["features"]["selections"] + feature_selections_files = [] + for file in feature_selections: + feature_selections_files += [ File(file) ] + + variant_dir = BUILDS_DIR.Dir( + "_".join(config["description"].split(" ")) + f"_{config_id}" + ) + generated_dir = variant_dir.Dir("generated") + config_env.Append( + LINKFLAGS=f"-I{generated_dir.abspath}", + ) + makedirs(generated_dir.abspath, exist_ok=True) + + generated_sources = NETWORK_ENV.GenerateNodes({ f"vcpdu": generated_dir, }) + + features = {"features": config_env.GenerateFeatures(feature_selections_files, config["features"]["overrides"]) } + generated_features = render_generated_files(features, renderers["featureDefs"], generated_dir) + + build_options = {} + build_options["config"] = config["options"] + build_options["configId"] = config_id + generated_defs = render_generated_files(build_options, renderers["buildDefs"], generated_dir) + + ## actually compile stuff + proj_include_dirs = PROJECT_INCLUDE_DIRS + [generated_dir] + + paths = ( + RTOS_INCLUDE_DIRS + DRIVERS_INCLUDE_DIRS + proj_include_dirs + LIBS_INCLUDE_DIRS + ) + + config_env.Append( + ASFLAGS=as_flags, + CPPPATH=paths, + CCFLAGS=common_flags + c_flags, + LINKSCRIPT=chip_config["linker_file"], + LINKFLAGS=c_flags + link_flags + common_flags, + ) + + uds_env = config_env.Clone() + uds_env.Append( + CCFLAGS=[ + "-Wno-missing-prototypes", + "-Wno-unused-parameter", + "-DBYTE_ORDER=_BYTE_ORDER", + "-DLITTLE_ENDIAN=_LITTLE_ENDIAN", + "-Wno-inline", + "-Wno-conversion", + "-Wno-undef", + ] + ) + + rtos_env.Append( + CPPPATH=paths, + CCFLAGS=common_flags + c_flags + free_rtos_flags, + ) + + objs = [] # store objects here + + # compile platform files + objs.extend( + compile_objects( + config_env, + platform_source_files, + variant_dir=variant_dir, + target_dir="embedded/", + CPPPATH=paths + [generated_dir], + ) + ) + + # compile rtos source files + objs.extend( + compile_objects( + rtos_env, + rtos_source_files, + variant_dir=variant_dir, + target_dir="FreeRTOS/", + CPPPATH=paths + [generated_dir], + ) + ) + + # compile project source files + objs.extend( + compile_objects( + config_env, + project_source_files, + variant_dir=variant_dir, + CPPPATH=paths + [generated_dir] + ) + ) + + # compile UDS source files + objs.extend(compile_objects(uds_env, uds_srcs, variant_dir=variant_dir, target_dir="uds/")) + + gen_env = config_env.Clone() + gen_env.Append( + CCFLAGS=[ + "-Wno-inline", + "-Wno-conversion", + ] + ) + gen_srcs = [] + for generated_source in generated_sources: + gen_srcs += [generated_dir.File(generated_source)] + objs.extend( + compile_objects( + gen_env, + gen_srcs, + variant_dir=variant_dir, + target_dir=variant_dir.Dir("generated/obj"), + CPPPATH=paths + [generated_dir], + ) + ) + + # link all the compiled objects into an elf + elf, map = config_env.Program( + variant_dir.File(ARTIFACT_NAME + ".elf"), + objs, + MAPFILE=variant_dir.File(ARTIFACT_NAME + ".map"), + ) + elfs.append(elf) + Depends(elf, config_env["LINKSCRIPT"]) + Clean(elf, generated_defs) + + # generate a binary for flashing + binary = config_env.Bin(source=elf) + binaries.append(binary) + + crc_env = PLATFORM_ENV.Clone(tools=["hextools"]) + + # generate the CRCd binary + if "app_start_addr" not in env: + env["app_start_addr"] = features["features"]["defs"]["app_start_addr"] + binaries_crced.append( + crc_env.InjectMpeg2CRC(source=binary, start_addr=env["app_start_addr"]) + ) + + # Generate compile_commands.json + config_env["COMPILATIONDB_PATH_FILTER"] = "*/" + variant_dir.name + "/*" + compile_db = config_env.CompilationDatabase(variant_dir.File("compile_commands.json")) + Depends(compile_db, objs) + # generate it by default + Default(compile_db) + # add an alias to _only_ generate the compilation database + config_env.Alias("compiledb", compile_db) + +Default(binaries_crced) + +# build doxygen files for this component +#env.Alias("docs", env.Doxygen("doxygen_stw.conf")) +#env.Depends("docs", project_source_files) +#env.Clean("docs", Dir("docs")) + +# Return artifacts to the caller +artifacts = {} +if len(binaries) == 1: + artifacts["FLASHABLE_ARTIFACT"] = { + "artifact": binaries_crced[0], + "addr": env["app_start_addr"], + "tools": ["st-flash"], + } + +if len(elfs) == 1: + artifacts["DEBUG_ARTIFACT"] = { + "artifact": elfs[0], + "args": [], + "tools": ["gcc-arm-none-eabi", "openocd"], + "env": { + "OPENOCD_INTERFACE": "stlink", + "OPENOCD_MCU": "stm32f103c8", + }, + } + +Return("artifacts") diff --git a/components/vc/pdu/include/CANIO_componentSpecific.h b/components/vc/pdu/include/CANIO_componentSpecific.h new file mode 100644 index 00000000..27a54844 --- /dev/null +++ b/components/vc/pdu/include/CANIO_componentSpecific.h @@ -0,0 +1,39 @@ +/** + RX_config* CAN.h + * Header file for CANRX configuration + */ + +#pragma once + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// imports for timebase +#include "HW_tim.h" + +// imports for CAN generated types +#include "CANTypes_generated.h" + +// imports for data access +#include "Module.h" + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define CANIO_UDS_BUFFER_LENGTH 8U +#define CANIO_getTimeMs() (HW_TIM_getTimeMS()) + +#define set_taskUsage1kHz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1kHz_TASK)); +#define set_taskUsage100Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_100Hz_TASK)); +#define set_taskUsage10Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_10Hz_TASK)); +#define set_taskUsage1Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1Hz_TASK)); +#define set_taskUsageIdle(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_IDLE_TASK)); + +#include "TemporaryStubbing.h" diff --git a/components/vc/pdu/include/FreeRTOSConfig.h b/components/vc/pdu/include/FreeRTOSConfig.h new file mode 100644 index 00000000..3975aab6 --- /dev/null +++ b/components/vc/pdu/include/FreeRTOSConfig.h @@ -0,0 +1,162 @@ +/* + * FreeRTOS Kernel V10.0.1 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * These parameters and more are described within the 'configuration' section of the + * FreeRTOS API documentation available on the FreeRTOS.org web site. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +// Section where include file can be added + +// #if (defined(__ARMCC_VERSION) || defined(GNUC) || defined(ICCARM)) +// # include "RTE_Components.h" +// # include CMSIS_device_header +// #endif + +// Ensure definitions are only used by the compiler, and not by the assembler. +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) +# include +extern uint32_t SystemCoreClock; +#endif +#define configUSE_PREEMPTION (1) +#define configSUPPORT_STATIC_ALLOCATION (1) +#define configSUPPORT_DYNAMIC_ALLOCATION (0) +#define configUSE_IDLE_HOOK (0) +#define configUSE_TICK_HOOK (0) +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES (16) +#define configMAX_TASK_NAME_LEN (16) +#define configUSE_16_BIT_TICKS (0) +#define configUSE_MUTEXES (1) +#define configQUEUE_REGISTRY_SIZE (0) +#define configUSE_RECURSIVE_MUTEXES (1) +#define configUSE_COUNTING_SEMAPHORES (1) +#define configENABLE_BACKWARD_COMPATIBILITY (0) +#define configUSE_PORT_OPTIMISED_TASK_SELECTION (1) +#define configGENERATE_RUN_TIME_STATS (1) +#define configUSE_TRACE_FACILITY (1) + +/**< Used for RTOS profiling */ +extern void HW_TIM_configureRunTimeStatsTimer(void); +extern uint64_t HW_TIM_getBaseTick(void); +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() HW_TIM_configureRunTimeStatsTimer() +#define portGET_RUN_TIME_COUNTER_VALUE() (uint32_t)HW_TIM_getBaseTick() + +#define configSTACK_DEPTH_TYPE UBaseType_t +#define configMINIMAL_STACK_SIZE (256) +#define configIDLE_TASK_STACK_DEPTH (128) + +// heap is not used because dynamic allocation disabled +#define configAPPLICATION_ALLOCATED_HEAP (0) +#define configTOTAL_HEAP_SIZE ((size_t)3072) + +// Co-routine definitions. +#define configUSE_CO_ROUTINES (0) +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +// Software timer definitions. +#define configUSE_TIMERS (1) +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#define configTIMER_QUEUE_LENGTH (10) +#define configTIMER_TASK_STACK_DEPTH (128) + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet (1) +#define INCLUDE_uxTaskPriorityGet (1) +#define INCLUDE_vTaskDelete (1) +#define INCLUDE_vTaskCleanUpResources (0) +#define INCLUDE_vTaskSuspend (1) +#define INCLUDE_vTaskDelayUntil (1) +#define INCLUDE_vTaskDelay (1) +#define INCLUDE_xTaskGetSchedulerState (1) +#define INCLUDE_xTaskGetCurrentTaskHandle (1) +#define INCLUDE_xTimerPendFunctionCall (1) +#define INCLUDE_xQueueGetMutexHolder (1) +#define INCLUDE_uxTaskGetStackHighWaterMark (1) +#define INCLUDE_eTaskGetState (1) + +// Cortex-M specific definitions. +#ifdef __NVIC_PRIO_BITS +// __BVIC_PRIO_BITS will be specified when CMSIS is being used. +# define configPRIO_BITS __NVIC_PRIO_BITS +#else +# define configPRIO_BITS 4 +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" + * function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY (15) + +/* The highest interrupt priority that can be used by any interrupt service + * routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + * INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + * PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (5) + +/* Interrupt priorities used by the kernel port layer itself. These are generic + * to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/**< Define conversion from us to ticks */ +#define pdMS_TO_TICKS(xTime) (((xTime) * configTICK_RATE_HZ) / 1000U) + +/* Normal assert() semantics without relying on the provision of an assert.h + * header file. */ +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + taskDISABLE_INTERRUPTS(); \ + for (;;) \ + ; \ + } + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS + * standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + +// Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) + +#define RTOS_EVENT_ALL 0x00000FFF +#define RTOS_EVENT_COUNT 12U + +#endif /* FREERTOS_CONFIG_H */ diff --git a/components/vc/pdu/include/HW/BuildDefines.h b/components/vc/pdu/include/HW/BuildDefines.h new file mode 100644 index 00000000..4e0672dc --- /dev/null +++ b/components/vc/pdu/include/HW/BuildDefines.h @@ -0,0 +1,20 @@ +/* + * BuildDefines.h + * + */ + +#pragma once + +#include "FeatureDefines_generated.h" +#include "BuildDefines_generated.h" + +#if (MCU_STM32_PN == FDEFS_STM32_PN_STM32F105) +#define STM32F1 +#define STM32F105xC +#else +#error "Chipset not supported" +#endif + +#if FEATURE_IS_ENABLED(MCU_STM32_USE_HAL) +#define USE_HAL_DRIVER +#endif // MCU_STM32_USE_HAL diff --git a/components/vc/pdu/include/HW/HW.h b/components/vc/pdu/include/HW/HW.h new file mode 100644 index 00000000..3b6b05b2 --- /dev/null +++ b/components/vc/pdu/include/HW/HW.h @@ -0,0 +1,36 @@ +/** + * @file HW.h + * @brief Header file for generic firmware functions + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "stm32f1xx.h" + +// System Includes +#include "LIB_Types.h" + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + HW_OK = 0x00U, + HW_ERROR = 0x01U +} HW_StatusTypeDef_E; + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +bool HW_init(void); +uint32_t HW_getTick(void); +void HW_delay(uint32_t delay); +void HW_usDelay(uint8_t us); +void HW_systemHardReset(void); +void Error_Handler(void); diff --git a/components/vc/pdu/include/HW/HW_adc.h b/components/vc/pdu/include/HW/HW_adc.h new file mode 100644 index 00000000..596dde6b --- /dev/null +++ b/components/vc/pdu/include/HW/HW_adc.h @@ -0,0 +1,58 @@ +/** + * @file HW_adc.h + * @brief Header file for ADC firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" +#include "stdbool.h" +#include "LIB_Types.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define ADC_MAX_VAL 4095U // Max integer value of ADC reading (2^12 for this chip) +#define ADC_REF_VOLTAGE 2.5F + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + BUFFER_HALF_LOWER = 0U, + BUFFER_HALF_UPPER, +} bufferHalf_E; + +typedef struct +{ + uint32_t raw; + float32_t value; + uint16_t count; +} simpleFilter_S; + + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern ADC_HandleTypeDef hadc1; +extern ADC_HandleTypeDef hadc2; +extern DMA_HandleTypeDef hdma_adc1; + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_ADC_init(void); +bool HW_ADC_calibrate(ADC_HandleTypeDef* hadc); +bool HW_ADC_startDMA(ADC_HandleTypeDef* hadc, uint32_t* data, uint32_t size); +uint16_t HW_ADC_getVFromCount(uint16_t cnt); diff --git a/components/vc/pdu/include/HW/HW_can_componentSpecific.h b/components/vc/pdu/include/HW/HW_can_componentSpecific.h new file mode 100644 index 00000000..d3012b3e --- /dev/null +++ b/components/vc/pdu/include/HW/HW_can_componentSpecific.h @@ -0,0 +1,25 @@ +/** + * @file HW_can_componentSpecific.h + * @brief Header file for component specific CAN firmware + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + CAN_TX_MAILBOX_0 = 0U, + CAN_TX_MAILBOX_1, + CAN_TX_MAILBOX_2, + CAN_TX_MAILBOX_COUNT, +} CAN_TxMailbox_E; + +typedef enum +{ + CAN_RX_FIFO_0 = 0U, + CAN_RX_FIFO_1, + CAN_RX_FIFO_COUNT, +} CAN_RxFifo_E; diff --git a/components/vc/pdu/include/HW/HW_clock.h b/components/vc/pdu/include/HW/HW_clock.h new file mode 100644 index 00000000..773727c5 --- /dev/null +++ b/components/vc/pdu/include/HW/HW_clock.h @@ -0,0 +1,67 @@ +/** + * @file HW_clock.h + * @brief Header file for clock configuration + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW.h" + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_systemClockConfig(void); + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief System Clock Configuration + */ +void HW_systemClockConfig(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; + + // Initializes the RCC Oscillators according to the specified parameters + // in the RCC_OscInitTypeDef structure. + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; /**< HSE is 8MHz */ + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; /**< PLL is 8Mhz */ + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; /**< PLL output is 64MHz */ + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + // Initializes the CPU, AHB and APB buses clocks + + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /**< SYSCLK is 64MHz */ + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /**< SYSCLK output is 64MHz */ + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; /**< APB1 is 32MHz */ + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; /**< APB2 is 64MHz */ + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8; /**< ADC is 8MHz from APB2 */ + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } +} diff --git a/components/vc/pdu/include/HW/HW_dma.h b/components/vc/pdu/include/HW/HW_dma.h new file mode 100644 index 00000000..f51bb7a7 --- /dev/null +++ b/components/vc/pdu/include/HW/HW_dma.h @@ -0,0 +1,20 @@ +/** + * @file HW_dma.h + * @brief Header file for DMA firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_DMA_init(void); diff --git a/components/vc/pdu/include/HW/HW_gpio_componentSpecific.h b/components/vc/pdu/include/HW/HW_gpio_componentSpecific.h new file mode 100644 index 00000000..3e1f27fa --- /dev/null +++ b/components/vc/pdu/include/HW/HW_gpio_componentSpecific.h @@ -0,0 +1,20 @@ +/** + * @file HW_gpio_componentSpecific.h + * @brief Header file for GPIO firmware component specific + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + HW_GPIO_CAN1_RX = 0U, + HW_GPIO_CAN1_TX, + HW_GPIO_CAN2_RX, + HW_GPIO_CAN2_TX, + HW_GPIO_LED, + HW_GPIO_COUNT, +} HW_GPIO_pinmux_E; diff --git a/components/vc/pdu/include/HW/HW_intc.h b/components/vc/pdu/include/HW/HW_intc.h new file mode 100644 index 00000000..3dc99f02 --- /dev/null +++ b/components/vc/pdu/include/HW/HW_intc.h @@ -0,0 +1,35 @@ +/** + * @file HW_intc.h + * @brief Header file for STM32F1xx Cortex M3 Interrupts + */ + +#pragma once + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +#include "stm32f1xx.h" + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void DebugMon_Handler(void); + +void DMA1_Channel1_IRQHandler(void); +void ADC1_2_IRQHandler(void); +void TIM1_TRG_COM_IRQHandler(void); +void TIM2_IRQHandler(void); +void TIM1_CC_IRQHandler(void); + +void CAN1_SCE_IRQHandler(void); +void CAN1_TX_IRQHandler(void); +void CAN1_RX0_IRQHandler(void); +void CAN1_RX1_IRQHandler(void); + +void CAN2_SCE_IRQHandler(void); +void CAN2_TX_IRQHandler(void); +void CAN2_RX0_IRQHandler(void); +void CAN2_RX1_IRQHandler(void); diff --git a/components/vc/pdu/include/HW/HW_tim.h b/components/vc/pdu/include/HW/HW_tim.h new file mode 100644 index 00000000..22e450a2 --- /dev/null +++ b/components/vc/pdu/include/HW/HW_tim.h @@ -0,0 +1,25 @@ +/** + * @file HW_tim.h + * @brief Header file for TIM firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "stm32f1xx_hal.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +HAL_StatusTypeDef HW_TIM_init(void); +void HW_TIM_configureRunTimeStatsTimer(void); +uint32_t HW_TIM_getTick(void); +uint32_t HW_TIM_getTimeMS(void); +void HW_TIM_incBaseTick(void); +uint64_t HW_TIM_getBaseTick(void); diff --git a/components/vc/pdu/include/HW/SystemConfig.h b/components/vc/pdu/include/HW/SystemConfig.h new file mode 100644 index 00000000..f389823a --- /dev/null +++ b/components/vc/pdu/include/HW/SystemConfig.h @@ -0,0 +1,31 @@ +/** + * @file SystemConfig.h + * @brief Define System Configuration + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW.h" + +// FreeRTOS Includes +#include "FreeRTOSConfig.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// System altering defines +#define USE_FULL_LL_DRIVER + +// NVIC interrupt priorities, lower number is higher priority +// tick interrupt is highest priority +#define DMA_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 4U +#define ADC_IRQ_PRIO DMA_IRQ_PRIO + 1U +#define CAN_RX_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 6U +#define CAN_TX_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 8U +#define EXTI_IRQ_PRIO ADC_IRQ_PRIO diff --git a/components/vc/pdu/include/HW/stm32f105.yaml b/components/vc/pdu/include/HW/stm32f105.yaml new file mode 100644 index 00000000..0f366998 --- /dev/null +++ b/components/vc/pdu/include/HW/stm32f105.yaml @@ -0,0 +1,24 @@ +mcu: STM32F105 +features: + controller: + definition: "#/shared/FeatureDefs/Controller_FeatureDefs.yaml" + selection: "" +linker: + useDefault: true +drivers: + hal: # required + adc: + adc_ex: + can: + cortex: # required + dma: + flash: + gpio: + i2c: + pwr: + rcc: + rcc_ex: # required + spi: + use_ll: true + tim: + tim_ex: # required with tim diff --git a/components/vc/pdu/include/HW/stm32f1xx_hal_conf.h b/components/vc/pdu/include/HW/stm32f1xx_hal_conf.h new file mode 100644 index 00000000..67bfe0aa --- /dev/null +++ b/components/vc/pdu/include/HW/stm32f1xx_hal_conf.h @@ -0,0 +1,259 @@ +/** + * @file stm32f1xx_hal_conf.h + * @brief Header file for STM32F1xx Configuration + */ + +#pragma once + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// Enable HAL modules here +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +// #define HAL_CRYP_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +// #define HAL_CAN_LEGACY_MODULE_ENABLED +// #define HAL_CEC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +// #define HAL_CRC_MODULE_ENABLED +// #define HAL_DAC_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +// #define HAL_ETH_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +// #define HAL_I2S_MODULE_ENABLED +// #define HAL_IRDA_MODULE_ENABLED +// #define HAL_IWDG_MODULE_ENABLED +// #define HAL_NOR_MODULE_ENABLED +// #define HAL_NAND_MODULE_ENABLED +// #define HAL_PCCARD_MODULE_ENABLED +// #define HAL_PCD_MODULE_ENABLED +// #define HAL_HCD_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +// #define HAL_RTC_MODULE_ENABLED +// #define HAL_SD_MODULE_ENABLED +// #define HAL_MMC_MODULE_ENABLED +// #define HAL_SDRAM_MODULE_ENABLED +// #define HAL_SMARTCARD_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 + +// Adjust Oscillator settings + +#if !defined(HSE_VALUE) +# define HSE_VALUE 8000000U // Value of the External oscillator in Hz +#endif + +#if !defined(HSE_STARTUP_TIMEOUT) +# define HSE_STARTUP_TIMEOUT 100U // Time out for HSE start up, in ms +#endif + +#if !defined(HSI_VALUE) +# define HSI_VALUE 8000000U // Value of the Internal oscillator in Hz +#endif + +#if !defined(LSI_VALUE) +# define LSI_VALUE 40000U // LSI Typical Value in Hz +#endif + +#if !defined(LSE_VALUE) +# define LSE_VALUE 32768U // Value of the External oscillator in Hz +#endif + +#if !defined(LSE_STARTUP_TIMEOUT) +# define LSE_STARTUP_TIMEOUT 5000U // Time out for LSE start up, in ms +#endif + +// ########################### System Configuration ######################### +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3000U // Value of VDD in mv +#define TICK_INT_PRIORITY 0U // tick interrupt priority (lowest by default) +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U // ADC register callback disabled +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U // CAN register callback disabled +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U // CEC register callback disabled +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U // DAC register callback disabled +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U // ETH register callback disabled +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U // HCD register callback disabled +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U // I2C register callback disabled +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U // I2S register callback disabled +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U // MMC register callback disabled +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U // NAND register callback disabled +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U // NOR register callback disabled +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U // PCCARD register callback disabled +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U // PCD register callback disabled +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U // RTC register callback disabled +#define USE_HAL_SD_REGISTER_CALLBACKS 0U // SD register callback disabled +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U // SMARTCARD register callback disabled +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U // IRDA register callback disabled +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U // SRAM register callback disabled +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U // SPI register callback disabled +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U // TIM register callback disabled +#define USE_HAL_UART_REGISTER_CALLBACKS 0U // UART register callback disabled +#define USE_HAL_USART_REGISTER_CALLBACKS 0U // USART register callback disabled +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U // WWDG register callback disabled + + +// Uncomment the line below to expanse the "assert_param" macro in the +// HAL drivers code +// #define USE_FULL_ASSERT +#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__)) + +void assert_failed(uint8_t* file, uint32_t line); +#else +# define assert_param(expr) ((void)0U) +#endif // ifdef USE_FULL_ASSERT + + +// 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 + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Include headers for enabled HAL modules + +#ifdef HAL_RCC_MODULE_ENABLED +# include "stm32f1xx_hal_rcc.h" +#endif + +#ifdef HAL_GPIO_MODULE_ENABLED +# include "stm32f1xx_hal_gpio.h" +#endif + +#ifdef HAL_EXTI_MODULE_ENABLED +# include "stm32f1xx_hal_exti.h" +#endif + +#ifdef HAL_DMA_MODULE_ENABLED +# include "stm32f1xx_hal_dma.h" +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +# include "stm32f1xx_hal_can.h" +#endif + +#ifdef HAL_CEC_MODULE_ENABLED +# include "stm32f1xx_hal_cec.h" +#endif + +#ifdef HAL_CORTEX_MODULE_ENABLED +# include "stm32f1xx_hal_cortex.h" +#endif + +#ifdef HAL_ADC_MODULE_ENABLED +# include "stm32f1xx_hal_adc.h" +#endif + +#ifdef HAL_CRC_MODULE_ENABLED +# include "stm32f1xx_hal_crc.h" +#endif + +#ifdef HAL_DAC_MODULE_ENABLED +# include "stm32f1xx_hal_dac.h" +#endif + +#ifdef HAL_FLASH_MODULE_ENABLED +# include "stm32f1xx_hal_flash.h" +#endif + +#ifdef HAL_SRAM_MODULE_ENABLED +# include "stm32f1xx_hal_sram.h" +#endif + +#ifdef HAL_NOR_MODULE_ENABLED +# include "stm32f1xx_hal_nor.h" +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +# include "stm32f1xx_hal_i2c.h" +#endif + +#ifdef HAL_IWDG_MODULE_ENABLED +# include "stm32f1xx_hal_iwdg.h" +#endif + +#ifdef HAL_PWR_MODULE_ENABLED +# include "stm32f1xx_hal_pwr.h" +#endif + +#ifdef HAL_RTC_MODULE_ENABLED +# include "stm32f1xx_hal_rtc.h" +#endif + +#ifdef HAL_PCCARD_MODULE_ENABLED +# include "stm32f1xx_hal_pccard.h" +#endif + +#ifdef HAL_SD_MODULE_ENABLED +# include "stm32f1xx_hal_sd.h" +#endif + +#ifdef HAL_NAND_MODULE_ENABLED +# include "stm32f1xx_hal_nand.h" +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +# include "stm32f1xx_hal_spi.h" +#endif + +#ifdef HAL_TIM_MODULE_ENABLED +# include "stm32f1xx_hal_tim.h" +#endif + +#ifdef HAL_UART_MODULE_ENABLED +# include "stm32f1xx_hal_uart.h" +#endif + +#ifdef HAL_USART_MODULE_ENABLED +# include "stm32f1xx_hal_usart.h" +#endif + +#ifdef HAL_IRDA_MODULE_ENABLED +# include "stm32f1xx_hal_irda.h" +#endif + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +# include "stm32f1xx_hal_smartcard.h" +#endif + +#ifdef HAL_WWDG_MODULE_ENABLED +# include "stm32f1xx_hal_wwdg.h" +#endif + +#ifdef HAL_PCD_MODULE_ENABLED +# include "stm32f1xx_hal_pcd.h" +#endif + +#ifdef HAL_HCD_MODULE_ENABLED +# include "stm32f1xx_hal_hcd.h" +#endif + +#ifdef HAL_MMC_MODULE_ENABLED +# include "stm32f1xx_hal_mmc.h" +#endif diff --git a/components/vc/pdu/include/IO.h b/components/vc/pdu/include/IO.h new file mode 100644 index 00000000..c2dae852 --- /dev/null +++ b/components/vc/pdu/include/IO.h @@ -0,0 +1,45 @@ +/** + * @file IO.h + * @brief Header file for IO Module + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" + +// Firmware Includes +#include "HW_adc.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define VREF ADC_REF_VOLTAGE /**< Shunt Diode reference voltage */ + +#define IO_ADC_BUF_LEN 192U /**< To fit the number of measurements into a time less than 100us \ + the buffer length must be less than 100us / (ADC clock freq * \ + cycles per conversion). For this firmware, there is 14 cycles \ + per conversion. Therefore the max samples per 100us is 57, which \ + rounded down to the nearest multiple of 12 is 48 */ + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef struct +{ + float32_t mcu_temp; +} IO_S; + + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern IO_S IO; diff --git a/components/vc/pdu/include/Module_componentSpecific.h b/components/vc/pdu/include/Module_componentSpecific.h new file mode 100644 index 00000000..e1ed821b --- /dev/null +++ b/components/vc/pdu/include/Module_componentSpecific.h @@ -0,0 +1,36 @@ +/** + * @file Module_componentSpecific.h + * @brief Header file for Module Manager for the component specific modules + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "ModuleDesc.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +/**< Modules */ +extern const ModuleDesc_S IO_desc; +extern const ModuleDesc_S UDS_desc; +extern const ModuleDesc_S CANIO_rx; +extern const ModuleDesc_S CANIO_tx; + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + MODULE_IO = 0x00, + MODULE_UDS, + MODULE_CANIO_tx, + MODULE_CANIO_rx, + MODULE_CNT +} Module_tasks_E; diff --git a/components/vc/pdu/include/UDS.h b/components/vc/pdu/include/UDS.h new file mode 100644 index 00000000..437dd32e --- /dev/null +++ b/components/vc/pdu/include/UDS.h @@ -0,0 +1,19 @@ +/* + * UDS.h + * UDS module header file + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "FeatureDefines_generated.h" +#if APP_UDS +// component-specific UDS configuration +#include "uds_componentSpecific.h" + +// other includes +#include "LIB_Types.h" +#endif // FEATURE_UDS diff --git a/components/vc/pdu/include/Utility.h b/components/vc/pdu/include/Utility.h new file mode 100644 index 00000000..a3edc42d --- /dev/null +++ b/components/vc/pdu/include/Utility.h @@ -0,0 +1,477 @@ +/** + * @file Utility.h + * @brief Header file for Utlity functions + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" +#include "stddef.h" +#include "string.h" + +/****************************************************************************** + * M A C R O S + ******************************************************************************/ + +// Count number of items in array +#define COUNTOF(x) ((uint16_t)(sizeof(x) / sizeof(x[0]))) // return size of an array as uint16 +// Count leading zeroes +static inline uint16_t u32CountLeadingZeroes(uint32_t x) +{ + uint16_t c = 0U; + while (((x & 0x80000000UL) == 0UL) && (c < 32U)) + { + c++; + x <<= 1UL; + } + + return c; +} + +#define VAR_IN_SECTION(s) __attribute__((section(s))) // place a given variable in the specified linker section + +#ifndef UNUSED +# define UNUSED(x) (void)x +#endif + +#define zero() (0U) + +// Join macros +// Convert token to string (doesn't expand) +#define STR(x) #x + +// Expand and convert token to string +#define XSTR(x) STR(x) + +// Join two tokens (doesn't expand) +#define DO_JOIN(x, y) x##y + +// Expand and join tokens +#define JOIN(x, y) DO_JOIN(x, y) +#define JOIN3(x, y, z) JOIN(x, JOIN(y, z)) + +// Expand and join with `_` separating tokens +#define SNAKE(x, y) JOIN3(x, _, y) +#define SNAKE3(x, y, z) SNAKE(x, SNAKE(y, z)) +#define SNAKE4(x, y, z, a) SNAKE3(x, y, SNAKE(z, a)) + +// atomic bit stuff +// FIXME: check if these compile down to one instruction +// If not, make this atomic +#define setBitAtomic(bit) ((bit) = true) +#define clearBitAtomic(bit) ((bit) = false) +#define assignBitAtomic(bit, condition) \ + do { \ + if (condition) \ + { \ + (bit) = true; \ + } \ + else \ + { \ + (bit) = false; \ + } \ + } while (zero()) + + +// FLAGS +// This should get moved elsewhere at some point +#define FLAG_bits_each 16 +#define WORDS_FROM_COUNT(count) (uint16_t)((count + (FLAG_bits_each - 1)) / FLAG_bits_each) +#define FLAG_GET_WORD(name, flag) (name[(uint16_t)flag / FLAG_bits_each]) +#define FLAG_GET_MASK(flag) (1U << ((uint16_t)flag % FLAG_bits_each)) + +#define FLAG_create(name, size) uint16_t(name)[WORDS_FROM_COUNT(size)] +#define FLAG_set(name, pos) FLAG_GET_WORD(name, pos) |= (uint16_t)FLAG_GET_MASK(pos) +#define FLAG_clear(name, pos) FLAG_GET_WORD(name, pos) &= (uint16_t)~FLAG_GET_MASK(pos) +#define FLAG_get(name, pos) ((bool)((FLAG_GET_WORD(name, pos) & FLAG_GET_MASK(pos)) == FLAG_GET_MASK(pos))) +#define FLAG_assign(name, pos, value) \ + do { \ + if (value) \ + { \ + FLAG_set(name, pos); \ + } \ + else \ + { \ + FLAG_clear(name, pos); \ + } \ + } while (zero()) + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/* + * FLAG_setAll + * @brief Sets all of the flags in the given flag word + * @param name Flag word name + * @param count Number of flags in the given flag + */ +static inline void FLAG_setAll(uint16_t* name, uint16_t count) +{ + uint16_t numWords = WORDS_FROM_COUNT(count); + uint16_t extraBits = count % FLAG_bits_each; + + if (numWords > 1U) + { + memset(name, 0xFF, (uint16_t)(numWords * FLAG_bits_each)); + } + if (extraBits > 0U) + { + name[numWords] |= (0xFF >> (FLAG_bits_each - extraBits)); + } +} + + +/* + * FLAG_clearAll + * @brief clears all of the bits in the given flag + * @param name Flag word name + * @param count Number of bits in the given flag + */ +static inline void FLAG_clearAll(uint16_t* name, uint16_t count) +{ + memset(name, 0x00, (uint16_t)(WORDS_FROM_COUNT(count) * FLAG_bits_each)); +} + + +/* + * FLAG_any + * @brief check if any of the flags in the flag word is set + * @param name Flag word name + * @param count Number of flags in the given flag + */ +static inline bool FLAG_any(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0U) + { + return true; + } + } + return false; +} + + +/* + * FLAG_all + * @brief checks if all flags in the flag word are set + * @param name Flag word name + * @param count Number of bits in the given flag word + */ +static inline bool FLAG_all(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0xFF) + { + return false; + } + } + return true; +} + + +/* + * FLAG_none + * @brief checks if none of the flags in the flag word are set + * @param name Flag word name + * @param count Number of bits in the given flag word + */ +static inline bool FLAG_none(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0U) + { + return false; + } + } + return true; +} + +static inline uint8_t reverse_byte(uint8_t x) +{ + static const uint8_t table[] = { + 0x00, + 0x80, + 0x40, + 0xc0, + 0x20, + 0xa0, + 0x60, + 0xe0, + 0x10, + 0x90, + 0x50, + 0xd0, + 0x30, + 0xb0, + 0x70, + 0xf0, + 0x08, + 0x88, + 0x48, + 0xc8, + 0x28, + 0xa8, + 0x68, + 0xe8, + 0x18, + 0x98, + 0x58, + 0xd8, + 0x38, + 0xb8, + 0x78, + 0xf8, + 0x04, + 0x84, + 0x44, + 0xc4, + 0x24, + 0xa4, + 0x64, + 0xe4, + 0x14, + 0x94, + 0x54, + 0xd4, + 0x34, + 0xb4, + 0x74, + 0xf4, + 0x0c, + 0x8c, + 0x4c, + 0xcc, + 0x2c, + 0xac, + 0x6c, + 0xec, + 0x1c, + 0x9c, + 0x5c, + 0xdc, + 0x3c, + 0xbc, + 0x7c, + 0xfc, + 0x02, + 0x82, + 0x42, + 0xc2, + 0x22, + 0xa2, + 0x62, + 0xe2, + 0x12, + 0x92, + 0x52, + 0xd2, + 0x32, + 0xb2, + 0x72, + 0xf2, + 0x0a, + 0x8a, + 0x4a, + 0xca, + 0x2a, + 0xaa, + 0x6a, + 0xea, + 0x1a, + 0x9a, + 0x5a, + 0xda, + 0x3a, + 0xba, + 0x7a, + 0xfa, + 0x06, + 0x86, + 0x46, + 0xc6, + 0x26, + 0xa6, + 0x66, + 0xe6, + 0x16, + 0x96, + 0x56, + 0xd6, + 0x36, + 0xb6, + 0x76, + 0xf6, + 0x0e, + 0x8e, + 0x4e, + 0xce, + 0x2e, + 0xae, + 0x6e, + 0xee, + 0x1e, + 0x9e, + 0x5e, + 0xde, + 0x3e, + 0xbe, + 0x7e, + 0xfe, + 0x01, + 0x81, + 0x41, + 0xc1, + 0x21, + 0xa1, + 0x61, + 0xe1, + 0x11, + 0x91, + 0x51, + 0xd1, + 0x31, + 0xb1, + 0x71, + 0xf1, + 0x09, + 0x89, + 0x49, + 0xc9, + 0x29, + 0xa9, + 0x69, + 0xe9, + 0x19, + 0x99, + 0x59, + 0xd9, + 0x39, + 0xb9, + 0x79, + 0xf9, + 0x05, + 0x85, + 0x45, + 0xc5, + 0x25, + 0xa5, + 0x65, + 0xe5, + 0x15, + 0x95, + 0x55, + 0xd5, + 0x35, + 0xb5, + 0x75, + 0xf5, + 0x0d, + 0x8d, + 0x4d, + 0xcd, + 0x2d, + 0xad, + 0x6d, + 0xed, + 0x1d, + 0x9d, + 0x5d, + 0xdd, + 0x3d, + 0xbd, + 0x7d, + 0xfd, + 0x03, + 0x83, + 0x43, + 0xc3, + 0x23, + 0xa3, + 0x63, + 0xe3, + 0x13, + 0x93, + 0x53, + 0xd3, + 0x33, + 0xb3, + 0x73, + 0xf3, + 0x0b, + 0x8b, + 0x4b, + 0xcb, + 0x2b, + 0xab, + 0x6b, + 0xeb, + 0x1b, + 0x9b, + 0x5b, + 0xdb, + 0x3b, + 0xbb, + 0x7b, + 0xfb, + 0x07, + 0x87, + 0x47, + 0xc7, + 0x27, + 0xa7, + 0x67, + 0xe7, + 0x17, + 0x97, + 0x57, + 0xd7, + 0x37, + 0xb7, + 0x77, + 0xf7, + 0x0f, + 0x8f, + 0x4f, + 0xcf, + 0x2f, + 0xaf, + 0x6f, + 0xef, + 0x1f, + 0x9f, + 0x5f, + 0xdf, + 0x3f, + 0xbf, + 0x7f, + 0xff, + }; + return table[x]; +} + +uint8_t* reverse_bytes(uint8_t* in, uint8_t len); + +/** + * @brief Simple fast accurate natural log approximation + * + * @note Lingdong Huang, 2020, Public Domain + * @note Floating point bit hacking + * Remez Algorithm + * x=m*2^p => ln(x)=ln(m)+ln(2)p* + * + * @param x Number to calculate ln of + * + * @retval result of ln(x) + */ +float ln(float x); diff --git a/components/vc/pdu/include/uds_componentSpecific.h b/components/vc/pdu/include/uds_componentSpecific.h new file mode 100644 index 00000000..c8b81853 --- /dev/null +++ b/components/vc/pdu/include/uds_componentSpecific.h @@ -0,0 +1,27 @@ +/* + * uds_componentSpecific.h + * Component-specific defines for the UDS library + */ +#pragma once + +#include "NetworkDefines_generated.h" +#include "FeatureDefines_generated.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#if APP_UDS +#define UDS_ENABLE_LIB APP_UDS + +#define UDS_REQUEST_ID CAN_VEH_UDSCLIENT_vcpduUdsRequest_ID +#define UDS_RESPONSE_ID CAN_VEH_VCPDU_udsResponse_ID + +#define ISOTP_TX_BUF_SIZE 128U // [bytes] mostly arbitrary +#define ISOTP_RX_BUF_SIZE 128U // [bytes] maximum size of a multi-frame ISOTP transaction (mostly arbitrary, increase if necessary) + +// supported UDS services +#define UDS_SERVICE_SUPPORTED_ECU_RESET true +#define UDS_SERVICE_SUPPORTED_ROUTINE_CONTROL true +#define UDS_SERVICE_SUPPORTED_DID_READ true +#endif // FEATURE_UDS diff --git a/components/vc/pdu/renderers/BuildDefines_generated.h.mako b/components/vc/pdu/renderers/BuildDefines_generated.h.mako new file mode 100644 index 00000000..38a1d744 --- /dev/null +++ b/components/vc/pdu/renderers/BuildDefines_generated.h.mako @@ -0,0 +1,8 @@ +/* + * BuildDefines_generated.h + * + */ + +#pragma once + +#define VCPDU_CONFIG_ID ${configId}U diff --git a/components/vc/pdu/src/CANIO_componentSpecific.c b/components/vc/pdu/src/CANIO_componentSpecific.c new file mode 100644 index 00000000..91dc880f --- /dev/null +++ b/components/vc/pdu/src/CANIO_componentSpecific.c @@ -0,0 +1,32 @@ +/** + RX_config* CAN.h + * Header file for CANRX configuration + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "CAN/CAN.h" +#include "CANIO_componentSpecific.h" +#include "Utility.h" +#include "MessageUnpack_generated.h" + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +void CANRX_unpackMessage(CAN_bus_E bus, uint32_t id, CAN_data_T *data) +{ + switch (bus) + { + case CAN_BUS_BODY: + CANRX_BODY_unpackMessage(id, data); + break; + case CAN_BUS_VEH: + CANRX_VEH_unpackMessage(id, data); + break; + default: + break; + } +} diff --git a/components/vc/pdu/src/HW/HW.c b/components/vc/pdu/src/HW/HW.c new file mode 100644 index 00000000..dff17f3d --- /dev/null +++ b/components/vc/pdu/src/HW/HW.c @@ -0,0 +1,91 @@ +/** + * @file HW.c + * @brief Source code for generic firmware functions + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Header file +#include "HW.h" + +// System Includes +#include "stdbool.h" + +// Firmware Includes +#include "stm32f1xx.h" +#include "HW_tim.h" + +typedef struct +{ + volatile uint32_t const CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint32_t SHPR[3]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; +} SCB_regMap; +#define pSCB ((SCB_regMap*)SCB_BASE) + +#define AIRCR_RESET (0x05FA0000UL) +#define AIRCR_RESET_REQ (AIRCR_RESET | 0x04UL) + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +/** + * @brief Initializes the generic low-level firmware + * + * @retval Always true + */ +bool HW_init(void) +{ + return HAL_Init() == HAL_OK; +} + +/** + * @brief Get the number of ticks since clock start + * + * @retval Number of ticks + */ +uint32_t HW_getTick(void) +{ + return HAL_GetTick(); +} + +/** + * @brief Delay the execution in blocking mode for amount of ticks + * + * @param delay Number of ticks to delay in blocking mode + */ +void HW_delay(uint32_t delay) +{ + HAL_Delay(delay); +} + +/** + * @brief This function is blocking and should be avoided + * + * @param us Microsecond blocking delay + */ +void HW_usDelay(uint8_t us) +{ + uint64_t us_start = HW_TIM_getBaseTick(); + + while (HW_TIM_getBaseTick() < us_start + us); +} + +void HW_systemHardReset(void) +{ + pSCB->AIRCR = AIRCR_RESET_REQ; +} diff --git a/components/vc/pdu/src/HW/HW_adc.c b/components/vc/pdu/src/HW/HW_adc.c new file mode 100644 index 00000000..73c7785a --- /dev/null +++ b/components/vc/pdu/src/HW/HW_adc.c @@ -0,0 +1,203 @@ +/** + * @file HW_adc.c + * @brief Source code for ADC firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// FreeRTOS Includes +#include "FreeRTOS.h" +#include "task.h" + +// System Inlcudes +#include "string.h" + +// Firmware Includes +#include "HW_adc.h" + +// Other Includes +#include "IO.h" +#include "SystemConfig.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES 2U +#define ADC_CALIBRATION_TIMEOUT 10U + +#define ADC_MAX_COUNT 4095 + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +ADC_HandleTypeDef hadc1; +ADC_HandleTypeDef hadc2; +DMA_HandleTypeDef hdma_adc1; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_ADC_unpackBuffer(bufferHalf_E half); + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Init function for ADC firmware + */ +void HW_ADC_init(void) +{ + ADC_MultiModeTypeDef multimode = { 0 }; + ADC_ChannelConfTypeDef sConfig = { 0 }; + + // Cell Measurement config + hadc1.Instance = ADC1; + hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc1.Init.ContinuousConvMode = ENABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + multimode.Mode = ADC_DUALMODE_REGSIMULT; + if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) + { + Error_Handler(); + } + + // Configure Regular Channels + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + hadc2.Instance = ADC2; + hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc2.Init.ContinuousConvMode = ENABLE; + hadc2.Init.DiscontinuousConvMode = DISABLE; + hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc2.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc2) != HAL_OK) + { + Error_Handler(); + } + + // Configure Regular Channels + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5; + if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + HAL_ADC_Start(&hadc2); +} + +/** + * @brief Callback for STM32 HAL once ADC initialization is complete + * + * @param adcHandle pointer to ADC peripheral + */ +void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) +{ + if (adcHandle->Instance == ADC1) + { + // ADC1 clock enable + __HAL_RCC_ADC1_CLK_ENABLE(); + + // ADC1 DMA Init + // ADC1 Init + hdma_adc1.Instance = DMA1_Channel1; + hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + hdma_adc1.Init.Mode = DMA_CIRCULAR; + hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM; + if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(adcHandle, DMA_Handle, hdma_adc1); + + HAL_NVIC_SetPriority(ADC1_2_IRQn, ADC_IRQ_PRIO, 0U); + HAL_NVIC_EnableIRQ(ADC1_2_IRQn); + } + else if (adcHandle->Instance == ADC2) + { + // ADC1 clock enable + __HAL_RCC_ADC2_CLK_ENABLE(); + } +} + +/** + * @brief STM32 HAL callback. Called once de-init is complete + * + * @param adcHandle Pointer to ADC peripheral + */ +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) +{ + if (adcHandle->Instance == ADC1) + { + __HAL_RCC_ADC1_CLK_DISABLE(); + + // ADC1 DMA DeInit + HAL_DMA_DeInit(adcHandle->DMA_Handle); + } + if (adcHandle->Instance == ADC2) + { + // Peripheral clock disable + __HAL_RCC_ADC2_CLK_DISABLE(); + } +} + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Firmware function to initiate ADC calibration. + * + * @param hadc Pointer to ADC peripheral + * + * @retval true = Success, false = Failure + */ +bool HW_ADC_calibrate(ADC_HandleTypeDef* hadc) +{ + return HAL_ADCEx_Calibration_Start(hadc) == HAL_OK; +} + +/** + * @brief Firmware function to start DMA transfer + * + * @param hadc Pointer to ADC peripheral + * @param data Pointer to memory start address + * @param size Size of buffer + * + * @retval true = Success, false = Failure + */ +bool HW_ADC_startDMA(ADC_HandleTypeDef* hadc, uint32_t* data, uint32_t size) +{ + return HAL_ADCEx_MultiModeStart_DMA(hadc, data, size) == HAL_OK; +} diff --git a/components/vc/pdu/src/HW/HW_can_componentSpecific.c b/components/vc/pdu/src/HW/HW_can_componentSpecific.c new file mode 100644 index 00000000..362572ab --- /dev/null +++ b/components/vc/pdu/src/HW/HW_can_componentSpecific.c @@ -0,0 +1,410 @@ +/** + * @file HW_can.c + * @brief Source code for CAN firmware + */ + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "HW_can.h" + +#include "HW.h" +#include "stdint.h" +#include "SystemConfig.h" + +#include "CAN/CAN.h" +#include "CAN/CanTypes.h" + +#include "NetworkDefines_generated.h" +#include "MessageUnpack_generated.h" +#include "uds.h" +#include "uds_componentSpecific.h" +#include "LIB_app.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// which CAN interrupts we want to enable +// stm32f1xx_hal_can.h from ST drivers for description of each one +// Description of interrupts: +// CAN_IER_TMEIE Transmit Mailbox Empty +// CAN_IER_FMPIEx FIFO x Message Pending (RX FIFO) +// CAN_IER_FFIEx FIFO x Full +// CAN_IER_FOVIEx FIFO x Overrun +// CAN_IER_WKUIE Wakeup Interrupt +// CAN_IER_SLKIE Sleep Interrupt +// CAN_IER_EWGIE Error Warning Interrupt +// CAN_IER_EPVIE Error Passive Interrupt +// CAN_IER_BOFIE Bus Off Interrupt +// CAN_IER_LECIE Last Error Code Interrupt +// CAN_IER_ERRIE Error Interrupt +#define CAN_ENABLED_INTERRUPTS (CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_FFIE0 | \ + CAN_IER_FFIE1 | CAN_IER_FOVIE0 | CAN_IER_FOVIE1 | CAN_IER_EWGIE | \ + CAN_IER_EPVIE | CAN_IER_BOFIE | CAN_IER_LECIE | CAN_IER_ERRIE) + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +CAN_HandleTypeDef hcan[CAN_BUS_COUNT]; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +static inline CAN_bus_E HW_CAN_getBusFromPeripheral(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = 0U; + + for (CAN_bus_E i = 0U; i < CAN_BUS_COUNT; i++) + { + if (&hcan[i] == canHandle) + { + bus = i; + i = CAN_BUS_COUNT; + } + } + + return bus; +} + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * HW_CAN_sendMsgBus0 + * @param priority TODO + * @param data TODO + * @param id TODO + * @param len TODO + * @return TODO + */ +bool HW_CAN_sendMsg(CAN_bus_E bus, CAN_data_T data, uint32_t id, uint8_t len) +{ + CAN_TxMessage_T msg = {0}; + + msg.id = id; + msg.data = data; + msg.lengthBytes = len; + msg.IDE = (id <= 0x7ff) ? CAN_IDENTIFIER_STD : CAN_IDENTIFIER_EXT; + + return HW_CAN_sendMsgOnPeripheral(bus, msg) == HW_OK; +} + +/** + * HW_CAN_Init + * initialize the CAN peripheral + */ +HW_StatusTypeDef_E HW_CAN_init(void) +{ + hcan[CAN_BUS_VEH].Instance = CAN1; + hcan[CAN_BUS_CHEST].Instance = CAN2; + for (CAN_bus_E bus = 0U; bus < CAN_BUS_COUNT; bus++) + { + hcan[bus].Init.Mode = CAN_MODE_NORMAL; + hcan[bus].Init.TimeTriggeredMode = DISABLE; + hcan[bus].Init.AutoBusOff = ENABLE; + hcan[bus].Init.AutoWakeUp = DISABLE; + hcan[bus].Init.AutoRetransmission = ENABLE; + hcan[bus].Init.ReceiveFifoLocked = DISABLE; + hcan[bus].Init.TransmitFifoPriority = DISABLE; + + switch(CAN_busConfig[bus].baudrate) + { + case CAN_BAUDRATE_1MBIT: + hcan[bus].Init.Prescaler = 4; + hcan[bus].Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan[bus].Init.TimeSeg1 = CAN_BS1_6TQ; + hcan[bus].Init.TimeSeg2 = CAN_BS2_1TQ; + break; + case CAN_BAUDRATE_500KBIT: + hcan[bus].Init.Prescaler = 4; + hcan[bus].Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan[bus].Init.TimeSeg1 = CAN_BS1_12TQ; + hcan[bus].Init.TimeSeg2 = CAN_BS2_3TQ; + break; + default: + return HW_ERROR; + } + + if (HAL_CAN_Init(&hcan[bus]) != HAL_OK) + { + Error_Handler(); + } + } + + _Static_assert(((COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4) + (COUNTOF(CANRX_VEH_unpackListExtID) / 2U) + + ((COUNTOF(CANRX_CHEST_unpackList) + ((4U - COUNTOF(CANRX_CHEST_unpackList) % 4U) % 4U)) / 4) + (COUNTOF(CANRX_CHEST_unpackListExtID) / 2U) + <= CAN_FILTERBANK_LENGTH, "Too many CAN filter bank's used"); + uint8_t filterBank = 0U; + for (uint32_t i = 0U; i < COUNTOF(CANRX_VEH_unpackList); i += 4U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_16BIT; + // All filters are shifted left 5 bits + filt.FilterIdHigh = CANRX_VEH_unpackList[i + 0U] << 5U; + if ((i + 1U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterIdLow = CANRX_VEH_unpackList[i + 1U] << 5U; } + if ((i + 2U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterMaskIdHigh = CANRX_VEH_unpackList[i + 2U] << 5U; } + if ((i + 3U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterMaskIdLow = CANRX_VEH_unpackList[i + 3U] << 5U; } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_VEH], &filt); + } + for (uint32_t i = 0U; i < COUNTOF(CANRX_VEH_unpackListExtID); i+= 2U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_32BIT; + // All filters are fucky - lookup RM0008 information + filt.FilterIdHigh = (uint16_t)(CANRX_VEH_unpackListExtID[i + 0U] >> 13U); + filt.FilterIdLow = (uint16_t)(CANRX_VEH_unpackListExtID[i + 0U] << 3U) | (0x01 << 2U); + if ((i + 1U) < COUNTOF(CANRX_VEH_unpackListExtID)) { + filt.FilterMaskIdHigh = (uint16_t)(CANRX_VEH_unpackListExtID[i + 1U] >> 13U); + filt.FilterMaskIdLow = (uint16_t)(CANRX_VEH_unpackListExtID[i + 1U] << 3U) | (0x01 << 2U); + } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_VEH], &filt); + } + HAL_CAN_ActivateNotification(&hcan[CAN_BUS_VEH], CAN_ENABLED_INTERRUPTS); + + for (uint32_t i = 0U; i < COUNTOF(CANRX_CHEST_unpackList); i += 4U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_16BIT; + // All filters are shifted left 5 bits + filt.FilterIdHigh = CANRX_CHEST_unpackList[i + 0U] << 5U; + if ((i + 1U) < COUNTOF(CANRX_CHEST_unpackList)) { filt.FilterIdLow = CANRX_CHEST_unpackList[i + 1U] << 5U; } + if ((i + 2U) < COUNTOF(CANRX_CHEST_unpackList)) { filt.FilterMaskIdHigh = CANRX_CHEST_unpackList[i + 2U] << 5U; } + if ((i + 3U) < COUNTOF(CANRX_CHEST_unpackList)) { filt.FilterMaskIdLow = CANRX_CHEST_unpackList[i + 3U] << 5U; } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_CHEST], &filt); + } + for (uint32_t i = 0U; i < COUNTOF(CANRX_CHEST_unpackListExtID); i+= 2U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_32BIT; + // All filters are fucky - lookup RM0008 information + filt.FilterIdHigh = (uint16_t)(CANRX_CHEST_unpackListExtID[i + 0U] >> 13U); + filt.FilterIdLow = (uint16_t)(CANRX_CHEST_unpackListExtID[i + 0U] << 3U) | (0x01 << 2U); + if ((i + 1U) < COUNTOF(CANRX_CHEST_unpackListExtID)) { + filt.FilterMaskIdHigh = (uint16_t)(CANRX_CHEST_unpackListExtID[i + 1U] >> 13U); + filt.FilterMaskIdLow = (uint16_t)(CANRX_CHEST_unpackListExtID[i + 1U] << 3U) | (0x01 << 2U); + } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_CHEST], &filt); + } + HAL_CAN_ActivateNotification(&hcan[CAN_BUS_CHEST], CAN_ENABLED_INTERRUPTS); + + return HW_OK; +} + +/** + * HAL_CAN_MspInit + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) +{ + if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // CAN1 clock enable + __HAL_RCC_CAN1_CLK_ENABLE(); + + HAL_NVIC_SetPriority(CAN1_SCE_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_TX_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_RX0_IRQn, CAN_RX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_RX1_IRQn, CAN_RX_IRQ_PRIO, 0U); + + HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn); + HAL_NVIC_EnableIRQ(CAN1_TX_IRQn); + HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); + HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn); + + } + else if (canHandle->Instance == hcan[CAN_BUS_CHEST].Instance) + { + __HAL_RCC_CAN2_CLK_ENABLE(); + + HAL_NVIC_SetPriority(CAN2_SCE_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_TX_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_RX0_IRQn, CAN_RX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_RX1_IRQn, CAN_RX_IRQ_PRIO, 0U); + + HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn); + HAL_NVIC_EnableIRQ(CAN2_TX_IRQn); + HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn); + } +} + +/** + * HAL_CAN_MspDeInit + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle) +{ + if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // Peripheral clock disable + __HAL_RCC_CAN1_CLK_DISABLE(); + + HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn); + HAL_NVIC_DisableIRQ(CAN1_TX_IRQn); + HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn); + HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn); + } + else if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // Peripheral clock disable + __HAL_RCC_CAN2_CLK_DISABLE(); + + HAL_NVIC_DisableIRQ(CAN2_SCE_IRQn); + HAL_NVIC_DisableIRQ(CAN2_TX_IRQn); + HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn); + } +} + +// overload default interrupt callback functions provided by HAL +/** + * HAL_CAN_TxMailbox0CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_0); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox1CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_1); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox2CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_2); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox0AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_0); +} + +/** + * HAL_CAN_TxMailbox1AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_1); +} + +/** + * HAL_CAN_TxMailbox2AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_2); +} + +/** + * HAL_CAN_RxFifo0MsgPendingCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FMPIE0); +#endif // FEATURE_CANRX_SWI + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_0); +} + +/** + * HAL_CAN_RxFifo1MsgPendingCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FMPIE1); +#endif // FEATURE_CANRX_SWI + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_1); +} + +/** + * HAL_CAN_RxFifo0FullCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_0); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FFIE0); + SWI_invokeFromISR(CANRX_swi); +#endif // FEATURE_CANRX_SWI +} + +/** + * HAL_CAN_RxFifo1FullCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_1); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FFIE1); + SWI_invokeFromISR(CANRX_swi); +#endif // FEATURE_CANRX_SWI +} + +/** + * HAL_CAN_ErrorCallback + * @param canHandle TODO + */ +void HAL_CAN_ErrorCallback(CAN_HandleTypeDef* canHandle) +{ + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_ERRIE); +} diff --git a/components/vc/pdu/src/HW/HW_dma.c b/components/vc/pdu/src/HW/HW_dma.c new file mode 100644 index 00000000..f4c5bba0 --- /dev/null +++ b/components/vc/pdu/src/HW/HW_dma.c @@ -0,0 +1,29 @@ +/** + * @file HW_dma.c + * @brief Source code for DMA firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "HW_dma.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Firmware DMA Initialization function + */ +void HW_DMA_init(void) +{ + // DMA controller clock enable + __HAL_RCC_DMA1_CLK_ENABLE(); + + // DMA interrupt init + // DMA1_Channel1_IRQn interrupt configuration + HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, DMA_IRQ_PRIO, 0U); + HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); +} diff --git a/components/vc/pdu/src/HW/HW_gpio_componentSpecific.c b/components/vc/pdu/src/HW/HW_gpio_componentSpecific.c new file mode 100644 index 00000000..5d89dfca --- /dev/null +++ b/components/vc/pdu/src/HW/HW_gpio_componentSpecific.c @@ -0,0 +1,54 @@ +/** + * @file HW_gpio_componentSpecific.c + * @brief Source code for GPIO firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW_gpio.h" + +const HW_GPIO_S HW_GPIO_pinmux[HW_GPIO_COUNT] = { + [HW_GPIO_CAN1_RX] = { + .port = GPIOB, + .pin = GPIO_PIN_8, + .mode = GPIO_MODE_INPUT, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_NOSET, + }, + [HW_GPIO_CAN1_TX] = { + .port = GPIOB, + .pin = GPIO_PIN_9, + .mode = GPIO_MODE_AF_PP, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINSET, + }, + [HW_GPIO_CAN2_RX] = { + .port = GPIOB, + .pin = GPIO_PIN_12, + .mode = GPIO_MODE_INPUT, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_NOSET, + }, + [HW_GPIO_CAN2_TX] = { + .port = GPIOB, + .pin = GPIO_PIN_13, + .mode = GPIO_MODE_AF_PP, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINSET, + }, + [HW_GPIO_LED] = { + .port = GPIOB, + .pin = GPIO_PIN_8, + .mode = GPIO_MODE_OUTPUT_PP, + .speed = GPIO_SPEED_FREQ_LOW, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINRESET, + }, +}; diff --git a/components/vc/pdu/src/HW/HW_intc.c b/components/vc/pdu/src/HW/HW_intc.c new file mode 100644 index 00000000..4d8fb29e --- /dev/null +++ b/components/vc/pdu/src/HW/HW_intc.c @@ -0,0 +1,172 @@ +/** + * @file HW_intc.c + * @brief Source code for STM32F1xx Cortex M3 Interrupts + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW_intc.h" +#include "NetworkDefines_generated.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern ADC_HandleTypeDef hadc1; +extern ADC_HandleTypeDef hadc2; +extern DMA_HandleTypeDef hdma_adc1; +extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim4; +extern TIM_HandleTypeDef htim2; +extern CAN_HandleTypeDef hcan[CAN_BUS_COUNT]; + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + volatile uint8_t c = 0; + + while (c == 0) + { + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ +} + +// Peripheral Interrupt Handlers + +/** + * @brief This function handles DMA1 channel1 global interrupt. + */ +void DMA1_Channel1_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_adc1); +} + +void ADC1_2_IRQHandler(void) +{ + HAL_ADC_IRQHandler(&hadc1); + // HAL_ADC_IRQHandler(&hadc2); +} + +void TIM2_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim2); +} + +void TIM1_TRG_COM_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim1); +} + +void TIM1_CC_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim1); +} + +// CAN interrupts +void CAN1_SCE_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_TX_IRQHandler + * + */ +void CAN1_TX_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_RX0_IRQHandler + * + */ +void CAN1_RX0_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_RX1_IRQHandler + * + */ +void CAN1_RX1_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +void CAN2_SCE_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_CHEST]); +} + +void CAN2_TX_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_CHEST]); +} + +void CAN2_RX0_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_CHEST]); +} + +void CAN2_RX1_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_CHEST]); +} diff --git a/components/vc/pdu/src/HW/HW_msp.c b/components/vc/pdu/src/HW/HW_msp.c new file mode 100644 index 00000000..e43824a5 --- /dev/null +++ b/components/vc/pdu/src/HW/HW_msp.c @@ -0,0 +1,30 @@ +/** + * @file HW_msp.c + * @brief Source code for generic Msp firmware calls + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" + + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Overrides weak HAL Link for our implementation + */ +void HAL_MspInit(void) +{ + __HAL_RCC_AFIO_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); + + // Enable SWD, disable JTAG + __HAL_AFIO_REMAP_SWJ_NOJTAG(); +} diff --git a/components/vc/pdu/src/HW/HW_tim.c b/components/vc/pdu/src/HW/HW_tim.c new file mode 100644 index 00000000..9deec4eb --- /dev/null +++ b/components/vc/pdu/src/HW/HW_tim.c @@ -0,0 +1,264 @@ +/** + * @file HW_tim.c + * @brief Source code for TIM firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" +#include "LIB_Types.h" + +// Firmware Includes +#include "HW_tim.h" + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim2; + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called TIMx interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) +{ + if (htim->Instance == TIM2) + { + HAL_IncTick(); + } +} + +/** + * @brief Initializes TIM peripherals + * + * @retval true = Success, false = Failure + */ +HAL_StatusTypeDef HW_TIM_init(void) +{ + TIM_ClockConfigTypeDef sClockSourceConfig = { 0 }; + TIM_SlaveConfigTypeDef sSlaveConfig = { 0 }; + TIM_IC_InitTypeDef sConfigIC = { 0 }; + TIM_MasterConfigTypeDef sMasterConfig = { 0 }; + + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock = 0; + uint32_t uwPrescalerValue = 0; + uint32_t pFLatency; + + // Get clock configuration + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + // Compute TIM4 clock + uwTimclock = 2 * HAL_RCC_GetPCLK2Freq(); + // Compute the prescaler value to have TIM4 counter clock equal to 1MHz + uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U); + + htim1.Instance = TIM1; + htim1.Init.Prescaler = uwPrescalerValue; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 1000000000; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_IC_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; + sSlaveConfig.InputTrigger = TIM_TS_TI2FP2; + sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; + sSlaveConfig.TriggerFilter = 0; + if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; + sConfigIC.ICFilter = 0; + if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; + sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; + if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + // Configure the TIM4 IRQ priority + HAL_NVIC_SetPriority(TIM1_CC_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_BRK_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_UP_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, TICK_INT_PRIORITY, 0); + + // Enable the TIM4 global Interrupt + HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + HAL_NVIC_EnableIRQ(TIM1_BRK_IRQn); + HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); + HAL_NVIC_EnableIRQ(TIM1_TRG_COM_IRQn); + + HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2); // main channel + HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1); // indirect channel + + return HAL_OK; +} + +/** + * @brief HAL callback once Initialization is complete. Used for GPIO/INTERRUPT configuration + * + * @param htim_base TIM peripheral + */ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim) +{ + if (tim->Instance == TIM1) + { + __HAL_RCC_TIM1_CLK_ENABLE(); + } +} + +/** + * @brief HAL callback called once an input capture has triggered + * + * @param htim TIM peripheral + */ +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) +{ + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) // If the interrupt is triggered by channel 1 + { + } +} + +/** + * @brief RTOS callback to configure a more precise timebase for cpu profiling + */ +void HW_TIM_configureRunTimeStatsTimer(void) +{ +} + +/** + * @brief RTOS Profiling has a ~1us accuracy by using the OS CLK and internal counter + * + * @retval Elapsed time in us from clock start + */ +uint64_t HW_TIM_getBaseTick() +{ + // return fast_clk; + + return ((uint64_t)HW_getTick() * 1000) + htim2.Instance->CNT; +} + +/** + * @brief Get the number of ticks since clock start + * + * @retval Number of ticks + */ +uint32_t HW_TIM_getTick(void) +{ + return HAL_GetTick(); +} + +uint32_t HW_TIM_getTimeMS() +{ + return HW_TIM_getTick(); +} + +/** + * HAL_InitTick + * This function configures the TIM4 as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority Tick interrupt priority. + * @return exit status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock = 0; + uint32_t uwPrescalerValue = 0; + uint32_t pFLatency; + + // Configure the TIM4 IRQ priority + HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority, 0); + + // Enable the TIM4 global Interrupt + HAL_NVIC_EnableIRQ(TIM2_IRQn); + + // Enable TIM4 clock + __HAL_RCC_TIM2_CLK_ENABLE(); + + // Get clock configuration + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + + // Compute TIM2 clock + uwTimclock = 1 * HAL_RCC_GetPCLK2Freq(); + // Compute the prescaler value to have TIM4 counter clock equal to 1MHz + uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U); + + // Initialize TIM4 + htim2.Instance = TIM2; + + // Initialize TIMx peripheral as follow: + // Period = [(TIM4CLK/1000) - 1]. to have a (1/1000) s time base. + // Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. + // ClockDivision = 0 + // Counter direction = Up + htim2.Init.Period = (1000000U / 1000) - 1U; + htim2.Init.Prescaler = uwPrescalerValue; + htim2.Init.ClockDivision = 0; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + + if (HAL_TIM_Base_Init(&htim2) == HAL_OK) + { + // Start the TIM time Base generation in interrupt mode + return HAL_TIM_Base_Start_IT(&htim2); + } + + return HAL_ERROR; +} + +/** + * @brief Suspends the tick interrupt + */ +void HAL_SuspendTick(void) +{ + __HAL_TIM_DISABLE_IT(&htim2, TIM_IT_UPDATE); +} + + +/** + * @brief Resumes tick interrupt + */ +void HAL_ResumeTick(void) +{ + __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE); +} diff --git a/components/vc/pdu/src/IO.c b/components/vc/pdu/src/IO.c new file mode 100644 index 00000000..c875dc70 --- /dev/null +++ b/components/vc/pdu/src/IO.c @@ -0,0 +1,161 @@ +/** + * @file IO.c + * @brief Source code for IO Module + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Module Header */ +#include "IO.h" + +/**< System Includes*/ +#include "LIB_Types.h" +#include + +/**< Firmware Includes */ +#include "HW.h" +#include "HW_adc.h" +#include "HW_dma.h" +#include "HW_gpio.h" + +/**< Other Includes */ +#include "ModuleDesc.h" +#include "Utility.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + ADC_STATE_INIT = 0, + ADC_STATE_CALIBRATION, + ADC_STATE_RUNNING, + ADC_STATE_CALIBRATION_FAILED, + ADC_STATE_COUNT, +} adcState_E; + +typedef enum +{ + ADC_MCU_TEMP, + ADC_MCU_TEMP_temporary, + ADC_CHANNEL_COUNT, +} adcChannels_E; +_Static_assert(IO_ADC_BUF_LEN % ADC_CHANNEL_COUNT == 0, "ADC Buffer Length should be a multiple of the number of ADC channels"); +_Static_assert((IO_ADC_BUF_LEN / 2) % ADC_CHANNEL_COUNT == 0, "ADC Buffer Length divided by two should be a multiple of the number of ADC channels"); + +typedef struct +{ + adcState_E adcState; + uint32_t adcBuffer[IO_ADC_BUF_LEN]; + simpleFilter_S adcData[ADC_CHANNEL_COUNT]; +} io_S; + + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +static io_S io; + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +/** + * @brief Stores the public IO struct + */ +IO_S IO; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void IO_unpackADCBuffer(void); + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief IO Module Init function + */ +static void IO_init(void) +{ + memset(&io, 0x00, sizeof(io)); + memset(&IO, 0x00, sizeof(IO)); +} + +static void IO10Hz_PRD(void) +{ + if (io.adcState == ADC_STATE_INIT) + { + io.adcState = ADC_STATE_CALIBRATION; + if (HW_ADC_calibrate(&hadc1) && HW_ADC_calibrate(&hadc2)) + { + HW_ADC_startDMA(&hadc1, (uint32_t*)&io.adcBuffer, IO_ADC_BUF_LEN); + io.adcState = ADC_STATE_RUNNING; + } + else + { + io.adcState = ADC_STATE_CALIBRATION_FAILED; + } + } + else if (io.adcState == ADC_STATE_CALIBRATION_FAILED) + { + // adc calibration failed + // what do now? + } + else if (io.adcState == ADC_STATE_RUNNING) + { + IO_unpackADCBuffer(); + IO.mcu_temp = (io.adcData[ADC_MCU_TEMP].value / ADC_MAX_VAL) * VREF; + } +} + +/** + * @brief IO Module descriptor + */ +const ModuleDesc_S IO_desc = { + .moduleInit = &IO_init, + .periodic10Hz_CLK = &IO10Hz_PRD, +}; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Unpack ADC buffer + */ +void IO_unpackADCBuffer(void) +{ + for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) + { + io.adcData[i].raw = 0; + io.adcData[i].count = 0; + } + + for (uint16_t i = 0; i < IO_ADC_BUF_LEN; i++) + { + if (i % 2 == 0) + { + } + else + { + io.adcData[ADC_MCU_TEMP].raw += io.adcBuffer[i] & 0xffff; + io.adcData[ADC_MCU_TEMP].count++; + } + } + + io.adcData[ADC_MCU_TEMP].value = (float32_t)io.adcData[ADC_MCU_TEMP].raw / io.adcData[ADC_MCU_TEMP].count; +} diff --git a/components/vc/pdu/src/Module_componentSpecific.c b/components/vc/pdu/src/Module_componentSpecific.c new file mode 100644 index 00000000..6f25f4c0 --- /dev/null +++ b/components/vc/pdu/src/Module_componentSpecific.c @@ -0,0 +1,27 @@ +/** + * @file Module.c + * @brief Source code for Module Manager + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Module Header */ +#include "Module.h" + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +/** + * @brief Modules run by the Module Manager. Order will apply to execution. + */ +const ModuleDesc_S* modules[] = { + &IO_desc, +#if APP_UDS + &UDS_desc, +#endif + &CANIO_rx, + &CANIO_tx, +}; diff --git a/components/vc/pdu/src/SystemManager.c b/components/vc/pdu/src/SystemManager.c new file mode 100644 index 00000000..29aa1c1c --- /dev/null +++ b/components/vc/pdu/src/SystemManager.c @@ -0,0 +1,107 @@ +/** + * @file SystemManager.c + * @brief Runs the Embedded System. Contains main called by the startup assembly. + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Firmware Includes */ +#include "HW.h" +#include "HW_adc.h" +#include "HW_can.h" +#include "HW_clock.h" +#include "HW_dma.h" +#include "HW_gpio.h" +#include "HW_tim.h" + +/**< FreeRTOS Includes */ +#include "FreeRTOS.h" +#include "FreeRTOS_SWI.h" +#include "task.h" + +/**< Other Includes */ +#include "Module.h" + +#include "LIB_app.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern void RTOS_createResources(void); + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +// defined by linker +extern const uint32_t __app_start_addr; +extern const uint32_t __app_end_addr; +extern const uint32_t __app_crc_addr; + +__attribute__((section(".appDescriptor"))) +const lib_app_appDesc_S appDesc = { + .appStart = (const uint32_t)&__app_start_addr, + .appEnd = (const uint32_t)&__app_end_addr, + // .appCrcLocation = (const uint32_t)&__app_crc_addr, + .appCrcLocation = (const uint32_t)&__app_end_addr, + .appComponentId = APP_COMPONENT_ID, + .appPcbaId = APP_PCBA_ID, +}; + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Main function called by the bootloader + * + * @retval none + */ +int main(void) +{ + /**< Setup HAL Reset all peripherals. Initializes the Flash interface and the Systick. */ + HW_init(); + + /**< Configure system clocks */ + HW_systemClockConfig(); + + /**< Initiate Firmware */ + /**< Order is important, don't change without checking */ + HW_TIM_init(); + HW_CAN_init(); + HW_DMA_init(); + HW_ADC_init(); + HW_GPIO_init(); + + ///**< Create RTOS Tasks, Timers, etc... */ + RTOS_SWI_Init(); + RTOS_createResources(); + + ///**< Initialize Modules */ + Module_Init(); + + ///**< Start RTOS task scheduler. Should never return */ + vTaskStartScheduler(); + + return 0; +} + +/** + * @brief This function is executed in case of error occurrence. + */ +void Error_Handler(void) +{ + __disable_irq(); + + /**< Fast Toggle LED */ + while (1) + { + uint32_t cnt = 6400000; + HW_GPIO_togglePin(HW_GPIO_LED); + while (cnt--) + ; + } +} diff --git a/components/vc/pdu/src/UDS.c b/components/vc/pdu/src/UDS.c new file mode 100644 index 00000000..d7241e08 --- /dev/null +++ b/components/vc/pdu/src/UDS.c @@ -0,0 +1,291 @@ +/* + * UDS.c + * UDS module implementation + */ + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "FeatureDefines_generated.h" +#if APP_UDS + +#ifndef ISO_TP_USER_DEBUG_ENABLED +#define ISO_TP_USER_DEBUG_ENABLED 0U +#endif + +// module include +#include "UDS.h" + +// other includes +#include "CAN/CanTypes.h" +#include "FreeRTOS.h" +#include "HW.h" +#include "HW_can.h" +#include "ModuleDesc.h" +#include "task.h" +#include "uds.h" +#include "LIB_app.h" +#include "Utility.h" + +// system includes +#include + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern uint16_t isotp_user_send_can(const uint32_t id, const uint8_t data[], const uint8_t len); +extern uint32_t isotp_user_get_ms(void); +#if ISO_TP_USER_DEBUG_ENABLED +extern void isotp_user_debug(const char* message, ...); +#endif + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +// typedef struct +// { +// } uds_S; + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +// static uds_S uds; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/* + * UDS_init + * @brief initialize the UDS module + */ +static void UDS_init(void) +{ + udsSrv_init(); // initialize the UDS library +} + +/* + * UDS_periodic + * @brief periodic UDS function. Needs to be called at 1kHz + */ +static void UDS_periodic_1kHz(void) +{ + udsSrv_periodic(); +} + + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +// module description +// TODO: right now there are no UDS operations that will really block for anything. +// If ever that changes, UDS should probably get its own dedicated task +const ModuleDesc_S UDS_desc = { + .moduleInit = &UDS_init, + .periodic1kHz_CLK = &UDS_periodic_1kHz, +}; + + +/****************************************************************************** + * U D S L I B R A R Y C A L L B A C K S + ******************************************************************************/ + +/* + * uds_cb_ecuReset + * @brief callback for uds ecu reset service + */ +void uds_cb_ecuReset(udsResetType_E resetType) +{ + switch (resetType) + { + case UDS_RESET_TYPE_HARD: + // have to send positive response from here since this function + // won't return in this case + uds_sendPositiveResponse(UDS_SID_ECU_RESET, resetType, NULL, 0U); + + // one day we can have an actual check here to see if the ecu is ready to reset + // i.e. check eeprom writes finished, etc. + vTaskDelay(pdMS_TO_TICKS(10U)); + + // Reset + // FIXME: move this to a function somewhere + { + HW_systemHardReset(); + + // loop while we wait for the reset to happen + while (1) + { + __asm__ volatile ("nop"); + } + } + break; + + case UDS_RESET_TYPE_KEY: + case UDS_RESET_TYPE_SOFT: + case UDS_RESET_RAPID_SHUTDOWN_ENABLE: + case UDS_RESET_RAPID_SHUTDOWN_DISABLE: + // not implemented + uds_sendNegativeResponse(UDS_SID_ECU_RESET, UDS_NRC_SUB_FUNCTION_NOT_SUPPORTED); + break; + + default: + uds_sendNegativeResponse(UDS_SID_ECU_RESET, UDS_NRC_GENERAL_REJECT); + break; + } +} + + +/* + * uds_cb_routineControl + * @brief callback for uds routine control service + */ +void uds_cb_routineControl(udsRoutineControlType_E routineControlType, uint8_t *payload, uint8_t payloadLengthBytes) +{ + UNUSED(routineControlType); + if (payloadLengthBytes < 2U) + { + uds_sendNegativeResponse(UDS_SID_ROUTINE_CONTROL, UDS_NRC_INVALID_LEN_FORMAT); + return; + } + + union + { + uint8_t u8[2U]; + uint16_t u16; + } routineId; + + memcpy(routineId.u8, payload, 2); + + switch (routineId.u16) + { + default: + uds_sendNegativeResponse(UDS_SID_ROUTINE_CONTROL, UDS_NRC_SERVICE_NOT_SUPPORTED); + break; + } +} + + +/* + * uds_cb_DIDRead + * @brief callback for a data ID read + */ +void uds_cb_DIDRead(uint8_t *payload, uint8_t payloadLengthBytes) +{ + if (payloadLengthBytes != 2U) + { + uds_sendNegativeResponse(UDS_SID_READ_DID, UDS_NRC_INVALID_LEN_FORMAT); + return; + } + + union + { + uint8_t u8[2U]; + uint16_t u16; + } did; + + memcpy(did.u8, payload, 2); + + switch (did.u16) + { + case 0x00: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appStart, sizeof(appDesc.appStart)); + break; + } + case 0x01: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appEnd, sizeof(appDesc.appEnd)); + break; + } + case 0x02: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appCrcLocation, sizeof(appDesc.appCrcLocation)); + break; + } + case 0x03: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&(*((uint32_t*)appDesc.appCrcLocation)), sizeof(*((uint32_t*)appDesc.appCrcLocation))); + break; + } + case 0x04: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appComponentId, sizeof(appDesc.appComponentId)); + break; + } + case 0x05: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appPcbaId, sizeof(appDesc.appPcbaId)); + break; + } + case 0x101: + { + // always respond with 0x01 since we're in the app + uint8_t data = 0x01; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, &data, 1); + break; + } + + default: + uds_sendNegativeResponse(UDS_SID_READ_DID, UDS_NRC_GENERAL_REJECT); + break; + } +} + + +/****************************************************************************** + * U D S L I B R A R Y F U N C T I O N S + ******************************************************************************/ +// define functions required for isotp library + +uint16_t isotp_user_send_can(const uint32_t id, const uint8_t data[], const uint8_t len) +{ + CAN_data_T d; + bool sent = false; + + memcpy(&d, data, len); + + if (HW_CAN_sendMsg(CAN_BUS_VEH, d, id, len)) + { + sent = true; + } + return sent; +} + + +uint32_t isotp_user_get_ms(void) +{ + return xTaskGetTickCount(); +} + + +#if ISO_TP_USER_DEBUG_ENABLED +extern void isotp_user_debug(const char* message, ...); +void isotp_user_debug(const char* message, ...) +{ + UNUSED(message); +} +#endif // ISO_TP_USER_DEBUG_ENABLED +#endif // FEATURE_UDS diff --git a/components/vc/pdu/src/Utility.c b/components/vc/pdu/src/Utility.c new file mode 100644 index 00000000..fcc03a54 --- /dev/null +++ b/components/vc/pdu/src/Utility.c @@ -0,0 +1,26 @@ +#include "Utility.h" + +float32_t ln(float32_t x) +{ + uint32_t bx = *(uint32_t*)(&x); + uint32_t ex = bx >> 23; + int32_t t = (int32_t)ex - (int32_t)127; + + // unsigned int s = (t < 0) ? (-t) : t; + bx = 1065353216 | (bx & 8388607); + x = *(float32_t*)(&bx); + return (float32_t)(-1.49278f + (2.11263f + (-0.729104f + 0.10969f * x) * x) * x + 0.6931471806f * (float32_t)t); +} + +uint8_t* reverse_bytes(uint8_t* in, uint8_t len) +{ + for (uint8_t i = 0; i < (len / 2); i++) + { + uint8_t tmp = in[i]; + + in[i] = in[len - i - 1]; + in[len - i - 1] = tmp; + } + + return in; +} diff --git a/components/vc/pdu/variants.yaml b/components/vc/pdu/variants.yaml new file mode 100644 index 00000000..2202f0c2 --- /dev/null +++ b/components/vc/pdu/variants.yaml @@ -0,0 +1,11 @@ +configs: + 0: + description: Power Distribution Unit + options: + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/APP_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 diff --git a/components/vc/rear/FeatureDefs.yaml b/components/vc/rear/FeatureDefs.yaml new file mode 100644 index 00000000..9a3acabb --- /dev/null +++ b/components/vc/rear/FeatureDefs.yaml @@ -0,0 +1,6 @@ +config: + prefix: feature + description: Feature definitions for the BMS Boss +defs: + canrx_swi: + cantx_swi: diff --git a/components/vc/rear/FeatureSels.yaml b/components/vc/rear/FeatureSels.yaml new file mode 100644 index 00000000..0316feef --- /dev/null +++ b/components/vc/rear/FeatureSels.yaml @@ -0,0 +1,6 @@ +featureDefs: "#/components/bms_boss/FeatureDefs.yaml" +features: + feature_cantx_swi: true + feature_canrx_swi: true + app_component_id: vcrear + app_uds: true diff --git a/components/vc/rear/SConscript b/components/vc/rear/SConscript new file mode 100644 index 00000000..7457f898 --- /dev/null +++ b/components/vc/rear/SConscript @@ -0,0 +1,448 @@ +#!/usr/bin/python3 + +from os import makedirs +from typing import List, Optional, Tuple, Union + +from mako.template import Template +from SCons.Node import FS +from SCons.Script import Clean, Default, Depends, Dir, GetOption, Import, Return + +from site_scons.site_tools.variants import generate + +Import("PLATFORM_ENV", "NETWORK_ENV", "CONFIG_IDS") + +SRC_DIR = Dir("src") +HW_DIR= Dir("src/HW") +LIBS_DIR = Dir("#/embedded/libs") +FREERTOS_DIR = LIBS_DIR.Dir("FreeRTOS") +CMSIS_DIR = LIBS_DIR.Dir("CMSIS") + +ARTIFACT_NAME = "vcrear" +BUILDS_DIR = Dir(f"build") +UDS_DIR = LIBS_DIR.Dir("uds") +ISOTP_DIR = LIBS_DIR.Dir("isotp") +SHARED_CODE = Dir("#/components/shared/code") +SHARED_LIBS = SHARED_CODE.Dir("libs") +SHARED_APP = SHARED_CODE.Dir("app") +SHARED_HW = SHARED_CODE.Dir("HW") +SHARED_RTOS = SHARED_CODE.Dir("RTOS") + +env = PLATFORM_ENV.Clone( + tools=[ + "gcc-arm-none-eabi", + "chip_config", + "st-flash", + "openocd", + "compilation_db", + "variants", + # "doxygen", + ] +) +rtos_env = PLATFORM_ENV.Clone(tools=["gcc-arm-none-eabi"]) + +env["OPENOCD_INTERFACE"] = "stlink" +env["OPENOCD_MCU"] = "stm32f103c8" + +common_flags = [ + "-mthumb", + "-mcpu=cortex-m3", +] + +debug_flags = [ + "-ggdb3", + "-g3", + "-Og", +] + +release_flags = [ + "-O2", +] + +if GetOption("release"): + common_flags += release_flags +else: + common_flags += debug_flags + +link_flags = [ + "-Wl,--gc-sections", + "-Wl,--relax", + "-Wl,--print-memory-usage", + # "-Wl,--print-gc-sections", + "--specs=nano.specs", + "-Icomponents/vc/pdu/include/HW" +] + +as_flags = ["-xassembler-with-cpp"] + +c_flags = [ + "-std=c11", + "-ffunction-sections", + "-fdata-sections", + "-fshort-enums", + "-funsigned-char", + "-fstack-usage", + "-nostdlib", + "-msoft-float", + "-Wall", + "-Wextra", + "-Werror", + "-Wfloat-equal", + "-Wcast-align", + "-Wlogical-op", + "-Winline", + "-Wshadow", + "-Winit-self", + "-Wmissing-prototypes", + "-Wunused-function", + "-Wpointer-arith", + "-Wno-type-limits", + "-Wno-unused-local-typedefs", + "-Wundef", + "-Wconversion", + # FIXME: When in single quotes outputs to cmdline with "" + "-include", "BuildDefines.h", # Executed one after eachother +] + +free_rtos_flags = [ + "-Wno-missing-prototypes", + "-Wno-cast-align", + "-Wno-conversion", +] + + +RTOS_INCLUDE_DIRS = [ + SHARED_RTOS, + FREERTOS_DIR.Dir("Source/include/"), + FREERTOS_DIR.Dir("Source/portable/GCC/ARM_CM3/"), + CMSIS_DIR.Dir("CMSIS/Core/Include/"), +] + +LIBS_INCLUDE_DIRS = [ + LIBS_DIR.Dir("printf"), + LIBS_DIR.Dir("atomic"), + LIBS_DIR.Dir("pack"), + UDS_DIR.Dir("include"), + ISOTP_DIR.Dir("include"), + SHARED_LIBS, + SHARED_APP, + SHARED_HW, + SHARED_RTOS, +] + +PROJECT_INCLUDE_DIRS = [ + "include/", + "include/HW/", +] +# List of component C files + +project_source_files = [ + SRC_DIR.File("SystemManager.c"), + SRC_DIR.File("Module_componentSpecific.c"), + SHARED_RTOS.File("Module.c"), + SRC_DIR.File("CANIO_componentSpecific.c"), + SHARED_APP.File("CAN/CANIO-tx.c"), + SHARED_APP.File("CAN/CANIO-rx.c"), + SRC_DIR.File("IO.c"), + SRC_DIR.File("Utility.c"), + SRC_DIR.File("UDS.c"), + SHARED_LIBS.File("LIB_app.c"), +] + +project_hw_files = [ + HW_DIR.File("HW.c"), + HW_DIR.File("HW_adc.c"), + HW_DIR.File("HW_can_componentSpecific.c"), + HW_DIR.File("HW_gpio_componentSpecific.c"), + HW_DIR.File("HW_dma.c"), + HW_DIR.File("HW_intc.c"), + HW_DIR.File("HW_msp.c"), + HW_DIR.File("HW_tim.c"), + SHARED_HW.File("HW_can.c"), + SHARED_HW.File("HW_gpio.c"), +] + +project_source_files += project_hw_files + +rtos_source_files = [ + SHARED_RTOS.File("FreeRTOSResources.c"), + SHARED_RTOS.File("FreeRTOS_SWI.c"), + FREERTOS_DIR.File("Source/croutine.c"), + FREERTOS_DIR.File("Source/event_groups.c"), + FREERTOS_DIR.File("Source/list.c"), + FREERTOS_DIR.File("Source/queue.c"), + FREERTOS_DIR.File("Source/tasks.c"), + FREERTOS_DIR.File("Source/timers.c"), + FREERTOS_DIR.File("Source/portable/GCC/ARM_CM3/port.c"), + # FREERTOS_DIR.File("Source/stream_buffer.c"), + # FREERTOS_DIR.File("Source/portable/MemMang/heap_4.c"), +] + +uds_srcs = [ + ISOTP_DIR.File("isotp.c"), + UDS_DIR.File("src/udsServer.c"), +] + +def render_generated_files(options, renderer, output_dir): + targets = [] + if options is None: + return + + for template in renderer: + renderer = Template(filename=template.abspath) + rendered = renderer.render(**options) + if not isinstance(rendered, str): + raise Exception("Mako rendering didn't produce a str to write to the file") + + file = ( + output_dir.File(template.name) + .target_from_source(prefix="", suffix="") + .abspath + ) + + with open(file, "w") as out_fd: + out_fd.write(rendered) + + targets.append(file) + return targets + +def create_output_file_path( + variant_dir: FS.Dir, + file: FS.File, + new_ext: str, + target_dir: Optional[str] = None, +) -> str: + fn = file.target_from_source(prefix="", suffix=new_ext).name + + if target_dir: + return variant_dir.Dir(target_dir).File(fn) + + return variant_dir.Dir("/".join(file.path.split("/")[2:-1]) + "/").File(fn) + + +def compile_objects( + env, + files: List[Union[FS.File, Tuple[FS.File, List[str]]]], + variant_dir: FS.Dir, + target_dir: Optional[str] = None, + **kwargs, +) -> List[FS.File]: + objs = [] + flags = env["CCFLAGS"] + for src in files: + if isinstance(src, tuple): + src_file = src[0] + these_flags = flags + src[1] + elif isinstance(src, FS.File): + src_file = src + these_flags = flags + else: + raise Exception( + "Source file should either be a 'File' \ + object or a tuple of a 'File' and a list of extra flags to compile with" + ) + + target = create_output_file_path(variant_dir, src_file, ".obj", target_dir) + objs.append( + env.Object(target=target, source=src_file, CCFLAGS=these_flags, **kwargs) + ) + return objs + +renderers = { + "buildDefs": [File("renderers/BuildDefines_generated.h.mako")], + "featureDefs": [File("#/shared/renderers/mako/FeatureDefines_generated.h.mako")], +} + +chip_config = env.ChipConfig(config_file="include/HW/stm32f105.yaml") +configs = env.GenerateVariants(File("variants.yaml"), CONFIG_IDS) +elfs = [] +binaries = [] +binaries_crced = [] +asms = [] + +for config_id, config in configs.items(): + config_env = env.Clone() + c_flags.extend(chip_config.get("defines", [])) + DRIVERS_INCLUDE_DIRS = [ + chip_config["cmsis_includes"], + chip_config["hal_includes"], + ] + platform_source_files = [] + # add driver source files + platform_source_files.extend( + [(src[0], src[1] + ["-Wno-inline"]) for src in chip_config["sources"]] + ) + feature_selections = [] + feature_selections += config["features"]["selections"] + feature_selections_files = [] + for file in feature_selections: + feature_selections_files += [ File(file) ] + + variant_dir = BUILDS_DIR.Dir( + "_".join(config["description"].split(" ")) + f"_{config_id}" + ) + generated_dir = variant_dir.Dir("generated") + config_env.Append( + LINKFLAGS=f"-I{generated_dir.abspath}", + ) + makedirs(generated_dir.abspath, exist_ok=True) + + generated_sources = NETWORK_ENV.GenerateNodes({ f"{ARTIFACT_NAME}": generated_dir, }) + + features = {"features": config_env.GenerateFeatures(feature_selections_files, config["features"]["overrides"]) } + generated_features = render_generated_files(features, renderers["featureDefs"], generated_dir) + + build_options = {} + build_options["config"] = config["options"] + build_options["configId"] = config_id + generated_defs = render_generated_files(build_options, renderers["buildDefs"], generated_dir) + + ## actually compile stuff + proj_include_dirs = PROJECT_INCLUDE_DIRS + [generated_dir] + + paths = ( + RTOS_INCLUDE_DIRS + DRIVERS_INCLUDE_DIRS + proj_include_dirs + LIBS_INCLUDE_DIRS + ) + + config_env.Append( + ASFLAGS=as_flags, + CPPPATH=paths, + CCFLAGS=common_flags + c_flags, + LINKSCRIPT=chip_config["linker_file"], + LINKFLAGS=c_flags + link_flags + common_flags, + ) + + uds_env = config_env.Clone() + uds_env.Append( + CCFLAGS=[ + "-Wno-missing-prototypes", + "-Wno-unused-parameter", + "-DBYTE_ORDER=_BYTE_ORDER", + "-DLITTLE_ENDIAN=_LITTLE_ENDIAN", + "-Wno-inline", + "-Wno-conversion", + "-Wno-undef", + ] + ) + + rtos_env.Append( + CPPPATH=paths, + CCFLAGS=common_flags + c_flags + free_rtos_flags, + ) + + objs = [] # store objects here + + # compile platform files + objs.extend( + compile_objects( + config_env, + platform_source_files, + variant_dir=variant_dir, + target_dir="embedded/", + CPPPATH=paths + [generated_dir], + ) + ) + + # compile rtos source files + objs.extend( + compile_objects( + rtos_env, + rtos_source_files, + variant_dir=variant_dir, + target_dir="FreeRTOS/", + CPPPATH=paths + [generated_dir], + ) + ) + + # compile project source files + objs.extend( + compile_objects( + config_env, + project_source_files, + variant_dir=variant_dir, + CPPPATH=paths + [generated_dir] + ) + ) + + # compile UDS source files + objs.extend(compile_objects(uds_env, uds_srcs, variant_dir=variant_dir, target_dir="uds/")) + + gen_env = config_env.Clone() + gen_env.Append( + CCFLAGS=[ + "-Wno-inline", + "-Wno-conversion", + ] + ) + gen_srcs = [] + for generated_source in generated_sources: + gen_srcs += [generated_dir.File(generated_source)] + objs.extend( + compile_objects( + gen_env, + gen_srcs, + variant_dir=variant_dir, + target_dir=variant_dir.Dir("generated/obj"), + CPPPATH=paths + [generated_dir], + ) + ) + + # link all the compiled objects into an elf + elf, map = config_env.Program( + variant_dir.File(ARTIFACT_NAME + ".elf"), + objs, + MAPFILE=variant_dir.File(ARTIFACT_NAME + ".map"), + ) + elfs.append(elf) + Depends(elf, config_env["LINKSCRIPT"]) + Clean(elf, generated_defs) + + # generate a binary for flashing + binary = config_env.Bin(source=elf) + binaries.append(binary) + + crc_env = PLATFORM_ENV.Clone(tools=["hextools"]) + + # generate the CRCd binary + if "app_start_addr" not in env: + env["app_start_addr"] = features["features"]["defs"]["app_start_addr"] + binaries_crced.append( + crc_env.InjectMpeg2CRC(source=binary, start_addr=env["app_start_addr"]) + ) + + # Generate compile_commands.json + config_env["COMPILATIONDB_PATH_FILTER"] = "*/" + variant_dir.name + "/*" + compile_db = config_env.CompilationDatabase(variant_dir.File("compile_commands.json")) + Depends(compile_db, objs) + # generate it by default + Default(compile_db) + # add an alias to _only_ generate the compilation database + config_env.Alias("compiledb", compile_db) + +Default(binaries_crced) + +# build doxygen files for this component +#env.Alias("docs", env.Doxygen("doxygen_stw.conf")) +#env.Depends("docs", project_source_files) +#env.Clean("docs", Dir("docs")) + +# Return artifacts to the caller +artifacts = {} +if len(binaries) == 1: + artifacts["FLASHABLE_ARTIFACT"] = { + "artifact": binaries_crced[0], + "addr": env["app_start_addr"], + "tools": ["st-flash"], + } + +if len(elfs) == 1: + artifacts["DEBUG_ARTIFACT"] = { + "artifact": elfs[0], + "args": [], + "tools": ["gcc-arm-none-eabi", "openocd"], + "env": { + "OPENOCD_INTERFACE": "stlink", + "OPENOCD_MCU": "stm32f103c8", + }, + } + +Return("artifacts") diff --git a/components/vc/rear/include/CANIO_componentSpecific.h b/components/vc/rear/include/CANIO_componentSpecific.h new file mode 100644 index 00000000..27a54844 --- /dev/null +++ b/components/vc/rear/include/CANIO_componentSpecific.h @@ -0,0 +1,39 @@ +/** + RX_config* CAN.h + * Header file for CANRX configuration + */ + +#pragma once + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// imports for timebase +#include "HW_tim.h" + +// imports for CAN generated types +#include "CANTypes_generated.h" + +// imports for data access +#include "Module.h" + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define CANIO_UDS_BUFFER_LENGTH 8U +#define CANIO_getTimeMs() (HW_TIM_getTimeMS()) + +#define set_taskUsage1kHz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1kHz_TASK)); +#define set_taskUsage100Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_100Hz_TASK)); +#define set_taskUsage10Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_10Hz_TASK)); +#define set_taskUsage1Hz(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_1Hz_TASK)); +#define set_taskUsageIdle(m,b,n,s) set(m,b,n,s, Module_getTotalRuntimePercentage(MODULE_IDLE_TASK)); + +#include "TemporaryStubbing.h" diff --git a/components/vc/rear/include/FreeRTOSConfig.h b/components/vc/rear/include/FreeRTOSConfig.h new file mode 100644 index 00000000..3975aab6 --- /dev/null +++ b/components/vc/rear/include/FreeRTOSConfig.h @@ -0,0 +1,162 @@ +/* + * FreeRTOS Kernel V10.0.1 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * These parameters and more are described within the 'configuration' section of the + * FreeRTOS API documentation available on the FreeRTOS.org web site. + * + * See http://www.freertos.org/a00110.html + *----------------------------------------------------------*/ + +// Section where include file can be added + +// #if (defined(__ARMCC_VERSION) || defined(GNUC) || defined(ICCARM)) +// # include "RTE_Components.h" +// # include CMSIS_device_header +// #endif + +// Ensure definitions are only used by the compiler, and not by the assembler. +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) +# include +extern uint32_t SystemCoreClock; +#endif +#define configUSE_PREEMPTION (1) +#define configSUPPORT_STATIC_ALLOCATION (1) +#define configSUPPORT_DYNAMIC_ALLOCATION (0) +#define configUSE_IDLE_HOOK (0) +#define configUSE_TICK_HOOK (0) +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES (16) +#define configMAX_TASK_NAME_LEN (16) +#define configUSE_16_BIT_TICKS (0) +#define configUSE_MUTEXES (1) +#define configQUEUE_REGISTRY_SIZE (0) +#define configUSE_RECURSIVE_MUTEXES (1) +#define configUSE_COUNTING_SEMAPHORES (1) +#define configENABLE_BACKWARD_COMPATIBILITY (0) +#define configUSE_PORT_OPTIMISED_TASK_SELECTION (1) +#define configGENERATE_RUN_TIME_STATS (1) +#define configUSE_TRACE_FACILITY (1) + +/**< Used for RTOS profiling */ +extern void HW_TIM_configureRunTimeStatsTimer(void); +extern uint64_t HW_TIM_getBaseTick(void); +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() HW_TIM_configureRunTimeStatsTimer() +#define portGET_RUN_TIME_COUNTER_VALUE() (uint32_t)HW_TIM_getBaseTick() + +#define configSTACK_DEPTH_TYPE UBaseType_t +#define configMINIMAL_STACK_SIZE (256) +#define configIDLE_TASK_STACK_DEPTH (128) + +// heap is not used because dynamic allocation disabled +#define configAPPLICATION_ALLOCATED_HEAP (0) +#define configTOTAL_HEAP_SIZE ((size_t)3072) + +// Co-routine definitions. +#define configUSE_CO_ROUTINES (0) +#define configMAX_CO_ROUTINE_PRIORITIES (2) + +// Software timer definitions. +#define configUSE_TIMERS (1) +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#define configTIMER_QUEUE_LENGTH (10) +#define configTIMER_TASK_STACK_DEPTH (128) + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet (1) +#define INCLUDE_uxTaskPriorityGet (1) +#define INCLUDE_vTaskDelete (1) +#define INCLUDE_vTaskCleanUpResources (0) +#define INCLUDE_vTaskSuspend (1) +#define INCLUDE_vTaskDelayUntil (1) +#define INCLUDE_vTaskDelay (1) +#define INCLUDE_xTaskGetSchedulerState (1) +#define INCLUDE_xTaskGetCurrentTaskHandle (1) +#define INCLUDE_xTimerPendFunctionCall (1) +#define INCLUDE_xQueueGetMutexHolder (1) +#define INCLUDE_uxTaskGetStackHighWaterMark (1) +#define INCLUDE_eTaskGetState (1) + +// Cortex-M specific definitions. +#ifdef __NVIC_PRIO_BITS +// __BVIC_PRIO_BITS will be specified when CMSIS is being used. +# define configPRIO_BITS __NVIC_PRIO_BITS +#else +# define configPRIO_BITS 4 +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" + * function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY (15) + +/* The highest interrupt priority that can be used by any interrupt service + * routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + * INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + * PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (5) + +/* Interrupt priorities used by the kernel port layer itself. These are generic + * to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/**< Define conversion from us to ticks */ +#define pdMS_TO_TICKS(xTime) (((xTime) * configTICK_RATE_HZ) / 1000U) + +/* Normal assert() semantics without relying on the provision of an assert.h + * header file. */ +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + taskDISABLE_INTERRUPTS(); \ + for (;;) \ + ; \ + } + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS + * standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + +// Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) + +#define RTOS_EVENT_ALL 0x00000FFF +#define RTOS_EVENT_COUNT 12U + +#endif /* FREERTOS_CONFIG_H */ diff --git a/components/vc/rear/include/HW/BuildDefines.h b/components/vc/rear/include/HW/BuildDefines.h new file mode 100644 index 00000000..4e0672dc --- /dev/null +++ b/components/vc/rear/include/HW/BuildDefines.h @@ -0,0 +1,20 @@ +/* + * BuildDefines.h + * + */ + +#pragma once + +#include "FeatureDefines_generated.h" +#include "BuildDefines_generated.h" + +#if (MCU_STM32_PN == FDEFS_STM32_PN_STM32F105) +#define STM32F1 +#define STM32F105xC +#else +#error "Chipset not supported" +#endif + +#if FEATURE_IS_ENABLED(MCU_STM32_USE_HAL) +#define USE_HAL_DRIVER +#endif // MCU_STM32_USE_HAL diff --git a/components/vc/rear/include/HW/HW.h b/components/vc/rear/include/HW/HW.h new file mode 100644 index 00000000..3b6b05b2 --- /dev/null +++ b/components/vc/rear/include/HW/HW.h @@ -0,0 +1,36 @@ +/** + * @file HW.h + * @brief Header file for generic firmware functions + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "stm32f1xx.h" + +// System Includes +#include "LIB_Types.h" + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + HW_OK = 0x00U, + HW_ERROR = 0x01U +} HW_StatusTypeDef_E; + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +bool HW_init(void); +uint32_t HW_getTick(void); +void HW_delay(uint32_t delay); +void HW_usDelay(uint8_t us); +void HW_systemHardReset(void); +void Error_Handler(void); diff --git a/components/vc/rear/include/HW/HW_adc.h b/components/vc/rear/include/HW/HW_adc.h new file mode 100644 index 00000000..ccb41fd7 --- /dev/null +++ b/components/vc/rear/include/HW/HW_adc.h @@ -0,0 +1,58 @@ +/** + * @file HW_adc.h + * @brief Header file for ADC firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" +#include "stdbool.h" +#include "LIB_Types.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define ADC_MAX_VAL 4095U // Max integer value of ADC reading (2^12 for this chip) +#define ADC_REF_VOLTAGE 3.0F + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + BUFFER_HALF_LOWER = 0U, + BUFFER_HALF_UPPER, +} bufferHalf_E; + +typedef struct +{ + uint32_t raw; + float32_t value; + uint16_t count; +} simpleFilter_S; + + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern ADC_HandleTypeDef hadc1; +extern ADC_HandleTypeDef hadc2; +extern DMA_HandleTypeDef hdma_adc1; + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_ADC_init(void); +bool HW_ADC_calibrate(ADC_HandleTypeDef* hadc); +bool HW_ADC_startDMA(ADC_HandleTypeDef* hadc, uint32_t* data, uint32_t size); +uint16_t HW_ADC_getVFromCount(uint16_t cnt); diff --git a/components/vc/rear/include/HW/HW_can_componentSpecific.h b/components/vc/rear/include/HW/HW_can_componentSpecific.h new file mode 100644 index 00000000..d3012b3e --- /dev/null +++ b/components/vc/rear/include/HW/HW_can_componentSpecific.h @@ -0,0 +1,25 @@ +/** + * @file HW_can_componentSpecific.h + * @brief Header file for component specific CAN firmware + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + CAN_TX_MAILBOX_0 = 0U, + CAN_TX_MAILBOX_1, + CAN_TX_MAILBOX_2, + CAN_TX_MAILBOX_COUNT, +} CAN_TxMailbox_E; + +typedef enum +{ + CAN_RX_FIFO_0 = 0U, + CAN_RX_FIFO_1, + CAN_RX_FIFO_COUNT, +} CAN_RxFifo_E; diff --git a/components/vc/rear/include/HW/HW_clock.h b/components/vc/rear/include/HW/HW_clock.h new file mode 100644 index 00000000..773727c5 --- /dev/null +++ b/components/vc/rear/include/HW/HW_clock.h @@ -0,0 +1,67 @@ +/** + * @file HW_clock.h + * @brief Header file for clock configuration + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW.h" + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_systemClockConfig(void); + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief System Clock Configuration + */ +void HW_systemClockConfig(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; + + // Initializes the RCC Oscillators according to the specified parameters + // in the RCC_OscInitTypeDef structure. + + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; /**< HSE is 8MHz */ + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; /**< PLL is 8Mhz */ + RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8; /**< PLL output is 64MHz */ + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + // Initializes the CPU, AHB and APB buses clocks + + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /**< SYSCLK is 64MHz */ + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /**< SYSCLK output is 64MHz */ + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; /**< APB1 is 32MHz */ + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; /**< APB2 is 64MHz */ + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) + { + Error_Handler(); + } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8; /**< ADC is 8MHz from APB2 */ + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } +} diff --git a/components/vc/rear/include/HW/HW_dma.h b/components/vc/rear/include/HW/HW_dma.h new file mode 100644 index 00000000..f51bb7a7 --- /dev/null +++ b/components/vc/rear/include/HW/HW_dma.h @@ -0,0 +1,20 @@ +/** + * @file HW_dma.h + * @brief Header file for DMA firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_DMA_init(void); diff --git a/components/vc/rear/include/HW/HW_gpio_componentSpecific.h b/components/vc/rear/include/HW/HW_gpio_componentSpecific.h new file mode 100644 index 00000000..3e1f27fa --- /dev/null +++ b/components/vc/rear/include/HW/HW_gpio_componentSpecific.h @@ -0,0 +1,20 @@ +/** + * @file HW_gpio_componentSpecific.h + * @brief Header file for GPIO firmware component specific + */ + +#pragma once + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + HW_GPIO_CAN1_RX = 0U, + HW_GPIO_CAN1_TX, + HW_GPIO_CAN2_RX, + HW_GPIO_CAN2_TX, + HW_GPIO_LED, + HW_GPIO_COUNT, +} HW_GPIO_pinmux_E; diff --git a/components/vc/rear/include/HW/HW_intc.h b/components/vc/rear/include/HW/HW_intc.h new file mode 100644 index 00000000..3dc99f02 --- /dev/null +++ b/components/vc/rear/include/HW/HW_intc.h @@ -0,0 +1,35 @@ +/** + * @file HW_intc.h + * @brief Header file for STM32F1xx Cortex M3 Interrupts + */ + +#pragma once + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +#include "stm32f1xx.h" + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void DebugMon_Handler(void); + +void DMA1_Channel1_IRQHandler(void); +void ADC1_2_IRQHandler(void); +void TIM1_TRG_COM_IRQHandler(void); +void TIM2_IRQHandler(void); +void TIM1_CC_IRQHandler(void); + +void CAN1_SCE_IRQHandler(void); +void CAN1_TX_IRQHandler(void); +void CAN1_RX0_IRQHandler(void); +void CAN1_RX1_IRQHandler(void); + +void CAN2_SCE_IRQHandler(void); +void CAN2_TX_IRQHandler(void); +void CAN2_RX0_IRQHandler(void); +void CAN2_RX1_IRQHandler(void); diff --git a/components/vc/rear/include/HW/HW_tim.h b/components/vc/rear/include/HW/HW_tim.h new file mode 100644 index 00000000..22e450a2 --- /dev/null +++ b/components/vc/rear/include/HW/HW_tim.h @@ -0,0 +1,25 @@ +/** + * @file HW_tim.h + * @brief Header file for TIM firmware + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "stm32f1xx_hal.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +HAL_StatusTypeDef HW_TIM_init(void); +void HW_TIM_configureRunTimeStatsTimer(void); +uint32_t HW_TIM_getTick(void); +uint32_t HW_TIM_getTimeMS(void); +void HW_TIM_incBaseTick(void); +uint64_t HW_TIM_getBaseTick(void); diff --git a/components/vc/rear/include/HW/SystemConfig.h b/components/vc/rear/include/HW/SystemConfig.h new file mode 100644 index 00000000..f389823a --- /dev/null +++ b/components/vc/rear/include/HW/SystemConfig.h @@ -0,0 +1,31 @@ +/** + * @file SystemConfig.h + * @brief Define System Configuration + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW.h" + +// FreeRTOS Includes +#include "FreeRTOSConfig.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// System altering defines +#define USE_FULL_LL_DRIVER + +// NVIC interrupt priorities, lower number is higher priority +// tick interrupt is highest priority +#define DMA_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 4U +#define ADC_IRQ_PRIO DMA_IRQ_PRIO + 1U +#define CAN_RX_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 6U +#define CAN_TX_IRQ_PRIO configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 8U +#define EXTI_IRQ_PRIO ADC_IRQ_PRIO diff --git a/components/vc/rear/include/HW/stm32f105.yaml b/components/vc/rear/include/HW/stm32f105.yaml new file mode 100644 index 00000000..0f366998 --- /dev/null +++ b/components/vc/rear/include/HW/stm32f105.yaml @@ -0,0 +1,24 @@ +mcu: STM32F105 +features: + controller: + definition: "#/shared/FeatureDefs/Controller_FeatureDefs.yaml" + selection: "" +linker: + useDefault: true +drivers: + hal: # required + adc: + adc_ex: + can: + cortex: # required + dma: + flash: + gpio: + i2c: + pwr: + rcc: + rcc_ex: # required + spi: + use_ll: true + tim: + tim_ex: # required with tim diff --git a/components/vc/rear/include/HW/stm32f1xx_hal_conf.h b/components/vc/rear/include/HW/stm32f1xx_hal_conf.h new file mode 100644 index 00000000..67bfe0aa --- /dev/null +++ b/components/vc/rear/include/HW/stm32f1xx_hal_conf.h @@ -0,0 +1,259 @@ +/** + * @file stm32f1xx_hal_conf.h + * @brief Header file for STM32F1xx Configuration + */ + +#pragma once + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// Enable HAL modules here +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +// #define HAL_CRYP_MODULE_ENABLED +#define HAL_CAN_MODULE_ENABLED +// #define HAL_CAN_LEGACY_MODULE_ENABLED +// #define HAL_CEC_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +// #define HAL_CRC_MODULE_ENABLED +// #define HAL_DAC_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +// #define HAL_ETH_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +// #define HAL_I2S_MODULE_ENABLED +// #define HAL_IRDA_MODULE_ENABLED +// #define HAL_IWDG_MODULE_ENABLED +// #define HAL_NOR_MODULE_ENABLED +// #define HAL_NAND_MODULE_ENABLED +// #define HAL_PCCARD_MODULE_ENABLED +// #define HAL_PCD_MODULE_ENABLED +// #define HAL_HCD_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +// #define HAL_RTC_MODULE_ENABLED +// #define HAL_SD_MODULE_ENABLED +// #define HAL_MMC_MODULE_ENABLED +// #define HAL_SDRAM_MODULE_ENABLED +// #define HAL_SMARTCARD_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 + +// Adjust Oscillator settings + +#if !defined(HSE_VALUE) +# define HSE_VALUE 8000000U // Value of the External oscillator in Hz +#endif + +#if !defined(HSE_STARTUP_TIMEOUT) +# define HSE_STARTUP_TIMEOUT 100U // Time out for HSE start up, in ms +#endif + +#if !defined(HSI_VALUE) +# define HSI_VALUE 8000000U // Value of the Internal oscillator in Hz +#endif + +#if !defined(LSI_VALUE) +# define LSI_VALUE 40000U // LSI Typical Value in Hz +#endif + +#if !defined(LSE_VALUE) +# define LSE_VALUE 32768U // Value of the External oscillator in Hz +#endif + +#if !defined(LSE_STARTUP_TIMEOUT) +# define LSE_STARTUP_TIMEOUT 5000U // Time out for LSE start up, in ms +#endif + +// ########################### System Configuration ######################### +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3000U // Value of VDD in mv +#define TICK_INT_PRIORITY 0U // tick interrupt priority (lowest by default) +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U // ADC register callback disabled +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U // CAN register callback disabled +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U // CEC register callback disabled +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U // DAC register callback disabled +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U // ETH register callback disabled +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U // HCD register callback disabled +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U // I2C register callback disabled +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U // I2S register callback disabled +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U // MMC register callback disabled +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U // NAND register callback disabled +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U // NOR register callback disabled +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U // PCCARD register callback disabled +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U // PCD register callback disabled +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U // RTC register callback disabled +#define USE_HAL_SD_REGISTER_CALLBACKS 0U // SD register callback disabled +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U // SMARTCARD register callback disabled +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U // IRDA register callback disabled +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U // SRAM register callback disabled +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U // SPI register callback disabled +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U // TIM register callback disabled +#define USE_HAL_UART_REGISTER_CALLBACKS 0U // UART register callback disabled +#define USE_HAL_USART_REGISTER_CALLBACKS 0U // USART register callback disabled +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U // WWDG register callback disabled + + +// Uncomment the line below to expanse the "assert_param" macro in the +// HAL drivers code +// #define USE_FULL_ASSERT +#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__)) + +void assert_failed(uint8_t* file, uint32_t line); +#else +# define assert_param(expr) ((void)0U) +#endif // ifdef USE_FULL_ASSERT + + +// 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 + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Include headers for enabled HAL modules + +#ifdef HAL_RCC_MODULE_ENABLED +# include "stm32f1xx_hal_rcc.h" +#endif + +#ifdef HAL_GPIO_MODULE_ENABLED +# include "stm32f1xx_hal_gpio.h" +#endif + +#ifdef HAL_EXTI_MODULE_ENABLED +# include "stm32f1xx_hal_exti.h" +#endif + +#ifdef HAL_DMA_MODULE_ENABLED +# include "stm32f1xx_hal_dma.h" +#endif + +#ifdef HAL_CAN_MODULE_ENABLED +# include "stm32f1xx_hal_can.h" +#endif + +#ifdef HAL_CEC_MODULE_ENABLED +# include "stm32f1xx_hal_cec.h" +#endif + +#ifdef HAL_CORTEX_MODULE_ENABLED +# include "stm32f1xx_hal_cortex.h" +#endif + +#ifdef HAL_ADC_MODULE_ENABLED +# include "stm32f1xx_hal_adc.h" +#endif + +#ifdef HAL_CRC_MODULE_ENABLED +# include "stm32f1xx_hal_crc.h" +#endif + +#ifdef HAL_DAC_MODULE_ENABLED +# include "stm32f1xx_hal_dac.h" +#endif + +#ifdef HAL_FLASH_MODULE_ENABLED +# include "stm32f1xx_hal_flash.h" +#endif + +#ifdef HAL_SRAM_MODULE_ENABLED +# include "stm32f1xx_hal_sram.h" +#endif + +#ifdef HAL_NOR_MODULE_ENABLED +# include "stm32f1xx_hal_nor.h" +#endif + +#ifdef HAL_I2C_MODULE_ENABLED +# include "stm32f1xx_hal_i2c.h" +#endif + +#ifdef HAL_IWDG_MODULE_ENABLED +# include "stm32f1xx_hal_iwdg.h" +#endif + +#ifdef HAL_PWR_MODULE_ENABLED +# include "stm32f1xx_hal_pwr.h" +#endif + +#ifdef HAL_RTC_MODULE_ENABLED +# include "stm32f1xx_hal_rtc.h" +#endif + +#ifdef HAL_PCCARD_MODULE_ENABLED +# include "stm32f1xx_hal_pccard.h" +#endif + +#ifdef HAL_SD_MODULE_ENABLED +# include "stm32f1xx_hal_sd.h" +#endif + +#ifdef HAL_NAND_MODULE_ENABLED +# include "stm32f1xx_hal_nand.h" +#endif + +#ifdef HAL_SPI_MODULE_ENABLED +# include "stm32f1xx_hal_spi.h" +#endif + +#ifdef HAL_TIM_MODULE_ENABLED +# include "stm32f1xx_hal_tim.h" +#endif + +#ifdef HAL_UART_MODULE_ENABLED +# include "stm32f1xx_hal_uart.h" +#endif + +#ifdef HAL_USART_MODULE_ENABLED +# include "stm32f1xx_hal_usart.h" +#endif + +#ifdef HAL_IRDA_MODULE_ENABLED +# include "stm32f1xx_hal_irda.h" +#endif + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +# include "stm32f1xx_hal_smartcard.h" +#endif + +#ifdef HAL_WWDG_MODULE_ENABLED +# include "stm32f1xx_hal_wwdg.h" +#endif + +#ifdef HAL_PCD_MODULE_ENABLED +# include "stm32f1xx_hal_pcd.h" +#endif + +#ifdef HAL_HCD_MODULE_ENABLED +# include "stm32f1xx_hal_hcd.h" +#endif + +#ifdef HAL_MMC_MODULE_ENABLED +# include "stm32f1xx_hal_mmc.h" +#endif diff --git a/components/vc/rear/include/IO.h b/components/vc/rear/include/IO.h new file mode 100644 index 00000000..c2dae852 --- /dev/null +++ b/components/vc/rear/include/IO.h @@ -0,0 +1,45 @@ +/** + * @file IO.h + * @brief Header file for IO Module + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" + +// Firmware Includes +#include "HW_adc.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define VREF ADC_REF_VOLTAGE /**< Shunt Diode reference voltage */ + +#define IO_ADC_BUF_LEN 192U /**< To fit the number of measurements into a time less than 100us \ + the buffer length must be less than 100us / (ADC clock freq * \ + cycles per conversion). For this firmware, there is 14 cycles \ + per conversion. Therefore the max samples per 100us is 57, which \ + rounded down to the nearest multiple of 12 is 48 */ + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef struct +{ + float32_t mcu_temp; +} IO_S; + + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern IO_S IO; diff --git a/components/vc/rear/include/Module_componentSpecific.h b/components/vc/rear/include/Module_componentSpecific.h new file mode 100644 index 00000000..e1ed821b --- /dev/null +++ b/components/vc/rear/include/Module_componentSpecific.h @@ -0,0 +1,36 @@ +/** + * @file Module_componentSpecific.h + * @brief Header file for Module Manager for the component specific modules + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "ModuleDesc.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +/**< Modules */ +extern const ModuleDesc_S IO_desc; +extern const ModuleDesc_S UDS_desc; +extern const ModuleDesc_S CANIO_rx; +extern const ModuleDesc_S CANIO_tx; + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + MODULE_IO = 0x00, + MODULE_UDS, + MODULE_CANIO_tx, + MODULE_CANIO_rx, + MODULE_CNT +} Module_tasks_E; diff --git a/components/vc/rear/include/UDS.h b/components/vc/rear/include/UDS.h new file mode 100644 index 00000000..437dd32e --- /dev/null +++ b/components/vc/rear/include/UDS.h @@ -0,0 +1,19 @@ +/* + * UDS.h + * UDS module header file + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "FeatureDefines_generated.h" +#if APP_UDS +// component-specific UDS configuration +#include "uds_componentSpecific.h" + +// other includes +#include "LIB_Types.h" +#endif // FEATURE_UDS diff --git a/components/vc/rear/include/Utility.h b/components/vc/rear/include/Utility.h new file mode 100644 index 00000000..a3edc42d --- /dev/null +++ b/components/vc/rear/include/Utility.h @@ -0,0 +1,477 @@ +/** + * @file Utility.h + * @brief Header file for Utlity functions + */ + +#pragma once + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" +#include "stddef.h" +#include "string.h" + +/****************************************************************************** + * M A C R O S + ******************************************************************************/ + +// Count number of items in array +#define COUNTOF(x) ((uint16_t)(sizeof(x) / sizeof(x[0]))) // return size of an array as uint16 +// Count leading zeroes +static inline uint16_t u32CountLeadingZeroes(uint32_t x) +{ + uint16_t c = 0U; + while (((x & 0x80000000UL) == 0UL) && (c < 32U)) + { + c++; + x <<= 1UL; + } + + return c; +} + +#define VAR_IN_SECTION(s) __attribute__((section(s))) // place a given variable in the specified linker section + +#ifndef UNUSED +# define UNUSED(x) (void)x +#endif + +#define zero() (0U) + +// Join macros +// Convert token to string (doesn't expand) +#define STR(x) #x + +// Expand and convert token to string +#define XSTR(x) STR(x) + +// Join two tokens (doesn't expand) +#define DO_JOIN(x, y) x##y + +// Expand and join tokens +#define JOIN(x, y) DO_JOIN(x, y) +#define JOIN3(x, y, z) JOIN(x, JOIN(y, z)) + +// Expand and join with `_` separating tokens +#define SNAKE(x, y) JOIN3(x, _, y) +#define SNAKE3(x, y, z) SNAKE(x, SNAKE(y, z)) +#define SNAKE4(x, y, z, a) SNAKE3(x, y, SNAKE(z, a)) + +// atomic bit stuff +// FIXME: check if these compile down to one instruction +// If not, make this atomic +#define setBitAtomic(bit) ((bit) = true) +#define clearBitAtomic(bit) ((bit) = false) +#define assignBitAtomic(bit, condition) \ + do { \ + if (condition) \ + { \ + (bit) = true; \ + } \ + else \ + { \ + (bit) = false; \ + } \ + } while (zero()) + + +// FLAGS +// This should get moved elsewhere at some point +#define FLAG_bits_each 16 +#define WORDS_FROM_COUNT(count) (uint16_t)((count + (FLAG_bits_each - 1)) / FLAG_bits_each) +#define FLAG_GET_WORD(name, flag) (name[(uint16_t)flag / FLAG_bits_each]) +#define FLAG_GET_MASK(flag) (1U << ((uint16_t)flag % FLAG_bits_each)) + +#define FLAG_create(name, size) uint16_t(name)[WORDS_FROM_COUNT(size)] +#define FLAG_set(name, pos) FLAG_GET_WORD(name, pos) |= (uint16_t)FLAG_GET_MASK(pos) +#define FLAG_clear(name, pos) FLAG_GET_WORD(name, pos) &= (uint16_t)~FLAG_GET_MASK(pos) +#define FLAG_get(name, pos) ((bool)((FLAG_GET_WORD(name, pos) & FLAG_GET_MASK(pos)) == FLAG_GET_MASK(pos))) +#define FLAG_assign(name, pos, value) \ + do { \ + if (value) \ + { \ + FLAG_set(name, pos); \ + } \ + else \ + { \ + FLAG_clear(name, pos); \ + } \ + } while (zero()) + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/* + * FLAG_setAll + * @brief Sets all of the flags in the given flag word + * @param name Flag word name + * @param count Number of flags in the given flag + */ +static inline void FLAG_setAll(uint16_t* name, uint16_t count) +{ + uint16_t numWords = WORDS_FROM_COUNT(count); + uint16_t extraBits = count % FLAG_bits_each; + + if (numWords > 1U) + { + memset(name, 0xFF, (uint16_t)(numWords * FLAG_bits_each)); + } + if (extraBits > 0U) + { + name[numWords] |= (0xFF >> (FLAG_bits_each - extraBits)); + } +} + + +/* + * FLAG_clearAll + * @brief clears all of the bits in the given flag + * @param name Flag word name + * @param count Number of bits in the given flag + */ +static inline void FLAG_clearAll(uint16_t* name, uint16_t count) +{ + memset(name, 0x00, (uint16_t)(WORDS_FROM_COUNT(count) * FLAG_bits_each)); +} + + +/* + * FLAG_any + * @brief check if any of the flags in the flag word is set + * @param name Flag word name + * @param count Number of flags in the given flag + */ +static inline bool FLAG_any(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0U) + { + return true; + } + } + return false; +} + + +/* + * FLAG_all + * @brief checks if all flags in the flag word are set + * @param name Flag word name + * @param count Number of bits in the given flag word + */ +static inline bool FLAG_all(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0xFF) + { + return false; + } + } + return true; +} + + +/* + * FLAG_none + * @brief checks if none of the flags in the flag word are set + * @param name Flag word name + * @param count Number of bits in the given flag word + */ +static inline bool FLAG_none(uint16_t* name, uint16_t count) +{ + for (uint16_t word = 0U; word < WORDS_FROM_COUNT(count); word++) + { + if ((FLAG_GET_WORD(name, word) & 0xFF) != 0U) + { + return false; + } + } + return true; +} + +static inline uint8_t reverse_byte(uint8_t x) +{ + static const uint8_t table[] = { + 0x00, + 0x80, + 0x40, + 0xc0, + 0x20, + 0xa0, + 0x60, + 0xe0, + 0x10, + 0x90, + 0x50, + 0xd0, + 0x30, + 0xb0, + 0x70, + 0xf0, + 0x08, + 0x88, + 0x48, + 0xc8, + 0x28, + 0xa8, + 0x68, + 0xe8, + 0x18, + 0x98, + 0x58, + 0xd8, + 0x38, + 0xb8, + 0x78, + 0xf8, + 0x04, + 0x84, + 0x44, + 0xc4, + 0x24, + 0xa4, + 0x64, + 0xe4, + 0x14, + 0x94, + 0x54, + 0xd4, + 0x34, + 0xb4, + 0x74, + 0xf4, + 0x0c, + 0x8c, + 0x4c, + 0xcc, + 0x2c, + 0xac, + 0x6c, + 0xec, + 0x1c, + 0x9c, + 0x5c, + 0xdc, + 0x3c, + 0xbc, + 0x7c, + 0xfc, + 0x02, + 0x82, + 0x42, + 0xc2, + 0x22, + 0xa2, + 0x62, + 0xe2, + 0x12, + 0x92, + 0x52, + 0xd2, + 0x32, + 0xb2, + 0x72, + 0xf2, + 0x0a, + 0x8a, + 0x4a, + 0xca, + 0x2a, + 0xaa, + 0x6a, + 0xea, + 0x1a, + 0x9a, + 0x5a, + 0xda, + 0x3a, + 0xba, + 0x7a, + 0xfa, + 0x06, + 0x86, + 0x46, + 0xc6, + 0x26, + 0xa6, + 0x66, + 0xe6, + 0x16, + 0x96, + 0x56, + 0xd6, + 0x36, + 0xb6, + 0x76, + 0xf6, + 0x0e, + 0x8e, + 0x4e, + 0xce, + 0x2e, + 0xae, + 0x6e, + 0xee, + 0x1e, + 0x9e, + 0x5e, + 0xde, + 0x3e, + 0xbe, + 0x7e, + 0xfe, + 0x01, + 0x81, + 0x41, + 0xc1, + 0x21, + 0xa1, + 0x61, + 0xe1, + 0x11, + 0x91, + 0x51, + 0xd1, + 0x31, + 0xb1, + 0x71, + 0xf1, + 0x09, + 0x89, + 0x49, + 0xc9, + 0x29, + 0xa9, + 0x69, + 0xe9, + 0x19, + 0x99, + 0x59, + 0xd9, + 0x39, + 0xb9, + 0x79, + 0xf9, + 0x05, + 0x85, + 0x45, + 0xc5, + 0x25, + 0xa5, + 0x65, + 0xe5, + 0x15, + 0x95, + 0x55, + 0xd5, + 0x35, + 0xb5, + 0x75, + 0xf5, + 0x0d, + 0x8d, + 0x4d, + 0xcd, + 0x2d, + 0xad, + 0x6d, + 0xed, + 0x1d, + 0x9d, + 0x5d, + 0xdd, + 0x3d, + 0xbd, + 0x7d, + 0xfd, + 0x03, + 0x83, + 0x43, + 0xc3, + 0x23, + 0xa3, + 0x63, + 0xe3, + 0x13, + 0x93, + 0x53, + 0xd3, + 0x33, + 0xb3, + 0x73, + 0xf3, + 0x0b, + 0x8b, + 0x4b, + 0xcb, + 0x2b, + 0xab, + 0x6b, + 0xeb, + 0x1b, + 0x9b, + 0x5b, + 0xdb, + 0x3b, + 0xbb, + 0x7b, + 0xfb, + 0x07, + 0x87, + 0x47, + 0xc7, + 0x27, + 0xa7, + 0x67, + 0xe7, + 0x17, + 0x97, + 0x57, + 0xd7, + 0x37, + 0xb7, + 0x77, + 0xf7, + 0x0f, + 0x8f, + 0x4f, + 0xcf, + 0x2f, + 0xaf, + 0x6f, + 0xef, + 0x1f, + 0x9f, + 0x5f, + 0xdf, + 0x3f, + 0xbf, + 0x7f, + 0xff, + }; + return table[x]; +} + +uint8_t* reverse_bytes(uint8_t* in, uint8_t len); + +/** + * @brief Simple fast accurate natural log approximation + * + * @note Lingdong Huang, 2020, Public Domain + * @note Floating point bit hacking + * Remez Algorithm + * x=m*2^p => ln(x)=ln(m)+ln(2)p* + * + * @param x Number to calculate ln of + * + * @retval result of ln(x) + */ +float ln(float x); diff --git a/components/vc/rear/include/uds_componentSpecific.h b/components/vc/rear/include/uds_componentSpecific.h new file mode 100644 index 00000000..52a6a05e --- /dev/null +++ b/components/vc/rear/include/uds_componentSpecific.h @@ -0,0 +1,27 @@ +/* + * uds_componentSpecific.h + * Component-specific defines for the UDS library + */ +#pragma once + +#include "NetworkDefines_generated.h" +#include "FeatureDefines_generated.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#if APP_UDS +#define UDS_ENABLE_LIB APP_UDS + +#define UDS_REQUEST_ID CAN_VEH_UDSCLIENT_vcrearUdsRequest_ID +#define UDS_RESPONSE_ID CAN_VEH_VCREAR_udsResponse_ID + +#define ISOTP_TX_BUF_SIZE 128U // [bytes] mostly arbitrary +#define ISOTP_RX_BUF_SIZE 128U // [bytes] maximum size of a multi-frame ISOTP transaction (mostly arbitrary, increase if necessary) + +// supported UDS services +#define UDS_SERVICE_SUPPORTED_ECU_RESET true +#define UDS_SERVICE_SUPPORTED_ROUTINE_CONTROL true +#define UDS_SERVICE_SUPPORTED_DID_READ true +#endif // FEATURE_UDS diff --git a/components/vc/rear/renderers/BuildDefines_generated.h.mako b/components/vc/rear/renderers/BuildDefines_generated.h.mako new file mode 100644 index 00000000..38a1d744 --- /dev/null +++ b/components/vc/rear/renderers/BuildDefines_generated.h.mako @@ -0,0 +1,8 @@ +/* + * BuildDefines_generated.h + * + */ + +#pragma once + +#define VCPDU_CONFIG_ID ${configId}U diff --git a/components/vc/rear/src/CANIO_componentSpecific.c b/components/vc/rear/src/CANIO_componentSpecific.c new file mode 100644 index 00000000..c4c95466 --- /dev/null +++ b/components/vc/rear/src/CANIO_componentSpecific.c @@ -0,0 +1,32 @@ +/** + RX_config* CAN.h + * Header file for CANRX configuration + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "CAN/CAN.h" +#include "CANIO_componentSpecific.h" +#include "Utility.h" +#include "MessageUnpack_generated.h" + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +void CANRX_unpackMessage(CAN_bus_E bus, uint32_t id, CAN_data_T *data) +{ + switch (bus) + { + case CAN_BUS_ASS: + CANRX_ASS_unpackMessage(id, data); + break; + case CAN_BUS_VEH: + CANRX_VEH_unpackMessage(id, data); + break; + default: + break; + } +} diff --git a/components/vc/rear/src/HW/HW.c b/components/vc/rear/src/HW/HW.c new file mode 100644 index 00000000..dff17f3d --- /dev/null +++ b/components/vc/rear/src/HW/HW.c @@ -0,0 +1,91 @@ +/** + * @file HW.c + * @brief Source code for generic firmware functions + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Header file +#include "HW.h" + +// System Includes +#include "stdbool.h" + +// Firmware Includes +#include "stm32f1xx.h" +#include "HW_tim.h" + +typedef struct +{ + volatile uint32_t const CPUID; + volatile uint32_t ICSR; + volatile uint32_t VTOR; + volatile uint32_t AIRCR; + volatile uint32_t SCR; + volatile uint32_t CCR; + volatile uint32_t SHPR[3]; + volatile uint32_t SHCSR; + volatile uint32_t CFSR; + volatile uint32_t HFSR; + volatile uint32_t DFSR; + volatile uint32_t MMFAR; + volatile uint32_t BFAR; + volatile uint32_t AFSR; +} SCB_regMap; +#define pSCB ((SCB_regMap*)SCB_BASE) + +#define AIRCR_RESET (0x05FA0000UL) +#define AIRCR_RESET_REQ (AIRCR_RESET | 0x04UL) + +/****************************************************************************** + * P U B L I C F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +/** + * @brief Initializes the generic low-level firmware + * + * @retval Always true + */ +bool HW_init(void) +{ + return HAL_Init() == HAL_OK; +} + +/** + * @brief Get the number of ticks since clock start + * + * @retval Number of ticks + */ +uint32_t HW_getTick(void) +{ + return HAL_GetTick(); +} + +/** + * @brief Delay the execution in blocking mode for amount of ticks + * + * @param delay Number of ticks to delay in blocking mode + */ +void HW_delay(uint32_t delay) +{ + HAL_Delay(delay); +} + +/** + * @brief This function is blocking and should be avoided + * + * @param us Microsecond blocking delay + */ +void HW_usDelay(uint8_t us) +{ + uint64_t us_start = HW_TIM_getBaseTick(); + + while (HW_TIM_getBaseTick() < us_start + us); +} + +void HW_systemHardReset(void) +{ + pSCB->AIRCR = AIRCR_RESET_REQ; +} diff --git a/components/vc/rear/src/HW/HW_adc.c b/components/vc/rear/src/HW/HW_adc.c new file mode 100644 index 00000000..73c7785a --- /dev/null +++ b/components/vc/rear/src/HW/HW_adc.c @@ -0,0 +1,203 @@ +/** + * @file HW_adc.c + * @brief Source code for ADC firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// FreeRTOS Includes +#include "FreeRTOS.h" +#include "task.h" + +// System Inlcudes +#include "string.h" + +// Firmware Includes +#include "HW_adc.h" + +// Other Includes +#include "IO.h" +#include "SystemConfig.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +#define ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES 2U +#define ADC_CALIBRATION_TIMEOUT 10U + +#define ADC_MAX_COUNT 4095 + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +ADC_HandleTypeDef hadc1; +ADC_HandleTypeDef hadc2; +DMA_HandleTypeDef hdma_adc1; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void HW_ADC_unpackBuffer(bufferHalf_E half); + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Init function for ADC firmware + */ +void HW_ADC_init(void) +{ + ADC_MultiModeTypeDef multimode = { 0 }; + ADC_ChannelConfTypeDef sConfig = { 0 }; + + // Cell Measurement config + hadc1.Instance = ADC1; + hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc1.Init.ContinuousConvMode = ENABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + multimode.Mode = ADC_DUALMODE_REGSIMULT; + if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK) + { + Error_Handler(); + } + + // Configure Regular Channels + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + hadc2.Instance = ADC2; + hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc2.Init.ContinuousConvMode = ENABLE; + hadc2.Init.DiscontinuousConvMode = DISABLE; + hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc2.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc2) != HAL_OK) + { + Error_Handler(); + } + + // Configure Regular Channels + sConfig.Channel = ADC_CHANNEL_TEMPSENSOR; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_13CYCLES_5; + if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + HAL_ADC_Start(&hadc2); +} + +/** + * @brief Callback for STM32 HAL once ADC initialization is complete + * + * @param adcHandle pointer to ADC peripheral + */ +void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) +{ + if (adcHandle->Instance == ADC1) + { + // ADC1 clock enable + __HAL_RCC_ADC1_CLK_ENABLE(); + + // ADC1 DMA Init + // ADC1 Init + hdma_adc1.Instance = DMA1_Channel1; + hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; + hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + hdma_adc1.Init.Mode = DMA_CIRCULAR; + hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM; + if (HAL_DMA_Init(&hdma_adc1) != HAL_OK) + { + Error_Handler(); + } + + __HAL_LINKDMA(adcHandle, DMA_Handle, hdma_adc1); + + HAL_NVIC_SetPriority(ADC1_2_IRQn, ADC_IRQ_PRIO, 0U); + HAL_NVIC_EnableIRQ(ADC1_2_IRQn); + } + else if (adcHandle->Instance == ADC2) + { + // ADC1 clock enable + __HAL_RCC_ADC2_CLK_ENABLE(); + } +} + +/** + * @brief STM32 HAL callback. Called once de-init is complete + * + * @param adcHandle Pointer to ADC peripheral + */ +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) +{ + if (adcHandle->Instance == ADC1) + { + __HAL_RCC_ADC1_CLK_DISABLE(); + + // ADC1 DMA DeInit + HAL_DMA_DeInit(adcHandle->DMA_Handle); + } + if (adcHandle->Instance == ADC2) + { + // Peripheral clock disable + __HAL_RCC_ADC2_CLK_DISABLE(); + } +} + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Firmware function to initiate ADC calibration. + * + * @param hadc Pointer to ADC peripheral + * + * @retval true = Success, false = Failure + */ +bool HW_ADC_calibrate(ADC_HandleTypeDef* hadc) +{ + return HAL_ADCEx_Calibration_Start(hadc) == HAL_OK; +} + +/** + * @brief Firmware function to start DMA transfer + * + * @param hadc Pointer to ADC peripheral + * @param data Pointer to memory start address + * @param size Size of buffer + * + * @retval true = Success, false = Failure + */ +bool HW_ADC_startDMA(ADC_HandleTypeDef* hadc, uint32_t* data, uint32_t size) +{ + return HAL_ADCEx_MultiModeStart_DMA(hadc, data, size) == HAL_OK; +} diff --git a/components/vc/rear/src/HW/HW_can_componentSpecific.c b/components/vc/rear/src/HW/HW_can_componentSpecific.c new file mode 100644 index 00000000..349ade6d --- /dev/null +++ b/components/vc/rear/src/HW/HW_can_componentSpecific.c @@ -0,0 +1,410 @@ +/** + * @file HW_can.c + * @brief Source code for CAN firmware + */ + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "HW_can.h" + +#include "HW.h" +#include "stdint.h" +#include "SystemConfig.h" + +#include "CAN/CAN.h" +#include "CAN/CanTypes.h" + +#include "NetworkDefines_generated.h" +#include "MessageUnpack_generated.h" +#include "uds.h" +#include "uds_componentSpecific.h" +#include "LIB_app.h" + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +// which CAN interrupts we want to enable +// stm32f1xx_hal_can.h from ST drivers for description of each one +// Description of interrupts: +// CAN_IER_TMEIE Transmit Mailbox Empty +// CAN_IER_FMPIEx FIFO x Message Pending (RX FIFO) +// CAN_IER_FFIEx FIFO x Full +// CAN_IER_FOVIEx FIFO x Overrun +// CAN_IER_WKUIE Wakeup Interrupt +// CAN_IER_SLKIE Sleep Interrupt +// CAN_IER_EWGIE Error Warning Interrupt +// CAN_IER_EPVIE Error Passive Interrupt +// CAN_IER_BOFIE Bus Off Interrupt +// CAN_IER_LECIE Last Error Code Interrupt +// CAN_IER_ERRIE Error Interrupt +#define CAN_ENABLED_INTERRUPTS (CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_FFIE0 | \ + CAN_IER_FFIE1 | CAN_IER_FOVIE0 | CAN_IER_FOVIE1 | CAN_IER_EWGIE | \ + CAN_IER_EPVIE | CAN_IER_BOFIE | CAN_IER_LECIE | CAN_IER_ERRIE) + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +CAN_HandleTypeDef hcan[CAN_BUS_COUNT]; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +static inline CAN_bus_E HW_CAN_getBusFromPeripheral(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = 0U; + + for (CAN_bus_E i = 0U; i < CAN_BUS_COUNT; i++) + { + if (&hcan[i] == canHandle) + { + bus = i; + i = CAN_BUS_COUNT; + } + } + + return bus; +} + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * HW_CAN_sendMsgBus0 + * @param priority TODO + * @param data TODO + * @param id TODO + * @param len TODO + * @return TODO + */ +bool HW_CAN_sendMsg(CAN_bus_E bus, CAN_data_T data, uint32_t id, uint8_t len) +{ + CAN_TxMessage_T msg = {0}; + + msg.id = id; + msg.data = data; + msg.lengthBytes = len; + msg.IDE = (id <= 0x7ff) ? CAN_IDENTIFIER_STD : CAN_IDENTIFIER_EXT; + + return HW_CAN_sendMsgOnPeripheral(bus, msg) == HW_OK; +} + +/** + * HW_CAN_Init + * initialize the CAN peripheral + */ +HW_StatusTypeDef_E HW_CAN_init(void) +{ + hcan[CAN_BUS_VEH].Instance = CAN1; + hcan[CAN_BUS_ASS].Instance = CAN2; + for (CAN_bus_E bus = 0U; bus < CAN_BUS_COUNT; bus++) + { + hcan[bus].Init.Mode = CAN_MODE_NORMAL; + hcan[bus].Init.TimeTriggeredMode = DISABLE; + hcan[bus].Init.AutoBusOff = ENABLE; + hcan[bus].Init.AutoWakeUp = DISABLE; + hcan[bus].Init.AutoRetransmission = ENABLE; + hcan[bus].Init.ReceiveFifoLocked = DISABLE; + hcan[bus].Init.TransmitFifoPriority = DISABLE; + + switch(CAN_busConfig[bus].baudrate) + { + case CAN_BAUDRATE_1MBIT: + hcan[bus].Init.Prescaler = 4; + hcan[bus].Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan[bus].Init.TimeSeg1 = CAN_BS1_6TQ; + hcan[bus].Init.TimeSeg2 = CAN_BS2_1TQ; + break; + case CAN_BAUDRATE_500KBIT: + hcan[bus].Init.Prescaler = 4; + hcan[bus].Init.SyncJumpWidth = CAN_SJW_1TQ; + hcan[bus].Init.TimeSeg1 = CAN_BS1_12TQ; + hcan[bus].Init.TimeSeg2 = CAN_BS2_3TQ; + break; + default: + return HW_ERROR; + } + + if (HAL_CAN_Init(&hcan[bus]) != HAL_OK) + { + Error_Handler(); + } + } + + _Static_assert(((COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4) + (COUNTOF(CANRX_VEH_unpackListExtID) / 2U) + + ((COUNTOF(CANRX_ASS_unpackList) + ((4U - COUNTOF(CANRX_ASS_unpackList) % 4U) % 4U)) / 4) + (COUNTOF(CANRX_ASS_unpackListExtID) / 2U) + <= CAN_FILTERBANK_LENGTH, "Too many CAN filter bank's used"); + uint8_t filterBank = 0U; + for (uint32_t i = 0U; i < COUNTOF(CANRX_VEH_unpackList); i += 4U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_16BIT; + // All filters are shifted left 5 bits + filt.FilterIdHigh = CANRX_VEH_unpackList[i + 0U] << 5U; + if ((i + 1U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterIdLow = CANRX_VEH_unpackList[i + 1U] << 5U; } + if ((i + 2U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterMaskIdHigh = CANRX_VEH_unpackList[i + 2U] << 5U; } + if ((i + 3U) < COUNTOF(CANRX_VEH_unpackList)) { filt.FilterMaskIdLow = CANRX_VEH_unpackList[i + 3U] << 5U; } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_VEH], &filt); + } + for (uint32_t i = 0U; i < COUNTOF(CANRX_VEH_unpackListExtID); i+= 2U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_32BIT; + // All filters are fucky - lookup RM0008 information + filt.FilterIdHigh = (uint16_t)(CANRX_VEH_unpackListExtID[i + 0U] >> 13U); + filt.FilterIdLow = (uint16_t)(CANRX_VEH_unpackListExtID[i + 0U] << 3U) | (0x01 << 2U); + if ((i + 1U) < COUNTOF(CANRX_VEH_unpackListExtID)) { + filt.FilterMaskIdHigh = (uint16_t)(CANRX_VEH_unpackListExtID[i + 1U] >> 13U); + filt.FilterMaskIdLow = (uint16_t)(CANRX_VEH_unpackListExtID[i + 1U] << 3U) | (0x01 << 2U); + } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_VEH], &filt); + } + HAL_CAN_ActivateNotification(&hcan[CAN_BUS_VEH], CAN_ENABLED_INTERRUPTS); + + for (uint32_t i = 0U; i < COUNTOF(CANRX_ASS_unpackList); i += 4U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_16BIT; + // All filters are shifted left 5 bits + filt.FilterIdHigh = CANRX_ASS_unpackList[i + 0U] << 5U; + if ((i + 1U) < COUNTOF(CANRX_ASS_unpackList)) { filt.FilterIdLow = CANRX_ASS_unpackList[i + 1U] << 5U; } + if ((i + 2U) < COUNTOF(CANRX_ASS_unpackList)) { filt.FilterMaskIdHigh = CANRX_ASS_unpackList[i + 2U] << 5U; } + if ((i + 3U) < COUNTOF(CANRX_ASS_unpackList)) { filt.FilterMaskIdLow = CANRX_ASS_unpackList[i + 3U] << 5U; } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_ASS], &filt); + } + for (uint32_t i = 0U; i < COUNTOF(CANRX_ASS_unpackListExtID); i+= 2U) + { + CAN_FilterTypeDef filt = { 0U }; + filt.FilterBank = filterBank++; + filt.FilterMode = CAN_FILTERMODE_IDLIST; + filt.FilterScale = CAN_FILTERSCALE_32BIT; + // All filters are fucky - lookup RM0008 information + filt.FilterIdHigh = (uint16_t)(CANRX_ASS_unpackListExtID[i + 0U] >> 13U); + filt.FilterIdLow = (uint16_t)(CANRX_ASS_unpackListExtID[i + 0U] << 3U) | (0x01 << 2U); + if ((i + 1U) < COUNTOF(CANRX_ASS_unpackListExtID)) { + filt.FilterMaskIdHigh = (uint16_t)(CANRX_ASS_unpackListExtID[i + 1U] >> 13U); + filt.FilterMaskIdLow = (uint16_t)(CANRX_ASS_unpackListExtID[i + 1U] << 3U) | (0x01 << 2U); + } + filt.FilterFIFOAssignment = i % CAN_RX_FIFO_COUNT; + filt.FilterActivation = ENABLE; + filt.SlaveStartFilterBank = (COUNTOF(CANRX_VEH_unpackList) + ((4U - COUNTOF(CANRX_VEH_unpackList) % 4U) % 4U)) / 4U; + HAL_CAN_ConfigFilter(&hcan[CAN_BUS_ASS], &filt); + } + HAL_CAN_ActivateNotification(&hcan[CAN_BUS_ASS], CAN_ENABLED_INTERRUPTS); + + return HW_OK; +} + +/** + * HAL_CAN_MspInit + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle) +{ + if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // CAN1 clock enable + __HAL_RCC_CAN1_CLK_ENABLE(); + + HAL_NVIC_SetPriority(CAN1_SCE_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_TX_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_RX0_IRQn, CAN_RX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN1_RX1_IRQn, CAN_RX_IRQ_PRIO, 0U); + + HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn); + HAL_NVIC_EnableIRQ(CAN1_TX_IRQn); + HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn); + HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn); + + } + else if (canHandle->Instance == hcan[CAN_BUS_ASS].Instance) + { + __HAL_RCC_CAN2_CLK_ENABLE(); + + HAL_NVIC_SetPriority(CAN2_SCE_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_TX_IRQn, CAN_TX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_RX0_IRQn, CAN_RX_IRQ_PRIO, 0U); + HAL_NVIC_SetPriority(CAN2_RX1_IRQn, CAN_RX_IRQ_PRIO, 0U); + + HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn); + HAL_NVIC_EnableIRQ(CAN2_TX_IRQn); + HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn); + } +} + +/** + * HAL_CAN_MspDeInit + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle) +{ + if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // Peripheral clock disable + __HAL_RCC_CAN1_CLK_DISABLE(); + + HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn); + HAL_NVIC_DisableIRQ(CAN1_TX_IRQn); + HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn); + HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn); + } + else if (canHandle->Instance == hcan[CAN_BUS_VEH].Instance) + { + // Peripheral clock disable + __HAL_RCC_CAN2_CLK_DISABLE(); + + HAL_NVIC_DisableIRQ(CAN2_SCE_IRQn); + HAL_NVIC_DisableIRQ(CAN2_TX_IRQn); + HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn); + HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn); + } +} + +// overload default interrupt callback functions provided by HAL +/** + * HAL_CAN_TxMailbox0CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_0); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox1CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_1); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox2CompleteCallback + * @param canHandle which CAN handle to operate on + */ +void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxComplete_ISR(bus, CAN_TX_MAILBOX_2); + HAL_CAN_DeactivateNotification(&hcan[bus], CAN_IER_TMEIE); +} + +/** + * HAL_CAN_TxMailbox0AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox0AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_0); +} + +/** + * HAL_CAN_TxMailbox1AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox1AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_1); +} + +/** + * HAL_CAN_TxMailbox2AbortCallback + * @param canHandle TODO + */ +void HAL_CAN_TxMailbox2AbortCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_TxError_ISR(bus, CAN_TX_MAILBOX_2); +} + +/** + * HAL_CAN_RxFifo0MsgPendingCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FMPIE0); +#endif // FEATURE_CANRX_SWI + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_0); +} + +/** + * HAL_CAN_RxFifo1MsgPendingCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FMPIE1); +#endif // FEATURE_CANRX_SWI + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_1); +} + +/** + * HAL_CAN_RxFifo0FullCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_0); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FFIE0); + SWI_invokeFromISR(CANRX_swi); +#endif // FEATURE_CANRX_SWI +} + +/** + * HAL_CAN_RxFifo1FullCallback + * @param canHandle TODO + */ +void HAL_CAN_RxFifo1FullCallback(CAN_HandleTypeDef* canHandle) +{ + CAN_bus_E bus = HW_CAN_getBusFromPeripheral(canHandle); + HW_CAN_RxMsgPending_ISR(bus, CAN_RX_FIFO_1); +#if FEATURE_IS_ENABLED(FEATURE_CANRX_SWI) + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_FFIE1); + SWI_invokeFromISR(CANRX_swi); +#endif // FEATURE_CANRX_SWI +} + +/** + * HAL_CAN_ErrorCallback + * @param canHandle TODO + */ +void HAL_CAN_ErrorCallback(CAN_HandleTypeDef* canHandle) +{ + HAL_CAN_DeactivateNotification(canHandle, CAN_IER_ERRIE); +} diff --git a/components/vc/rear/src/HW/HW_dma.c b/components/vc/rear/src/HW/HW_dma.c new file mode 100644 index 00000000..f4c5bba0 --- /dev/null +++ b/components/vc/rear/src/HW/HW_dma.c @@ -0,0 +1,29 @@ +/** + * @file HW_dma.c + * @brief Source code for DMA firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "HW_dma.h" + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Firmware DMA Initialization function + */ +void HW_DMA_init(void) +{ + // DMA controller clock enable + __HAL_RCC_DMA1_CLK_ENABLE(); + + // DMA interrupt init + // DMA1_Channel1_IRQn interrupt configuration + HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, DMA_IRQ_PRIO, 0U); + HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); +} diff --git a/components/vc/rear/src/HW/HW_gpio_componentSpecific.c b/components/vc/rear/src/HW/HW_gpio_componentSpecific.c new file mode 100644 index 00000000..b892719f --- /dev/null +++ b/components/vc/rear/src/HW/HW_gpio_componentSpecific.c @@ -0,0 +1,54 @@ +/** + * @file HW_gpio_componentSpecific.c + * @brief Source code for GPIO firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW_gpio.h" + +const HW_GPIO_S HW_GPIO_pinmux[HW_GPIO_COUNT] = { + [HW_GPIO_CAN1_RX] = { + .port = GPIOB, + .pin = GPIO_PIN_8, + .mode = GPIO_MODE_INPUT, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_NOSET, + }, + [HW_GPIO_CAN1_TX] = { + .port = GPIOB, + .pin = GPIO_PIN_9, + .mode = GPIO_MODE_AF_PP, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINSET, + }, + [HW_GPIO_CAN2_RX] = { + .port = GPIOB, + .pin = GPIO_PIN_12, + .mode = GPIO_MODE_INPUT, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_NOSET, + }, + [HW_GPIO_CAN2_TX] = { + .port = GPIOB, + .pin = GPIO_PIN_13, + .mode = GPIO_MODE_AF_PP, + .speed = GPIO_SPEED_FREQ_HIGH, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINSET, + }, + [HW_GPIO_LED] = { + .port = GPIOC, + .pin = GPIO_PIN_13, + .mode = GPIO_MODE_OUTPUT_PP, + .speed = GPIO_SPEED_FREQ_LOW, + .pull = GPIO_NOPULL, + .resetState = HW_GPIO_PINRESET, + }, +}; diff --git a/components/vc/rear/src/HW/HW_intc.c b/components/vc/rear/src/HW/HW_intc.c new file mode 100644 index 00000000..22bb3e84 --- /dev/null +++ b/components/vc/rear/src/HW/HW_intc.c @@ -0,0 +1,172 @@ +/** + * @file HW_intc.c + * @brief Source code for STM32F1xx Cortex M3 Interrupts + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// Firmware Includes +#include "HW_intc.h" +#include "NetworkDefines_generated.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern ADC_HandleTypeDef hadc1; +extern ADC_HandleTypeDef hadc2; +extern DMA_HandleTypeDef hdma_adc1; +extern TIM_HandleTypeDef htim1; +extern TIM_HandleTypeDef htim4; +extern TIM_HandleTypeDef htim2; +extern CAN_HandleTypeDef hcan[CAN_BUS_COUNT]; + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + volatile uint8_t c = 0; + + while (c == 0) + { + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + while (1) + { + } +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ +} + +// Peripheral Interrupt Handlers + +/** + * @brief This function handles DMA1 channel1 global interrupt. + */ +void DMA1_Channel1_IRQHandler(void) +{ + HAL_DMA_IRQHandler(&hdma_adc1); +} + +void ADC1_2_IRQHandler(void) +{ + HAL_ADC_IRQHandler(&hadc1); + // HAL_ADC_IRQHandler(&hadc2); +} + +void TIM2_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim2); +} + +void TIM1_TRG_COM_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim1); +} + +void TIM1_CC_IRQHandler(void) +{ + HAL_TIM_IRQHandler(&htim1); +} + +// CAN interrupts +void CAN1_SCE_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_TX_IRQHandler + * + */ +void CAN1_TX_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_RX0_IRQHandler + * + */ +void CAN1_RX0_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +/** + * CAN1_RX1_IRQHandler + * + */ +void CAN1_RX1_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_VEH]); +} + +void CAN2_SCE_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_ASS]); +} + +void CAN2_TX_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_ASS]); +} + +void CAN2_RX0_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_ASS]); +} + +void CAN2_RX1_IRQHandler(void) +{ + HAL_CAN_IRQHandler(&hcan[CAN_BUS_ASS]); +} diff --git a/components/vc/rear/src/HW/HW_msp.c b/components/vc/rear/src/HW/HW_msp.c new file mode 100644 index 00000000..e43824a5 --- /dev/null +++ b/components/vc/rear/src/HW/HW_msp.c @@ -0,0 +1,30 @@ +/** + * @file HW_msp.c + * @brief Source code for generic Msp firmware calls + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" + + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Overrides weak HAL Link for our implementation + */ +void HAL_MspInit(void) +{ + __HAL_RCC_AFIO_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); + + // Enable SWD, disable JTAG + __HAL_AFIO_REMAP_SWJ_NOJTAG(); +} diff --git a/components/vc/rear/src/HW/HW_tim.c b/components/vc/rear/src/HW/HW_tim.c new file mode 100644 index 00000000..9deec4eb --- /dev/null +++ b/components/vc/rear/src/HW/HW_tim.c @@ -0,0 +1,264 @@ +/** + * @file HW_tim.c + * @brief Source code for TIM firmware + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +// System Includes +#include "SystemConfig.h" +#include "LIB_Types.h" + +// Firmware Includes +#include "HW_tim.h" + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim2; + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called TIMx interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) +{ + if (htim->Instance == TIM2) + { + HAL_IncTick(); + } +} + +/** + * @brief Initializes TIM peripherals + * + * @retval true = Success, false = Failure + */ +HAL_StatusTypeDef HW_TIM_init(void) +{ + TIM_ClockConfigTypeDef sClockSourceConfig = { 0 }; + TIM_SlaveConfigTypeDef sSlaveConfig = { 0 }; + TIM_IC_InitTypeDef sConfigIC = { 0 }; + TIM_MasterConfigTypeDef sMasterConfig = { 0 }; + + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock = 0; + uint32_t uwPrescalerValue = 0; + uint32_t pFLatency; + + // Get clock configuration + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + // Compute TIM4 clock + uwTimclock = 2 * HAL_RCC_GetPCLK2Freq(); + // Compute the prescaler value to have TIM4 counter clock equal to 1MHz + uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U); + + htim1.Instance = TIM1; + htim1.Init.Prescaler = uwPrescalerValue; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 1000000000; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_IC_Init(&htim1) != HAL_OK) + { + Error_Handler(); + } + sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET; + sSlaveConfig.InputTrigger = TIM_TS_TI2FP2; + sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1; + sSlaveConfig.TriggerFilter = 0; + if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; + sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI; + sConfigIC.ICFilter = 0; + if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; + sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; + sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; + if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + // Configure the TIM4 IRQ priority + HAL_NVIC_SetPriority(TIM1_CC_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_BRK_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_UP_IRQn, TICK_INT_PRIORITY, 0); + HAL_NVIC_SetPriority(TIM1_TRG_COM_IRQn, TICK_INT_PRIORITY, 0); + + // Enable the TIM4 global Interrupt + HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + HAL_NVIC_EnableIRQ(TIM1_BRK_IRQn); + HAL_NVIC_EnableIRQ(TIM1_UP_IRQn); + HAL_NVIC_EnableIRQ(TIM1_TRG_COM_IRQn); + + HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2); // main channel + HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_1); // indirect channel + + return HAL_OK; +} + +/** + * @brief HAL callback once Initialization is complete. Used for GPIO/INTERRUPT configuration + * + * @param htim_base TIM peripheral + */ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim) +{ + if (tim->Instance == TIM1) + { + __HAL_RCC_TIM1_CLK_ENABLE(); + } +} + +/** + * @brief HAL callback called once an input capture has triggered + * + * @param htim TIM peripheral + */ +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim) +{ + if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) // If the interrupt is triggered by channel 1 + { + } +} + +/** + * @brief RTOS callback to configure a more precise timebase for cpu profiling + */ +void HW_TIM_configureRunTimeStatsTimer(void) +{ +} + +/** + * @brief RTOS Profiling has a ~1us accuracy by using the OS CLK and internal counter + * + * @retval Elapsed time in us from clock start + */ +uint64_t HW_TIM_getBaseTick() +{ + // return fast_clk; + + return ((uint64_t)HW_getTick() * 1000) + htim2.Instance->CNT; +} + +/** + * @brief Get the number of ticks since clock start + * + * @retval Number of ticks + */ +uint32_t HW_TIM_getTick(void) +{ + return HAL_GetTick(); +} + +uint32_t HW_TIM_getTimeMS() +{ + return HW_TIM_getTick(); +} + +/** + * HAL_InitTick + * This function configures the TIM4 as a time base source. + * The time source is configured to have 1ms time base with a dedicated + * Tick interrupt priority. + * @note This function is called automatically at the beginning of program after + * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). + * @param TickPriority Tick interrupt priority. + * @return exit status + */ +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + RCC_ClkInitTypeDef clkconfig; + uint32_t uwTimclock = 0; + uint32_t uwPrescalerValue = 0; + uint32_t pFLatency; + + // Configure the TIM4 IRQ priority + HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority, 0); + + // Enable the TIM4 global Interrupt + HAL_NVIC_EnableIRQ(TIM2_IRQn); + + // Enable TIM4 clock + __HAL_RCC_TIM2_CLK_ENABLE(); + + // Get clock configuration + HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); + + // Compute TIM2 clock + uwTimclock = 1 * HAL_RCC_GetPCLK2Freq(); + // Compute the prescaler value to have TIM4 counter clock equal to 1MHz + uwPrescalerValue = (uint32_t)((uwTimclock / 1000000U) - 1U); + + // Initialize TIM4 + htim2.Instance = TIM2; + + // Initialize TIMx peripheral as follow: + // Period = [(TIM4CLK/1000) - 1]. to have a (1/1000) s time base. + // Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. + // ClockDivision = 0 + // Counter direction = Up + htim2.Init.Period = (1000000U / 1000) - 1U; + htim2.Init.Prescaler = uwPrescalerValue; + htim2.Init.ClockDivision = 0; + htim2.Init.CounterMode = TIM_COUNTERMODE_UP; + + if (HAL_TIM_Base_Init(&htim2) == HAL_OK) + { + // Start the TIM time Base generation in interrupt mode + return HAL_TIM_Base_Start_IT(&htim2); + } + + return HAL_ERROR; +} + +/** + * @brief Suspends the tick interrupt + */ +void HAL_SuspendTick(void) +{ + __HAL_TIM_DISABLE_IT(&htim2, TIM_IT_UPDATE); +} + + +/** + * @brief Resumes tick interrupt + */ +void HAL_ResumeTick(void) +{ + __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE); +} diff --git a/components/vc/rear/src/IO.c b/components/vc/rear/src/IO.c new file mode 100644 index 00000000..c875dc70 --- /dev/null +++ b/components/vc/rear/src/IO.c @@ -0,0 +1,161 @@ +/** + * @file IO.c + * @brief Source code for IO Module + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Module Header */ +#include "IO.h" + +/**< System Includes*/ +#include "LIB_Types.h" +#include + +/**< Firmware Includes */ +#include "HW.h" +#include "HW_adc.h" +#include "HW_dma.h" +#include "HW_gpio.h" + +/**< Other Includes */ +#include "ModuleDesc.h" +#include "Utility.h" + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +typedef enum +{ + ADC_STATE_INIT = 0, + ADC_STATE_CALIBRATION, + ADC_STATE_RUNNING, + ADC_STATE_CALIBRATION_FAILED, + ADC_STATE_COUNT, +} adcState_E; + +typedef enum +{ + ADC_MCU_TEMP, + ADC_MCU_TEMP_temporary, + ADC_CHANNEL_COUNT, +} adcChannels_E; +_Static_assert(IO_ADC_BUF_LEN % ADC_CHANNEL_COUNT == 0, "ADC Buffer Length should be a multiple of the number of ADC channels"); +_Static_assert((IO_ADC_BUF_LEN / 2) % ADC_CHANNEL_COUNT == 0, "ADC Buffer Length divided by two should be a multiple of the number of ADC channels"); + +typedef struct +{ + adcState_E adcState; + uint32_t adcBuffer[IO_ADC_BUF_LEN]; + simpleFilter_S adcData[ADC_CHANNEL_COUNT]; +} io_S; + + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +static io_S io; + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +/** + * @brief Stores the public IO struct + */ +IO_S IO; + + +/****************************************************************************** + * P R I V A T E F U N C T I O N P R O T O T Y P E S + ******************************************************************************/ + +void IO_unpackADCBuffer(void); + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief IO Module Init function + */ +static void IO_init(void) +{ + memset(&io, 0x00, sizeof(io)); + memset(&IO, 0x00, sizeof(IO)); +} + +static void IO10Hz_PRD(void) +{ + if (io.adcState == ADC_STATE_INIT) + { + io.adcState = ADC_STATE_CALIBRATION; + if (HW_ADC_calibrate(&hadc1) && HW_ADC_calibrate(&hadc2)) + { + HW_ADC_startDMA(&hadc1, (uint32_t*)&io.adcBuffer, IO_ADC_BUF_LEN); + io.adcState = ADC_STATE_RUNNING; + } + else + { + io.adcState = ADC_STATE_CALIBRATION_FAILED; + } + } + else if (io.adcState == ADC_STATE_CALIBRATION_FAILED) + { + // adc calibration failed + // what do now? + } + else if (io.adcState == ADC_STATE_RUNNING) + { + IO_unpackADCBuffer(); + IO.mcu_temp = (io.adcData[ADC_MCU_TEMP].value / ADC_MAX_VAL) * VREF; + } +} + +/** + * @brief IO Module descriptor + */ +const ModuleDesc_S IO_desc = { + .moduleInit = &IO_init, + .periodic10Hz_CLK = &IO10Hz_PRD, +}; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Unpack ADC buffer + */ +void IO_unpackADCBuffer(void) +{ + for (uint8_t i = 0; i < ADC_CHANNEL_COUNT; i++) + { + io.adcData[i].raw = 0; + io.adcData[i].count = 0; + } + + for (uint16_t i = 0; i < IO_ADC_BUF_LEN; i++) + { + if (i % 2 == 0) + { + } + else + { + io.adcData[ADC_MCU_TEMP].raw += io.adcBuffer[i] & 0xffff; + io.adcData[ADC_MCU_TEMP].count++; + } + } + + io.adcData[ADC_MCU_TEMP].value = (float32_t)io.adcData[ADC_MCU_TEMP].raw / io.adcData[ADC_MCU_TEMP].count; +} diff --git a/components/vc/rear/src/Module_componentSpecific.c b/components/vc/rear/src/Module_componentSpecific.c new file mode 100644 index 00000000..6f25f4c0 --- /dev/null +++ b/components/vc/rear/src/Module_componentSpecific.c @@ -0,0 +1,27 @@ +/** + * @file Module.c + * @brief Source code for Module Manager + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Module Header */ +#include "Module.h" + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +/** + * @brief Modules run by the Module Manager. Order will apply to execution. + */ +const ModuleDesc_S* modules[] = { + &IO_desc, +#if APP_UDS + &UDS_desc, +#endif + &CANIO_rx, + &CANIO_tx, +}; diff --git a/components/vc/rear/src/SystemManager.c b/components/vc/rear/src/SystemManager.c new file mode 100644 index 00000000..29aa1c1c --- /dev/null +++ b/components/vc/rear/src/SystemManager.c @@ -0,0 +1,107 @@ +/** + * @file SystemManager.c + * @brief Runs the Embedded System. Contains main called by the startup assembly. + */ + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +/**< Firmware Includes */ +#include "HW.h" +#include "HW_adc.h" +#include "HW_can.h" +#include "HW_clock.h" +#include "HW_dma.h" +#include "HW_gpio.h" +#include "HW_tim.h" + +/**< FreeRTOS Includes */ +#include "FreeRTOS.h" +#include "FreeRTOS_SWI.h" +#include "task.h" + +/**< Other Includes */ +#include "Module.h" + +#include "LIB_app.h" + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern void RTOS_createResources(void); + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +// defined by linker +extern const uint32_t __app_start_addr; +extern const uint32_t __app_end_addr; +extern const uint32_t __app_crc_addr; + +__attribute__((section(".appDescriptor"))) +const lib_app_appDesc_S appDesc = { + .appStart = (const uint32_t)&__app_start_addr, + .appEnd = (const uint32_t)&__app_end_addr, + // .appCrcLocation = (const uint32_t)&__app_crc_addr, + .appCrcLocation = (const uint32_t)&__app_end_addr, + .appComponentId = APP_COMPONENT_ID, + .appPcbaId = APP_PCBA_ID, +}; + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/** + * @brief Main function called by the bootloader + * + * @retval none + */ +int main(void) +{ + /**< Setup HAL Reset all peripherals. Initializes the Flash interface and the Systick. */ + HW_init(); + + /**< Configure system clocks */ + HW_systemClockConfig(); + + /**< Initiate Firmware */ + /**< Order is important, don't change without checking */ + HW_TIM_init(); + HW_CAN_init(); + HW_DMA_init(); + HW_ADC_init(); + HW_GPIO_init(); + + ///**< Create RTOS Tasks, Timers, etc... */ + RTOS_SWI_Init(); + RTOS_createResources(); + + ///**< Initialize Modules */ + Module_Init(); + + ///**< Start RTOS task scheduler. Should never return */ + vTaskStartScheduler(); + + return 0; +} + +/** + * @brief This function is executed in case of error occurrence. + */ +void Error_Handler(void) +{ + __disable_irq(); + + /**< Fast Toggle LED */ + while (1) + { + uint32_t cnt = 6400000; + HW_GPIO_togglePin(HW_GPIO_LED); + while (cnt--) + ; + } +} diff --git a/components/vc/rear/src/UDS.c b/components/vc/rear/src/UDS.c new file mode 100644 index 00000000..d7241e08 --- /dev/null +++ b/components/vc/rear/src/UDS.c @@ -0,0 +1,291 @@ +/* + * UDS.c + * UDS module implementation + */ + + +/****************************************************************************** + * I N C L U D E S + ******************************************************************************/ + +#include "FeatureDefines_generated.h" +#if APP_UDS + +#ifndef ISO_TP_USER_DEBUG_ENABLED +#define ISO_TP_USER_DEBUG_ENABLED 0U +#endif + +// module include +#include "UDS.h" + +// other includes +#include "CAN/CanTypes.h" +#include "FreeRTOS.h" +#include "HW.h" +#include "HW_can.h" +#include "ModuleDesc.h" +#include "task.h" +#include "uds.h" +#include "LIB_app.h" +#include "Utility.h" + +// system includes +#include + +/****************************************************************************** + * E X T E R N S + ******************************************************************************/ + +extern uint16_t isotp_user_send_can(const uint32_t id, const uint8_t data[], const uint8_t len); +extern uint32_t isotp_user_get_ms(void); +#if ISO_TP_USER_DEBUG_ENABLED +extern void isotp_user_debug(const char* message, ...); +#endif + + +/****************************************************************************** + * D E F I N E S + ******************************************************************************/ + + +/****************************************************************************** + * T Y P E D E F S + ******************************************************************************/ + +// typedef struct +// { +// } uds_S; + +/****************************************************************************** + * P R I V A T E V A R S + ******************************************************************************/ + +// static uds_S uds; + +/****************************************************************************** + * P R I V A T E F U N C T I O N S + ******************************************************************************/ + + +/****************************************************************************** + * P U B L I C F U N C T I O N S + ******************************************************************************/ + +/* + * UDS_init + * @brief initialize the UDS module + */ +static void UDS_init(void) +{ + udsSrv_init(); // initialize the UDS library +} + +/* + * UDS_periodic + * @brief periodic UDS function. Needs to be called at 1kHz + */ +static void UDS_periodic_1kHz(void) +{ + udsSrv_periodic(); +} + + +/****************************************************************************** + * P U B L I C V A R S + ******************************************************************************/ + +// module description +// TODO: right now there are no UDS operations that will really block for anything. +// If ever that changes, UDS should probably get its own dedicated task +const ModuleDesc_S UDS_desc = { + .moduleInit = &UDS_init, + .periodic1kHz_CLK = &UDS_periodic_1kHz, +}; + + +/****************************************************************************** + * U D S L I B R A R Y C A L L B A C K S + ******************************************************************************/ + +/* + * uds_cb_ecuReset + * @brief callback for uds ecu reset service + */ +void uds_cb_ecuReset(udsResetType_E resetType) +{ + switch (resetType) + { + case UDS_RESET_TYPE_HARD: + // have to send positive response from here since this function + // won't return in this case + uds_sendPositiveResponse(UDS_SID_ECU_RESET, resetType, NULL, 0U); + + // one day we can have an actual check here to see if the ecu is ready to reset + // i.e. check eeprom writes finished, etc. + vTaskDelay(pdMS_TO_TICKS(10U)); + + // Reset + // FIXME: move this to a function somewhere + { + HW_systemHardReset(); + + // loop while we wait for the reset to happen + while (1) + { + __asm__ volatile ("nop"); + } + } + break; + + case UDS_RESET_TYPE_KEY: + case UDS_RESET_TYPE_SOFT: + case UDS_RESET_RAPID_SHUTDOWN_ENABLE: + case UDS_RESET_RAPID_SHUTDOWN_DISABLE: + // not implemented + uds_sendNegativeResponse(UDS_SID_ECU_RESET, UDS_NRC_SUB_FUNCTION_NOT_SUPPORTED); + break; + + default: + uds_sendNegativeResponse(UDS_SID_ECU_RESET, UDS_NRC_GENERAL_REJECT); + break; + } +} + + +/* + * uds_cb_routineControl + * @brief callback for uds routine control service + */ +void uds_cb_routineControl(udsRoutineControlType_E routineControlType, uint8_t *payload, uint8_t payloadLengthBytes) +{ + UNUSED(routineControlType); + if (payloadLengthBytes < 2U) + { + uds_sendNegativeResponse(UDS_SID_ROUTINE_CONTROL, UDS_NRC_INVALID_LEN_FORMAT); + return; + } + + union + { + uint8_t u8[2U]; + uint16_t u16; + } routineId; + + memcpy(routineId.u8, payload, 2); + + switch (routineId.u16) + { + default: + uds_sendNegativeResponse(UDS_SID_ROUTINE_CONTROL, UDS_NRC_SERVICE_NOT_SUPPORTED); + break; + } +} + + +/* + * uds_cb_DIDRead + * @brief callback for a data ID read + */ +void uds_cb_DIDRead(uint8_t *payload, uint8_t payloadLengthBytes) +{ + if (payloadLengthBytes != 2U) + { + uds_sendNegativeResponse(UDS_SID_READ_DID, UDS_NRC_INVALID_LEN_FORMAT); + return; + } + + union + { + uint8_t u8[2U]; + uint16_t u16; + } did; + + memcpy(did.u8, payload, 2); + + switch (did.u16) + { + case 0x00: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appStart, sizeof(appDesc.appStart)); + break; + } + case 0x01: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appEnd, sizeof(appDesc.appEnd)); + break; + } + case 0x02: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appCrcLocation, sizeof(appDesc.appCrcLocation)); + break; + } + case 0x03: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&(*((uint32_t*)appDesc.appCrcLocation)), sizeof(*((uint32_t*)appDesc.appCrcLocation))); + break; + } + case 0x04: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appComponentId, sizeof(appDesc.appComponentId)); + break; + } + case 0x05: + { + extern const lib_app_appDesc_S appDesc; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, (uint8_t*)&appDesc.appPcbaId, sizeof(appDesc.appPcbaId)); + break; + } + case 0x101: + { + // always respond with 0x01 since we're in the app + uint8_t data = 0x01; + uds_sendPositiveResponse(UDS_SID_READ_DID, UDS_NRC_NONE, &data, 1); + break; + } + + default: + uds_sendNegativeResponse(UDS_SID_READ_DID, UDS_NRC_GENERAL_REJECT); + break; + } +} + + +/****************************************************************************** + * U D S L I B R A R Y F U N C T I O N S + ******************************************************************************/ +// define functions required for isotp library + +uint16_t isotp_user_send_can(const uint32_t id, const uint8_t data[], const uint8_t len) +{ + CAN_data_T d; + bool sent = false; + + memcpy(&d, data, len); + + if (HW_CAN_sendMsg(CAN_BUS_VEH, d, id, len)) + { + sent = true; + } + return sent; +} + + +uint32_t isotp_user_get_ms(void) +{ + return xTaskGetTickCount(); +} + + +#if ISO_TP_USER_DEBUG_ENABLED +extern void isotp_user_debug(const char* message, ...); +void isotp_user_debug(const char* message, ...) +{ + UNUSED(message); +} +#endif // ISO_TP_USER_DEBUG_ENABLED +#endif // FEATURE_UDS diff --git a/components/vc/rear/src/Utility.c b/components/vc/rear/src/Utility.c new file mode 100644 index 00000000..fcc03a54 --- /dev/null +++ b/components/vc/rear/src/Utility.c @@ -0,0 +1,26 @@ +#include "Utility.h" + +float32_t ln(float32_t x) +{ + uint32_t bx = *(uint32_t*)(&x); + uint32_t ex = bx >> 23; + int32_t t = (int32_t)ex - (int32_t)127; + + // unsigned int s = (t < 0) ? (-t) : t; + bx = 1065353216 | (bx & 8388607); + x = *(float32_t*)(&bx); + return (float32_t)(-1.49278f + (2.11263f + (-0.729104f + 0.10969f * x) * x) * x + 0.6931471806f * (float32_t)t); +} + +uint8_t* reverse_bytes(uint8_t* in, uint8_t len) +{ + for (uint8_t i = 0; i < (len / 2); i++) + { + uint8_t tmp = in[i]; + + in[i] = in[len - i - 1]; + in[len - i - 1] = tmp; + } + + return in; +} diff --git a/components/vc/rear/variants.yaml b/components/vc/rear/variants.yaml new file mode 100644 index 00000000..c7ed6dc8 --- /dev/null +++ b/components/vc/rear/variants.yaml @@ -0,0 +1,11 @@ +configs: + 0: + description: Front Vehicle Control Unit + options: + features: + selections: + - "#/components/shared/FeatureSels/STM32F105_FeatureSels.yaml" + - "#/components/shared/FeatureSels/APP_V1_FeatureSels.yaml" + - "FeatureSels.yaml" + overrides: + app_pcba_id: 0 diff --git a/network/NetworkGen/templates/CANTypes_generated.h.mako b/network/NetworkGen/templates/CANTypes_generated.h.mako index e540011b..9cc3d517 100644 --- a/network/NetworkGen/templates/CANTypes_generated.h.mako +++ b/network/NetworkGen/templates/CANTypes_generated.h.mako @@ -7,14 +7,6 @@ #pragma once -/****************************************************************************** - * I N C L U D E S - ******************************************************************************/ - -#include "stdbool.h" -#include "stdint.h" -#include "FloatTypes.h" - /****************************************************************************** * T Y P E D E F S ******************************************************************************/ diff --git a/network/NetworkGen/templates/MessagePack_generated.h.mako b/network/NetworkGen/templates/MessagePack_generated.h.mako index 4f24d95a..77a62ead 100644 --- a/network/NetworkGen/templates/MessagePack_generated.h.mako +++ b/network/NetworkGen/templates/MessagePack_generated.h.mako @@ -10,7 +10,7 @@ ******************************************************************************/ #include "CAN/CanTypes.h" -#include "FloatTypes.h" +#include "LIB_FloatTypes.h" #include "Utility.h" #include "NetworkDefines_generated.h" diff --git a/network/NetworkGen/templates/SigRx.h.mako b/network/NetworkGen/templates/SigRx.h.mako index 2a85bdd7..91dd38ed 100644 --- a/network/NetworkGen/templates/SigRx.h.mako +++ b/network/NetworkGen/templates/SigRx.h.mako @@ -13,9 +13,8 @@ #include "MessageUnpack_generated.h" #include "CANTypes_generated.h" -#include "stdbool.h" -#include "stdint.h" -#include "FloatTypes.h" +#include "LIB_FloatTypes.h" +#include "LIB_Types.h" #include "Utility.h" #include "CANIO_componentSpecific.h" diff --git a/network/definition/buses/ass.yaml b/network/definition/buses/ass.yaml new file mode 100644 index 00000000..520fcab7 --- /dev/null +++ b/network/definition/buses/ass.yaml @@ -0,0 +1,4 @@ +name: "ass" +description: "CANBus for the rear of the vehicle" +defaultEndianness: "little" +baudrate: 500000 # kbps diff --git a/network/definition/buses/body.yaml b/network/definition/buses/body.yaml new file mode 100644 index 00000000..1a0f2148 --- /dev/null +++ b/network/definition/buses/body.yaml @@ -0,0 +1,4 @@ +name: "body" +description: "CANBus for the center of the vehicle" +defaultEndianness: "little" +baudrate: 500000 # kbps diff --git a/network/definition/buses/nose.yaml b/network/definition/buses/nose.yaml new file mode 100644 index 00000000..a8aa681f --- /dev/null +++ b/network/definition/buses/nose.yaml @@ -0,0 +1,4 @@ +name: "nose" +description: "CANBus for the front of the vehicle" +defaultEndianness: "little" +baudrate: 500000 # kbps diff --git a/network/definition/data/components/udsClient/udsClient-message.yaml b/network/definition/data/components/udsClient/udsClient-message.yaml index d1f1499e..ef7f1f9f 100644 --- a/network/definition/data/components/udsClient/udsClient-message.yaml +++ b/network/definition/data/components/udsClient/udsClient-message.yaml @@ -46,3 +46,21 @@ messages: cycleTimeMs: 10 id: 0x620 template: uds + + vcfrontUdsRequest: + description: UDS request message for the Steering Wheel + cycleTimeMs: 10 + id: 0x630 + template: uds + + vcrearUdsRequest: + description: UDS request message for the Steering Wheel + cycleTimeMs: 10 + id: 0x631 + template: uds + + vcpduUdsRequest: + description: UDS request message for the Steering Wheel + cycleTimeMs: 10 + id: 0x632 + template: uds diff --git a/network/definition/data/components/vcfront/vcfront-message.yaml b/network/definition/data/components/vcfront/vcfront-message.yaml new file mode 100644 index 00000000..21137d09 --- /dev/null +++ b/network/definition/data/components/vcfront/vcfront-message.yaml @@ -0,0 +1,13 @@ +messages: + udsResponse: + description: UDS response message from the VCFRONT + id: 0x670 + lengthBytes: 8 + sourceBuses: veh + template: uds + + rtosTaskInfo: + description: VCFRONT rtos task information + id: 0x551 + sourceBuses: veh + template: rtosTaskInfo diff --git a/network/definition/data/components/vcfront/vcfront-rx.yaml b/network/definition/data/components/vcfront/vcfront-rx.yaml new file mode 100644 index 00000000..aef5ce8b --- /dev/null +++ b/network/definition/data/components/vcfront/vcfront-rx.yaml @@ -0,0 +1,5 @@ +messages: + UDSCLIENT_vcfrontUdsRequest: + sourceBuses: veh + unrecorded: true +signals: diff --git a/network/definition/data/components/vcfront/vcfront-signals.yaml b/network/definition/data/components/vcfront/vcfront-signals.yaml new file mode 100644 index 00000000..a9d0736f --- /dev/null +++ b/network/definition/data/components/vcfront/vcfront-signals.yaml @@ -0,0 +1 @@ +signals: diff --git a/network/definition/data/components/vcfront/vcfront.yaml b/network/definition/data/components/vcfront/vcfront.yaml new file mode 100644 index 00000000..d63f9b74 --- /dev/null +++ b/network/definition/data/components/vcfront/vcfront.yaml @@ -0,0 +1,4 @@ +description: "Front Vehicle Controller" +onBuses: + - "veh" + - "nose" diff --git a/network/definition/data/components/vcpdu/vcpdu-message.yaml b/network/definition/data/components/vcpdu/vcpdu-message.yaml new file mode 100644 index 00000000..5944ed90 --- /dev/null +++ b/network/definition/data/components/vcpdu/vcpdu-message.yaml @@ -0,0 +1,12 @@ +messages: + udsResponse: + description: UDS response message from the VCPDU + id: 0x672 + sourceBuses: veh + template: uds + + rtosTaskInfo: + description: VCPDU rtos task information + id: 0x553 + sourceBuses: veh + template: rtosTaskInfo diff --git a/network/definition/data/components/vcpdu/vcpdu-rx.yaml b/network/definition/data/components/vcpdu/vcpdu-rx.yaml new file mode 100644 index 00000000..7b45975f --- /dev/null +++ b/network/definition/data/components/vcpdu/vcpdu-rx.yaml @@ -0,0 +1,5 @@ +messages: + UDSCLIENT_vcpduUdsRequest: + sourceBuses: veh + unrecorded: true +signals: diff --git a/network/definition/data/components/vcpdu/vcpdu-signals.yaml b/network/definition/data/components/vcpdu/vcpdu-signals.yaml new file mode 100644 index 00000000..a9d0736f --- /dev/null +++ b/network/definition/data/components/vcpdu/vcpdu-signals.yaml @@ -0,0 +1 @@ +signals: diff --git a/network/definition/data/components/vcpdu/vcpdu.yaml b/network/definition/data/components/vcpdu/vcpdu.yaml new file mode 100644 index 00000000..0eb01e29 --- /dev/null +++ b/network/definition/data/components/vcpdu/vcpdu.yaml @@ -0,0 +1,4 @@ +description: "Power Distribution Unit Controller" +onBuses: + - "veh" + - "body" diff --git a/network/definition/data/components/vcrear/vcrear-message.yaml b/network/definition/data/components/vcrear/vcrear-message.yaml new file mode 100644 index 00000000..466e13b8 --- /dev/null +++ b/network/definition/data/components/vcrear/vcrear-message.yaml @@ -0,0 +1,13 @@ +messages: + udsResponse: + description: UDS response message from the VCREAR + id: 0x671 + lengthBytes: 8 + sourceBuses: veh + template: uds + + rtosTaskInfo: + description: VCREAR rtos task information + id: 0x552 + sourceBuses: veh + template: rtosTaskInfo diff --git a/network/definition/data/components/vcrear/vcrear-rx.yaml b/network/definition/data/components/vcrear/vcrear-rx.yaml new file mode 100644 index 00000000..d1d8cfe4 --- /dev/null +++ b/network/definition/data/components/vcrear/vcrear-rx.yaml @@ -0,0 +1,5 @@ +messages: + UDSCLIENT_vcrearUdsRequest: + sourceBuses: veh + unrecorded: true +signals: diff --git a/network/definition/data/components/vcrear/vcrear-signals.yaml b/network/definition/data/components/vcrear/vcrear-signals.yaml new file mode 100644 index 00000000..a9d0736f --- /dev/null +++ b/network/definition/data/components/vcrear/vcrear-signals.yaml @@ -0,0 +1 @@ +signals: diff --git a/network/definition/data/components/vcrear/vcrear.yaml b/network/definition/data/components/vcrear/vcrear.yaml new file mode 100644 index 00000000..a4e2132f --- /dev/null +++ b/network/definition/data/components/vcrear/vcrear.yaml @@ -0,0 +1,4 @@ +description: "Rear Vehicle Controller" +onBuses: + - "veh" + - "ass" diff --git a/site_scons/components.yaml b/site_scons/components.yaml index 0519cbd1..f5c898bb 100644 --- a/site_scons/components.yaml +++ b/site_scons/components.yaml @@ -8,3 +8,9 @@ heartbeat: path: components/heartbeat/ stw: path: components/steering_wheel/ +vcfront: + path: components/vc/ +vcrear: + path: components/vc/ +vcpdu: + path: components/vc/ diff --git a/site_scons/platforms.yaml b/site_scons/platforms.yaml index 1ba01d75..3d188dc5 100644 --- a/site_scons/platforms.yaml +++ b/site_scons/platforms.yaml @@ -29,3 +29,12 @@ configs: 4: # BMS Worker 5: # BMS Worker 11: # BMS Boss + 30: # VCFRONT + 31: # VCREAR + 32: # VCPDU + vcfront: + 0: + vcrear: + 0: + vcpdu: + 0: diff --git a/site_scons/site_tools/network.py b/site_scons/site_tools/network.py index c56d8962..bcab51dd 100644 --- a/site_scons/site_tools/network.py +++ b/site_scons/site_tools/network.py @@ -32,7 +32,6 @@ def emitBuild(target, source, env): buses = [file.name.split('.')[0] for file in recursive_glob(env["NETWORK_DATA_DIR"].Dir("buses"), "*.yaml")] source.extend(recursive_glob(env["NETWORK_PATH"], "*.py")) source.extend(recursive_glob(env["NETWORK_DATA_DIR"], "*.yaml")) - source.extend(recursive_glob(env["NETWORK_DATA_DIR"], "*.mako")) target.append([ env["NETWORK_OUTPUT_DIR"].File(f"{bus}.dbc") for bus in buses ]) target.append([ env["NETWORK_OUTPUT_DIR"].File(f"{bus}-stats.txt") for bus in buses ]) target.append(env["NETWORK_CACHE_DIR"].File("CachedNodes.pickle")) @@ -42,7 +41,7 @@ def emitBuild(target, source, env): return (target, source) def emitGen(target, source, env): - source.extend(recursive_glob(env["NETWORK_DATA_DIR"], "*.mako")) + source.extend(recursive_glob(env["NETWORK_PATH"], "*.mako")) source.append(env["NETWORK_CACHE_DIR"].File("CachedNodes.pickle")) source.append(env["NETWORK_CACHE_DIR"].File("CachedBusDefs.pickle")) source.append(env["NETWORK_CACHE_DIR"].File("CachedDiscreteValues.pickle"))