diff --git a/.gitignore b/.gitignore index 68d5f6e5fb38d07046ae2d8dc3a73ef36c1739bd..b343c6b2757c76d96ce39f08c5d2e62e0fe30fc5 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ cmake-build-* store.json **/generated/ -core __pycache__ /scripts/generators/generated diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 895903d9393dbc530e59f77112078e50f5c70426..b16913f5d592d9ad34870956331d1f027fc482d5 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -20,15 +20,16 @@ ] }, "configurations": [ + // Skyward boards { - "name": "stm32f205rc_skyward_ciuti", + "name": "stm32f205rc_ciuti", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f205RC_skyward_ciuti", - "_BOARD_STM32F205RC_SKYWARD_CIUTI", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f205rc_ciuti", + "_BOARD_STM32F205RC_CIUTI", "_ARCH_CORTEXM3_STM32F2", "STM32F205xx", "HSE_VALUE=25000000", @@ -38,64 +39,43 @@ "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM3_stm32f2/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM3_stm32f2/stm32f205rc_skyward_ciuti", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM3_stm32f2/stm32f205rc_skyward_ciuti" + "${workspaceFolder}/src/bsps/stm32f205rc_ciuti/config", + "${workspaceFolder}/src/bsps/stm32f205rc_ciuti" ] }, { - "name": "stm32f407vg_stm32f4discovery", + "name": "stm32f429zi_death_stack_v1", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f407vg_stm32f4discovery", - "_BOARD_STM32F4DISCOVERY", - "_ARCH_CORTEXM4_STM32F4", - "STM32F407xx", - "HSE_VALUE=8000000", - "SYSCLK_FREQ_168MHz=168000000", - "V_DDA_VOLTAGE=3.0f" - ], - "includePath": [ - "${defaultIncludePaths}", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery" - ] - }, - { - "name": "stm32f429zi_hre_test_stand", - "cStandard": "c11", - "cppStandard": "c++14", - "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", - "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_hre_test_stand", - "_BOARD_STM32F429ZI_HRE_TEST_STAND", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_death_stack_v1", + "_BOARD_STM32F429ZI_DEATH_STACK_V1", "_ARCH_CORTEXM4_STM32F4", "STM32F429xx", "HSE_VALUE=8000000", "SYSCLK_FREQ_168MHz=168000000", "__ENABLE_XRAM", - "V_DDA_VOLTAGE=3.0f" + "V_DDA_VOLTAGE=3.3f" ], "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_hre_test_stand", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_hre_test_stand" - ] + "${workspaceFolder}/src/bsps/stm32f429zi_death_stack_v1/config", + "${workspaceFolder}/src/bsps/stm32f429zi_death_stack_v1" + ], + "configurationProvider": "ms-vscode.cmake-tools" }, { - "name": "stm32f429zi_skyward_death_stack_v3", + "name": "stm32f429zi_death_stack_v2", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_death_stack_v3", - "_BOARD_STM32F429ZI_SKYWARD_DEATHST_X", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_death_stack_v2", + "_BOARD_STM32F429ZI_DEATH_STACK_V2", "_ARCH_CORTEXM4_STM32F4", "STM32F429xx", "HSE_VALUE=8000000", @@ -106,19 +86,19 @@ "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_death_stack_v3", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_death_stack_v3" + "${workspaceFolder}/src/bsps/stm32f429zi_death_stack_v2/config", + "${workspaceFolder}/src/bsps/stm32f429zi_death_stack_v2" ] }, { - "name": "stm32f429zi_skyward_death_stack_x", + "name": "stm32f429zi_death_stack_v3", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_death_stack_x", - "_BOARD_STM32F429ZI_SKYWARD_DEATHST_X", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_death_stack_v3", + "_BOARD_STM32F429ZI_DEATH_STACK_V3", "_ARCH_CORTEXM4_STM32F4", "STM32F429xx", "HSE_VALUE=8000000", @@ -129,42 +109,42 @@ "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_death_stack_x", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_death_stack_x" + "${workspaceFolder}/src/bsps/stm32f429zi_death_stack_v3/config", + "${workspaceFolder}/src/bsps/stm32f429zi_death_stack_v3" ] }, { - "name": "stm32f429zi_skyward_death_stack_x_maker_faire", + "name": "stm32f429zi_nokia", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_death_stack_x_maker_faire", - "_BOARD_STM32F429ZI_SKYWARD_DEATHST_X_MAKER_FAIRE", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_nokia", + "_BOARD_STM32F429ZI_NOKIA", "_ARCH_CORTEXM4_STM32F4", "STM32F429xx", "HSE_VALUE=8000000", "SYSCLK_FREQ_168MHz=168000000", "__ENABLE_XRAM", - "V_DDA_VOLTAGE=3.3f" + "V_DDA_VOLTAGE=3.0f" ], "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_death_stack_x_maker_faire", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_death_stack_x_maker_faire" + "${workspaceFolder}/src/bsps/stm32f429zi_nokia/config", + "${workspaceFolder}/src/bsps/stm32f429zi_nokia" ] }, { - "name": "stm32f429zi_skyward_groundstation", + "name": "stm32f429zi_parafoil", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_groundstation", - "_BOARD_STM32F429ZI_SKYWARD_GS", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_parafoil", + "_BOARD_STM32F429ZI_PARAFOIL", "_ARCH_CORTEXM4_STM32F4", "STM32F429xx", "HSE_VALUE=8000000", @@ -175,42 +155,41 @@ "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation" + "${workspaceFolder}/src/bsps/stm32f429zi_parafoil/config", + "${workspaceFolder}/src/bsps/stm32f429zi_parafoil" ] }, { - "name": "stm32f429zi_skyward_groundstation_parafoil", + "name": "stm32f429zi_pyxis_auxiliary", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_groundstation_parafoil", - "D_BOARD_STM32F429ZI_SKYWARD_GS_PARAFOIL", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_pyxis_auxiliary", + "_BOARD_STM32F429ZI_PYXIS_AUXILIARY", "_ARCH_CORTEXM4_STM32F4", "STM32F429xx", "HSE_VALUE=8000000", "SYSCLK_FREQ_168MHz=168000000", - "__ENABLE_XRAM", - "V_DDA_VOLTAGE=3.0f" + "V_DDA_VOLTAGE=3.3f" ], "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_parafoil", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_parafoil" + "${workspaceFolder}/src/bsps/stm32f429zi_pyxis_auxiliary/config", + "${workspaceFolder}/src/bsps/stm32f429zi_pyxis_auxiliary" ] }, { - "name": "stm32f429zi_skyward_groundstation_v2", + "name": "stm32f429zi_rig", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_groundstation_v2", - "_BOARD_STM32F429ZI_SKYWARD_GS_V2", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_rig", + "_BOARD_STM32F429ZI_RIG", "_ARCH_CORTEXM4_STM32F4", "STM32F429xx", "HSE_VALUE=8000000", @@ -221,110 +200,111 @@ "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_groundstation_v2" + "${workspaceFolder}/src/bsps/stm32f429zi_rig/config", + "${workspaceFolder}/src/bsps/stm32f429zi_rig" ] }, { - "name": "stm32f429zi_skyward_parafoil", + "name": "stm32f756zg_nucleo", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_parafoil", - "_BOARD_STM32F429ZI_SKYWARD_PARAFOIL", - "_ARCH_CORTEXM4_STM32F4", - "STM32F429xx", - "HSE_VALUE=8000000", - "SYSCLK_FREQ_168MHz=168000000", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f756zg_nucleo", + "D_BOARD_STM32F756ZG_NUCLEO", + "_ARCH_CORTEXM7_STM32F7", + "STM32F756xx", + "HSE_VALUE=25000000", + "SYSCLK_FREQ_216MHz=216000000", "__ENABLE_XRAM", - "V_DDA_VOLTAGE=3.0f" + "V_DDA_VOLTAGE=3.3f" ], "includePath": [ "${defaultIncludePaths}", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_parafoil", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_parafoil" + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", + "${workspaceFolder}/src/bsps/stm32f756zg_nucleo/config", + "${workspaceFolder}/src/bsps/stm32f756zg_nucleo" ] }, { - "name": "stm32f429zi_skyward_pyxis_auxiliary", + "name": "stm32f767zi_automated_antennas", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_pyxis_auxiliary", - "_BOARD_STM32F429ZI_SKYWARD_PYXIS_AUXILIARY", - "_ARCH_CORTEXM4_STM32F4", - "STM32F429xx", - "HSE_VALUE=8000000", - "SYSCLK_FREQ_168MHz=168000000", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f767zi_automated_antennas", + "_BOARD_STM32F767ZI_AUTOMATED_ANTENNAS", + "_ARCH_CORTEXM7_STM32F7", + "STM32F769xx", + "HSE_VALUE=25000000", + "SYSCLK_FREQ_216MHz=216000000", + "__ENABLE_XRAM", "V_DDA_VOLTAGE=3.3f" ], "includePath": [ "${defaultIncludePaths}", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_pyxis_auxiliary", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_pyxis_auxiliary" + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", + "${workspaceFolder}/src/bsps/stm32f767zi_automated_antennas/config", + "${workspaceFolder}/src/bsps/stm32f767zi_automated_antennas" ] }, { - "name": "stm32f429zi_skyward_rig", + "name": "stm32f767zi_compute_unit", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_skyward_rig", - "_BOARD_STM32F429ZI_SKYWARD_RIG", - "_ARCH_CORTEXM4_STM32F4", - "STM32F429xx", - "HSE_VALUE=8000000", - "SYSCLK_FREQ_168MHz=168000000", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f767zi_compute_unit", + "_BOARD_STM32F767ZI_COMPUTE_UNIT", + "_ARCH_CORTEXM7_STM32F7", + "STM32F769xx", + "HSE_VALUE=25000000", + "SYSCLK_FREQ_216MHz=216000000", "__ENABLE_XRAM", - "V_DDA_VOLTAGE=3.0f" + "V_DDA_VOLTAGE=3.3f" ], "includePath": [ "${defaultIncludePaths}", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_skyward_rig", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_skyward_rig" + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", + "${workspaceFolder}/src/bsps/stm32f767zi_compute_unit/config", + "${workspaceFolder}/src/bsps/stm32f767zi_compute_unit" ] }, { - "name": "stm32f429zi_stm32f4discovery", + "name": "stm32f767zi_death_stack_v4", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f429zi_stm32f4discovery", - "_BOARD_STM32F429ZI_STM32F4DISCOVERY", - "_ARCH_CORTEXM4_STM32F4", - "STM32F429xx", - "HSE_VALUE=8000000", - "SYSCLK_FREQ_168MHz=168000000", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f767zi_death_stack_v4", + "_BOARD_STM32F767ZI_DEATH_STACK_V4", + "_ARCH_CORTEXM7_STM32F7", + "STM32F769xx", + "HSE_VALUE=25000000", + "SYSCLK_FREQ_216MHz=216000000", "__ENABLE_XRAM", - "V_DDA_VOLTAGE=3.0f" + "V_DDA_VOLTAGE=3.3f" ], "includePath": [ "${defaultIncludePaths}", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery" + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", + "${workspaceFolder}/src/bsps/stm32f767zi_death_stack_v4/config", + "${workspaceFolder}/src/bsps/stm32f767zi_death_stack_v4" ] }, { - "name": "stm32f767zi_compute_unit", + "name": "stm32f767zi_gemini_gs", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f767zi_compute_unit", - "_BOARD_STM32F767ZI_COMPUTE_UNIT", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f767zi_gemini_gs", + "_BOARD_STM32F767ZI_GEMINI_GS", "_ARCH_CORTEXM7_STM32F7", "STM32F769xx", "HSE_VALUE=25000000", @@ -335,19 +315,19 @@ "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/stm32f767zi_compute_unit", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM7_stm32f7/stm32f767zi_compute_unit" + "${workspaceFolder}/src/bsps/stm32f767zi_gemini_gs/config", + "${workspaceFolder}/src/bsps/stm32f767zi_gemini_gs" ] }, { - "name": "stm32f767zi_gemini_gs", + "name": "stm32f767zi_gemini_motor", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f767zi_gemini_gs", - "_BOARD_STM32F767ZI_GEMINI_GS", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f767zi_gemini_motor", + "_BOARD_STM32F767ZI_GEMINI_MOTOR", "_ARCH_CORTEXM7_STM32F7", "STM32F769xx", "HSE_VALUE=25000000", @@ -358,31 +338,54 @@ "includePath": [ "${defaultIncludePaths}", "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/stm32f767zi_gemini_gs", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM7_stm32f7/stm32f767zi_gemini_gs" + "${workspaceFolder}/src/bsps/stm32f767zi_gemini_motor/config", + "${workspaceFolder}/src/bsps/stm32f767zi_gemini_motor" ] }, + // Miosix boards { - "name": "stm32f756zg_nucleo", + "name": "stm32f407vg_stm32f4discovery", "cStandard": "c11", "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", - "_MIOSIX_BOARDNAME=stm32f756zg_nucleo", - "D_BOARD_STM32F756ZG_NUCLEO", - "_ARCH_CORTEXM7_STM32F7", - "STM32F756xx", - "HSE_VALUE=25000000", - "SYSCLK_FREQ_216MHz=216000000", + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f407vg_stm32f4discovery", + "_BOARD_STM32F4DISCOVERY", + "_ARCH_CORTEXM4_STM32F4", + "STM32F407xx", + "HSE_VALUE=8000000", + "SYSCLK_FREQ_168MHz=168000000", + "V_DDA_VOLTAGE=3.0f" + ], + "includePath": [ + "${defaultIncludePaths}", + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery", + "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery" + ] + }, + { + "name": "stm32f429zi_stm32f4discovery", + "cStandard": "c11", + "cppStandard": "c++14", + "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", + "defines": [ + "${defaultDefines}", + "_MIOSIX_BOARDNAME=stm32f429zi_stm32f4discovery", + "_BOARD_STM32F429ZI_STM32F4DISCOVERY", + "_ARCH_CORTEXM4_STM32F4", + "STM32F429xx", + "HSE_VALUE=8000000", + "SYSCLK_FREQ_168MHz=168000000", "__ENABLE_XRAM", - "V_DDA_VOLTAGE=3.3f" + "V_DDA_VOLTAGE=3.0f" ], "includePath": [ "${defaultIncludePaths}", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/common", - "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM7_stm32f7/stm32f756zg_nucleo", - "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM7_stm32f7/stm32f756zg_nucleo" + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/common", + "${workspaceFolder}/libs/miosix-kernel/miosix/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery", + "${workspaceFolder}/libs/miosix-kernel/miosix/config/arch/cortexM4_stm32f4/stm32f429zi_stm32f4discovery" ] }, { @@ -391,7 +394,7 @@ "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", + "${defaultDefines}", "_MIOSIX_BOARDNAME=stm32f767zi_nucleo", "D_BOARD_STM32F767ZI_NUCLEO", "_ARCH_CORTEXM7_STM32F7", @@ -414,7 +417,7 @@ "cppStandard": "c++14", "compilerPath": "/opt/arm-miosix-eabi/bin/arm-miosix-eabi-g++", "defines": [ - "{defaultDefines}", + "${defaultDefines}", "_MIOSIX_BOARDNAME=stm32f769ni_discovery", "_BOARD_STM32F769NI_DISCO", "_ARCH_CORTEXM7_STM32F7", @@ -433,4 +436,4 @@ } ], "version": 4 -} +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f50a6b1ba33c7a5edfa0ba33fee2218f89bb7b22..2671df6f6a2cac5b9de395b7e3df6fdf23776b7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.25) enable_testing() include(cmake/sbs.cmake) @@ -27,43 +27,43 @@ include(cmake/sbs.cmake) # Project # #-----------------------------------------------------------------------------# -project(SkywardBoardcore) +project(Boardcore) #-----------------------------------------------------------------------------# # Entrypoints # #-----------------------------------------------------------------------------# add_executable(bmx160-calibration-v2 src/entrypoints/bmx160-calibration-entry.cpp) -sbs_target(bmx160-calibration-v2 stm32f429zi_skyward_death_stack_x) +sbs_target(bmx160-calibration-v2 stm32f429zi_death_stack_v2) add_executable(bmx160-calibration-v3 src/entrypoints/bmx160-calibration-entry.cpp) -sbs_target(bmx160-calibration-v3 stm32f429zi_skyward_death_stack_v3) +sbs_target(bmx160-calibration-v3 stm32f429zi_death_stack_v3) add_executable(config-dsgamma src/entrypoints/config-dsgamma.cpp) sbs_target(config-dsgamma stm32f429zi_stm32f4discovery) add_executable(imu-calibration src/entrypoints/imu-calibration.cpp) -sbs_target(imu-calibration stm32f429zi_skyward_parafoil) +sbs_target(imu-calibration stm32f429zi_parafoil) add_executable(mxgui-helloworld src/entrypoints/examples/mxgui-helloworld.cpp) sbs_target(mxgui-helloworld stm32f429zi_stm32f4discovery) -add_executable(kernel-testsuite src/entrypoints/kernel-testsuite.cpp) -sbs_target(kernel-testsuite stm32f767zi_compute_unit) +# add_executable(kernel-testsuite src/entrypoints/kernel-testsuite.cpp) +# sbs_target(kernel-testsuite stm32f767zi_compute_unit) add_executable(runcam-settings src/entrypoints/runcam-settings.cpp) sbs_target(runcam-settings stm32f407vg_stm32f4discovery) add_executable(sdcard-benchmark src/entrypoints/sdcard-benchmark.cpp) -sbs_target(sdcard-benchmark stm32f429zi_skyward_death_stack_x) +sbs_target(sdcard-benchmark stm32f429zi_death_stack_v2) add_executable(sx1278fsk-ra01-serial src/entrypoints/sx1278-serial.cpp) target_compile_definitions(sx1278fsk-ra01-serial PRIVATE SX1278_IS_FSK) -sbs_target(sx1278fsk-ra01-serial stm32f429zi_skyward_groundstation_v2) +sbs_target(sx1278fsk-ra01-serial stm32f429zi_nokia) add_executable(sx1278lora-ra01-serial src/entrypoints/sx1278-serial.cpp) target_compile_definitions(sx1278lora-ra01-serial PRIVATE SX1278_IS_LORA) -sbs_target(sx1278lora-ra01-serial stm32f429zi_skyward_groundstation_v2) +sbs_target(sx1278lora-ra01-serial stm32f429zi_nokia) add_executable(sx1278fsk-skyward433-serial src/entrypoints/sx1278-serial.cpp) target_compile_definitions(sx1278fsk-skyward433-serial PRIVATE SX1278_IS_FSK SX1278_IS_SKYWARD433) @@ -71,11 +71,11 @@ sbs_target(sx1278fsk-skyward433-serial stm32f767zi_gemini_gs) add_executable(sx1278lora-skyward433-serial src/entrypoints/sx1278-serial.cpp) target_compile_definitions(sx1278lora-skyward433-serial PRIVATE SX1278_IS_LORA SX1278_IS_SKYWARD433) -sbs_target(sx1278lora-skyward433-serial stm32f429zi_skyward_groundstation_v2) +sbs_target(sx1278lora-skyward433-serial stm32f429zi_nokia) add_executable(sx1278fsk-ebyterig-serial src/entrypoints/sx1278-serial.cpp) target_compile_definitions(sx1278fsk-ebyterig-serial PRIVATE SX1278_IS_FSK) -sbs_target(sx1278fsk-ebyterig-serial stm32f429zi_skyward_rig) +sbs_target(sx1278fsk-ebyterig-serial stm32f429zi_rig) #-----------------------------------------------------------------------------# # Tests # @@ -103,10 +103,10 @@ add_executable(test-rtc src/tests/test-rtc.cpp) sbs_target(test-rtc stm32f767zi_compute_unit) add_executable(test-sensormanager src/tests/test-sensormanager.cpp) -sbs_target(test-sensormanager stm32f429zi_skyward_death_stack_x) +sbs_target(test-sensormanager stm32f429zi_death_stack_v2) add_executable(test-serial src/tests/test-serial.cpp) -sbs_target(test-serial stm32f756zg_nucleo) +sbs_target(test-serial stm32f767zi_nucleo) add_executable(test-taskscheduler src/tests/scheduler/test-taskscheduler.cpp) sbs_target(test-taskscheduler stm32f407vg_stm32f4discovery) @@ -150,8 +150,8 @@ sbs_target(test-hbridge stm32f429zi_stm32f4discovery) add_executable(test-servo src/tests/actuators/test-servo.cpp) sbs_target(test-servo stm32f429zi_stm32f4discovery) -add_executable(test-buzzer src/tests/actuators/test-buzzer.cpp) -sbs_target(test-buzzer stm32f429zi_hre_test_stand) +# add_executable(test-buzzer src/tests/actuators/test-buzzer.cpp) +# sbs_target(test-buzzer stm32f429zi_hre_test_stand) add_executable(test-stepper src/tests/actuators/test-stepper.cpp) sbs_target(test-stepper stm32f767zi_nucleo) @@ -167,28 +167,28 @@ add_executable(test-kalman-benchmark src/tests/algorithms/Kalman/test-kalman-ben sbs_target(test-kalman-benchmark stm32f429zi_stm32f4discovery) add_executable(test-attitude-parafoil src/tests/algorithms/NAS/test-attitude-parafoil.cpp) -sbs_target(test-attitude-parafoil stm32f429zi_skyward_parafoil) +sbs_target(test-attitude-parafoil stm32f429zi_parafoil) add_executable(test-attitude-stack src/tests/algorithms/NAS/test-attitude-stack.cpp) -sbs_target(test-attitude-stack stm32f429zi_skyward_death_stack_x) +sbs_target(test-attitude-stack stm32f429zi_death_stack_v2) add_executable(test-nas-parafoil src/tests/algorithms/NAS/test-nas-parafoil.cpp) -sbs_target(test-nas-parafoil stm32f429zi_skyward_parafoil) +sbs_target(test-nas-parafoil stm32f429zi_parafoil) add_executable(test-nas src/tests/algorithms/NAS/test-nas.cpp) -sbs_target(test-nas stm32f429zi_skyward_death_stack_v3) +sbs_target(test-nas stm32f429zi_death_stack_v3) add_executable(test-nas-with-triad src/tests/algorithms/NAS/test-nas-with-triad.cpp) -sbs_target(test-nas-with-triad stm32f429zi_skyward_death_stack_x) +sbs_target(test-nas-with-triad stm32f429zi_death_stack_v2) add_executable(test-triad src/tests/algorithms/NAS/test-triad.cpp) -sbs_target(test-triad stm32f429zi_skyward_death_stack_v3) +sbs_target(test-triad stm32f429zi_death_stack_v3) add_executable(test-triad-parafoil src/tests/algorithms/NAS/test-triad-parafoil.cpp) -sbs_target(test-triad-parafoil stm32f429zi_skyward_parafoil) +sbs_target(test-triad-parafoil stm32f429zi_parafoil) add_executable(test-ada src/tests/algorithms/ADA/test-ada.cpp) -sbs_target(test-ada stm32f429zi_skyward_death_stack_v3) +sbs_target(test-ada stm32f429zi_death_stack_v3) #-----------------------------------------------------------------------------# # Tests - Boards # @@ -205,19 +205,19 @@ sbs_target(test-qspi-flash stm32f767zi_compute_unit) #-----------------------------------------------------------------------------# add_executable(test-ad5204 src/tests/drivers/test-ad5204.cpp) -sbs_target(test-ad5204 stm32f205rc_skyward_ciuti) +sbs_target(test-ad5204 stm32f205rc_ciuti) add_executable(test-can-2way src/tests/drivers/canbus/CanDriver/test-can-2way.cpp) -sbs_target(test-can-2way stm32f429zi_skyward_pyxis_auxiliary) +sbs_target(test-can-2way stm32f429zi_pyxis_auxiliary) add_executable(test-can-filters src/tests/drivers/canbus/CanDriver/test-can-filters.cpp) -sbs_target(test-can-filters stm32f429zi_skyward_pyxis_auxiliary) +sbs_target(test-can-filters stm32f429zi_pyxis_auxiliary) add_executable(test-can-loopback src/tests/drivers/canbus/CanDriver/test-can-loopback.cpp) -sbs_target(test-can-loopback stm32f429zi_skyward_death_stack_x) +sbs_target(test-can-loopback stm32f429zi_death_stack_v2) add_executable(test-can-protocol src/tests/drivers/canbus/CanProtocol/test-can-protocol.cpp) -sbs_target(test-can-protocol stm32f429zi_skyward_death_stack_x) +sbs_target(test-can-protocol stm32f429zi_death_stack_v2) add_executable(test-dsgamma src/tests/drivers/test-dsgamma.cpp) sbs_target(test-dsgamma stm32f429zi_stm32f4discovery) @@ -250,7 +250,7 @@ add_executable(test-timestamptimer src/tests/drivers/timer/test-timestamptimer.c sbs_target(test-timestamptimer stm32f429zi_stm32f4discovery) add_executable(test-xbee-bidir src/tests/drivers/xbee/test-xbee-bidir.cpp) -sbs_target(test-xbee-bidir stm32f429zi_skyward_death_stack_x) +sbs_target(test-xbee-bidir stm32f429zi_death_stack_v2) add_executable(test-xbee-gui src/tests/drivers/xbee/test-xbee-gui.cpp @@ -297,59 +297,59 @@ sbs_target(test-fsm stm32f429zi_stm32f4discovery) #-----------------------------------------------------------------------------# add_executable(test-sx1278fsk-bidir src/tests/radio/sx1278/fsk/test-sx1278-bidir.cpp) -sbs_target(test-sx1278fsk-bidir stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278fsk-bidir stm32f429zi_nokia) add_executable(test-sx1278fsk-tx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp) target_compile_definitions(test-sx1278fsk-tx PRIVATE DISABLE_RX) -sbs_target(test-sx1278fsk-tx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278fsk-tx stm32f429zi_nokia) add_executable(test-sx1278fsk-rx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp) target_compile_definitions(test-sx1278fsk-rx PRIVATE DISABLE_TX) -sbs_target(test-sx1278fsk-rx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278fsk-rx stm32f429zi_nokia) add_executable(test-sx1278fsk-gui-tx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp) target_compile_definitions(test-sx1278fsk-gui-tx PRIVATE DISABLE_RX) -sbs_target(test-sx1278fsk-gui-tx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278fsk-gui-tx stm32f429zi_nokia) add_executable(test-sx1278fsk-gui-rx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp) target_compile_definitions(test-sx1278fsk-gui-rx PRIVATE DISABLE_TX) -sbs_target(test-sx1278fsk-gui-rx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278fsk-gui-rx stm32f429zi_nokia) add_executable(test-sx1278fsk-mavlink src/tests/radio/sx1278/fsk/test-sx1278-mavlink.cpp) -sbs_target(test-sx1278fsk-mavlink stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278fsk-mavlink stm32f429zi_nokia) # add_executable(test-mavlinkdriver src/tests/radio/test-mavlinkdriver.cpp) # sbs_target(test-mavlinkdriver stm32f407vg_stm32f4discovery) add_executable(test-sx1278lora-bidir src/tests/radio/sx1278/lora/test-sx1278-bidir.cpp) -sbs_target(test-sx1278lora-bidir stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-bidir stm32f429zi_nokia) add_executable(test-sx1278lora-mavlink src/tests/radio/sx1278/lora/test-sx1278-mavlink.cpp) -sbs_target(test-sx1278lora-mavlink stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-mavlink stm32f429zi_nokia) add_executable(test-sx1278lora-simple-rx src/tests/radio/sx1278/lora/test-sx1278-simple.cpp) target_compile_definitions(test-sx1278lora-simple-rx PRIVATE ENABLE_RX) -sbs_target(test-sx1278lora-simple-rx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-simple-rx stm32f429zi_nokia) add_executable(test-sx1278lora-simple-tx src/tests/radio/sx1278/lora/test-sx1278-simple.cpp) target_compile_definitions(test-sx1278lora-simple-tx PRIVATE ENABLE_TX) -sbs_target(test-sx1278lora-simple-tx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-simple-tx stm32f429zi_nokia) add_executable(test-sx1278lora-tx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp) target_compile_definitions(test-sx1278lora-tx PRIVATE DISABLE_RX SX1278_IS_LORA) -sbs_target(test-sx1278lora-tx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-tx stm32f429zi_nokia) add_executable(test-sx1278lora-rx src/tests/radio/sx1278/test-sx1278-bench-serial.cpp) target_compile_definitions(test-sx1278lora-rx PRIVATE DISABLE_TX SX1278_IS_LORA) -sbs_target(test-sx1278lora-rx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-rx stm32f429zi_nokia) add_executable(test-sx1278lora-gui-rx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp) target_compile_definitions(test-sx1278lora-gui-rx PRIVATE DISABLE_TX SX1278_IS_LORA) -sbs_target(test-sx1278lora-gui-rx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-gui-rx stm32f429zi_nokia) add_executable(test-sx1278lora-gui-tx src/tests/radio/sx1278/test-sx1278-bench-gui.cpp) target_compile_definitions(test-sx1278lora-gui-tx PRIVATE DISABLE_RX SX1278_IS_LORA) -sbs_target(test-sx1278lora-gui-tx stm32f429zi_skyward_groundstation_v2) +sbs_target(test-sx1278lora-gui-tx stm32f429zi_nokia) #-----------------------------------------------------------------------------# # Tests - Sensors # @@ -359,7 +359,7 @@ add_executable(test-ads1118 src/tests/sensors/test-ads1118.cpp) sbs_target(test-ads1118 stm32f407vg_stm32f4discovery) add_executable(test-ads131m04 src/tests/sensors/test-ads131m04.cpp) -sbs_target(test-ads131m04 stm32f429zi_skyward_death_stack_v3) +sbs_target(test-ads131m04 stm32f429zi_death_stack_v3) add_executable(test-ads131m08 src/tests/sensors/test-ads131m08.cpp) sbs_target(test-ads131m08 stm32f767zi_compute_unit) @@ -392,10 +392,10 @@ add_executable(test-bmp280-i2c src/tests/sensors/test-bmp280-i2c.cpp) sbs_target(test-bmp280-i2c stm32f429zi_stm32f4discovery) add_executable(test-bmx160 src/tests/sensors/test-bmx160.cpp) -sbs_target(test-bmx160 stm32f429zi_skyward_death_stack_x) +sbs_target(test-bmx160 stm32f429zi_death_stack_v2) add_executable(test-bmx160-with-correction src/tests/sensors/test-bmx160-with-correction.cpp) -sbs_target(test-bmx160-with-correction stm32f429zi_skyward_death_stack_x) +sbs_target(test-bmx160-with-correction stm32f429zi_death_stack_v2) add_executable(test-hx711 src/tests/sensors/test-hx711.cpp) sbs_target(test-hx711 stm32f429zi_stm32f4discovery) @@ -410,10 +410,10 @@ add_executable(test-lis3dsh src/tests/sensors/test-lis3dsh.cpp) sbs_target(test-lis3dsh stm32f407vg_stm32f4discovery) add_executable(test-lis3mdl src/tests/sensors/test-lis3mdl.cpp) -sbs_target(test-lis3mdl stm32f429zi_skyward_death_stack_x) +sbs_target(test-lis3mdl stm32f429zi_death_stack_v2) add_executable(test-lis331hh src/tests/sensors/test-lis331hh.cpp) -sbs_target(test-lis331hh stm32f205rc_skyward_ciuti) +sbs_target(test-lis331hh stm32f205rc_ciuti) add_executable(test-lps331ap src/tests/sensors/test-lps331ap.cpp) sbs_target(test-lps331ap stm32f429zi_stm32f4discovery) @@ -428,19 +428,19 @@ add_executable(test-max31856 src/tests/sensors/test-max31856.cpp) sbs_target(test-max31856 stm32f767zi_compute_unit) add_executable(test-mpu9250 src/tests/sensors/test-mpu9250.cpp) -sbs_target(test-mpu9250 stm32f429zi_skyward_parafoil) +sbs_target(test-mpu9250 stm32f429zi_parafoil) add_executable(test-ms5803-spi src/tests/sensors/test-ms5803-spi.cpp) -sbs_target(test-ms5803-spi stm32f429zi_skyward_death_stack_x) +sbs_target(test-ms5803-spi stm32f429zi_death_stack_v2) add_executable(test-ms5803-i2c src/tests/sensors/test-ms5803-i2c.cpp) sbs_target(test-ms5803-i2c stm32f429zi_stm32f4discovery) add_executable(test-ubxgps-serial src/tests/sensors/test-ubxgps-serial.cpp) -sbs_target(test-ubxgps-serial stm32f429zi_skyward_death_stack_x) +sbs_target(test-ubxgps-serial stm32f429zi_death_stack_v2) add_executable(test-ubxgps-spi src/tests/sensors/test-ubxgps-spi.cpp) -sbs_target(test-ubxgps-spi stm32f429zi_skyward_death_stack_x) +sbs_target(test-ubxgps-spi stm32f429zi_death_stack_v2) add_executable(test-vn100 src/tests/sensors/test-vn100.cpp) sbs_target(test-vn100 stm32f407vg_stm32f4discovery) diff --git a/cmake/boardcore-host.cmake b/cmake/boardcore-host.cmake index 977102ebbfb21ae52befaac414cea42d649da0d5..f99e104f04bea80d1c40307b4f294759ed49a1b4 100644 --- a/cmake/boardcore-host.cmake +++ b/cmake/boardcore-host.cmake @@ -19,7 +19,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -add_library(boardcore-host STATIC EXCLUDE_FROM_ALL +# Boardcore source files used when compiling for host +set(BOARDCORE_HOST_SRC # Debug ${SBS_BASE}/src/shared/utils/Debug.cpp ${SBS_BASE}/src/shared/diagnostic/CpuMeter/CpuMeter.cpp @@ -58,8 +59,14 @@ add_library(boardcore-host STATIC EXCLUDE_FROM_ALL ${SBS_BASE}/src/shared/utils/Stats/Stats.cpp ${SBS_BASE}/src/shared/utils/TestUtils/TestHelper.cpp ) -add_library(SkywardBoardcore::Boardcore::host ALIAS boardcore-host) -target_include_directories(boardcore-host PUBLIC ${SBS_BASE}/src/shared) + +# Create a library specific for host builds +add_library(boardcore-host STATIC EXCLUDE_FROM_ALL ${BOARDCORE_HOST_SRC}) + +# Only one include directory for Boardcore! +target_include_directories(boardcore-host PUBLIC ${BOARDCORE_PATH}/src/shared) + +# Link libraries target_link_libraries(boardcore-host PUBLIC Miosix::Miosix::host TSCPP::TSCPP @@ -68,3 +75,6 @@ target_link_libraries(boardcore-host PUBLIC Catch2::Catch2 Mavlink::Mavlink ) + +# Create a nice alias for the library +add_library(Skyward::Boardcore::host ALIAS boardcore-host) \ No newline at end of file diff --git a/cmake/boardcore.cmake b/cmake/boardcore.cmake index 49c749382bc5f0c28f9c8cadaaa283afae039ec5..b45ff0b53fae4a5620a104a5a32253d665b054ff 100644 --- a/cmake/boardcore.cmake +++ b/cmake/boardcore.cmake @@ -19,123 +19,141 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -include(dependencies) - -include(boardcore-host) - -foreach(OPT_BOARD ${BOARDS}) - set(BOARDCORE_LIBRARY boardcore-${OPT_BOARD}) - add_library(${BOARDCORE_LIBRARY} STATIC EXCLUDE_FROM_ALL - - # Actuators - ${SBS_BASE}/src/shared/actuators/HBridge/HBridge.cpp - ${SBS_BASE}/src/shared/actuators/Servo/Servo.cpp - ${SBS_BASE}/src/shared/actuators/stepper/Stepper.cpp - ${SBS_BASE}/src/shared/actuators/stepper/StepperPWM.cpp - - # Algorithms - ${SBS_BASE}/src/shared/algorithms/ADA/ADA.cpp - ${SBS_BASE}/src/shared/algorithms/MEA/MEA.cpp - ${SBS_BASE}/src/shared/algorithms/AirBrakes/AirBrakes.cpp - ${SBS_BASE}/src/shared/algorithms/AirBrakes/AirBrakesPI.cpp - ${SBS_BASE}/src/shared/algorithms/AirBrakes/AirBrakesInterp.cpp - ${SBS_BASE}/src/shared/algorithms/NAS/NAS.cpp - ${SBS_BASE}/src/shared/algorithms/NAS/StateInitializer.cpp - - # Debug - ${SBS_BASE}/src/shared/utils/Debug.cpp - ${SBS_BASE}/src/shared/diagnostic/CpuMeter/CpuMeter.cpp - ${SBS_BASE}/src/shared/diagnostic/PrintLogger.cpp - - # Drivers - ${SBS_BASE}/src/shared/drivers/AD5204/AD5204.cpp - ${SBS_BASE}/src/shared/drivers/adc/InternalADC.cpp - ${SBS_BASE}/src/shared/drivers/canbus/CanDriver/CanDriver.cpp - ${SBS_BASE}/src/shared/drivers/canbus/CanDriver/CanInterrupt.cpp - ${SBS_BASE}/src/shared/drivers/canbus/CanProtocol/CanProtocol.cpp - ${SBS_BASE}/src/shared/drivers/interrupt/external_interrupts.cpp - ${SBS_BASE}/src/shared/drivers/timer/PWM.cpp - ${SBS_BASE}/src/shared/drivers/timer/CountedPWM.cpp - ${SBS_BASE}/src/shared/drivers/timer/TimestampTimer.cpp - ${SBS_BASE}/src/shared/drivers/runcam/Runcam.cpp - ${SBS_BASE}/src/shared/drivers/spi/SPITransaction.cpp - ${SBS_BASE}/src/shared/drivers/usart/USART.cpp - ${SBS_BASE}/src/shared/drivers/i2c/I2CDriver-f4.cpp - ${SBS_BASE}/src/shared/drivers/i2c/I2CDriver-f7.cpp - ${SBS_BASE}/src/shared/drivers/i2c/I2C.cpp - ${SBS_BASE}/src/shared/drivers/WIZ5500/WIZ5500.cpp - - # Events - ${SBS_BASE}/src/shared/events/EventBroker.cpp - - # Logger - ${SBS_BASE}/src/shared/logger/Logger.cpp - - # Radio - ${SBS_BASE}/src/shared/radio/gamma868/Gamma868.cpp - ${SBS_BASE}/src/shared/radio/Xbee/APIFrameParser.cpp - ${SBS_BASE}/src/shared/radio/Xbee/Xbee.cpp - ${SBS_BASE}/src/shared/radio/SX1278/SX1278Fsk.cpp - ${SBS_BASE}/src/shared/radio/SX1278/SX1278Lora.cpp - ${SBS_BASE}/src/shared/radio/SX1278/SX1278Common.cpp - - # Scheduler - ${SBS_BASE}/src/shared/scheduler/TaskScheduler.cpp - - # Sensors - ${SBS_BASE}/src/shared/sensors/ADS1118/ADS1118.cpp - ${SBS_BASE}/src/shared/sensors/ADS131M04/ADS131M04.cpp - ${SBS_BASE}/src/shared/sensors/ADS131M08/ADS131M08.cpp - ${SBS_BASE}/src/shared/sensors/BME280/BME280.cpp - ${SBS_BASE}/src/shared/sensors/BME280/BME280I2C.cpp - ${SBS_BASE}/src/shared/sensors/BMP280/BMP280.cpp - ${SBS_BASE}/src/shared/sensors/BMP280/BMP280I2C.cpp - ${SBS_BASE}/src/shared/sensors/BMX160/BMX160.cpp - ${SBS_BASE}/src/shared/sensors/BMX160/BMX160WithCorrection.cpp - ${SBS_BASE}/src/shared/sensors/H3LIS331DL/H3LIS331DL.cpp - ${SBS_BASE}/src/shared/sensors/HX711/HX711.cpp - ${SBS_BASE}/src/shared/sensors/LIS3MDL/LIS3MDL.cpp - ${SBS_BASE}/src/shared/sensors/LIS331HH/LIS331HH.cpp - ${SBS_BASE}/src/shared/sensors/LPS331AP/LPS331AP.cpp - ${SBS_BASE}/src/shared/sensors/MAX6675/MAX6675.cpp - ${SBS_BASE}/src/shared/sensors/MAX31855/MAX31855.cpp - ${SBS_BASE}/src/shared/sensors/MAX31856/MAX31856.cpp - ${SBS_BASE}/src/shared/sensors/MBLoadCell/MBLoadCell.cpp - ${SBS_BASE}/src/shared/sensors/MPU9250/MPU9250.cpp - ${SBS_BASE}/src/shared/sensors/MS5803/MS5803.cpp - ${SBS_BASE}/src/shared/sensors/MS5803/MS5803I2C.cpp - ${SBS_BASE}/src/shared/sensors/SensorManager.cpp - ${SBS_BASE}/src/shared/sensors/SensorSampler.cpp - ${SBS_BASE}/src/shared/sensors/UBXGPS/UBXGPSSerial.cpp - ${SBS_BASE}/src/shared/sensors/UBXGPS/UBXGPSSpi.cpp - ${SBS_BASE}/src/shared/sensors/VN100/VN100.cpp - ${SBS_BASE}/src/shared/sensors/LIS2MDL/LIS2MDL.cpp - ${SBS_BASE}/src/shared/sensors/LPS28DFW/LPS28DFW.cpp - ${SBS_BASE}/src/shared/sensors/LPS22DF/LPS22DF.cpp - ${SBS_BASE}/src/shared/sensors/LSM6DSRX/LSM6DSRX.cpp - - # Calibration - ${SBS_BASE}/src/shared/sensors/calibration/BiasCalibration/BiasCalibration.cpp - ${SBS_BASE}/src/shared/sensors/calibration/SensorDataExtra/SensorDataExtra.cpp - ${SBS_BASE}/src/shared/sensors/calibration/SixParameterCalibration/SixParameterCalibration.cpp - ${SBS_BASE}/src/shared/sensors/calibration/SoftAndHardIronCalibration/SoftAndHardIronCalibration.cpp - - # Correction - ${SBS_BASE}/src/shared/sensors/correction/BiasCorrector/BiasCorrector.cpp - ${SBS_BASE}/src/shared/sensors/correction/SixParametersCorrector/SixParametersCorrector.cpp - - # Utils - ${SBS_BASE}/src/shared/utils/AeroUtils/AeroUtils.cpp - ${SBS_BASE}/src/shared/utils/ButtonHandler/ButtonHandler.cpp - ${SBS_BASE}/src/shared/utils/PinObserver/PinObserver.cpp - ${SBS_BASE}/src/shared/utils/SkyQuaternion/SkyQuaternion.cpp - ${SBS_BASE}/src/shared/utils/Stats/Stats.cpp - ${SBS_BASE}/src/shared/utils/TestUtils/TestHelper.cpp - ) - add_library(SkywardBoardcore::Boardcore::${OPT_BOARD} ALIAS ${BOARDCORE_LIBRARY}) - target_include_directories(${BOARDCORE_LIBRARY} PUBLIC ${SBS_BASE}/src/shared) - target_link_libraries(${BOARDCORE_LIBRARY} PUBLIC - Miosix::Miosix::${OPT_BOARD} +# Load in BOARDCORE_PATH the project path +cmake_path(GET CMAKE_CURRENT_LIST_DIR PARENT_PATH BOARDCORE_PATH) + +# Include dependencies and board list +include(${BOARDCORE_PATH}/cmake/dependencies.cmake) +include(${BOARDCORE_PATH}/cmake/boardcore-host.cmake) +include(${BOARDCORE_PATH}/cmake/boards.cmake) + +# Boardcore source files +set(BOARDCORE_SRC + # Actuators + ${BOARDCORE_PATH}/src/shared/actuators/HBridge/HBridge.cpp + ${BOARDCORE_PATH}/src/shared/actuators/Servo/Servo.cpp + ${BOARDCORE_PATH}/src/shared/actuators/stepper/Stepper.cpp + ${BOARDCORE_PATH}/src/shared/actuators/stepper/StepperPWM.cpp + + # Algorithms + ${BOARDCORE_PATH}/src/shared/algorithms/ADA/ADA.cpp + ${BOARDCORE_PATH}/src/shared/algorithms/MEA/MEA.cpp + ${BOARDCORE_PATH}/src/shared/algorithms/AirBrakes/AirBrakes.cpp + ${BOARDCORE_PATH}/src/shared/algorithms/AirBrakes/AirBrakesPI.cpp + ${BOARDCORE_PATH}/src/shared/algorithms/AirBrakes/AirBrakesInterp.cpp + ${BOARDCORE_PATH}/src/shared/algorithms/NAS/NAS.cpp + ${BOARDCORE_PATH}/src/shared/algorithms/NAS/StateInitializer.cpp + + # Debug + ${BOARDCORE_PATH}/src/shared/utils/Debug.cpp + ${BOARDCORE_PATH}/src/shared/diagnostic/CpuMeter/CpuMeter.cpp + ${BOARDCORE_PATH}/src/shared/diagnostic/PrintLogger.cpp + + # Drivers + ${BOARDCORE_PATH}/src/shared/drivers/AD5204/AD5204.cpp + ${BOARDCORE_PATH}/src/shared/drivers/adc/InternalADC.cpp + ${BOARDCORE_PATH}/src/shared/drivers/canbus/CanDriver/CanDriver.cpp + ${BOARDCORE_PATH}/src/shared/drivers/canbus/CanDriver/CanInterrupt.cpp + ${BOARDCORE_PATH}/src/shared/drivers/canbus/CanProtocol/CanProtocol.cpp + ${BOARDCORE_PATH}/src/shared/drivers/interrupt/external_interrupts.cpp + ${BOARDCORE_PATH}/src/shared/drivers/timer/PWM.cpp + ${BOARDCORE_PATH}/src/shared/drivers/timer/CountedPWM.cpp + ${BOARDCORE_PATH}/src/shared/drivers/timer/TimestampTimer.cpp + ${BOARDCORE_PATH}/src/shared/drivers/runcam/Runcam.cpp + ${BOARDCORE_PATH}/src/shared/drivers/spi/SPITransaction.cpp + ${BOARDCORE_PATH}/src/shared/drivers/usart/USART.cpp + ${BOARDCORE_PATH}/src/shared/drivers/i2c/I2CDriver-f4.cpp + ${BOARDCORE_PATH}/src/shared/drivers/i2c/I2CDriver-f7.cpp + ${BOARDCORE_PATH}/src/shared/drivers/i2c/I2C.cpp + ${BOARDCORE_PATH}/src/shared/drivers/WIZ5500/WIZ5500.cpp + + # Events + ${BOARDCORE_PATH}/src/shared/events/EventBroker.cpp + + # Logger + ${BOARDCORE_PATH}/src/shared/logger/Logger.cpp + + # Radio + ${BOARDCORE_PATH}/src/shared/radio/gamma868/Gamma868.cpp + ${BOARDCORE_PATH}/src/shared/radio/Xbee/APIFrameParser.cpp + ${BOARDCORE_PATH}/src/shared/radio/Xbee/Xbee.cpp + ${BOARDCORE_PATH}/src/shared/radio/SX1278/SX1278Fsk.cpp + ${BOARDCORE_PATH}/src/shared/radio/SX1278/SX1278Lora.cpp + ${BOARDCORE_PATH}/src/shared/radio/SX1278/SX1278Common.cpp + + # Scheduler + ${BOARDCORE_PATH}/src/shared/scheduler/TaskScheduler.cpp + + # Sensors + ${BOARDCORE_PATH}/src/shared/sensors/ADS1118/ADS1118.cpp + ${BOARDCORE_PATH}/src/shared/sensors/ADS131M04/ADS131M04.cpp + ${BOARDCORE_PATH}/src/shared/sensors/ADS131M08/ADS131M08.cpp + ${BOARDCORE_PATH}/src/shared/sensors/BME280/BME280.cpp + ${BOARDCORE_PATH}/src/shared/sensors/BME280/BME280I2C.cpp + ${BOARDCORE_PATH}/src/shared/sensors/BMP280/BMP280.cpp + ${BOARDCORE_PATH}/src/shared/sensors/BMP280/BMP280I2C.cpp + ${BOARDCORE_PATH}/src/shared/sensors/BMX160/BMX160.cpp + ${BOARDCORE_PATH}/src/shared/sensors/BMX160/BMX160WithCorrection.cpp + ${BOARDCORE_PATH}/src/shared/sensors/H3LIS331DL/H3LIS331DL.cpp + ${BOARDCORE_PATH}/src/shared/sensors/HX711/HX711.cpp + ${BOARDCORE_PATH}/src/shared/sensors/LIS3MDL/LIS3MDL.cpp + ${BOARDCORE_PATH}/src/shared/sensors/LIS331HH/LIS331HH.cpp + ${BOARDCORE_PATH}/src/shared/sensors/LPS331AP/LPS331AP.cpp + ${BOARDCORE_PATH}/src/shared/sensors/MAX6675/MAX6675.cpp + ${BOARDCORE_PATH}/src/shared/sensors/MAX31855/MAX31855.cpp + ${BOARDCORE_PATH}/src/shared/sensors/MAX31856/MAX31856.cpp + ${BOARDCORE_PATH}/src/shared/sensors/MBLoadCell/MBLoadCell.cpp + ${BOARDCORE_PATH}/src/shared/sensors/MPU9250/MPU9250.cpp + ${BOARDCORE_PATH}/src/shared/sensors/MS5803/MS5803.cpp + ${BOARDCORE_PATH}/src/shared/sensors/MS5803/MS5803I2C.cpp + ${BOARDCORE_PATH}/src/shared/sensors/SensorManager.cpp + ${BOARDCORE_PATH}/src/shared/sensors/SensorSampler.cpp + ${BOARDCORE_PATH}/src/shared/sensors/UBXGPS/UBXGPSSerial.cpp + ${BOARDCORE_PATH}/src/shared/sensors/UBXGPS/UBXGPSSpi.cpp + ${BOARDCORE_PATH}/src/shared/sensors/VN100/VN100.cpp + ${BOARDCORE_PATH}/src/shared/sensors/LIS2MDL/LIS2MDL.cpp + ${BOARDCORE_PATH}/src/shared/sensors/LPS28DFW/LPS28DFW.cpp + ${BOARDCORE_PATH}/src/shared/sensors/LPS22DF/LPS22DF.cpp + ${BOARDCORE_PATH}/src/shared/sensors/LSM6DSRX/LSM6DSRX.cpp + + # Calibration + ${BOARDCORE_PATH}/src/shared/sensors/calibration/BiasCalibration/BiasCalibration.cpp + ${BOARDCORE_PATH}/src/shared/sensors/calibration/SensorDataExtra/SensorDataExtra.cpp + ${BOARDCORE_PATH}/src/shared/sensors/calibration/SixParameterCalibration/SixParameterCalibration.cpp + ${BOARDCORE_PATH}/src/shared/sensors/calibration/SoftAndHardIronCalibration/SoftAndHardIronCalibration.cpp + + # Correction + ${BOARDCORE_PATH}/src/shared/sensors/correction/BiasCorrector/BiasCorrector.cpp + ${BOARDCORE_PATH}/src/shared/sensors/correction/SixParametersCorrector/SixParametersCorrector.cpp + + # Utils + ${BOARDCORE_PATH}/src/shared/utils/AeroUtils/AeroUtils.cpp + ${BOARDCORE_PATH}/src/shared/utils/ButtonHandler/ButtonHandler.cpp + ${BOARDCORE_PATH}/src/shared/utils/PinObserver/PinObserver.cpp + ${BOARDCORE_PATH}/src/shared/utils/SkyQuaternion/SkyQuaternion.cpp + ${BOARDCORE_PATH}/src/shared/utils/Stats/Stats.cpp + ${BOARDCORE_PATH}/src/shared/utils/TestUtils/TestHelper.cpp +) + +# Creates the Skyward::Boardcore::${BOARD_NAME} library +function(add_boardcore_library BOARD_OPTIONS_FILE) + # Get board options + include(${BOARD_OPTIONS_FILE}) + + # Create a library for the board + set(BOARDCORE_LIB boardcore-${BOARD_NAME}) + add_library(${BOARDCORE_LIB} STATIC EXCLUDE_FROM_ALL ${BOARDCORE_SRC}) + + # Only one include directory for Boardcore! + target_include_directories(${BOARDCORE_LIB} PUBLIC ${BOARDCORE_PATH}/src/shared) + + # Define DEBUG when in Debug mode + target_compile_definitions(${BOARDCORE_LIB} PUBLIC $<$<CONFIG:Debug>:DEBUG>) + + # Link libraries + target_link_libraries(${BOARDCORE_LIB} PUBLIC + $<TARGET_OBJECTS:Miosix::Boot::${BOARD_NAME}> + $<LINK_GROUP:RESCAN,Miosix::Kernel::${BOARD_NAME},stdc++,c,m,gcc,atomic> TSCPP::TSCPP Eigen3::Eigen fmt::fmt-header-only @@ -143,8 +161,23 @@ foreach(OPT_BOARD ${BOARDS}) Mavlink::Mavlink ) - # Link MxGui only if supported by the target - if(${OPT_BOARD} IN_LIST MXGUI_BOARDS) - target_link_libraries(${BOARDCORE_LIBRARY} PUBLIC Mxgui::Mxgui::${OPT_BOARD}) + # Link MxGui if supported by the target + if(DEFINED MXGUI_BASE_BOARD_NAME) + target_link_libraries(${BOARDCORE_LIB} PUBLIC MxGui::${MXGUI_BASE_BOARD_NAME}) + elseif(TARGET MxGui::${BOARD_NAME}) + target_link_libraries(${BOARDCORE_LIB} PUBLIC MxGui::${BOARD_NAME}) endif() + + # Create a nice alias for the library + add_library(Skyward::Boardcore::${BOARD_NAME} ALIAS ${BOARDCORE_LIB}) +endfunction() + +# Create the Miosix libraries for Boardcore custom boards +foreach(BOARD_OPTIONS_FILE ${BOARDCORE_BOARDS_OPTIONS_FILES}) + add_miosix_libraries(${BOARD_OPTIONS_FILE}) +endforeach() + +# Create Boardcore library for each board +foreach(BOARD_OPTIONS_FILE ${MIOSIX_BOARDS_OPTIONS_FILES} ${BOARDCORE_BOARDS_OPTIONS_FILES}) + add_boardcore_library(${BOARD_OPTIONS_FILE}) endforeach() diff --git a/cmake/boards.cmake b/cmake/boards.cmake new file mode 100644 index 0000000000000000000000000000000000000000..aaf6074cbba4061cf1e15989a4c5b97de5cad32d --- /dev/null +++ b/cmake/boards.cmake @@ -0,0 +1,37 @@ +# Copyright (c) 2023 Skyward Experimental Rocketry +# Authors: Alberto Nidasio +# +# 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. + +set(BOARDCORE_BOARDS_OPTIONS_FILES + ${BOARDCORE_PATH}/src/bsps/stm32f205rc_ciuti/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f429zi_nokia/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f429zi_parafoil/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f429zi_death_stack_v1/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f429zi_death_stack_v2/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f429zi_death_stack_v3/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f429zi_pyxis_auxiliary/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f429zi_rig/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f756zg_nucleo/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f767zi_automated_antennas/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f767zi_compute_unit/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f767zi_gemini_gs/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f767zi_gemini_motor/config/board_options.cmake + ${BOARDCORE_PATH}/src/bsps/stm32f767zi_death_stack_v4/config/board_options.cmake +) diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 7a4f691a0b7e31a97e6bce06bad6713bf2c4d437..f0a5db0585af4e5db1b53c972b0b69b8b0050896 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -19,33 +19,34 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -file(GLOB KPATH ${SBS_BASE}/libs/miosix-kernel/miosix) -if(NOT KPATH) - message(FATAL_ERROR "Kernel directory not found") -endif() -add_subdirectory(${KPATH} EXCLUDE_FROM_ALL) -include(${KPATH}/config/boards.cmake) +# Miosix Kernel +include(${SBS_BASE}/libs/miosix-kernel/miosix/cmake/miosix.cmake EXCLUDE_FROM_ALL) +# Miosix Host add_subdirectory(${SBS_BASE}/libs/miosix-host EXCLUDE_FROM_ALL) -set(KPATH ${KPATH} CACHE PATH "Path to kernel directory") -add_subdirectory(${SBS_BASE}/libs/mxgui EXCLUDE_FROM_ALL) -include(${SBS_BASE}/libs/mxgui/cmake/boards.cmake) +# MxGui graphical library +include(${SBS_BASE}/libs/mxgui/cmake/mxgui.cmake) +# Serialization library add_subdirectory(${SBS_BASE}/libs/tscpp EXCLUDE_FROM_ALL) +# Eigen library set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) set(EIGEN_TEST_NOQT ON CACHE BOOL "Disable Qt support in unit tests") set(CMAKE_Fortran_COMPILER NOTFOUND) add_subdirectory(${SBS_BASE}/libs/eigen EXCLUDE_FROM_ALL) target_compile_definitions(eigen INTERFACE EIGEN_MAX_ALIGN_BYTES=0) +# Format library add_subdirectory(${SBS_BASE}/libs/fmt EXCLUDE_FROM_ALL) target_compile_definitions(fmt-header-only INTERFACE _GLIBCXX_USE_WCHAR_T FMT_UNICODE=0 FMT_STATIC_THOUSANDS_SEPARATOR=0) target_compile_options(fmt-header-only INTERFACE -fno-math-errno) +# Catch2 library add_subdirectory(${SBS_BASE}/libs/Catch2 EXCLUDE_FROM_ALL) list(APPEND CMAKE_MODULE_PATH ${SBS_BASE}/libs/Catch2/contrib) include(Catch) +# MavLink library add_subdirectory(${SBS_BASE}/libs/mavlink-skyward-lib EXCLUDE_FROM_ALL) diff --git a/cmake/sbs.cmake b/cmake/sbs.cmake index e3d2065733043e139997f535b224820f82e00b8a..7cd5a66c2c8cf0578c4ecaa613577d82498a1a14 100644 --- a/cmake/sbs.cmake +++ b/cmake/sbs.cmake @@ -21,19 +21,15 @@ enable_language(C CXX ASM) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) -get_filename_component(SBS_BASE ${CMAKE_CURRENT_LIST_DIR} DIRECTORY) - -if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL SBS_BASE) - add_subdirectory(${SBS_BASE} EXCLUDE_FROM_ALL) - list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) - include(${CMAKE_SOURCE_DIR}/cmake/dependencies.cmake OPTIONAL) - return() -endif() +# Load in SBS_BASE the project path +cmake_path(GET CMAKE_CURRENT_LIST_DIR PARENT_PATH SBS_BASE) +# Include the Boardcore libraries +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) include(boardcore) -string(REPLACE ";" "\\n" BOARDS_STR "${BOARDS}") +# Command to print all the available boards used by the sbs script +string(REPLACE ";" "\\n" BOARDS_STR "${MIOSIX_BOARDS};${BOARDCORE_BOARDS}") add_custom_target( help-boards COMMAND printf ${BOARDS_STR} @@ -41,13 +37,22 @@ add_custom_target( VERBATIM ) +# Function to link the Boardcore library to the target function(sbs_target TARGET OPT_BOARD) if(NOT OPT_BOARD) message(FATAL_ERROR "No board selected") endif() + + # The only include directory of Boardcore is shared! target_include_directories(${TARGET} PRIVATE src/shared) + if(CMAKE_CROSSCOMPILING) - target_link_libraries(${TARGET} PRIVATE SkywardBoardcore::Boardcore::${OPT_BOARD}) + # Link the embedded Boardcore library + target_link_libraries(${TARGET} PRIVATE Skyward::Boardcore::${OPT_BOARD}) + + # Linker script and linking options are eredited from the kernel library + + # Add a post build command to create the hex file to flash on the board add_custom_command( TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_OBJCOPY} -O ihex ${TARGET} ${TARGET}.hex @@ -56,7 +61,7 @@ function(sbs_target TARGET OPT_BOARD) VERBATIM ) else() - target_link_libraries(${TARGET} PRIVATE SkywardBoardcore::Boardcore::host) + target_link_libraries(${TARGET} PRIVATE Skyward::Boardcore::host) endif() endfunction() diff --git a/libs/miosix-host b/libs/miosix-host index ed8a4d8c24e59ce7513b1cebc9b6427fde55c7ce..5b09ee5386e53b9c0e350603a9f0994934e4deea 160000 --- a/libs/miosix-host +++ b/libs/miosix-host @@ -1 +1 @@ -Subproject commit ed8a4d8c24e59ce7513b1cebc9b6427fde55c7ce +Subproject commit 5b09ee5386e53b9c0e350603a9f0994934e4deea diff --git a/libs/miosix-kernel b/libs/miosix-kernel index fb3e5b7c8047ea08b111c9beab94745556e0f8d3..331b5d5c0b54e05ed2fdd6b59eeb6037123f567c 160000 --- a/libs/miosix-kernel +++ b/libs/miosix-kernel @@ -1 +1 @@ -Subproject commit fb3e5b7c8047ea08b111c9beab94745556e0f8d3 +Subproject commit 331b5d5c0b54e05ed2fdd6b59eeb6037123f567c diff --git a/libs/mxgui b/libs/mxgui index 85c4cfb0cddab47ceb14ed158559ffd4fa7af288..e300a6c2587d29f4795b67ee0eaebf18aeebb5cb 160000 --- a/libs/mxgui +++ b/libs/mxgui @@ -1 +1 @@ -Subproject commit 85c4cfb0cddab47ceb14ed158559ffd4fa7af288 +Subproject commit e300a6c2587d29f4795b67ee0eaebf18aeebb5cb diff --git a/sbs b/sbs index 5cecc767b3b150d49d150ef857a71c3247dc2c83..f867e996023a6212e05367413329cbe40ce40a03 100755 --- a/sbs +++ b/sbs @@ -47,7 +47,7 @@ init_dirs() { source_dir="$PWD" build_default_dir="$source_dir/$BUILD_DEFAULT_DIRNAME" build_host_dir="$source_dir/$BUILD_HOST_DIRNAME" - toolchain_file="$sbs_base/libs/miosix-kernel/miosix/_tools/toolchain.cmake" + toolchain_file="$sbs_base/libs/miosix-kernel/miosix/cmake/toolchain.cmake" } find_deps() { diff --git a/src/bsps/stm32f205rc_ciuti/config/board_options.cmake b/src/bsps/stm32f205rc_ciuti/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..2c0856354d6e7cb423d58f4d677de9142614dc17 --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/config/board_options.cmake @@ -0,0 +1,99 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f205rc_ciuti) +set(ARCH_NAME cortexM3_stm32f2) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file and linker script +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_512k+128k_rom.ld) + +# Clock frequency +set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_120MHz=120000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m3 -mthumb) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +set(CFLAGS_BASE + -D_BOARD_STM32F205_GENERIC "-D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\"" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM3_STM32F2 + ${CLOCK_FREQ} ${XRAM} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${BOARD_PATH}/interfaces-impl/delays.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F2xx/Source/Templates/system_stm32f2xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp +) diff --git a/src/bsps/stm32f205rc_ciuti/config/board_settings.h b/src/bsps/stm32f205rc_ciuti/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..d53b41328b527d069f73c227b7111b4fb4f55f67 --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/config/board_settings.h @@ -0,0 +1,68 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1.5KB) and the +/// STM32F205RC has 128KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 4 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA //Serial 2 is used by the pogo pins +// #define SERIAL_3_DMA //Serial 3 is used by the pogo pins + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +// #define SD_ONE_BIT_DATABUS // This board supports 4 bit data bus to SD card + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f205rc_ciuti/config/miosix_settings.h b/src/bsps/stm32f205rc_ciuti/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..22c33aa669e90ce3ce872c672a623f431203bc2d --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +// #define SCHED_TYPE_CONTROL_BASED +// #define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +// #define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +// #define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +// #define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +// #define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f205rc_ciuti/core/stage_1_boot.cpp b/src/bsps/stm32f205rc_ciuti/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3f27e6bb432640fa9a47b2ed403879a0f39ce56 --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/core/stage_1_boot.cpp @@ -0,0 +1,399 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f2 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + // The memcpy is usually enclosed in an #ifndef __ENABLE_XRAM, in other + // boards but in this case it is not, since the *_code_in_xram.ld linker + // script puts code in XRAM, but data in the internal one, so there's still + // the need to copy it in its final place + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + /* + * SystemInit() is called *before* initializing .data and zeroing .bss + * Despite all startup files provided by ST do the opposite, there are three + * good reasons to do so: + * First, the CMSIS specifications say that SystemInit() must not access + * global variables, so it is actually possible to call it before + * Second, when running Miosix with the xram linker scripts .data and .bss + * are placed in the external RAM, so we *must* call SystemInit(), which + * enables xram, before touching .data and .bss + * Third, this is a performance improvement since the loops that initialize + * .data and zeros .bss now run with the CPU at full speed instead of 16MHz + * Note that it is called before switching stacks because the memory + * at _heap_end can be unavailable until the external RAM is initialized. + */ + SystemInit(); + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FSMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FSMC_IRQHandler, + SDIO_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + 0, + 0, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + 0, + 0, + HASH_RNG_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FSMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f205rc_ciuti/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f205rc_ciuti/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..3c336decc801886410f9d1d3ce88c665d240ea28 --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +#define STM32F205xx +#include "CMSIS/Device/ST/STM32F2xx/Include/stm32f2xx.h" +#include "CMSIS/Device/ST/STM32F2xx/Include/system_stm32f2xx.h" +#include "CMSIS/Include/core_cm3.h" + +#define RCC_SYNC() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f205rc_ciuti/interfaces-impl/bsp.cpp b/src/bsps/stm32f205rc_ciuti/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..39c47a1384b699e1917634cf2085ff22cd1f1123 --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/interfaces-impl/bsp.cpp @@ -0,0 +1,173 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/dcc.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +using namespace std; + +namespace miosix +{ + +// +// Initialization +// + +void IRQbspInit() +{ + // Enable all gpios + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN; + RCC_SYNC(); + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOS + GPIOB->OSPEEDR = 0xaaaaaaaa; + GPIOC->OSPEEDR = 0xaaaaaaaa; + GPIOD->OSPEEDR = 0xaaaaaaaa; + + using namespace interfaces; + + spi1::cs::mode(Mode::OUTPUT); + spi1::cs::high(); + spi1::sck::mode(Mode::ALTERNATE); + spi1::sck::alternateFunction(5); + spi1::miso::mode(Mode::ALTERNATE); + spi1::miso::alternateFunction(5); + spi1::mosi::mode(Mode::ALTERNATE); + spi1::mosi::alternateFunction(5); + + spi2::sck::mode(Mode::ALTERNATE); + spi2::sck::alternateFunction(5); + spi2::miso::mode(Mode::ALTERNATE); + spi2::miso::alternateFunction(5); + spi2::mosi::mode(Mode::ALTERNATE); + spi2::mosi::alternateFunction(5); + + usart1::rx::mode(Mode::ALTERNATE); + usart1::rx::alternateFunction(7); + usart1::tx::mode(Mode::ALTERNATE); + usart1::tx::alternateFunction(7); + + usart2::rx::mode(Mode::ALTERNATE); + usart2::rx::alternateFunction(7); + usart2::tx::mode(Mode::ALTERNATE); + usart2::tx::alternateFunction(7); + + usart3::rx::mode(Mode::ALTERNATE); + usart3::rx::alternateFunction(7); + usart3::tx::mode(Mode::ALTERNATE); + usart3::tx::alternateFunction(7); + + can1::rx::mode(Mode::ALTERNATE); + can1::rx::alternateFunction(9); + can1::tx::mode(Mode::ALTERNATE); + can1::tx::alternateFunction(9); + + using namespace devices; + + lis331hh::cs::mode(Mode::OUTPUT); + lis331hh::cs::high(); + + ad5204::cs::mode(Mode::OUTPUT); + ad5204::cs::high(); + + ina188::vsense1::mode(Mode::INPUT_ANALOG); + ina188::vsense2::mode(Mode::INPUT_ANALOG); + ina188::mosfet1::mode(Mode::OUTPUT); + ina188::mosfet1::high(); + ina188::mosfet2::mode(Mode::OUTPUT); + ina188::mosfet2::high(); + + vbat::mode(Mode::INPUT_ANALOG); + + buttons::bypass::mode(Mode::INPUT); + buttons::record::mode(Mode::INPUT); + + buzzer::drive::mode(Mode::ALTERNATE); + buzzer::drive::alternateFunction(3); + + leds::led1::mode(Mode::OUTPUT); + leds::led1::low(); + leds::led2::mode(Mode::OUTPUT); + leds::led2::low(); + leds::led3::mode(Mode::OUTPUT); + leds::led3::low(); + leds::led4::mode(Mode::OUTPUT); + leds::led4::low(); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM +} + +// +// Shutdown and reboot +// + +/** + * For safety reasons, we never want to shutdown. When requested to shutdown, we + * reboot instead. + */ +void shutdown() { reboot(); } + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} +} // namespace miosix diff --git a/src/bsps/stm32f205rc_ciuti/interfaces-impl/bsp_impl.h b/src/bsps/stm32f205rc_ciuti/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..b2158cabcb30e748d54f0f85ef1778405c69b84f --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/interfaces-impl/bsp_impl.h @@ -0,0 +1,72 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +inline void ledOn() +{ + devices::leds::led1::high(); + devices::leds::led2::high(); + devices::leds::led3::high(); + devices::leds::led4::high(); +} + +inline void ledOff() +{ + devices::leds::led1::low(); + devices::leds::led2::low(); + devices::leds::led3::low(); + devices::leds::led4::low(); +} + +/** + * Polls the SD card sense GPIO + * \return true if there is an uSD card in the socket. + */ +inline bool sdCardSense() { return true; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f205rc_ciuti/interfaces-impl/delays.cpp b/src/bsps/stm32f205rc_ciuti/interfaces-impl/delays.cpp new file mode 100644 index 0000000000000000000000000000000000000000..65ff9f9c47c3433216e220bb94100ddf6b39532d --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/interfaces-impl/delays.cpp @@ -0,0 +1,76 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#include "interfaces/delays.h" + +namespace miosix +{ + +void delayMs(unsigned int mseconds) +{ +#ifndef __CODE_IN_XRAM + +#ifndef SYSCLK_FREQ_120MHz +#error "Delays are uncalibrated for this clock frequency" +#endif + const unsigned int count = 29999; + + for (unsigned int i = 0; i < mseconds; i++) + { + // This delay has been calibrated to take 1 millisecond + // It is written in assembler to be independent on compiler optimization + asm volatile( + " mov r1, #0 \n" + "___loop_m: cmp r1, %0 \n" + " itt lo \n" + " addlo r1, r1, #1 \n" + " blo ___loop_m \n" ::"r"(count) + : "r1"); + } + +#else //__CODE_IN_XRAM +#error "No delays" +#endif //__CODE_IN_XRAM +} + +void delayUs(unsigned int useconds) +{ +#ifndef __CODE_IN_XRAM + + // This delay has been calibrated to take x microseconds + // It is written in assembler to be independent on compiler optimization + asm volatile( + " mov r1, #30 \n" + " mul r2, %0, r1 \n" + " mov r1, #0 \n" + "___loop_u: cmp r1, r2 \n" + " itt lo \n" + " addlo r1, r1, #1 \n" + " blo ___loop_u \n" ::"r"(useconds) + : "r1", "r2"); + +#else //__CODE_IN_XRAM +#error "No delays" +#endif //__CODE_IN_XRAM +} + +} // namespace miosix diff --git a/src/bsps/stm32f205rc_ciuti/interfaces-impl/hwmapping.h b/src/bsps/stm32f205rc_ciuti/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..7edc4d4b35532fb2b2b21ba1063555413c7f4629 --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/interfaces-impl/hwmapping.h @@ -0,0 +1,125 @@ +/* Copyright (c) 2021 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef HWMAPPING_H +#define HWMAPPING_H + +#include "interfaces/gpio.h" + +namespace miosix +{ + +namespace interfaces +{ + +namespace spi1 +{ +using cs = Gpio<GPIOA_BASE, 4>; +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +// LIS331HH and AD8403 +namespace spi2 +{ +using sck = Gpio<GPIOB_BASE, 13>; +using miso = Gpio<GPIOB_BASE, 14>; +using mosi = Gpio<GPIOB_BASE, 15>; +} // namespace spi2 + +// Debug +namespace usart1 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace usart1 + +// Pogo pin +namespace usart2 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace usart2 + +// Pogo pin +namespace usart3 +{ +using tx = Gpio<GPIOB_BASE, 10>; +using rx = Gpio<GPIOB_BASE, 11>; +} // namespace usart3 + +namespace can1 +{ +using rx = Gpio<GPIOA_BASE, 11>; +using tx = Gpio<GPIOA_BASE, 12>; +} // namespace can1 + +} // namespace interfaces + +namespace devices +{ + +namespace lis331hh +{ +using cs = Gpio<GPIOC_BASE, 4>; +} + +namespace ad5204 +{ +using cs = Gpio<GPIOC_BASE, 0>; +} + +namespace ina188 +{ +using vsense1 = Gpio<GPIOA_BASE, 0>; +using vsense2 = Gpio<GPIOA_BASE, 1>; +using mosfet1 = Gpio<GPIOC_BASE, 3>; +using mosfet2 = Gpio<GPIOC_BASE, 2>; +} // namespace ina188 + +using vbat = Gpio<GPIOC_BASE, 5>; + +namespace buttons +{ +using bypass = Gpio<GPIOC_BASE, 7>; +using record = Gpio<GPIOA_BASE, 8>; +} // namespace buttons + +namespace buzzer +{ +using drive = Gpio<GPIOC_BASE, 6>; // PWM TIM8_CH1 +} + +namespace leds +{ +using led1 = Gpio<GPIOB_BASE, 0>; // TIM3_CH3 +using led2 = Gpio<GPIOB_BASE, 5>; +using led3 = Gpio<GPIOB_BASE, 6>; +using led4 = Gpio<GPIOB_BASE, 7>; +} // namespace leds + +} // namespace devices + +} // namespace miosix + +#endif // HWMAPPING_H diff --git a/src/bsps/stm32f205rc_ciuti/stm32_512k+128k_rom.ld b/src/bsps/stm32f205rc_ciuti/stm32_512k+128k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..62406d42b17c1cf7ab13a60cd89c62b0127abf94 --- /dev/null +++ b/src/bsps/stm32f205rc_ciuti/stm32_512k+128k_rom.ld @@ -0,0 +1,170 @@ +/* + * C++ enabled linker script for Skyward stormtrooper board + * Developed by Terraneo Federico, adapted by Silvano Seva + * STM32F205RC has 512KB of flash and 128KB of RAM + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in flash + * - stacks, heap and sections .data and .bss in the internal ram + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* end of the heap on 128KB microcontrollers */ +_heap_end = 0x20020000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0, LENGTH = 512K + + /* + * Note, the ram starts at 0x20000000 but it is necessary to add the size + * of the main stack, so it is 0x20000200. + */ + ram(wx) : ORIGIN = 0x20000200, LENGTH = 128K-0x200 +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > ram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > ram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f429zi_death_stack_v1/config/board_options.cmake b/src/bsps/stm32f429zi_death_stack_v1/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..f9da510a8b6b58d3d9d4b26b56a2e3c61504576a --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/config/board_options.cmake @@ -0,0 +1,122 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f429zi_death_stack_v1) +set(ARCH_NAME cortexM4_stm32f4) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot and linker files +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) + +# Linker script type, there are three options +# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld) +# the most common choice, available for all microcontrollers +# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld) +# You must uncomment -D__ENABLE_XRAM below in this case. +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld) + +# Uncommenting __ENABLE_XRAM enables the initialization of the external +# 8MB SDRAM memory. +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency. Warning: the default clock frequency for +# this board is 168MHz and not 180MHz because, due to a limitation in +# the PLL, it is not possible to generate a precise 48MHz output when +# running the core at 180MHz. If 180MHz is chosen the USB peripheral will +# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48) +# Define USE_INTERNAL_CLOCK to bypass the external oscillator +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000 -DUSE_INTERNAL_CLOCK) +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM4_STM32F4 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp + ${KPATH}/arch/common/drivers/servo_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_wd.cpp + ${KPATH}/arch/common/drivers/stm32f2_f4_i2c.cpp +) diff --git a/src/bsps/stm32f429zi_death_stack_v1/config/board_settings.h b/src/bsps/stm32f429zi_death_stack_v1/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..9dfffe6c7a941ed58298fb8e374c9279d902e525 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/config/board_settings.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2019 Skyward Experimental Rocketry + * Authors: Silvano Seva, Alberto Nidasio + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) but the +/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA //Serial 2 can't be used (GPIO conflict), so no DMA +// #define SERIAL_3_DMA //Serial 3 can't be used (GPIO conflict), so no DMA + +// #define I2C_WITH_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +#ifdef __ENABLE_XRAM +// Reduce SD clock to ~4.8MHz +#define OVERRIDE_SD_CLOCK_DIVIDER_MAX 8 +#endif //__ENABLE_XRAM +// #define SD_ONE_BIT_DATABUS //This board supports 4 bit databus to SD card + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f429zi_death_stack_v1/config/miosix_settings.h b/src/bsps/stm32f429zi_death_stack_v1/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..dcffa1b92935ab23b831f202ea04735c0becd2a5 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2019 Skyward Experimental Rocketry + * Authors: Silvano Seva, Alberto Nidasio + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_death_stack_v1/core/stage_1_boot.cpp b/src/bsps/stm32f429zi_death_stack_v1/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0abb640f9f6fae63ade9944af577df40aec50897 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/core/stage_1_boot.cpp @@ -0,0 +1,372 @@ +/* Copyright (c) 2019 Skyward Experimental Rocketry + * Authors: Silvano Seva, Alberto Nidasio + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f42x devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); +// ST does not provide code to initialize the stm32f429-disco SDRAM at boot. +// Put after SystemInit() as SDRAM is timing-sensitive and needs the full +// clock speed. +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, PVD_IRQHandler, TAMP_STAMP_IRQHandler, RTC_WKUP_IRQHandler, + FLASH_IRQHandler, RCC_IRQHandler, EXTI0_IRQHandler, EXTI1_IRQHandler, + EXTI2_IRQHandler, EXTI3_IRQHandler, EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, DMA1_Stream1_IRQHandler, DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, DMA1_Stream4_IRQHandler, DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, ADC_IRQHandler, CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, CAN1_RX1_IRQHandler, CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, TIM1_BRK_TIM9_IRQHandler, TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, TIM1_CC_IRQHandler, TIM2_IRQHandler, + TIM3_IRQHandler, TIM4_IRQHandler, I2C1_EV_IRQHandler, I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, I2C2_ER_IRQHandler, SPI1_IRQHandler, SPI2_IRQHandler, + USART1_IRQHandler, USART2_IRQHandler, USART3_IRQHandler, + EXTI15_10_IRQHandler, RTC_Alarm_IRQHandler, OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, TIM8_CC_IRQHandler, DMA1_Stream7_IRQHandler, + FMC_IRQHandler, SDIO_IRQHandler, TIM5_IRQHandler, SPI3_IRQHandler, + UART4_IRQHandler, UART5_IRQHandler, TIM6_DAC_IRQHandler, TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, DMA2_Stream1_IRQHandler, DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, DMA2_Stream4_IRQHandler, ETH_IRQHandler, + ETH_WKUP_IRQHandler, CAN2_TX_IRQHandler, CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, CAN2_SCE_IRQHandler, OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, DMA2_Stream6_IRQHandler, DMA2_Stream7_IRQHandler, + USART6_IRQHandler, I2C3_EV_IRQHandler, I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, OTG_HS_EP1_IN_IRQHandler, OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, DCMI_IRQHandler, CRYP_IRQHandler, HASH_RNG_IRQHandler, + FPU_IRQHandler, UART7_IRQHandler, UART8_IRQHandler, SPI4_IRQHandler, + SPI5_IRQHandler, SPI6_IRQHandler, SAI1_IRQHandler, LTDC_IRQHandler, + LTDC_ER_IRQHandler, DMA2D_IRQHandler}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..0ff1e6919a1a84015e40d958c9ba4801fd179a94 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2019 Skyward Experimental Rocketry + * Authors: Silvano Seva, Alberto Nidasio + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency +#define STM32F429xx +#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" +#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h" +#include "CMSIS/Include/core_cm4.h" + +#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/bsp.cpp b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..646ee99b221f0f426d5eff6d306c4d909cea9969 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/bsp.cpp @@ -0,0 +1,483 @@ +/* Copyright (c) 2019 Skyward Experimental Rocketry + * Authors: Silvano Seva, Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +/** + * The example code from ST checks for the busy flag after each command. + * Interestingly I couldn't find any mention of this in the datsheet. + */ +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +#ifdef SDRAM_ISSI + +void configureSdram() +{ + // Enable all gpios, passing clock + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | + FMC_SDCR1_CAS_1; // 2 cycle CAS latency (F<133MHz) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (7 - 1) << 4 // 7 cycle TXSR (77.7ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>15ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (6 - 1) << 4 // 6 cycle TXSR (71.4ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>15ns) +#else +#error No SDRAM timings for this clock +#endif + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // ST and SDRAM datasheet agree a 100us delay is required here. + delayUs(100); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (8 - 1) << 5 // NRFS=8 SDRAM datasheet says + // "at least two AUTO REFRESH cycles" + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + +// 64ms/4096=15.625us +#ifdef SYSCLK_FREQ_180MHz + // 15.625us*90MHz=1406-20=1386 + FMC_Bank5_6->SDRTR = 1386 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 15.625us*84MHz=1312-20=1292 + FMC_Bank5_6->SDRTR = 1292 << 1; +#else +#error No refresh timings for this clock +#endif +} + +#else + +void configureSdram() +{ + // Enable all gpios + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a AS4C4M16SA-6TAN, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = + 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | FMC_SDCR1_CAS_1; // 2 cycle CAS latency (TCK>9+0.5ns [1]) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>60ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>18ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | + (6 - 1) << 4 // 6 cycle TXSR (66.6ns>61.5+0.5ns [1]) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>18ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>60ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>18ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | + (6 - 1) << 4 // 6 cycle TXSR (71.4ns>61.5+0.5ns [1]) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>18ns) +#else +#error No SDRAM timings for this clock +#endif + // NOTE [1]: the timings for TCK and TIS depend on rise and fall times + //(see note 9 and 10 on datasheet). Timings are adjusted accordingly to + // the measured 2ns rise and fall time + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // SDRAM datasheet requires 200us delay here (note 11), here we use 10% more + delayUs(220); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + // FIXME: note 11 on SDRAM datasheet says extended mode register must be + // set, but the ST datasheet does not seem to explain how + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (4 - 1) << 5 // NRFS=8 SDRAM datasheet requires + // a minimum of 2 cycles, here we use 4 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + +// 32ms/4096=7.8125us, but datasheet says to round that to 7.8us +#ifdef SYSCLK_FREQ_180MHz + // 7.8us*90MHz=702-20=682 + FMC_Bank5_6->SDRTR = 682 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 7.8us*84MHz=655-20=635 + FMC_Bank5_6->SDRTR = 635 << 1; +#else +#error No refresh timings for this clock +#endif +} + +#endif + +void IRQbspInit() +{ +// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here +#ifndef __ENABLE_XRAM + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); +#endif //__ENABLE_XRAM + + using namespace interfaces; + spi1::sck::mode(Mode::ALTERNATE); + spi1::sck::alternateFunction(5); + spi1::miso::mode(Mode::ALTERNATE); + spi1::miso::alternateFunction(5); + spi1::mosi::mode(Mode::ALTERNATE); + spi1::mosi::alternateFunction(5); + + spi2::sck::mode(Mode::ALTERNATE); + spi2::sck::alternateFunction(5); + spi2::miso::mode(Mode::ALTERNATE); + spi2::miso::alternateFunction(5); + spi2::mosi::mode(Mode::ALTERNATE); + spi2::mosi::alternateFunction(5); + + // Software I2C + i2c::scl::high(); + i2c::scl::mode(Mode::OPEN_DRAIN); + i2c::sda::high(); + i2c::sda::mode(Mode::OPEN_DRAIN); + + uart4::rx::mode(Mode::ALTERNATE); + uart4::rx::alternateFunction(8); + uart4::tx::mode(Mode::ALTERNATE); + uart4::tx::alternateFunction(8); + + can::rx::mode(Mode::ALTERNATE); + can::rx::alternateFunction(9); + can::tx::mode(Mode::ALTERNATE); + can::tx::alternateFunction(9); + + using namespace sensors; + adis16405::cs::mode(Mode::OUTPUT); + adis16405::cs::high(); + adis16405::ckIn::mode(Mode::ALTERNATE); + adis16405::ckIn::alternateFunction(2); + adis16405::dio1::mode(Mode::INPUT); + adis16405::rst::mode(Mode::OUTPUT); + adis16405::rst::high(); + + ad7994::ab::mode(Mode::INPUT); + ad7994::nconvst::mode(Mode::OUTPUT); + + mpu9250::cs::mode(Mode::OUTPUT); + mpu9250::cs::high(); + mpu9250::intr::mode(Mode::INPUT); + + ms5803::cs::mode(Mode::OUTPUT); + ms5803::cs::high(); + + lsm6ds3h::cs::mode(Mode::OUTPUT); + lsm6ds3h::cs::high(); + lsm6ds3h::int1::mode(Mode::INPUT); + lsm6ds3h::int2::mode(Mode::INPUT); + + using namespace inputs; + vbat::mode(Mode::INPUT_ANALOG); + lp_dtch::mode(Mode::INPUT); + btn_open::mode(Mode::INPUT); + btn_close::mode(Mode::INPUT); + + using namespace nosecone; + motEn::mode(Mode::OUTPUT); + motEn::low(); + + motP1::mode(Mode::OUTPUT); + motP1::low(); + motP2::mode(Mode::OUTPUT); + motP2::low(); + + rogP1::mode(Mode::ALTERNATE); + rogP1::alternateFunction(2); + + rogP2::mode(Mode::ALTERNATE); + rogP2::alternateFunction(2); + + nc_dtch::mode(Mode::INPUT); + motor_act::mode(Mode::INPUT); + + motor_3v::mode(Mode::OUTPUT); + motor_3v::high(); + + motor_gnd::mode(Mode::OUTPUT); + motor_gnd::low(); + + using namespace actuators; + tcPwm::mode(Mode::ALTERNATE); + tcPwm::alternateFunction(3); + + thCut1::ena::mode(Mode::OUTPUT); + thCut1::ena::low(); + thCut1::csens::mode(Mode::INPUT_ANALOG); + + thCut2::ena::mode(Mode::OUTPUT); + thCut2::ena::low(); + thCut2::csens::mode(Mode::INPUT_ANALOG); + + misc::buzz::mode(Mode::OUTPUT); + misc::buzz::low(); + + xbee::cs::mode(Mode::OUTPUT); + xbee::cs::high(); + xbee::attn::mode(Mode::INPUT_PULL_UP); + xbee::sleep_status::mode(Mode::INPUT); + + xbee::reset::mode(Mode::OPEN_DRAIN); + xbee::reset::high(); + + // Led blink + led1::mode(Mode::OUTPUT); + + ledOn(); + delayMs(100); + ledOff(); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + // PA2,PA3 + intrusive_ref_ptr<DevFs> devFs = + basicFilesystemSetup(SDIODriver::instance()); + devFs->addDevice("gps", + intrusive_ref_ptr<Device>(new STM32Serial(2, 115200))); +#endif // WITH_FILESYSTEM +} + +// +// Shutdown and reboot +// + +/** + * For safety reasons, we never want the board to shutdown. + * When requested to shutdown, we reboot instead. + */ +void shutdown() { reboot(); } + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/bsp_impl.h b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..b3fa832232ae474d9b606d1413b745eab445cfd9 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/bsp_impl.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2019 Skyward Experimental Rocketry + * Authors: Silvano Seva, Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * used by the ledOn() and ledOff() implementation + */ + +inline void ledOn() { led1::high(); } + +inline void ledOff() { led1::low(); } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/hwmapping.h b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..f3e2accb62cbe3f2ccbfa11bfab8c867c1164f76 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/interfaces-impl/hwmapping.h @@ -0,0 +1,192 @@ +/* Copyright (c) 2019 Skyward Experimental Rocketry + * Authors: Silvano Seva, Alberto Nidasio + * + * 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. + */ + +#ifndef HWMAPPING_H +#define HWMAPPING_H + +#include "interfaces/gpio.h" + +namespace miosix +{ + +namespace interfaces +{ + +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +namespace spi2 +{ +using sck = Gpio<GPIOB_BASE, 13>; +using miso = Gpio<GPIOB_BASE, 14>; +using mosi = Gpio<GPIOB_BASE, 15>; +} // namespace spi2 + +namespace i2c +{ +using scl = Gpio<GPIOB_BASE, 8>; +using sda = Gpio<GPIOB_BASE, 9>; +} // namespace i2c + +namespace uart4 +{ +using tx = Gpio<GPIOA_BASE, 0>; +using rx = Gpio<GPIOA_BASE, 1>; +} // namespace uart4 + +namespace can +{ +using rx = Gpio<GPIOA_BASE, 11>; +using tx = Gpio<GPIOA_BASE, 12>; +} // namespace can +} // namespace interfaces + +namespace sensors +{ + +namespace adis16405 +{ +using cs = Gpio<GPIOA_BASE, 8>; +using dio1 = Gpio<GPIOB_BASE, 4>; +using dio2 = Gpio<GPIOD_BASE, 6>; +using dio3 = Gpio<GPIOD_BASE, 4>; +using rst = Gpio<GPIOD_BASE, 5>; +using ckIn = Gpio<GPIOA_BASE, 15>; +} // namespace adis16405 + +namespace ad7994 +{ +using ab = Gpio<GPIOB_BASE, 1>; +using nconvst = Gpio<GPIOG_BASE, 9>; +static constexpr uint8_t addr = 0x22 << 1; +} // namespace ad7994 + +namespace lm75b_analog +{ +static constexpr uint8_t addr = 0x48 << 1; +} // namespace lm75b_analog + +namespace lm75b_imu +{ +static constexpr uint8_t addr = 0x49 << 1; +} // namespace lm75b_imu + +namespace mpu9250 +{ +using cs = Gpio<GPIOC_BASE, 3>; +using intr = Gpio<GPIOE_BASE, 5>; +} // namespace mpu9250 + +namespace ms5803 +{ +using cs = Gpio<GPIOD_BASE, 7>; +} // namespace ms5803 + +namespace lsm6ds3h +{ +using cs = Gpio<GPIOC_BASE, 1>; +using int1 = Gpio<GPIOB_BASE, 12>; +using int2 = Gpio<GPIOG_BASE, 3>; +} // namespace lsm6ds3h + +} // namespace sensors + +namespace inputs +{ +using vbat = Gpio<GPIOF_BASE, 7>; +using lp_dtch = Gpio<GPIOC_BASE, 6>; // launchpad detach +using btn_open = Gpio<GPIOG_BASE, 11>; +using btn_close = Gpio<GPIOG_BASE, 13>; +} // namespace inputs + +namespace nosecone +{ +using motEn = Gpio<GPIOG_BASE, 14>; +using motP1 = Gpio<GPIOC_BASE, 7>; // Pwm motore 1 +using motP2 = Gpio<GPIOB_BASE, 0>; // Pwm motore 2 +using rogP1 = Gpio<GPIOD_BASE, 12>; // Pwm rogallina 1 +using rogP2 = Gpio<GPIOD_BASE, 13>; // Pwm rogallina 2 +using nc_dtch = Gpio<GPIOB_BASE, 7>; // Nosecone detach + +using motor_act = Gpio<GPIOE_BASE, 3>; // Motor actuation +using motor_3v = Gpio<GPIOC_BASE, 15>; // Motor actuation 3v +using motor_gnd = Gpio<GPIOE_BASE, 2>; // Motor actuation gnd +} // namespace nosecone + +namespace actuators +{ + +using tcPwm = Gpio<GPIOE_BASE, 6>; // Pwm thermal cutters + +namespace thCut2 +{ +using ena = Gpio<GPIOD_BASE, 11>; +using csens = Gpio<GPIOF_BASE, 8>; +} // namespace thCut2 + +namespace thCut1 +{ +using ena = Gpio<GPIOG_BASE, 2>; +using csens = Gpio<GPIOF_BASE, 6>; +} // namespace thCut1 +} // namespace actuators + +namespace misc +{ +using buzz = Gpio<GPIOD_BASE, 3>; + +using aux1 = Gpio<GPIOE_BASE, 2>; +using aux2 = Gpio<GPIOE_BASE, 3>; +using aux3 = Gpio<GPIOE_BASE, 4>; +using aux4 = Gpio<GPIOC_BASE, 14>; +using aux5 = Gpio<GPIOC_BASE, 15>; + +} // namespace misc + +using led1 = Gpio<GPIOC_BASE, 4>; + +/* NOTE: Direct access to these leds is possible + * only when the STM board is detached from + * the rest of the stack + */ +/* +using led2 = Gpio<GPIOG_BASE, 2>; +using led3 = Gpio<GPIOD_BASE, 11>; +using led4 = Gpio<GPIOB_BASE, 1>; +using led1 = Gpio<GPIOG_BASE, 3>; +*/ + +namespace xbee +{ +using cs = Gpio<GPIOF_BASE, 9>; +using attn = Gpio<GPIOF_BASE, 10>; +using reset = Gpio<GPIOC_BASE, 13>; +using sleep_req = Gpio<GPIOC_BASE, 2>; +using sleep_status = Gpio<GPIOA_BASE, 4>; +} // namespace xbee +} // namespace miosix + +#endif // HWMAPPING_H diff --git a/src/bsps/stm32f429zi_death_stack_v1/stm32_2m+256k_rom.ld b/src/bsps/stm32f429zi_death_stack_v1/stm32_2m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..cfcc2ce53bd9e1b821cbfe90aeedd73fcdce1522 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/stm32_2m+256k_rom.ld @@ -0,0 +1,181 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 192KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 192KB RAM */ +_end = 0x20000000; +_heap_end = 0x20030000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/src/bsps/stm32f429zi_death_stack_v1/stm32_2m+8m_xram.ld b/src/bsps/stm32f429zi_death_stack_v1/stm32_2m+8m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..b6a0d26683cbff52ac66b7f275f9269d61dfbf41 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v1/stm32_2m+8m_xram.ld @@ -0,0 +1,178 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - .data, .bss, stacks and heap in the external 8MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0800000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f429zi_death_stack_v2/config/board_options.cmake b/src/bsps/stm32f429zi_death_stack_v2/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..9b4741c604f63dc4101fa7ffb42049e1398f08c7 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/config/board_options.cmake @@ -0,0 +1,120 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f429zi_death_stack_v2) +set(ARCH_NAME cortexM4_stm32f4) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot and linker files +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) + +# Linker script type, there are three options +# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld) +# the most common choice, available for all microcontrollers +# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld) +# You must uncomment -D__ENABLE_XRAM below in this case. +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld) + +# Uncommenting __ENABLE_XRAM enables the initialization of the external +# 8MB SDRAM memory. Do not uncomment this even if you don't use a linker +# script that requires it, as it is used for the LCD framebuffer. +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency. Warning: the default clock frequency for +# this board is 168MHz and not 180MHz because, due to a limitation in +# the PLL, it is not possible to generate a precise 48MHz output when +# running the core at 180MHz. If 180MHz is chosen the USB peripheral will +# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48) +# Define USE_INTERNAL_CLOCK to bypass the external oscillator +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000) +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM4_STM32F4 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f429zi_death_stack_v2/config/board_settings.h b/src/bsps/stm32f429zi_death_stack_v2/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..85e9714725a70c94356a390ca6d72712bfd0d526 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/config/board_settings.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) but the +/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA //Serial 2 can't be used (GPIO conflict), so no DMA +// #define SERIAL_3_DMA //Serial 3 can't be used (GPIO conflict), so no DMA + +// #define I2C_WITH_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +#ifdef __ENABLE_XRAM +// Reduce SD clock to ~4.8MHz +#define OVERRIDE_SD_CLOCK_DIVIDER_MAX 8 +#endif //__ENABLE_XRAM +// #define SD_ONE_BIT_DATABUS //This board supports 4 bit databus to SD card + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f429zi_death_stack_v2/config/miosix_settings.h b/src/bsps/stm32f429zi_death_stack_v2/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..5006e0bcaa1ae584f1ab62ed191167433d3746c2 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_death_stack_v2/core/stage_1_boot.cpp b/src/bsps/stm32f429zi_death_stack_v2/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e40004e979f18c659784a89babaaf3f2ab185187 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/core/stage_1_boot.cpp @@ -0,0 +1,372 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f42x devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); +// ST does not provide code to initialize the stm32f429-disco SDRAM at boot. +// Put after SystemInit() as SDRAM is timing-sensitive and needs the full +// clock speed. +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, PVD_IRQHandler, TAMP_STAMP_IRQHandler, RTC_WKUP_IRQHandler, + FLASH_IRQHandler, RCC_IRQHandler, EXTI0_IRQHandler, EXTI1_IRQHandler, + EXTI2_IRQHandler, EXTI3_IRQHandler, EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, DMA1_Stream1_IRQHandler, DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, DMA1_Stream4_IRQHandler, DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, ADC_IRQHandler, CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, CAN1_RX1_IRQHandler, CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, TIM1_BRK_TIM9_IRQHandler, TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, TIM1_CC_IRQHandler, TIM2_IRQHandler, + TIM3_IRQHandler, TIM4_IRQHandler, I2C1_EV_IRQHandler, I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, I2C2_ER_IRQHandler, SPI1_IRQHandler, SPI2_IRQHandler, + USART1_IRQHandler, USART2_IRQHandler, USART3_IRQHandler, + EXTI15_10_IRQHandler, RTC_Alarm_IRQHandler, OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, TIM8_CC_IRQHandler, DMA1_Stream7_IRQHandler, + FMC_IRQHandler, SDIO_IRQHandler, TIM5_IRQHandler, SPI3_IRQHandler, + UART4_IRQHandler, UART5_IRQHandler, TIM6_DAC_IRQHandler, TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, DMA2_Stream1_IRQHandler, DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, DMA2_Stream4_IRQHandler, ETH_IRQHandler, + ETH_WKUP_IRQHandler, CAN2_TX_IRQHandler, CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, CAN2_SCE_IRQHandler, OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, DMA2_Stream6_IRQHandler, DMA2_Stream7_IRQHandler, + USART6_IRQHandler, I2C3_EV_IRQHandler, I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, OTG_HS_EP1_IN_IRQHandler, OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, DCMI_IRQHandler, CRYP_IRQHandler, HASH_RNG_IRQHandler, + FPU_IRQHandler, UART7_IRQHandler, UART8_IRQHandler, SPI4_IRQHandler, + SPI5_IRQHandler, SPI6_IRQHandler, SAI1_IRQHandler, LTDC_IRQHandler, + LTDC_ER_IRQHandler, DMA2D_IRQHandler}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..aa9f5579fa679dccfeeff9c8173ee9db339340b6 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency +#define STM32F429xx +#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" +#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h" +#include "CMSIS/Include/core_cm4.h" + +#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/bsp.cpp b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b47e68191ef3dfec399a767b81c124887aac0d44 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/bsp.cpp @@ -0,0 +1,486 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +/** + * The example code from ST checks for the busy flag after each command. + * Interestingly I couldn't find any mention of this in the datsheet. + */ +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +#ifdef SDRAM_ISSI + +void configureSdram() +{ + // Enable all gpios, passing clock + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | + FMC_SDCR1_CAS_1; // 2 cycle CAS latency (F<133MHz) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (7 - 1) << 4 // 7 cycle TXSR (77.7ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>15ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (6 - 1) << 4 // 6 cycle TXSR (71.4ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>15ns) +#else +#error No SDRAM timings for this clock +#endif + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // ST and SDRAM datasheet agree a 100us delay is required here. + delayUs(100); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (8 - 1) << 5 // NRFS=8 SDRAM datasheet says + // "at least two AUTO REFRESH cycles" + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + +// 64ms/4096=15.625us +#ifdef SYSCLK_FREQ_180MHz + // 15.625us*90MHz=1406-20=1386 + FMC_Bank5_6->SDRTR = 1386 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 15.625us*84MHz=1312-20=1292 + FMC_Bank5_6->SDRTR = 1292 << 1; +#else +#error No refresh timings for this clock +#endif +} + +#else + +void configureSdram() +{ + // Enable all gpios + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a AS4C4M16SA-6TAN, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = + 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | FMC_SDCR1_CAS_1; // 2 cycle CAS latency (TCK>9+0.5ns [1]) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>60ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>18ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | + (6 - 1) << 4 // 6 cycle TXSR (66.6ns>61.5+0.5ns [1]) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>18ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>60ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>18ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | + (6 - 1) << 4 // 6 cycle TXSR (71.4ns>61.5+0.5ns [1]) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>18ns) +#else +#error No SDRAM timings for this clock +#endif + // NOTE [1]: the timings for TCK and TIS depend on rise and fall times + //(see note 9 and 10 on datasheet). Timings are adjusted accordingly to + // the measured 2ns rise and fall time + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // SDRAM datasheet requires 200us delay here (note 11), here we use 10% more + delayUs(220); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + // FIXME: note 11 on SDRAM datasheet says extended mode register must be + // set, but the ST datasheet does not seem to explain how + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (4 - 1) << 5 // NRFS=8 SDRAM datasheet requires + // a minimum of 2 cycles, here we use 4 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + +// 32ms/4096=7.8125us, but datasheet says to round that to 7.8us +#ifdef SYSCLK_FREQ_180MHz + // 7.8us*90MHz=702-20=682 + FMC_Bank5_6->SDRTR = 682 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 7.8us*84MHz=655-20=635 + FMC_Bank5_6->SDRTR = 635 << 1; +#else +#error No refresh timings for this clock +#endif +} + +#endif + +void IRQbspInit() +{ +// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here +#ifndef __ENABLE_XRAM + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); +#endif //__ENABLE_XRAM + + // enable spi1, spi2 + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; + + // enable can1 + RCC->APB1ENR |= RCC_APB1ENR_CAN1EN; + + RCC_SYNC(); + + using namespace interfaces; + + spi1::sck::mode(Mode::ALTERNATE); + spi1::sck::alternateFunction(5); + spi1::miso::mode(Mode::ALTERNATE); + spi1::miso::alternateFunction(5); + spi1::mosi::mode(Mode::ALTERNATE); + spi1::mosi::alternateFunction(5); + + spi2::sck::mode(Mode::ALTERNATE); + spi2::sck::alternateFunction(5); + spi2::miso::mode(Mode::ALTERNATE); + spi2::miso::alternateFunction(5); + spi2::mosi::mode(Mode::ALTERNATE); + spi2::mosi::alternateFunction(5); + + uart2::rx::mode(Mode::ALTERNATE); + uart2::rx::alternateFunction(7); + uart2::tx::mode(Mode::ALTERNATE); + uart2::tx::alternateFunction(7); + + uart3::rx::mode(Mode::ALTERNATE); + uart3::rx::alternateFunction(7); + uart3::tx::mode(Mode::ALTERNATE); + uart3::tx::alternateFunction(7); + + uart4::rx::mode(Mode::ALTERNATE); + uart4::rx::alternateFunction(8); + uart4::tx::mode(Mode::ALTERNATE); + uart4::tx::alternateFunction(8); + + can::rx::mode(Mode::ALTERNATE); + can::rx::alternateFunction(9); + can::tx::mode(Mode::ALTERNATE); + can::tx::alternateFunction(9); + + timers::tim4ch1::mode(Mode::ALTERNATE); + timers::tim4ch1::alternateFunction(2); + timers::tim8ch2::mode(Mode::ALTERNATE); + timers::tim8ch2::alternateFunction(3); + + camMosfet::mode(Mode::OUTPUT); + camMosfet::low(); + + using namespace sensors; + + ads1118::cs::mode(Mode::OUTPUT); + ads1118::cs::high(); + + bmx160::cs::mode(Mode::OUTPUT); + bmx160::cs::high(); + bmx160::intr::mode(Mode::INPUT_PULL_UP); + + lsm9ds1::cs_a_g::mode(Mode::OUTPUT); + lsm9ds1::cs_a_g::high(); + lsm9ds1::cs_m::mode(Mode::OUTPUT); + lsm9ds1::cs_m::high(); + lsm9ds1::intr_a_g::mode(Mode::INPUT); + + lis3mdl::cs::mode(Mode::OUTPUT); + lis3mdl::cs::high(); + + ms5803::cs::mode(Mode::OUTPUT); + ms5803::cs::high(); + + using namespace inputs; + + vbat::mode(Mode::INPUT_ANALOG); + expulsion::mode(Mode::INPUT); + + using namespace actuators; + + nosecone::th_cut_input::mode(Mode::OUTPUT); + + nosecone::thermal_cutter_1::enable::mode(Mode::OUTPUT); + nosecone::thermal_cutter_1::enable::low(); + nosecone::thermal_cutter_1::cutter_sens::mode(Mode::INPUT_ANALOG); + + nosecone::thermal_cutter_2::enable::mode(Mode::OUTPUT); + nosecone::thermal_cutter_2::enable::low(); + nosecone::thermal_cutter_2::cutter_sens::mode(Mode::INPUT_ANALOG); + + using namespace aux; + + sense_aux_1::mode(Mode::INPUT); + aux_pd_pu::mode(Mode::OUTPUT); + aux_spi1_cs::mode(Mode::OUTPUT); + + using namespace leds; + + led_red1::mode(Mode::OUTPUT); + led_red2::mode(Mode::OUTPUT); + led_blue1::mode(Mode::OUTPUT); + led_ring::mode(Mode::OUTPUT); + + using namespace xbee; + + xbee::cs::mode(Mode::OUTPUT); + xbee::cs::high(); + xbee::attn::mode(Mode::INPUT_PULL_UP); + xbee::reset::mode(Mode::OPEN_DRAIN); + xbee::reset::high(); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); + + for (uint8_t i = 0; i < 3; i++) + { + ledOn(); + delayMs(10); + ledOff(); + delayMs(10); + } +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + // PA2,PA3 + intrusive_ref_ptr<DevFs> devFs = + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM +} + +// +// Shutdown and reboot +// + +/** + * For safety reasons, we never want the board to shutdown. + * When requested to shutdown, we reboot instead. + */ +void shutdown() { reboot(); } + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/bsp_impl.h b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..91279b1f39463586602b85c893a835d10b200547 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/bsp_impl.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * used by the ledOn() and ledOff() implementation + */ + +inline void ledOn() +{ + leds::led_blue1::high(); + leds::led_ring::high(); +} + +inline void ledOff() +{ + leds::led_blue1::low(); + leds::led_ring::low(); +} + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/hwmapping.h b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..272509d075c761bc4ae83b47e0c9ce1487fce3fa --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/interfaces-impl/hwmapping.h @@ -0,0 +1,193 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef HWMAPPING_H +#define HWMAPPING_H + +#include "interfaces/gpio.h" + +namespace miosix +{ + +namespace interfaces +{ + +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +namespace spi2 +{ +using sck = Gpio<GPIOB_BASE, 13>; +using miso = Gpio<GPIOB_BASE, 14>; +using mosi = Gpio<GPIOB_BASE, 15>; +} // namespace spi2 + +// USB UART +namespace uart1 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace uart1 + +// GPS UART +namespace uart2 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace uart2 + +namespace uart3 +{ +using tx = Gpio<GPIOB_BASE, 10>; +using rx = Gpio<GPIOB_BASE, 11>; +} // namespace uart3 + +namespace uart4 +{ +using tx = Gpio<GPIOA_BASE, 0>; +using rx = Gpio<GPIOA_BASE, 1>; +} // namespace uart4 + +// CAN1 +namespace can +{ +using rx = Gpio<GPIOA_BASE, 11>; +using tx = Gpio<GPIOA_BASE, 12>; +} // namespace can + +// Servo motors timers +namespace timers +{ +using tim4ch1 = Gpio<GPIOD_BASE, 12>; // Servo 1 +using tim8ch2 = Gpio<GPIOC_BASE, 7>; // Servo 2 +} // namespace timers + +using camMosfet = Gpio<GPIOC_BASE, 14>; + +} // namespace interfaces + +namespace sensors +{ + +namespace ads1118 +{ +using cs = Gpio<GPIOB_BASE, 1>; +} // namespace ads1118 + +namespace bmx160 +{ +using cs = Gpio<GPIOA_BASE, 8>; +using intr = Gpio<GPIOE_BASE, 5>; +} // namespace bmx160 + +namespace lsm9ds1 +{ +using cs_a_g = Gpio<GPIOC_BASE, 1>; +using cs_m = Gpio<GPIOC_BASE, 3>; +using intr_a_g = Gpio<GPIOB_BASE, 12>; +} // namespace lsm9ds1 + +namespace lis3mdl +{ +using cs = Gpio<GPIOG_BASE, 6>; +} // namespace lis3mdl + +namespace ms5803 +{ +using cs = Gpio<GPIOD_BASE, 7>; +} // namespace ms5803 + +} // namespace sensors + +namespace inputs +{ +using vbat = Gpio<GPIOF_BASE, 7>; +using expulsion = Gpio<GPIOE_BASE, 4>; +} // namespace inputs + +namespace actuators +{ + +namespace servos +{ +using servo1 = interfaces::timers::tim4ch1; +using servo2 = interfaces::timers::tim8ch2; +} // namespace servos + +namespace nosecone +{ + +using th_cut_input = Gpio<GPIOE_BASE, 6>; // Input thermal cutters + +namespace thermal_cutter_1 +{ +using enable = Gpio<GPIOG_BASE, 2>; +using cutter_sens = Gpio<GPIOF_BASE, 6>; // ADC3 CH4 +} // namespace thermal_cutter_1 + +namespace thermal_cutter_2 +{ +using enable = Gpio<GPIOD_BASE, 11>; +using cutter_sens = Gpio<GPIOF_BASE, 8>; // ADC3 CH6 +} // namespace thermal_cutter_2 + +} // namespace nosecone + +} // namespace actuators + +namespace aux +{ +using sense_aux_1 = Gpio<GPIOE_BASE, 2>; +using aux_pd_pu = Gpio<GPIOC_BASE, 5>; +using aux_spi1_cs = Gpio<GPIOG_BASE, 7>; +} // namespace aux + +namespace leds +{ +using led_red1 = Gpio<GPIOG_BASE, 7>; +using led_red2 = Gpio<GPIOG_BASE, 10>; +using led_blue1 = Gpio<GPIOG_BASE, 14>; +using led_ring = Gpio<GPIOE_BASE, 3>; + +/** + * These are connected to the enable pin of the thermal cutters and the cs of + * the lis3mdl magnetometer. + */ +// using led_blue2 = Gpio<GPIOG_BASE, 2>; +// using led_green1 = Gpio<GPIOG_BASE, 6>; +// using led_green2 = Gpio<GPIOD_BASE, 11>; +} // namespace leds + +namespace xbee +{ +using cs = Gpio<GPIOF_BASE, 9>; +using attn = Gpio<GPIOF_BASE, 10>; +using reset = Gpio<GPIOC_BASE, 13>; +} // namespace xbee + +} // namespace miosix + +#endif // HWMAPPING_H diff --git a/src/bsps/stm32f429zi_death_stack_v2/stm32_2m+256k_rom.ld b/src/bsps/stm32f429zi_death_stack_v2/stm32_2m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..cfcc2ce53bd9e1b821cbfe90aeedd73fcdce1522 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/stm32_2m+256k_rom.ld @@ -0,0 +1,181 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 192KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 192KB RAM */ +_end = 0x20000000; +_heap_end = 0x20030000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/src/bsps/stm32f429zi_death_stack_v2/stm32_2m+8m_xram.ld b/src/bsps/stm32f429zi_death_stack_v2/stm32_2m+8m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..b6a0d26683cbff52ac66b7f275f9269d61dfbf41 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v2/stm32_2m+8m_xram.ld @@ -0,0 +1,178 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - .data, .bss, stacks and heap in the external 8MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0800000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f429zi_death_stack_v3/config/board_options.cmake b/src/bsps/stm32f429zi_death_stack_v3/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..21174c2231d33e1b2d6950418463a89dc38aef21 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/config/board_options.cmake @@ -0,0 +1,120 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f429zi_death_stack_v3) +set(ARCH_NAME cortexM4_stm32f4) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot and linker files +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) + +# Linker script type, there are three options +# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld) +# the most common choice, available for all microcontrollers +# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld) +# You must uncomment -D__ENABLE_XRAM below in this case. +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld) + +# Uncommenting __ENABLE_XRAM enables the initialization of the external +# 8MB SDRAM memory. Do not uncomment this even if you don't use a linker +# script that requires it, as it is used for the LCD framebuffer. +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency. Warning: the default clock frequency for +# this board is 168MHz and not 180MHz because, due to a limitation in +# the PLL, it is not possible to generate a precise 48MHz output when +# running the core at 180MHz. If 180MHz is chosen the USB peripheral will +# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48) +# Define USE_INTERNAL_CLOCK to bypass the external oscillator +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000) +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM4_STM32F4 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f429zi_death_stack_v3/config/board_settings.h b/src/bsps/stm32f429zi_death_stack_v3/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..226e0edadf65b4b1b645bcb067dacfb7fdb3bdfd --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/config/board_settings.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Alberto Nidasio + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) but the +/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; +// #define SERIAL_1_DMA +// #define SERIAL_2_DMA //Serial 2 can't be used (GPIO conflict), so no DMA +// #define SERIAL_3_DMA //Serial 3 can't be used (GPIO conflict), so no DMA + +// #define I2C_WITH_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +#ifdef __ENABLE_XRAM +// Reduce SD clock to ~4.8MHz +#define OVERRIDE_SD_CLOCK_DIVIDER_MAX 8 +#endif //__ENABLE_XRAM +// #define SD_ONE_BIT_DATABUS //This board supports 4 bit databus to SD card + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f429zi_death_stack_v3/config/miosix_settings.h b/src/bsps/stm32f429zi_death_stack_v3/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..cdef9ddab8da3e0805cb40b1267421740b358929 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Alberto Nidasio + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_death_stack_v3/core/stage_1_boot.cpp b/src/bsps/stm32f429zi_death_stack_v3/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47b5354aeefa5fbe0c639bf254a17a97eca62852 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/core/stage_1_boot.cpp @@ -0,0 +1,436 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Alberto Nidasio + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f42x devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); +// ST does not provide code to initialize the stm32f429-disco SDRAM at boot. +// Put after SystemInit() as SDRAM is timing-sensitive and needs the full +// clock speed. +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDIO_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + HASH_RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..5a2bfe8f0d60fdef75d89ea96cfd39b66cede885 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Alberto Nidasio + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency +#define STM32F429xx +#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" +#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h" +#include "CMSIS/Include/core_cm4.h" + +#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/bsp.cpp b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..94f8eee9ba433c2ae5435d36e62f6875752b25f1 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/bsp.cpp @@ -0,0 +1,505 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +/** + * The example code from ST checks for the busy flag after each command. + * Interestingly I couldn't find any mention of this in the datsheet. + */ +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +#ifdef SDRAM_ISSI + +void configureSdram() +{ + // Enable all gpios, passing clock + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | + FMC_SDCR1_CAS_1; // 2 cycle CAS latency (F<133MHz) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (7 - 1) << 4 // 7 cycle TXSR (77.7ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>15ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (6 - 1) << 4 // 6 cycle TXSR (71.4ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>15ns) +#else +#error No SDRAM timings for this clock +#endif + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // ST and SDRAM datasheet agree a 100us delay is required here. + delayUs(100); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (8 - 1) << 5 // NRFS=8 SDRAM datasheet says + // "at least two AUTO REFRESH cycles" + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + +// 64ms/4096=15.625us +#ifdef SYSCLK_FREQ_180MHz + // 15.625us*90MHz=1406-20=1386 + FMC_Bank5_6->SDRTR = 1386 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 15.625us*84MHz=1312-20=1292 + FMC_Bank5_6->SDRTR = 1292 << 1; +#else +#error No refresh timings for this clock +#endif +} + +#else + +void configureSdram() +{ + // Enable all gpios + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a AS4C4M16SA-6TAN, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = + 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | FMC_SDCR1_CAS_1; // 2 cycle CAS latency (TCK>9+0.5ns [1]) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>60ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>18ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | + (6 - 1) << 4 // 6 cycle TXSR (66.6ns>61.5+0.5ns [1]) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>18ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>60ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>18ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | + (6 - 1) << 4 // 6 cycle TXSR (71.4ns>61.5+0.5ns [1]) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>18ns) +#else +#error No SDRAM timings for this clock +#endif + // NOTE [1]: the timings for TCK and TIS depend on rise and fall times + //(see note 9 and 10 on datasheet). Timings are adjusted accordingly to + // the measured 2ns rise and fall time + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // SDRAM datasheet requires 200us delay here (note 11), here we use 10% more + delayUs(220); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + // FIXME: note 11 on SDRAM datasheet says extended mode register must be + // set, but the ST datasheet does not seem to explain how + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (4 - 1) << 5 // NRFS=8 SDRAM datasheet requires + // a minimum of 2 cycles, here we use 4 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + +// 32ms/4096=7.8125us, but datasheet says to round that to 7.8us +#ifdef SYSCLK_FREQ_180MHz + // 7.8us*90MHz=702-20=682 + FMC_Bank5_6->SDRTR = 682 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 7.8us*84MHz=655-20=635 + FMC_Bank5_6->SDRTR = 635 << 1; +#else +#error No refresh timings for this clock +#endif +} + +#endif + +void IRQbspInit() +{ +// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here +#ifndef __ENABLE_XRAM + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); +#endif //__ENABLE_XRAM + + // enable spi1, spi2 + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; + + // enable can1 + RCC->APB1ENR |= RCC_APB1ENR_CAN1EN; + + // Set the clock divider for the analog circuitry (/8) + ADC->CCR |= ADC_CCR_ADCPRE_0 | ADC_CCR_ADCPRE_1; + + RCC_SYNC(); + + interfaces::spi1::sck::mode(Mode::ALTERNATE); + interfaces::spi1::sck::alternateFunction(5); + interfaces::spi1::miso::mode(Mode::ALTERNATE); + interfaces::spi1::miso::alternateFunction(5); + interfaces::spi1::mosi::mode(Mode::ALTERNATE); + interfaces::spi1::mosi::alternateFunction(5); + + interfaces::spi2::sck::mode(Mode::ALTERNATE); + interfaces::spi2::sck::alternateFunction(5); + interfaces::spi2::miso::mode(Mode::ALTERNATE); + interfaces::spi2::miso::alternateFunction(5); + interfaces::spi2::mosi::mode(Mode::ALTERNATE); + interfaces::spi2::mosi::alternateFunction(5); + + interfaces::spi4::sck::mode(Mode::ALTERNATE); + interfaces::spi4::sck::alternateFunction(5); + interfaces::spi4::miso::mode(Mode::ALTERNATE); + interfaces::spi4::miso::alternateFunction(5); + interfaces::spi4::mosi::mode(Mode::ALTERNATE); + interfaces::spi4::mosi::alternateFunction(5); + + interfaces::spi5::sck::mode(Mode::ALTERNATE); + interfaces::spi5::sck::alternateFunction(5); + interfaces::spi5::miso::mode(Mode::ALTERNATE); + interfaces::spi5::miso::alternateFunction(5); + interfaces::spi5::mosi::mode(Mode::ALTERNATE); + interfaces::spi5::mosi::alternateFunction(5); + + interfaces::spi6::sck::mode(Mode::ALTERNATE); + interfaces::spi6::sck::alternateFunction(5); + interfaces::spi6::miso::mode(Mode::ALTERNATE); + interfaces::spi6::miso::alternateFunction(5); + interfaces::spi6::mosi::mode(Mode::ALTERNATE); + interfaces::spi6::mosi::alternateFunction(5); + + interfaces::usart1::rx::mode(Mode::ALTERNATE); + interfaces::usart1::rx::alternateFunction(7); + interfaces::usart1::tx::mode(Mode::ALTERNATE); + interfaces::usart1::tx::alternateFunction(7); + + interfaces::usart2::rx::mode(Mode::ALTERNATE); + interfaces::usart2::rx::alternateFunction(7); + interfaces::usart2::tx::mode(Mode::ALTERNATE); + interfaces::usart2::tx::alternateFunction(7); + + interfaces::usart3::rx::mode(Mode::ALTERNATE); + interfaces::usart3::rx::alternateFunction(7); + interfaces::usart3::tx::mode(Mode::ALTERNATE); + interfaces::usart3::tx::alternateFunction(7); + + interfaces::uart4::rx::mode(Mode::ALTERNATE); + interfaces::uart4::rx::alternateFunction(8); + interfaces::uart4::tx::mode(Mode::ALTERNATE); + interfaces::uart4::tx::alternateFunction(8); + + interfaces::can1::rx::mode(Mode::ALTERNATE); + interfaces::can1::rx::alternateFunction(9); + interfaces::can1::tx::mode(Mode::ALTERNATE); + interfaces::can1::tx::alternateFunction(9); + + sensors::ads131m04::cs1::mode(Mode::OUTPUT); + sensors::ads131m04::cs1::high(); + + sensors::bmx160::cs::mode(Mode::OUTPUT); + sensors::bmx160::cs::high(); + sensors::bmx160::intr::mode(Mode::INPUT_PULL_UP); + + sensors::mpu9250::cs::mode(Mode::OUTPUT); + sensors::mpu9250::cs::high(); + + sensors::cc3135::cs::mode(Mode::OUTPUT); + sensors::cc3135::cs::high(); + sensors::cc3135::intr::mode(Mode::INPUT_PULL_UP); + + sensors::sx127x::cs::mode(Mode::OUTPUT); + sensors::sx127x::cs::high(); + sensors::sx127x::dio0::mode(Mode::INPUT); + + sensors::gps::cs::mode(Mode::OUTPUT); + sensors::gps::cs::high(); + + sensors::ms5803::cs::mode(Mode::OUTPUT); + sensors::ms5803::cs::high(); + + sensors::mlx91221_1::vout::mode(Mode::INPUT_ANALOG); + sensors::mlx91221_1::vout::high(); + + sensors::mlx91221_2::vout::mode(Mode::INPUT_ANALOG); + sensors::mlx91221_2::vout::high(); + + sensors::launchpad_detach::mode(Mode::INPUT); + + expulsion::servo::mode(Mode::ALTERNATE); + expulsion::servo::alternateFunction(2); + expulsion::sense::mode(Mode::INPUT_PULL_UP); + expulsion::nosecone_detach::mode(Mode::INPUT); + + cutter::enable::mode(Mode::OUTPUT); + cutter::enable::low(); + cutter::enable_backup::mode(Mode::OUTPUT); + cutter::enable_backup::low(); + cutter::sense::mode(Mode::INPUT_ANALOG); + + airbrakes::servo::mode(Mode::ALTERNATE); + airbrakes::servo::alternateFunction(3); + airbrakes::sensor::mode(Mode::INPUT_ANALOG); + + leds::red::mode(Mode::OUTPUT); + leds::green::mode(Mode::OUTPUT); + leds::blue::mode(Mode::OUTPUT); + + buzzer::drive::mode(Mode::ALTERNATE); + buzzer::drive::alternateFunction(3); + + aux::servo::mode(Mode::ALTERNATE); + aux::servo::alternateFunction(3); + aux::sense_1::mode(Mode::INPUT); + aux::sense_2::mode(Mode::INPUT); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); + + for (uint8_t i = 0; i < 3; i++) + { + ledOn(); + delayMs(10); + ledOff(); + delayMs(10); + } +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + // PA2,PA3 + intrusive_ref_ptr<DevFs> devFs = + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM +} + +// +// Shutdown and reboot +// + +/** + * For safety reasons, we never want the board to shutdown. + * When requested to shutdown, we reboot instead. + */ +void shutdown() { reboot(); } + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/bsp_impl.h b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..687864e166e963e00ec4af026bc7f3c4581c04d9 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/bsp_impl.h @@ -0,0 +1,76 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * used by the ledOn() and ledOff() implementation + */ + +inline void ledOn() +{ + leds::red::high(); + leds::green::high(); + leds::blue::high(); +} + +inline void ledOff() +{ + leds::red::low(); + leds::green::low(); + leds::blue::low(); +} + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/hwmapping.h b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..1357f586ded6fdf612e3e9dadf6d634c77b8f3b9 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/interfaces-impl/hwmapping.h @@ -0,0 +1,209 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Authors: Emilio Corigliano, Alberto Nidasio + * + * 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. + */ + +#ifndef HWMAPPING_H +#define HWMAPPING_H + +#include "interfaces/gpio.h" + +// Remember to modify pins of leds +namespace miosix +{ + +namespace interfaces +{ + +// ADS131M04 +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +// MS5803 - GPS +namespace spi2 +{ +using sck = Gpio<GPIOB_BASE, 13>; +using miso = Gpio<GPIOB_BASE, 14>; +using mosi = Gpio<GPIOB_BASE, 15>; +} // namespace spi2 + +// BMX160 - MPU9250 +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +// SX127x +namespace spi5 +{ +using sck = Gpio<GPIOF_BASE, 7>; +using miso = Gpio<GPIOF_BASE, 8>; +using mosi = Gpio<GPIOF_BASE, 9>; +} // namespace spi5 + +// CC3135 +namespace spi6 +{ +using sck = Gpio<GPIOG_BASE, 13>; +using miso = Gpio<GPIOG_BASE, 12>; +using mosi = Gpio<GPIOG_BASE, 14>; +} // namespace spi6 + +// Debug +namespace usart1 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace usart1 + +// VN100 +namespace usart2 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace usart2 + +// HIL +namespace usart3 +{ +using tx = Gpio<GPIOB_BASE, 10>; +using rx = Gpio<GPIOB_BASE, 11>; +} // namespace usart3 + +// RunCam +namespace uart4 +{ +using tx = Gpio<GPIOA_BASE, 0>; +using rx = Gpio<GPIOA_BASE, 1>; +} // namespace uart4 + +namespace can1 +{ +using rx = Gpio<GPIOA_BASE, 11>; +using tx = Gpio<GPIOA_BASE, 12>; +} // namespace can1 + +} // namespace interfaces + +namespace sensors +{ + +namespace ads131m04 +{ +using cs1 = Gpio<GPIOA_BASE, 4>; +using cs2 = Gpio<GPIOA_BASE, 8>; // TIM1_CH1 +using sck2 = Gpio<GPIOB_BASE, 1>; // TIM3_CH4 +} // namespace ads131m04 + +namespace bmx160 +{ +using cs = Gpio<GPIOE_BASE, 4>; +using intr = Gpio<GPIOE_BASE, 3>; +} // namespace bmx160 + +namespace mpu9250 +{ +using cs = Gpio<GPIOD_BASE, 7>; +} // namespace mpu9250 + +namespace cc3135 +{ +using cs = Gpio<GPIOG_BASE, 11>; +using intr = Gpio<GPIOG_BASE, 10>; +} // namespace cc3135 + +namespace sx127x +{ +using cs = Gpio<GPIOF_BASE, 6>; +using dio0 = Gpio<GPIOF_BASE, 10>; +} // namespace sx127x + +namespace gps +{ +using cs = Gpio<GPIOB_BASE, 12>; +} // namespace gps + +namespace ms5803 +{ +using cs = Gpio<GPIOD_BASE, 11>; +} // namespace ms5803 + +namespace mlx91221_1 +{ +using vout = Gpio<GPIOC_BASE, 1>; // ADC +} // namespace mlx91221_1 + +namespace mlx91221_2 +{ +using vout = Gpio<GPIOC_BASE, 2>; // ADC +} // namespace mlx91221_2 + +using launchpad_detach = Gpio<GPIOD_BASE, 5>; // launchpad detach + +} // namespace sensors + +namespace expulsion +{ +using servo = Gpio<GPIOB_BASE, 7>; // Pwm expulsion servo, TIM4_CH2 +using sense = Gpio<GPIOD_BASE, 3>; // Expulsion sensor +using nosecone_detach = Gpio<GPIOD_BASE, 4>; // Nosecone detach +} // namespace expulsion + +namespace cutter +{ +using enable = Gpio<GPIOG_BASE, 2>; +using enable_backup = Gpio<GPIOG_BASE, 3>; +using sense = Gpio<GPIOC_BASE, 5>; +} // namespace cutter + +namespace airbrakes +{ +using servo = Gpio<GPIOB_BASE, 8>; // Airbrakes PWM, TIM10_CH1 +using sensor = Gpio<GPIOC_BASE, 3>; // Airbrakes ADC +} // namespace airbrakes + +namespace leds +{ +using red = Gpio<GPIOC_BASE, 4>; +using green = Gpio<GPIOD_BASE, 12>; +using blue = Gpio<GPIOD_BASE, 13>; +} // namespace leds + +namespace buzzer +{ +using drive = Gpio<GPIOC_BASE, 6>; // PWM TIM8_CH1 +} // namespace buzzer + +namespace aux +{ +using servo = Gpio<GPIOB_BASE, 9>; // TIM11_CH1 +using sense_1 = Gpio<GPIOG_BASE, 6>; +using sense_2 = Gpio<GPIOG_BASE, 7>; +} // namespace aux + +} // namespace miosix + +#endif // HWMAPPING_H diff --git a/src/bsps/stm32f429zi_death_stack_v3/stm32_2m+256k_rom.ld b/src/bsps/stm32f429zi_death_stack_v3/stm32_2m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..cfcc2ce53bd9e1b821cbfe90aeedd73fcdce1522 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/stm32_2m+256k_rom.ld @@ -0,0 +1,181 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 192KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 192KB RAM */ +_end = 0x20000000; +_heap_end = 0x20030000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/src/bsps/stm32f429zi_death_stack_v3/stm32_2m+8m_xram.ld b/src/bsps/stm32f429zi_death_stack_v3/stm32_2m+8m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..b6a0d26683cbff52ac66b7f275f9269d61dfbf41 --- /dev/null +++ b/src/bsps/stm32f429zi_death_stack_v3/stm32_2m+8m_xram.ld @@ -0,0 +1,178 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - .data, .bss, stacks and heap in the external 8MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0800000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f429zi_nokia/config/board_options.cmake b/src/bsps/stm32f429zi_nokia/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..c531b5c9aac4a7eb0eabe012e550987332c70dca --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/config/board_options.cmake @@ -0,0 +1,124 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f429zi_nokia) +set(ARCH_NAME cortexM4_stm32f4) + +# Specify which MxGui base library to use +set(MXGUI_BASE_BOARD_NAME stm32f429zi_stm32f4discovery) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) + +# Linker script type, there are three options +# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld) +# the most common choice, available for all microcontrollers +# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld) +# You must uncomment -D__ENABLE_XRAM below in this case. +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld) + +# Uncommenting __ENABLE_XRAM enables the initialization of the external +# 8MB SDRAM memory. Do not uncomment this even if you don't use a linker +# script that requires it, as it is used for the LCD framebuffer. +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency. +# Warning: the default clock frequency for +# this board is 168MHz and not 180MHz because, due to a limitation in +# the PLL, it is not possible to generate a precise 48MHz output when +# running the core at 180MHz. If 180MHz is chosen the USB peripheral will +# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48) +# Define USE_INTERNAL_CLOCK to bypass the external oscillator +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000) +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_STM32F429ZI_NOKIA -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM4_STM32F4 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f429zi_nokia/config/board_settings.h b/src/bsps/stm32f429zi_nokia/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..b817b53d438a16a70325a9634a7304956f036d36 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/config/board_settings.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) but the +/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 4 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; +// #define SERIAL_1_DMA +// #define SERIAL_2_DMA //Serial 2 can't be used (GPIO conflict), so no DMA +// #define SERIAL_3_DMA //Serial 3 can't be used (GPIO conflict), so no DMA + +// #define I2C_WITH_DMA + +// SD card driver +static const unsigned char sdVoltage = 30; // Board powered @ 3.0V +#define SD_ONE_BIT_DATABUS // Can't use 4 bit databus due to pin conflicts + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.0f + +/** + * \} + */ + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f429zi_nokia/config/miosix_settings.h b/src/bsps/stm32f429zi_nokia/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..2b82675b7ea6bda4d370257b9a2a932ebb711d8a --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_nokia/core/stage_1_boot.cpp b/src/bsps/stm32f429zi_nokia/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e86bb25fba6465be9ee761dfbbd846948cbafe1 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/core/stage_1_boot.cpp @@ -0,0 +1,372 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f42x devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); +// ST does not provide code to initialize the stm32f429-disco SDRAM at boot. +// Put after SystemInit() as SDRAM is timing-sensitive and needs the full +// clock speed. +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, PVD_IRQHandler, TAMP_STAMP_IRQHandler, RTC_WKUP_IRQHandler, + FLASH_IRQHandler, RCC_IRQHandler, EXTI0_IRQHandler, EXTI1_IRQHandler, + EXTI2_IRQHandler, EXTI3_IRQHandler, EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, DMA1_Stream1_IRQHandler, DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, DMA1_Stream4_IRQHandler, DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, ADC_IRQHandler, CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, CAN1_RX1_IRQHandler, CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, TIM1_BRK_TIM9_IRQHandler, TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, TIM1_CC_IRQHandler, TIM2_IRQHandler, + TIM3_IRQHandler, TIM4_IRQHandler, I2C1_EV_IRQHandler, I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, I2C2_ER_IRQHandler, SPI1_IRQHandler, SPI2_IRQHandler, + USART1_IRQHandler, USART2_IRQHandler, USART3_IRQHandler, + EXTI15_10_IRQHandler, RTC_Alarm_IRQHandler, OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, TIM8_CC_IRQHandler, DMA1_Stream7_IRQHandler, + FMC_IRQHandler, SDIO_IRQHandler, TIM5_IRQHandler, SPI3_IRQHandler, + UART4_IRQHandler, UART5_IRQHandler, TIM6_DAC_IRQHandler, TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, DMA2_Stream1_IRQHandler, DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, DMA2_Stream4_IRQHandler, ETH_IRQHandler, + ETH_WKUP_IRQHandler, CAN2_TX_IRQHandler, CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, CAN2_SCE_IRQHandler, OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, DMA2_Stream6_IRQHandler, DMA2_Stream7_IRQHandler, + USART6_IRQHandler, I2C3_EV_IRQHandler, I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, OTG_HS_EP1_IN_IRQHandler, OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, DCMI_IRQHandler, CRYP_IRQHandler, HASH_RNG_IRQHandler, + FPU_IRQHandler, UART7_IRQHandler, UART8_IRQHandler, SPI4_IRQHandler, + SPI5_IRQHandler, SPI6_IRQHandler, SAI1_IRQHandler, LTDC_IRQHandler, + LTDC_ER_IRQHandler, DMA2D_IRQHandler}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f429zi_nokia/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f429zi_nokia/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..87f3cf6616405c6761c1d23ac97ca9bcddffa7c6 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency +#define STM32F429xx +#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" +#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h" +#include "CMSIS/Include/core_cm4.h" + +#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f429zi_nokia/interfaces-impl/bsp.cpp b/src/bsps/stm32f429zi_nokia/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f79a64ec5a85f845752cb8b2dff3573607c05929 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/interfaces-impl/bsp.cpp @@ -0,0 +1,308 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" +// #include "kernel/IRQDisplayPrint.h" + +namespace miosix +{ + +// +// Initialization +// + +/** + * The example code from ST checks for the busy flag after each command. + * Interestingly I couldn't find any mention of this in the datsheet. + */ +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable all gpios, passing clock + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | + FMC_SDCR1_CAS_1; // 2 cycle CAS latency (F<133MHz) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (7 - 1) << 4 // 7 cycle TXSR (77.7ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>15ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (6 - 1) << 4 // 6 cycle TXSR (71.4ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>15ns) +#else +#error No SDRAM timings for this clock +#endif + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // ST and SDRAM datasheet agree a 100us delay is required here. + delayUs(100); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (8 - 1) << 5 // NRFS=8 SDRAM datasheet says + // "at least two AUTO REFRESH cycles" + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + +// 64ms/4096=15.625us +#ifdef SYSCLK_FREQ_180MHz + // 15.625us*90MHz=1406-20=1386 + FMC_Bank5_6->SDRTR = 1386 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 15.625us*84MHz=1312-20=1292 + FMC_Bank5_6->SDRTR = 1292 << 1; +#else +#error No refresh timings for this clock +#endif +} + +// static IRQDisplayPrint *irq_display; +void IRQbspInit() +{ +// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here +#ifndef __ENABLE_XRAM + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); +#endif //__ENABLE_XRAM + + // enable spi1, spi4 + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN | RCC_APB2ENR_SPI4EN; + + RCC_SYNC(); + + interfaces::spi1::sck::mode(Mode::ALTERNATE); + interfaces::spi1::sck::alternateFunction(5); + interfaces::spi1::miso::mode(Mode::ALTERNATE); + interfaces::spi1::miso::alternateFunction(5); + interfaces::spi1::mosi::mode(Mode::ALTERNATE); + interfaces::spi1::mosi::alternateFunction(5); + + interfaces::spi4::sck::mode(Mode::ALTERNATE); + interfaces::spi4::sck::alternateFunction(5); + interfaces::spi4::miso::mode(Mode::ALTERNATE); + interfaces::spi4::miso::alternateFunction(5); + interfaces::spi4::mosi::mode(Mode::ALTERNATE); + interfaces::spi4::mosi::alternateFunction(5); + + peripherals::ra01::pc13::cs::mode(Mode::OUTPUT); + peripherals::ra01::pc13::dio0::mode(Mode::INPUT); + peripherals::ra01::pc13::nrst::mode(Mode::OUTPUT); + peripherals::ra01::pc13::cs::high(); + peripherals::ra01::pc13::nrst::high(); + + peripherals::ra01::pe4::cs::mode(Mode::OUTPUT); + peripherals::ra01::pe4::dio0::mode(Mode::INPUT); + peripherals::ra01::pe4::nrst::mode(Mode::OUTPUT); + peripherals::ra01::pe4::cs::high(); + peripherals::ra01::pe4::nrst::high(); + + peripherals::cc3135::cs::mode(Mode::OUTPUT); + peripherals::cc3135::hib::mode(Mode::OUTPUT); + peripherals::cc3135::intr::mode(Mode::INPUT); + peripherals::cc3135::nrst::mode(Mode::OUTPUT); + peripherals::cc3135::cs::high(); + peripherals::cc3135::hib::high(); + peripherals::cc3135::nrst::high(); + + _led::mode(Mode::OUTPUT); + ledOn(); + delayMs(100); + ledOff(); + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); + // irq_display = new IRQDisplayPrint(); + // DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(irq_display)); +} + +// void* printIRQ(void *argv) +// { +// intrusive_ref_ptr<IRQDisplayPrint> irqq(irq_display); +// irqq.get()->printIRQ(); +// return NULL; +// } + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM + // Thread::create(printIRQ, 2048); +} + +// +// Shutdown and reboot +// + +/** +This function disables filesystem (if enabled), serial port (if enabled) and +puts the processor in deep sleep mode.<br> +Wakeup occurs when PA.0 goes high, but instead of sleep(), a new boot happens. +<br>This function does not return.<br> +WARNING: close all files before using this function, since it unmounts the +filesystem.<br> +When in shutdown mode, power consumption of the miosix board is reduced to ~ +5uA??, however, true power consumption depends on what is connected to the GPIO +pins. The user is responsible to put the devices connected to the GPIO pin in +the minimal power consumption mode before calling shutdown(). Please note that +to minimize power consumption all unused GPIO must not be left floating. +*/ +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + + for (;;) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_nokia/interfaces-impl/bsp_impl.h b/src/bsps/stm32f429zi_nokia/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..6b5cc0c6aeb87614df223863ec61e83e562e7169 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/interfaces-impl/bsp_impl.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * used by the ledOn() and ledOff() implementation + */ +typedef Gpio<GPIOG_BASE, 14> _led; + +inline void ledOn() { _led::high(); } + +inline void ledOff() { _led::low(); } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f429zi_nokia/interfaces-impl/hwmapping.h b/src/bsps/stm32f429zi_nokia/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..0e79ea7f11b2b9c0ced7e6120deaf34229561093 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/interfaces-impl/hwmapping.h @@ -0,0 +1,88 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef HWMAPPING_H +#define HWMAPPING_H + +#include "interfaces/gpio.h" + +namespace miosix +{ + +namespace interfaces +{ + +// CC3135 +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOB_BASE, 4>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +// RA-01 +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +} // namespace interfaces + +namespace peripherals +{ + +namespace ra01 +{ + +namespace pc13 +{ +using cs = Gpio<GPIOC_BASE, 13>; +using dio0 = Gpio<GPIOF_BASE, 6>; +using dio1 = Gpio<GPIOA_BASE, 4>; +using dio3 = Gpio<GPIOC_BASE, 11>; +using nrst = Gpio<GPIOC_BASE, 14>; +} // namespace pc13 + +namespace pe4 +{ +using cs = Gpio<GPIOE_BASE, 4>; +using dio0 = Gpio<GPIOE_BASE, 3>; +using nrst = Gpio<GPIOG_BASE, 2>; +} // namespace pe4 + +} // namespace ra01 + +namespace cc3135 +{ +using cs = Gpio<GPIOD_BASE, 4>; +using hib = Gpio<GPIOG_BASE, 3>; +using intr = Gpio<GPIOD_BASE, 5>; +using nrst = Gpio<GPIOB_BASE, 7>; +} // namespace cc3135 + +} // namespace peripherals + +} // namespace miosix + +#endif // HWMAPPING_H diff --git a/src/bsps/stm32f429zi_nokia/stm32_2m+256k_rom.ld b/src/bsps/stm32f429zi_nokia/stm32_2m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..e2425d265aaf968808b58724cebe4f785e4a21e8 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/stm32_2m+256k_rom.ld @@ -0,0 +1,180 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 192KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 192KB RAM */ +_end = 0x20000000; +_heap_end = 0x20030000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/src/bsps/stm32f429zi_nokia/stm32_2m+6m_xram.ld b/src/bsps/stm32f429zi_nokia/stm32_2m+6m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..b61f04cea1b19c15a54b55515100951d99048fc8 --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/stm32_2m+6m_xram.ld @@ -0,0 +1,183 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - .data, .bss, stacks and heap in the external 6MB SDRAM. + * Note that the SDRAM is 8MB, but this linker script only uses the lower 6. + * The upper 2MB are reserved as framebuffers for the LCD. Notice that the + * choice to allocate this space is due to the SDRAM architecture, composed of + * 4 banks of 2MB each. Reserving a bank for the LCD allows the software + * running on the board and the LCD to operate (almost) independently. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0600000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 6M + lcdram(wx) : ORIGIN = 0xd0600000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f429zi_nokia/stm32_2m+8m_xram.ld b/src/bsps/stm32f429zi_nokia/stm32_2m+8m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..78fe53104dfa12f2e1586b9af09c97b7958ecb4c --- /dev/null +++ b/src/bsps/stm32f429zi_nokia/stm32_2m+8m_xram.ld @@ -0,0 +1,177 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - .data, .bss, stacks and heap in the external 8MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0800000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f429zi_parafoil/config/board_options.cmake b/src/bsps/stm32f429zi_parafoil/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..9e545b1cf32b8f1d1db8c4d9b3e238af155c0417 --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/config/board_options.cmake @@ -0,0 +1,120 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f429zi_parafoil) +set(ARCH_NAME cortexM4_stm32f4) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot and linker files +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) + +# Linker script type, there are three options +# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld) +# the most common choice, available for all microcontrollers +# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld) +# You must uncomment -D__ENABLE_XRAM below in this case. +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld) + +# Uncommenting __ENABLE_XRAM enables the initialization of the external +# 8MB SDRAM memory. Do not uncomment this even if you don't use a linker +# script that requires it, as it is used for the LCD framebuffer. +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency. Warning: the default clock frequency for +# this board is 168MHz and not 180MHz because, due to a limitation in +# the PLL, it is not possible to generate a precise 48MHz output when +# running the core at 180MHz. If 180MHz is chosen the USB peripheral will +# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48) +# Define USE_INTERNAL_CLOCK to bypass the external oscillator +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000) +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM4_STM32F4 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f429zi_parafoil/config/board_settings.h b/src/bsps/stm32f429zi_parafoil/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..d016c08f981cf061bd9f44e44d0b2cef260de1c0 --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/config/board_settings.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) but the +/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 4 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA +// #define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 30; // Board powered @ 3.0V +#define SD_ONE_BIT_DATABUS // Can't use 4 bit databus due to pin conflicts + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.0f + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f429zi_parafoil/config/miosix_settings.h b/src/bsps/stm32f429zi_parafoil/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..5006e0bcaa1ae584f1ab62ed191167433d3746c2 --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_parafoil/core/stage_1_boot.cpp b/src/bsps/stm32f429zi_parafoil/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..10804a0b76859b330538a3d2f325b090163f18dd --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/core/stage_1_boot.cpp @@ -0,0 +1,436 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f42x devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); +// ST does not provide code to initialize the stm32f429-disco SDRAM at boot. +// Put after SystemInit() as SDRAM is timing-sensitive and needs the full +// clock speed. +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDIO_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + HASH_RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f429zi_parafoil/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f429zi_parafoil/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..aa9f5579fa679dccfeeff9c8173ee9db339340b6 --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency +#define STM32F429xx +#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" +#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h" +#include "CMSIS/Include/core_cm4.h" + +#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f429zi_parafoil/interfaces-impl/bsp.cpp b/src/bsps/stm32f429zi_parafoil/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12077a4c421fece90f52f9465fbeaf4f35e6d841 --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/interfaces-impl/bsp.cpp @@ -0,0 +1,313 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +/** + * The example code from ST checks for the busy flag after each command. + * Interestingly I couldn't find any mention of this in the datsheet. + */ +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable all gpios, passing clock + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | + FMC_SDCR1_CAS_1; // 2 cycle CAS latency (F<133MHz) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (7 - 1) << 4 // 7 cycle TXSR (77.7ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>15ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (6 - 1) << 4 // 6 cycle TXSR (71.4ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>15ns) +#else +#error No SDRAM timings for this clock +#endif + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // ST and SDRAM datasheet agree a 100us delay is required here. + delayUs(100); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (8 - 1) << 5 // NRFS=8 SDRAM datasheet says + // "at least two AUTO REFRESH cycles" + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + +// 64ms/4096=15.625us +#ifdef SYSCLK_FREQ_180MHz + // 15.625us*90MHz=1406-20=1386 + FMC_Bank5_6->SDRTR = 1386 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 15.625us*84MHz=1312-20=1292 + FMC_Bank5_6->SDRTR = 1292 << 1; +#else +#error No refresh timings for this clock +#endif +} + +void IRQbspInit() +{ +// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here +#ifndef __ENABLE_XRAM + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); +#endif //__ENABLE_XRAM + + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + RCC->APB2ENR |= RCC_APB2ENR_SPI4EN; + RCC->APB2ENR |= RCC_APB2ENR_SPI5EN; + + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM9EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM10EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM11EN; + + RCC_SYNC(); + + using namespace interfaces; + + spi1::sck::mode(Mode::ALTERNATE); + spi1::sck::alternateFunction(5); + spi1::miso::mode(Mode::ALTERNATE); + spi1::miso::alternateFunction(5); + spi1::mosi::mode(Mode::ALTERNATE); + spi1::mosi::alternateFunction(5); + + spi4::sck::mode(Mode::ALTERNATE); + spi4::sck::alternateFunction(5); + spi4::miso::mode(Mode::ALTERNATE); + spi4::miso::alternateFunction(5); + spi4::mosi::mode(Mode::ALTERNATE); + spi4::mosi::alternateFunction(5); + + uart1::rx::mode(Mode::ALTERNATE); + uart1::rx::alternateFunction(7); + uart1::tx::mode(Mode::ALTERNATE); + uart1::tx::alternateFunction(7); + + uart2::rx::mode(Mode::ALTERNATE); + uart2::rx::alternateFunction(7); + uart2::tx::mode(Mode::ALTERNATE); + uart2::tx::alternateFunction(7); + + timers::tim4ch2::mode(Mode::ALTERNATE); + timers::tim4ch2::alternateFunction(2); + timers::tim10ch1::mode(Mode::ALTERNATE); + timers::tim10ch1::alternateFunction(3); + + using namespace sensors; + + mpu9250::cs::mode(Mode::OUTPUT); + mpu9250::cs::high(); + + bme280::cs::mode(Mode::OUTPUT); + bme280::cs::high(); + + adc::battery::mode(Mode::INPUT_ANALOG); + + sx1278::cs::mode(Mode::OUTPUT); + sx1278::cs::high(); + sx1278::interrupt::mode(Mode::OUTPUT); + sx1278::interrupt::high(); + + using namespace ui; + + button::mode(Mode::INPUT); + + greenLed::mode(Mode::OUTPUT); + greenLed::low(); + redLed::mode(Mode::OUTPUT); + redLed::low(); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM +} + +// +// Shutdown and reboot +// + +/** + * @brief This function disables filesystem and serial port. + */ +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + + while (true) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_parafoil/interfaces-impl/bsp_impl.h b/src/bsps/stm32f429zi_parafoil/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..15913a0daf26844b379fb4bd67339f918a57978e --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/interfaces-impl/bsp_impl.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f429zi_parafoil/interfaces-impl/hwmapping.h b/src/bsps/stm32f429zi_parafoil/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..4002b6c91d336da3c57327250f1fc66ac1160b7c --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/interfaces-impl/hwmapping.h @@ -0,0 +1,123 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +#include "interfaces/gpio.h" + +namespace miosix +{ + +namespace interfaces +{ + +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOB_BASE, 4>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +// USB UART +namespace uart1 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace uart1 + +// GPS UART +namespace uart2 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace uart2 + +namespace timers +{ +using tim4ch2 = Gpio<GPIOB_BASE, 7>; // Servo 1 +using tim10ch1 = Gpio<GPIOF_BASE, 6>; // Servo 2 +} // namespace timers + +} // namespace interfaces + +namespace sensors +{ + +namespace mpu9250 +{ +using cs = Gpio<GPIOB_BASE, 2>; +using sck = interfaces::spi1::sck; +using miso = interfaces::spi1::miso; +using mosi = interfaces::spi1::mosi; +} // namespace mpu9250 + +namespace bme280 +{ +using cs = Gpio<GPIOC_BASE, 11>; +using sck = interfaces::spi1::sck; +using miso = interfaces::spi1::miso; +using mosi = interfaces::spi1::mosi; +} // namespace bme280 + +namespace gps +{ +using tx = interfaces::uart2::tx; +using rx = interfaces::uart2::rx; +} // namespace gps + +namespace adc +{ +using battery = Gpio<GPIOC_BASE, 3>; +} + +} // namespace sensors + +namespace sx1278 +{ +using cs = Gpio<GPIOC_BASE, 1>; +using interrupt = Gpio<GPIOF_BASE, 10>; +using sck = interfaces::spi4::sck; +using miso = interfaces::spi4::miso; +using mosi = interfaces::spi4::mosi; +} // namespace sx1278 + +namespace servos +{ +using servo1 = interfaces::timers::tim4ch2; +using servo2 = interfaces::timers::tim10ch1; +} // namespace servos + +namespace ui +{ +using button = Gpio<GPIOA_BASE, 0>; // User button +using greenLed = Gpio<GPIOG_BASE, 13>; // Green LED +using redLed = Gpio<GPIOG_BASE, 14>; // Red LED +} // namespace ui + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_parafoil/stm32_2m+256k_rom.ld b/src/bsps/stm32f429zi_parafoil/stm32_2m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..cfcc2ce53bd9e1b821cbfe90aeedd73fcdce1522 --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/stm32_2m+256k_rom.ld @@ -0,0 +1,181 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 192KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 192KB RAM */ +_end = 0x20000000; +_heap_end = 0x20030000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/src/bsps/stm32f429zi_parafoil/stm32_2m+8m_xram.ld b/src/bsps/stm32f429zi_parafoil/stm32_2m+8m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..b6a0d26683cbff52ac66b7f275f9269d61dfbf41 --- /dev/null +++ b/src/bsps/stm32f429zi_parafoil/stm32_2m+8m_xram.ld @@ -0,0 +1,178 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - .data, .bss, stacks and heap in the external 8MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0800000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/config/board_options.cmake b/src/bsps/stm32f429zi_pyxis_auxiliary/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..cb77b98ddf524c6e57ee621d3eeabef265fdd996 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/config/board_options.cmake @@ -0,0 +1,114 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f429zi_pyxis_auxiliary) +set(ARCH_NAME cortexM4_stm32f4) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot and linker files +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld) + +# Uncommenting __ENABLE_XRAM enables the initialization of the external +# 8MB SDRAM memory. Do not uncomment this even if you don't use a linker +# script that requires it, as it is used for the LCD framebuffer. +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency. +# Warning: the default clock frequency for +# this board is 168MHz and not 180MHz because, due to a limitation in +# the PLL, it is not possible to generate a precise 48MHz output when +# running the core at 180MHz. If 180MHz is chosen the USB peripheral will +# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48) +# Define USE_INTERNAL_CLOCK to bypass the external oscillator +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000) +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM4_STM32F4 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/config/board_settings.h b/src/bsps/stm32f429zi_pyxis_auxiliary/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..961c158098ec2db2a160a6ecbce1c55f895ca425 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/config/board_settings.h @@ -0,0 +1,64 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) but the +/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 4; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/config/miosix_settings.h b/src/bsps/stm32f429zi_pyxis_auxiliary/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..5006e0bcaa1ae584f1ab62ed191167433d3746c2 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/core/stage_1_boot.cpp b/src/bsps/stm32f429zi_pyxis_auxiliary/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c5b8d22f2b2f025b78aded35a5697ca61e01e9e6 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/core/stage_1_boot.cpp @@ -0,0 +1,430 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f42x devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDIO_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + HASH_RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..787b322d1a28efdd9beb34be74fd38a7d00d9233 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency +#define STM32F429xx +#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" +#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h" +#include "CMSIS/Include/core_cm4.h" + +#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H \ No newline at end of file diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/bsp.cpp b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..025840ce89f9f7191dd87089599acb4556eeb325 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/bsp.cpp @@ -0,0 +1,127 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +void IRQbspInit() +{ + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIOEEN | + RCC_AHB1ENR_GPIOFEN; + + // Enable can1 + RCC->APB1ENR |= RCC_APB1ENR_CAN1EN; + + RCC_SYNC(); + + using namespace interfaces; + + debug::rx::mode(Mode::ALTERNATE); + debug::rx::alternateFunction(8); + debug::tx::mode(Mode::ALTERNATE); + debug::tx::alternateFunction(8); + + cam1::rx::mode(Mode::ALTERNATE); + cam1::rx::alternateFunction(7); + cam1::tx::mode(Mode::ALTERNATE); + cam1::tx::alternateFunction(7); + + cam2::tx::mode(Mode::ALTERNATE); + cam2::tx::alternateFunction(8); + + cam3::tx::mode(Mode::ALTERNATE); + cam3::tx::alternateFunction(8); + + camMosfet::mode(Mode::OUTPUT); + camMosfet::low(); + + can1::rx::mode(Mode::ALTERNATE); + can1::rx::alternateFunction(9); + can1::tx::mode(Mode::ALTERNATE); + can1::tx::alternateFunction(9); + + using namespace leds; + + led1::mode(Mode::OUTPUT); + led2::mode(Mode::OUTPUT); + led3::mode(Mode::OUTPUT); + led4::mode(Mode::OUTPUT); + led5::mode(Mode::OUTPUT); + + for (uint8_t i = 0; i < 3; i++) + { + ledOn(); + delayMs(10); + ledOff(); + delayMs(10); + } + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() {} + +/** + * For safety reasons, we never want the board to shutdown. + * When requested to shutdown, we reboot instead. + */ +void shutdown() { reboot(); } + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/bsp_impl.h b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..9bfc06f02267e071054aa3d3201de22f61d6503f --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/bsp_impl.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * used by the ledOn() and ledOff() implementation + */ + +inline void ledOn() +{ + leds::led1::high(); + leds::led2::high(); + leds::led3::high(); + leds::led4::high(); + leds::led5::high(); +} + +inline void ledOff() +{ + leds::led1::low(); + leds::led2::low(); + leds::led3::low(); + leds::led4::low(); + leds::led5::low(); +} + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/hwmapping.h b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..a637939d42bf47e690aef59c3cd0554d0a3aa0e6 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/interfaces-impl/hwmapping.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2022 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef HWMAPPING_H +#define HWMAPPING_H + +#include "interfaces/gpio.h" + +// Remember to modify pins of leds +namespace miosix +{ + +namespace interfaces +{ + +// Debug - USART4 +namespace debug +{ +using tx = Gpio<GPIOA_BASE, 0>; +using rx = Gpio<GPIOA_BASE, 1>; +} // namespace debug + +// Cam 1 - USART2 +namespace cam1 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace cam1 + +// Cam 2 - UART7 +namespace cam2 +{ +using tx = Gpio<GPIOF_BASE, 7>; +} // namespace cam2 + +// Cam 3 - UART7 +namespace cam3 +{ +using tx = Gpio<GPIOE_BASE, 8>; +} // namespace cam3 + +using camMosfet = Gpio<GPIOE_BASE, 7>; + +namespace can1 +{ +using rx = Gpio<GPIOA_BASE, 11>; +using tx = Gpio<GPIOA_BASE, 12>; +} // namespace can1 + +} // namespace interfaces + +namespace leds +{ +using led1 = Gpio<GPIOC_BASE, 15>; +using led2 = Gpio<GPIOB_BASE, 4>; +using led3 = Gpio<GPIOB_BASE, 5>; +using led4 = Gpio<GPIOB_BASE, 6>; +using led5 = Gpio<GPIOB_BASE, 7>; +} // namespace leds + +} // namespace miosix + +#endif // HWMAPPING_H diff --git a/src/bsps/stm32f429zi_pyxis_auxiliary/stm32_2m+256k_rom.ld b/src/bsps/stm32f429zi_pyxis_auxiliary/stm32_2m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..cfcc2ce53bd9e1b821cbfe90aeedd73fcdce1522 --- /dev/null +++ b/src/bsps/stm32f429zi_pyxis_auxiliary/stm32_2m+256k_rom.ld @@ -0,0 +1,181 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 192KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 192KB RAM */ +_end = 0x20000000; +_heap_end = 0x20030000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/src/bsps/stm32f429zi_rig/config/board_options.cmake b/src/bsps/stm32f429zi_rig/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..7b87f4a0ee9d2183b589dc4649cc6e9b7e468168 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/config/board_options.cmake @@ -0,0 +1,121 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f429zi_rig) +set(ARCH_NAME cortexM4_stm32f4) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) + +# Linker script type, there are three options +# 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld) +# the most common choice, available for all microcontrollers +# 2) Code in FLASH, stack + heap in external RAM (file *8m_xram.ld) +# You must uncomment -D__ENABLE_XRAM below in this case. +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+256k_rom.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+8m_xram.ld) + +# Uncommenting __ENABLE_XRAM enables the initialization of the external +# 8MB SDRAM memory. Do not uncomment this even if you don't use a linker +# script that requires it, as it is used for the LCD framebuffer. +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency. +# Warning: the default clock frequency for +# this board is 168MHz and not 180MHz because, due to a limitation in +# the PLL, it is not possible to generate a precise 48MHz output when +# running the core at 180MHz. If 180MHz is chosen the USB peripheral will +# NOT WORK and the SDIO and RNG will run ~6% slower (45MHz insteand of 48) +# Define USE_INTERNAL_CLOCK to bypass the external oscillator +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_180MHz=180000000) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_168MHz=168000000) +# set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_100MHz=100000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM4_STM32F4 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f429zi_rig/config/board_settings.h b/src/bsps/stm32f429zi_rig/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..3946b4d3c3331b58e88cb483bb9cbf5dfd7d55f1 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/config/board_settings.h @@ -0,0 +1,59 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#ifndef BOARD_SETTINGS_H +#define BOARD_SETTINGS_H + +#include "util/version.h" + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) but the +/// STM32F407VG only has 192KB of RAM so there is room for a big 4K stack. +const unsigned int MAIN_STACK_SIZE = 4 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +const bool defaultSerialFlowctrl = false; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA +// #define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 30; // Board powered @ 3.0V +#define SD_ONE_BIT_DATABUS // Can't use 4 bit databus due to pin conflicts + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.0f + +} // namespace miosix + +#endif /* BOARD_SETTINGS_H */ diff --git a/src/bsps/stm32f429zi_rig/config/miosix_settings.h b/src/bsps/stm32f429zi_rig/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..5fe66bf6c7986666ec94c8c52588f3c5d8cfef58 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_rig/core/stage_1_boot.cpp b/src/bsps/stm32f429zi_rig/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d62f8100350f81ed34718f3b3617b79278a892e5 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/core/stage_1_boot.cpp @@ -0,0 +1,372 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#include <string.h> + +#include "core/interrupts.h" //For the unexpected interrupt call +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f42x devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M3 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); +// ST does not provide code to initialize the stm32f429-disco SDRAM at boot. +// Put after SystemInit() as SDRAM is timing-sensitive and needs the full +// clock speed. +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Initialize process stack and switch to it. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Privileged, process stack + "msr control, r0 \n\t" + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDIO_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) HASH_RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, PVD_IRQHandler, TAMP_STAMP_IRQHandler, RTC_WKUP_IRQHandler, + FLASH_IRQHandler, RCC_IRQHandler, EXTI0_IRQHandler, EXTI1_IRQHandler, + EXTI2_IRQHandler, EXTI3_IRQHandler, EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, DMA1_Stream1_IRQHandler, DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, DMA1_Stream4_IRQHandler, DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, ADC_IRQHandler, CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, CAN1_RX1_IRQHandler, CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, TIM1_BRK_TIM9_IRQHandler, TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, TIM1_CC_IRQHandler, TIM2_IRQHandler, + TIM3_IRQHandler, TIM4_IRQHandler, I2C1_EV_IRQHandler, I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, I2C2_ER_IRQHandler, SPI1_IRQHandler, SPI2_IRQHandler, + USART1_IRQHandler, USART2_IRQHandler, USART3_IRQHandler, + EXTI15_10_IRQHandler, RTC_Alarm_IRQHandler, OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, TIM8_CC_IRQHandler, DMA1_Stream7_IRQHandler, + FMC_IRQHandler, SDIO_IRQHandler, TIM5_IRQHandler, SPI3_IRQHandler, + UART4_IRQHandler, UART5_IRQHandler, TIM6_DAC_IRQHandler, TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, DMA2_Stream1_IRQHandler, DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, DMA2_Stream4_IRQHandler, ETH_IRQHandler, + ETH_WKUP_IRQHandler, CAN2_TX_IRQHandler, CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, CAN2_SCE_IRQHandler, OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, DMA2_Stream6_IRQHandler, DMA2_Stream7_IRQHandler, + USART6_IRQHandler, I2C3_EV_IRQHandler, I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, OTG_HS_EP1_IN_IRQHandler, OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, DCMI_IRQHandler, CRYP_IRQHandler, HASH_RNG_IRQHandler, + FPU_IRQHandler, UART7_IRQHandler, UART8_IRQHandler, SPI4_IRQHandler, + SPI5_IRQHandler, SPI6_IRQHandler, SAI1_IRQHandler, LTDC_IRQHandler, + LTDC_ER_IRQHandler, DMA2D_IRQHandler}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDIO_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak HASH_RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f429zi_rig/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f429zi_rig/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..06956a1831186283826ce0ca36c2917e9d4481de --- /dev/null +++ b/src/bsps/stm32f429zi_rig/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// Always include stm32f4xx.h before core_cm4.h, there's some nasty dependency +#define STM32F429xx +#include "CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" +#include "CMSIS/Device/ST/STM32F4xx/Include/system_stm32f4xx.h" +#include "CMSIS/Include/core_cm4.h" + +#define RCC_SYNC() __DSB() // Workaround for a bug in stm32f42x + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f429zi_rig/interfaces-impl/bsp.cpp b/src/bsps/stm32f429zi_rig/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2caef6f014c57c8eb40402bd6abb7340fae5d23b --- /dev/null +++ b/src/bsps/stm32f429zi_rig/interfaces-impl/bsp.cpp @@ -0,0 +1,364 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +/** + * The example code from ST checks for the busy flag after each command. + * Interestingly I couldn't find any mention of this in the datsheet. + */ +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable all gpios, passing clock + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + + // First, configure SDRAM GPIOs + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc00cc; + GPIOG->AFR[1] = 0xc000000c; + + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a0a; + + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOs... + GPIOB->OSPEEDR = + 0xaaaaaaaa | 0x00003c00; //...but 100MHz for the SDRAM pins + GPIOC->OSPEEDR = 0xaaaaaaaa | 0x00000003; + GPIOD->OSPEEDR = 0xaaaaaaaa | 0xf03f000f; + GPIOE->OSPEEDR = 0xaaaaaaaa | 0xffffc00f; + GPIOF->OSPEEDR = 0xaaaaaaaa | 0xffc00fff; + GPIOG->OSPEEDR = 0xaaaaaaaa | 0xc0030f0f; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + // Since we'we un-configured PB3/PB4 from the default at boot TDO,NTRST, + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Second, actually start the SDRAM controller + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // SDRAM is a IS42S16400J -7 speed grade, connected to bank 2 (0xd0000000) + // Some bits in SDCR[1] are don't care, and the have to be set in SDCR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDCR[0] = FMC_SDCR1_SDCLK_1 // SDRAM runs @ half CPU frequency + | FMC_SDCR1_RBURST // Enable read burst + | 0; // 0 delay between reads after CAS + FMC_Bank5_6->SDCR[1] = 0 // 8 bit column address + | FMC_SDCR1_NR_0 // 12 bit row address + | FMC_SDCR1_MWID_0 // 16 bit data bus + | FMC_SDCR1_NB // 4 banks + | + FMC_SDCR1_CAS_1; // 2 cycle CAS latency (F<133MHz) + +#ifdef SYSCLK_FREQ_180MHz + // One SDRAM clock cycle is 11.1ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (66.6ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (22.2ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (7 - 1) << 4 // 7 cycle TXSR (77.7ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (44.4ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (22.2ns>15ns) +#elif defined(SYSCLK_FREQ_168MHz) + // One SDRAM clock cycle is 11.9ns + // Some bits in SDTR[1] are don't care, and the have to be set in SDTR[0], + // they aren't just don't care, the controller will fail if they aren't at 0 + FMC_Bank5_6->SDTR[0] = (6 - 1) << 12 // 6 cycle TRC (71.4ns>63ns) + | (2 - 1) << 20; // 2 cycle TRP (23.8ns>15ns) + FMC_Bank5_6->SDTR[1] = (2 - 1) << 0 // 2 cycle TMRD + | (6 - 1) << 4 // 6 cycle TXSR (71.4ns>70ns) + | (4 - 1) << 8 // 4 cycle TRAS (47.6ns>42ns) + | (2 - 1) << 16 // 2 cycle TWR + | (2 - 1) << 24; // 2 cycle TRCD (23.8ns>15ns) +#else +#error No SDRAM timings for this clock +#endif + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 1; // MODE=001 clock enabled + sdramCommandWait(); + + // ST and SDRAM datasheet agree a 100us delay is required here. + delayUs(100); + + FMC_Bank5_6->SDCMR = FMC_SDCMR_CTB2 // Enable bank 2 + | 2; // MODE=010 precharge all command + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = (8 - 1) << 5 // NRFS=8 SDRAM datasheet says + // "at least two AUTO REFRESH cycles" + | FMC_SDCMR_CTB2 // Enable bank 2 + | 3; // MODE=011 auto refresh + sdramCommandWait(); + + FMC_Bank5_6->SDCMR = 0x220 << 9 // MRD=0x220:CAS latency=2 burst len=1 + | FMC_SDCMR_CTB2 // Enable bank 2 + | 4; // MODE=100 load mode register + sdramCommandWait(); + +// 64ms/4096=15.625us +#ifdef SYSCLK_FREQ_180MHz + // 15.625us*90MHz=1406-20=1386 + FMC_Bank5_6->SDRTR = 1386 << 1; +#elif defined(SYSCLK_FREQ_168MHz) + // 15.625us*84MHz=1312-20=1292 + FMC_Bank5_6->SDRTR = 1292 << 1; +#else +#error No refresh timings for this clock +#endif +} + +void IRQbspInit() +{ +// If using SDRAM GPIOs are enabled by configureSdram(), else enable them here +#ifndef __ENABLE_XRAM + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); +#endif //__ENABLE_XRAM + + RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; + RCC->APB1ENR |= RCC_APB1ENR_SPI2EN; + RCC->APB2ENR |= RCC_APB2ENR_SPI4EN; + RCC->APB2ENR |= RCC_APB2ENR_SPI5EN; + RCC->APB2ENR |= RCC_APB2ENR_SPI6EN; + + RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; + + RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM8EN; + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM10EN; + RCC->APB2ENR |= RCC_APB2ENR_TIM11EN; + + RCC_SYNC(); + + using namespace interfaces; + + spi1::sck::mode(Mode::ALTERNATE); + spi1::sck::alternateFunction(5); + spi1::miso::mode(Mode::ALTERNATE); + spi1::miso::alternateFunction(5); + spi1::mosi::mode(Mode::ALTERNATE); + spi1::mosi::alternateFunction(5); + + spi2::sck::mode(Mode::ALTERNATE); + spi2::sck::alternateFunction(5); + spi2::miso::mode(Mode::ALTERNATE); + spi2::miso::alternateFunction(5); + spi2::mosi::mode(Mode::ALTERNATE); + spi2::mosi::alternateFunction(5); + + spi4::sck::mode(Mode::ALTERNATE); + spi4::sck::alternateFunction(5); + spi4::miso::mode(Mode::ALTERNATE); + spi4::miso::alternateFunction(5); + spi4::mosi::mode(Mode::ALTERNATE); + spi4::mosi::alternateFunction(5); + + spi5::sck::mode(Mode::ALTERNATE); + spi5::sck::alternateFunction(5); + spi5::miso::mode(Mode::ALTERNATE); + spi5::miso::alternateFunction(5); + spi5::mosi::mode(Mode::ALTERNATE); + spi5::mosi::alternateFunction(5); + + spi6::sck::mode(Mode::ALTERNATE); + spi6::sck::alternateFunction(5); + spi6::miso::mode(Mode::ALTERNATE); + spi6::miso::alternateFunction(5); + spi6::mosi::mode(Mode::ALTERNATE); + spi6::mosi::alternateFunction(5); + + uart1::rx::mode(Mode::ALTERNATE); + uart1::rx::alternateFunction(7); + uart1::tx::mode(Mode::ALTERNATE); + uart1::tx::alternateFunction(7); + + can1::rx::mode(Mode::ALTERNATE); + can1::rx::alternateFunction(9); + can1::tx::mode(Mode::ALTERNATE); + can1::tx::alternateFunction(9); + + timers::tim4ch2::mode(Mode::ALTERNATE); + timers::tim11ch1::mode(Mode::ALTERNATE); + timers::tim3ch1::mode(Mode::ALTERNATE); + timers::tim10ch1::mode(Mode::ALTERNATE); + timers::tim8ch1::mode(Mode::ALTERNATE); + + timers::tim4ch2::alternateFunction(2); + timers::tim11ch1::alternateFunction(3); + timers::tim3ch1::alternateFunction(2); + timers::tim10ch1::alternateFunction(3); + timers::tim8ch1::alternateFunction(3); + + using namespace sensors; + ADS131_1::cs::mode(Mode::OUTPUT); + ADS131_1::cs::high(); + + ADS131_2::cs::mode(Mode::OUTPUT); + ADS131_2::cs::high(); + + MAX31855::cs::mode(Mode::OUTPUT); + MAX31855::cs::high(); + + using namespace relays; + ignition::mode(Mode::OUTPUT); + ledLamp::mode(Mode::OUTPUT); + nitrogen::mode(Mode::OUTPUT); + generalPurpose::mode(Mode::OUTPUT); + + ignition::high(); + ledLamp::high(); + nitrogen::high(); + generalPurpose::high(); + + using namespace radio; + cs::mode(Mode::OUTPUT); + dio0::mode(Mode::INPUT_PULL_UP); + dio1::mode(Mode::INPUT_PULL_UP); + dio3::mode(Mode::INPUT_PULL_UP); + txEn::mode(Mode::OUTPUT); + rxEn::mode(Mode::OUTPUT); + nrst::mode(Mode::OUTPUT); + + cs::high(); + nrst::high(); + + // TODO define default configs + + using namespace ui; + + button::mode(Mode::INPUT); + + greenLed::mode(Mode::OUTPUT); + greenLed::low(); + redLed::mode(Mode::OUTPUT); + redLed::low(); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(defaultSerial, defaultSerialSpeed, + defaultSerialFlowctrl ? STM32Serial::RTSCTS + : STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM +} + +// +// Shutdown and reboot +// + +/** + * @brief This function disables filesystem and serial port. + */ +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + + while (true) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_rig/interfaces-impl/bsp_impl.h b/src/bsps/stm32f429zi_rig/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..5317e8ae06f73695173e3f9fd6eea73afd647148 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/interfaces-impl/bsp_impl.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "drivers/stm32_hardware_rng.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f429zi_rig/interfaces-impl/hwmapping.h b/src/bsps/stm32f429zi_rig/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..6fe1b142a0262c7d4a96fd76cacf0882e72ab477 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/interfaces-impl/hwmapping.h @@ -0,0 +1,173 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#pragma once + +#include "interfaces/gpio.h" + +namespace miosix +{ + +namespace interfaces +{ + +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +namespace spi2 +{ +using sck = Gpio<GPIOD_BASE, 3>; +using miso = Gpio<GPIOC_BASE, 2>; +using mosi = Gpio<GPIOC_BASE, 3>; +} // namespace spi2 + +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +namespace spi5 +{ +using sck = Gpio<GPIOF_BASE, 7>; +using miso = Gpio<GPIOF_BASE, 8>; +using mosi = Gpio<GPIOF_BASE, 9>; +} // namespace spi5 + +namespace spi6 +{ +using sck = Gpio<GPIOG_BASE, 13>; +using miso = Gpio<GPIOG_BASE, 12>; +using mosi = Gpio<GPIOG_BASE, 14>; +} // namespace spi6 + +// USB UART +namespace uart1 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace uart1 + +namespace can1 +{ +using tx = Gpio<GPIOA_BASE, 12>; +using rx = Gpio<GPIOA_BASE, 11>; +} // namespace can1 + +namespace timers +{ +using tim4ch2 = Gpio<GPIOB_BASE, 7>; // Servo 1 +using tim11ch1 = Gpio<GPIOB_BASE, 9>; // Servo 2 +using tim3ch1 = Gpio<GPIOB_BASE, 4>; // Servo 3 +using tim10ch1 = Gpio<GPIOB_BASE, 8>; // Servo 4 +using tim8ch1 = Gpio<GPIOC_BASE, 6>; // Servo 5 +} // namespace timers + +} // namespace interfaces + +namespace sensors +{ + +namespace ADS131_1 +{ +using cs = Gpio<GPIOB_BASE, 1>; +using sck = interfaces::spi1::sck; +using miso = interfaces::spi1::miso; +using mosi = interfaces::spi1::mosi; +} // namespace ADS131_1 + +namespace ADS131_2 +{ +using cs = Gpio<GPIOE_BASE, 4>; +using sck = interfaces::spi1::sck; +using miso = interfaces::spi1::miso; +using mosi = interfaces::spi1::mosi; +} // namespace ADS131_2 + +namespace MAX31855 +{ +using cs = Gpio<GPIOF_BASE, 9>; +using sck = interfaces::spi1::sck; +using miso = interfaces::spi1::miso; +using mosi = interfaces::spi1::mosi; +} // namespace MAX31855 + +namespace HX711_1 +{ +using sck = interfaces::spi2::sck; +} +namespace HX711_2 +{ +using sck = interfaces::spi6::sck; +} + +namespace HX711_3 +{ +using sck = interfaces::spi4::sck; +} + +} // namespace sensors + +namespace servos +{ +using servo1 = interfaces::timers::tim4ch2; +using servo2 = interfaces::timers::tim11ch1; +using servo3 = interfaces::timers::tim3ch1; +using servo4 = interfaces::timers::tim10ch1; +using servo5 = interfaces::timers::tim8ch1; +} // namespace servos + +namespace relays +{ +using ignition = Gpio<GPIOC_BASE, 14>; +using ledLamp = Gpio<GPIOE_BASE, 3>; +using nitrogen = Gpio<GPIOC_BASE, 13>; +using generalPurpose = Gpio<GPIOA_BASE, 15>; +} // namespace relays + +namespace radio +{ +using cs = Gpio<GPIOF_BASE, 6>; +using sck = interfaces::spi4::sck; +using miso = interfaces::spi4::miso; +using mosi = interfaces::spi4::mosi; +using dio0 = Gpio<GPIOD_BASE, 5>; +using dio1 = Gpio<GPIOD_BASE, 12>; +using dio3 = Gpio<GPIOD_BASE, 13>; +using txEn = Gpio<GPIOG_BASE, 2>; +using rxEn = Gpio<GPIOG_BASE, 3>; +using nrst = Gpio<GPIOB_BASE, 0>; +} // namespace radio + +namespace ui +{ +using button = Gpio<GPIOA_BASE, 0>; // User button +using greenLed = Gpio<GPIOG_BASE, 13>; // Green LED +using redLed = Gpio<GPIOG_BASE, 14>; // Red LED +} // namespace ui + +} // namespace miosix diff --git a/src/bsps/stm32f429zi_rig/stm32_2m+256k_rom.ld b/src/bsps/stm32f429zi_rig/stm32_2m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..cfcc2ce53bd9e1b821cbfe90aeedd73fcdce1522 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/stm32_2m+256k_rom.ld @@ -0,0 +1,181 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - stacks and heap in the "large" 192KB RAM. + * + * Unfortunately thread stacks can't be put in the small RAM as Miosix + * allocates them inside the heap. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into the large 192KB RAM */ +_end = 0x20000000; +_heap_end = 0x20030000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > smallram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > smallram + _bss_end = .; + + /*_end = .;*/ + /*PROVIDE(end = .);*/ +} diff --git a/src/bsps/stm32f429zi_rig/stm32_2m+8m_xram.ld b/src/bsps/stm32f429zi_rig/stm32_2m+8m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..b6a0d26683cbff52ac66b7f275f9269d61dfbf41 --- /dev/null +++ b/src/bsps/stm32f429zi_rig/stm32_2m+8m_xram.ld @@ -0,0 +1,178 @@ +/* + * C++ enabled linker script for stm32 (2M FLASH, 256K RAM, 8M XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This chip has an unusual quirk that the RAM is divided in two block mapped + * at two non contiguous memory addresses. I don't know why they've done that, + * probably doing the obvious thing would have made writing code too easy... + * Anyway, since hardware can't be changed, we've got to live with that and + * try to make use of both RAMs. + * + * Given the constraints above, this linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM + * - .data, .bss, stacks and heap in the external 8MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ +_main_stack_size = 0x00000200; /* main stack = 512Bytes */ +_main_stack_top = 0x10000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0800000; /* end of available ram */ + +/* identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* specify the memory areas */ +MEMORY +{ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M + /* + * Note, the small ram starts at 0x10000000 but it is necessary to add the + * size of the main stack, so it is 0x10000200. + */ + smallram(wx) : ORIGIN = 0x10000200, LENGTH = 64K-0x200 + largeram(wx) : ORIGIN = 0x20000000, LENGTH = 192K + backupram(rw): ORIGIN = 0x40024000, LENGTH = 4K + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 8M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* .data section: global variables go to ram, but also store a copy to + flash to initialize them */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to ram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f756zg_nucleo/config/board_options.cmake b/src/bsps/stm32f756zg_nucleo/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..079c7af5d7c16018fccc7572f16eb49e45d09806 --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/config/board_options.cmake @@ -0,0 +1,102 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f756zg_nucleo) +set(ARCH_NAME cortexM7_stm32f7) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file and linker script +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_1m+256k_rom.ld) + +# Select clock frequency (HSE_VALUE is the xtal on board, fixed) +set(CLOCK_FREQ -DHSE_VALUE=8000000 -DSYSCLK_FREQ_216MHz=216000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM7_STM32F7 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c + ${KPATH}/arch/common/core/cache_cortexMx.cpp + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f756zg_nucleo/config/board_settings.h b/src/bsps/stm32f756zg_nucleo/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..bacc222e364f74443cb1cc89f9d326b126ee3f58 --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/config/board_settings.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Lorenzo Cucchi + * + * 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. + */ + +#pragma once + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) +const unsigned int MAIN_STACK_SIZE = 4 * 1024; + +/// Serial port +const unsigned int defaultSerialSpeed = 115200; +// #define SERIAL_1_DMA +// #define SERIAL_2_DMA +#define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +#define SD_ONE_BIT_DATABUS // For now we'll use 1 bit bus +#define SD_SDMMC 1 // Select either SDMMC1 or SDMMC2 + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f756zg_nucleo/config/miosix_settings.h b/src/bsps/stm32f756zg_nucleo/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..25ff282354a7b536cf65c740980c39de3be6eca7 --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Lorenzo Cucchi + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f756zg_nucleo/core/stage_1_boot.cpp b/src/bsps/stm32f756zg_nucleo/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f0bb489658a114c115568514238db7862aafaa07 --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/core/stage_1_boot.cpp @@ -0,0 +1,454 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Lorenzo Cucchi + * + * 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. + */ + +#include <string.h> + +#include "core/cache_cortexMx.h" +#include "core/interrupts.h" //For the unexpected interrupt call +#include "core/interrupts_cortexMx.h" +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f756 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M7 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + // SystemInit() is called *before* initializing .data and zeroing .bss + // Despite all startup files provided by ST do the opposite, there are three + // good reasons to do so: + // First, the CMSIS specifications say that SystemInit() must not access + // global variables, so it is actually possible to call it before + // Second, when running Miosix with the xram linker scripts .data and .bss + // are placed in the external RAM, so we *must* call SystemInit(), which + // enables xram, before touching .data and .bss + // Third, this is a performance improvement since the loops that initialize + //.data and zeros .bss now run with the CPU at full speed instead of 8MHz + SystemInit(); + + miosix::IRQconfigureCache(); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + /* + * Load into the program stack pointer the heap end address and switch from + * the msp to sps. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Set the control register to use + "msr control, r0 \n\t" // the process stack + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDMMC1_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); +void __attribute__((weak)) SAI2_IRQHandler(); +void __attribute__((weak)) QUADSPI_IRQHandler(); +void __attribute__((weak)) LPTIM1_IRQHandler(); +void __attribute__((weak)) CEC_IRQHandler(); +void __attribute__((weak)) I2C4_EV_IRQHandler(); +void __attribute__((weak)) I2C4_ER_IRQHandler(); +void __attribute__((weak)) SPDIF_RX_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDMMC1_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + 0, + RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, + SAI2_IRQHandler, + QUADSPI_IRQHandler, + LPTIM1_IRQHandler, + CEC_IRQHandler, + I2C4_EV_IRQHandler, + I2C4_ER_IRQHandler, + SPDIF_RX_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDMMC1_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler +#pragma weak SAI2_IRQHandler = Default_Handler +#pragma weak QUADSPI_IRQHandler = Default_Handler +#pragma weak LPTIM1_IRQHandler = Default_Handler +#pragma weak CEC_IRQHandler = Default_Handler +#pragma weak I2C4_EV_IRQHandler = Default_Handler +#pragma weak I2C4_ER_IRQHandler = Default_Handler +#pragma weak SPDIF_RX_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f756zg_nucleo/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f756zg_nucleo/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..ab9a545433a56d7925a9a85df9b88d925b9b8c7d --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Lorenzo Cucchi + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// stm32f7xx.h defines a few macros like __ICACHE_PRESENT, __DCACHE_PRESENT and +// includes core_cm7.h. Do not include core_cm7.h before. +#define STM32F756xx +#include "CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h" + +#if (__ICACHE_PRESENT != 1) || (__DCACHE_PRESENT != 1) +#error "Wrong include order" +#endif + +#include "CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h" + +#define RCC_SYNC() __DSB() // TODO: can this dsb be removed? + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f756zg_nucleo/interfaces-impl/bsp.cpp b/src/bsps/stm32f756zg_nucleo/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2cc3d8230ed05540f7b075e2d178a9e6293534ab --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/interfaces-impl/bsp.cpp @@ -0,0 +1,124 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Lorenzo Cucchi + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +void IRQbspInit() +{ + // Enable all gpios + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN | RCC_AHB1ENR_GPIOHEN; + RCC_SYNC(); + GPIOA->OSPEEDR = 0xaaaaaaaa; // Default to 50MHz speed for all GPIOS + GPIOB->OSPEEDR = 0xaaaaaaaa; + GPIOC->OSPEEDR = 0xaaaaaaaa; + GPIOD->OSPEEDR = 0xaaaaaaaa; + GPIOE->OSPEEDR = 0xaaaaaaaa; + GPIOF->OSPEEDR = 0xaaaaaaaa; + GPIOG->OSPEEDR = 0xaaaaaaaa; + GPIOH->OSPEEDR = 0xaaaaaaaa; + + userLed1::mode(Mode::OUTPUT); + userLed2::mode(Mode::OUTPUT); + userLed3::mode(Mode::OUTPUT); + userBtn::mode(Mode::INPUT); + + ledOn(); + delayMs(100); + ledOff(); + auto tx = Gpio<GPIOD_BASE, 8>::getPin(); + tx.alternateFunction(7); + auto rx = Gpio<GPIOD_BASE, 9>::getPin(); + rx.alternateFunction(7); + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>( + new STM32Serial(3, defaultSerialSpeed, tx, rx))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM +} + +// +// Shutdown and reboot +// + +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + for (;;) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f756zg_nucleo/interfaces-impl/bsp_impl.h b/src/bsps/stm32f756zg_nucleo/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..c4a613fd1697dc485ddff79d2d519b7fdd023ce8 --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/interfaces-impl/bsp_impl.h @@ -0,0 +1,95 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Lorenzo Cucchi + * + * 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. + */ + +/*********************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Board pin definition + */ +typedef Gpio<GPIOB_BASE, 0> userLed1; +typedef Gpio<GPIOB_BASE, 7> userLed2; +typedef Gpio<GPIOB_BASE, 14> userLed3; +typedef Gpio<GPIOC_BASE, 13> userBtn; + +inline void ledOn() +{ + userLed1::high(); + userLed2::high(); + userLed3::high(); +} + +inline void ledOff() +{ + userLed1::low(); + userLed2::low(); + userLed3::low(); +} + +inline void led1On() { userLed1::high(); } + +inline void led1Off() { userLed1::low(); } + +inline void led2On() { userLed2::high(); } + +inline void led2Off() { userLed2::low(); } + +inline void led3On() { userLed3::high(); } + +inline void led3Off() { userLed3::low(); } + +/** + * Polls the SD card sense GPIO. + * + * This board has no SD card whatsoever, but a card can be connected to the + * following GPIOs: + * TODO: never tested + * + * \return true. As there's no SD card sense switch, let's pretend that + * the card is present. + */ +inline bool sdCardSense() { return true; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f756zg_nucleo/stm32_1m+256k_rom.ld b/src/bsps/stm32f756zg_nucleo/stm32_1m+256k_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..1f81bdcc8c5aa7ce380d9141337a405a7297d5bd --- /dev/null +++ b/src/bsps/stm32f756zg_nucleo/stm32_1m+256k_rom.ld @@ -0,0 +1,178 @@ +/* + * C++ enabled linker script for stm32f746zg (1M FLASH, 256K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 64KB RAM + * - .data, .bss, stacks and heap in the internal RAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap to the end of SRAM2 */ +_heap_end = 0x20000000 + 320K; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 64KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 64KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + sram(wx) : ORIGIN = 0x20010000, LENGTH = 256K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 64K /* Used for main stack */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 1M +} + +/* Now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* These sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* These sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to sram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > sram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to sram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > sram + _bss_end = .; + + _end = .; + PROVIDE(end = .); +} diff --git a/src/bsps/stm32f767zi_automated_antennas/config/board_options.cmake b/src/bsps/stm32f767zi_automated_antennas/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..276c30af5c023db8d740e9e00674bede9e7aa519 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/config/board_options.cmake @@ -0,0 +1,106 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f767zi_automated_antennas) +set(ARCH_NAME cortexM7_stm32f7) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file and linker script +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+16m_xram.ld) + +# Enables the initialization of the external 16MB SDRAM memory +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency (HSE_VALUE is the xtal on board, fixed) +set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM7_STM32F7 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c + ${KPATH}/arch/common/core/cache_cortexMx.cpp + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f767zi_automated_antennas/config/board_settings.h b/src/bsps/stm32f767zi_automated_antennas/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..1fc053248cdc50ec55bb6fe81b5d4d6ffa0921b4 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/config/board_settings.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * 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. + */ + +#pragma once + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA +// #define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +#define SD_ONE_BIT_DATABUS +#define SD_SDMMC 1 // Select either SDMMC1 or SDMMC2 + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_automated_antennas/config/miosix_settings.h b/src/bsps/stm32f767zi_automated_antennas/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..5a19de638c12a439c7614beed3ef70f990fc280d --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_automated_antennas/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_automated_antennas/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d696c2eae4be05d89b417976393e4ca581bdca91 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/core/stage_1_boot.cpp @@ -0,0 +1,505 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * 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. + */ + +#include <string.h> + +#include "core/cache_cortexMx.h" +#include "core/interrupts.h" //For the unexpected interrupt call +#include "core/interrupts_cortexMx.h" +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f767 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M7 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + miosix::IRQconfigureCache((const unsigned int *)0xd0000000, + 8 * 1024 * 1024); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + /** + * SystemInit() is called *before* initializing .data and zeroing .bss + * Despite all startup files provided by ST do the opposite, there are three + * good reasons to do so: + * 1. First, the CMSIS specifications say that SystemInit() must not access + * global variables, so it is actually possible to call it before + * 2. Second, when running Miosix with the xram linker scripts .data and + * .bss are placed in the external RAM, so we *must* call SystemInit(), + * which enables xram, before touching .data and .bss + * 3. Third, this is a performance improvement since the loops that + * initialize .data and zeros .bss now run with the CPU at full speed + * instead of 8MHz + */ + SystemInit(); + +/** + * ST does not provide code to initialize the SDRAM at boot. + * Put after SystemInit() as SDRAM is timing-sensitive and needs the full + * clock speed. + */ +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Load into the program stack pointer the heap end address and switch from + * the msp to sps. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Set the control register to use + "msr control, r0 \n\t" // the process stack + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDMMC1_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); +void __attribute__((weak)) SAI2_IRQHandler(); +void __attribute__((weak)) QUADSPI_IRQHandler(); +void __attribute__((weak)) LPTIM1_IRQHandler(); +void __attribute__((weak)) CEC_IRQHandler(); +void __attribute__((weak)) I2C4_EV_IRQHandler(); +void __attribute__((weak)) I2C4_ER_IRQHandler(); +void __attribute__((weak)) SPDIF_RX_IRQHandler(); +void __attribute__((weak)) DSIHOST_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT0_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT1_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT2_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT3_IRQHandler(); +void __attribute__((weak)) SDMMC2_IRQHandler(); +void __attribute__((weak)) CAN3_TX_IRQHandler(); +void __attribute__((weak)) CAN3_RX0_IRQHandler(); +void __attribute__((weak)) CAN3_RX1_IRQHandler(); +void __attribute__((weak)) CAN3_SCE_IRQHandler(); +void __attribute__((weak)) JPEG_IRQHandler(); +void __attribute__((weak)) MDIOS_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDMMC1_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, + SAI2_IRQHandler, + QUADSPI_IRQHandler, + LPTIM1_IRQHandler, + CEC_IRQHandler, + I2C4_EV_IRQHandler, + I2C4_ER_IRQHandler, + SPDIF_RX_IRQHandler, + DSIHOST_IRQHandler, + DFSDM1_FLT0_IRQHandler, + DFSDM1_FLT1_IRQHandler, + DFSDM1_FLT2_IRQHandler, + DFSDM1_FLT3_IRQHandler, + SDMMC2_IRQHandler, + CAN3_TX_IRQHandler, + CAN3_RX0_IRQHandler, + CAN3_RX1_IRQHandler, + CAN3_SCE_IRQHandler, + JPEG_IRQHandler, + MDIOS_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDMMC1_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler +#pragma weak SAI2_IRQHandler = Default_Handler +#pragma weak QUADSPI_IRQHandler = Default_Handler +#pragma weak LPTIM1_IRQHandler = Default_Handler +#pragma weak CEC_IRQHandler = Default_Handler +#pragma weak I2C4_EV_IRQHandler = Default_Handler +#pragma weak I2C4_ER_IRQHandler = Default_Handler +#pragma weak SPDIF_RX_IRQHandler = Default_Handler +#pragma weak DSIHOST_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT0_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT1_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT2_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT3_IRQHandler = Default_Handler +#pragma weak SDMMC2_IRQHandler = Default_Handler +#pragma weak CAN3_TX_IRQHandler = Default_Handler +#pragma weak CAN3_RX0_IRQHandler = Default_Handler +#pragma weak CAN3_RX1_IRQHandler = Default_Handler +#pragma weak CAN3_SCE_IRQHandler = Default_Handler +#pragma weak JPEG_IRQHandler = Default_Handler +#pragma weak MDIOS_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..a2f830b2176f83b9acb6e9f0f4e5b418d79e9ad3 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// stm32f7xx.h defines a few macros like __ICACHE_PRESENT, __DCACHE_PRESENT and +// includes core_cm7.h. Do not include core_cm7.h before. +#define STM32F767xx +#include "CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h" + +#if (__ICACHE_PRESENT != 1) || (__DCACHE_PRESENT != 1) +#error "Wrong include order" +#endif + +#include "CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h" + +#define RCC_SYNC() __DSB() // TODO: can this dsb be removed? + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0853b1f8b51a361f67f78683477d2e28fb622b28 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/bsp.cpp @@ -0,0 +1,367 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "drivers/serial_stm32.h" +#include "drivers/stm32_sgm.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable gpios used by the ram + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | + RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | + RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN; + RCC_SYNC(); + + // On the compute unit with F767ZI, the SDRAM pins are: + // - PG8: FMC_SDCLK (sdram clock) + // - PB5: FMC_SDCKE1 (sdram bank 2 clock enable) + // - PB6: FMC_SDNE1 (sdram bank 2 chip enable) + // - PF0: FMC_A0 + // - PF1: FMC_A1 + // - PF2: FMC_A2 + // - PF3: FMC_A3 + // - PF4: FMC_A4 + // - PF5: FMC_A5 + // - PF12: FMC_A6 + // - PF13: FMC_A7 + // - PF14: FMC_A8 + // - PF15: FMC_A9 + // - PG0: FMC_A10 + // - PG1: FMC_A11 + // - PG2: FMC_A12 (used only by the 32MB ram, not by the 8MB one) + // - PD14: FMC_D0 + // - PD15: FMC_D1 + // - PD0: FMC_D2 + // - PD1: FMC_D3 + // - PE7: FMC_D4 + // - PE8: FMC_D5 + // - PE9: FMC_D6 + // - PE10: FMC_D7 + // - PE11: FMC_D8 + // - PE12: FMC_D9 + // - PE13: FMC_D10 + // - PE14: FMC_D11 + // - PE15: FMC_D12 + // - PD8: FMC_D13 + // - PD9: FMC_D14 + // - PD10: FMC_D15 + + // - PG4: FMC_BA0 + // - PG5: FMC_BA1 + // - PF11: FMC_SDNRAS + // - PG15: FMC_SDNCAS + // - PC0: FMC_SDNWE + // - PE0: FMC_NBL0 + // - PE1: FMC_NBL1 + + // All SDRAM GPIOs needs to be configured with alternate function 12 and + // maximum speed + + // WARNING: The current configuration is for the 8MB ram + + // Alternate functions + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc0ccc; + GPIOG->AFR[1] = 0xc000000c; + + // Mode + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a2a; + + // Speed (high speed for all, very high speed for SDRAM pins) + GPIOB->OSPEEDR = 0x00003c00; + GPIOC->OSPEEDR = 0x00000003; + GPIOD->OSPEEDR = 0xf03f000f; + GPIOE->OSPEEDR = 0xffffc00f; + GPIOF->OSPEEDR = 0xffc00fff; + GPIOG->OSPEEDR = 0xc0030f3f; + + // Since we'we un-configured PB3 and PB4 (by default they are SWO and NJRST) + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Enable the SDRAM controller clock + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // The SDRAM is a AS4C4M16SA-6TAN + // HCLK = 216MHz -> SDRAM clock = HCLK/2 = 133MHz + + // 1. Memory device features + FMC_Bank5_6->SDCR[0] = 0 // 0 delay after CAS latency + | FMC_SDCR1_RBURST // Enable read bursts + | FMC_SDCR1_SDCLK_1; // SDCLK = HCLK / 2 + FMC_Bank5_6->SDCR[1] = 0 // Write accesses allowed + | FMC_SDCR2_CAS_1 // 2 cycles CAS latency + | FMC_SDCR2_NB // 4 internal banks + | FMC_SDCR2_MWID_0 // 16 bit data bus + | FMC_SDCR2_NR_1 // 13 bit row address + // cppcheck-suppress duplicateExpression + | 0; // 8 bit column address + +// 2. Memory device timings +#ifdef SYSCLK_FREQ_216MHz + // SDRAM timings. One clock cycle is 9.26ns + FMC_Bank5_6->SDTR[0] = + (2 - 1) << FMC_SDTR1_TRP_Pos // 2 cycles TRP (18.52ns > 18ns) + | (7 - 1) << FMC_SDTR1_TRC_Pos; // 7 cycles TRC (64.82ns > 60ns) + FMC_Bank5_6->SDTR[1] = + (2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns) + | (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (min 2cc > 12ns) + | (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns) + | (7 - 1) << FMC_SDTR1_TXSR_Pos // 7 cycles TXSR (74.08ns > 61.5ns) + | (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (min 2cc > 12ns) +#else +#error No SDRAM timings for this clock +#endif + + // 3. Enable the bank 2 clock + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 4. Wait during command execution + delayUs(100); + + // 5. Issue a "Precharge All" command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 // Precharge all + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 6. Issue Auto-Refresh commands + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh + | FMC_SDCMR_CTB2 // Bank 2 + | (8 - 1) << FMC_SDCMR_NRFS_Pos; // 2 Auto-Refresh + sdramCommandWait(); + + // 7. Issue a Load Mode Register command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_2 /// Load mode register + | FMC_SDCMR_CTB2 // Bank 2 + | 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1 + sdramCommandWait(); + +// 8. Program the refresh rate (4K / 32ms) +// 64ms / 8192 = 7.8125us +#ifdef SYSCLK_FREQ_216MHz + // 7.8125us * 133MHz = 1039 - 20 = 1019 + FMC_Bank5_6->SDRTR = 1019 << FMC_SDRTR_COUNT_Pos; +#else +#error No SDRAM refresh timings for this clock +#endif +} + +void IRQbspInit() +{ + // Enable USART1 pins port + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; + + userLed1::mode(Mode::OUTPUT); + userLed2::mode(Mode::OUTPUT); + userLed3_1::mode(Mode::OUTPUT); + userLed3_2::mode(Mode::OUTPUT); + userLed4::mode(Mode::OUTPUT); + userSwitch::mode(Mode::INPUT); + + using namespace interfaces; + spi1::sck::mode(Mode::ALTERNATE); + spi1::sck::alternateFunction(5); + spi1::miso::mode(Mode::ALTERNATE); + spi1::miso::alternateFunction(5); + spi1::mosi::mode(Mode::ALTERNATE); + spi1::mosi::alternateFunction(5); + + spi3::sck::mode(Mode::ALTERNATE); + spi3::sck::alternateFunction(6); + spi3::miso::mode(Mode::ALTERNATE); + spi3::miso::alternateFunction(6); + spi3::mosi::mode(Mode::ALTERNATE); + spi3::mosi::alternateFunction(5); + + spi4::sck::mode(Mode::ALTERNATE); + spi4::sck::alternateFunction(5); + spi4::miso::mode(Mode::ALTERNATE); + spi4::miso::alternateFunction(5); + spi4::mosi::mode(Mode::ALTERNATE); + spi4::mosi::alternateFunction(5); + + can2::rx::mode(Mode::ALTERNATE); + can2::rx::alternateFunction(9); + can2::tx::mode(Mode::ALTERNATE); + can2::tx::alternateFunction(9); + + usart1::tx::mode(Mode::ALTERNATE); + usart1::tx::alternateFunction(7); + usart1::rx::mode(Mode::ALTERNATE); + usart1::rx::alternateFunction(7); + + usart2::tx::mode(Mode::ALTERNATE); + usart2::tx::alternateFunction(7); + usart2::rx::mode(Mode::ALTERNATE); + usart2::rx::alternateFunction(7); + + using namespace radio; + cs::mode(Mode::OUTPUT); + cs::getPin().high(); + dio0::mode(Mode::INPUT); + dio1::mode(Mode::INPUT); + dio3::mode(Mode::INPUT); + tx_enable::mode(Mode::OUTPUT); + rx_enable::mode(Mode::OUTPUT); + + using namespace timers; + tim3ch2::mode(Mode::ALTERNATE); + tim3ch2::alternateFunction(2); + tim4ch1::mode(Mode::ALTERNATE); + tim4ch1::alternateFunction(2); + + stepper1::enable::mode(Mode::OUTPUT); + stepper1::direction::mode(Mode::OUTPUT); + + stepper2::enable::mode(Mode::OUTPUT); + stepper2::direction::mode(Mode::OUTPUT); + + ethernet::cs::mode(Mode::OUTPUT); + ethernet::cs::high(); + ethernet::nrst::mode(Mode::OUTPUT); + ethernet::nrst::high(); + ethernet::intr::mode(Mode::INPUT); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial( + defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM + +#ifdef WITH_BACKUP_SRAM + // Print the reset reason + bootlog("Reset reson: "); + switch (SGM::instance().lastResetReason()) + { + case ResetReason::RST_LOW_PWR: + bootlog("low power\n"); + break; + case ResetReason::RST_WINDOW_WDG: + bootlog("window watchdog\n"); + break; + case ResetReason::RST_INDEPENDENT_WDG: + bootlog("indeendent watchdog\n"); + break; + case ResetReason::RST_SW: + bootlog("software reset\n"); + break; + case ResetReason::RST_POWER_ON: + bootlog("power on\n"); + break; + case ResetReason::RST_PIN: + bootlog("reset pin\n"); + break; + case ResetReason::RST_UNKNOWN: + bootlog("unknown\n"); + break; + } +#endif // WITH_BACKUP_SRAM +} + +// +// Shutdown and reboot +// + +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + for (;;) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..1e0498f6b28133971222e7fdb0061ea1ad8ed3b9 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/bsp_impl.h @@ -0,0 +1,116 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * 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. + */ + +/*************************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ***************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * Board pin definition + */ +typedef Gpio<GPIOB_BASE, 7> userLed1; +typedef Gpio<GPIOE_BASE, 3> userLed2; +typedef Gpio<GPIOC_BASE, 13> userLed3_1; +typedef Gpio<GPIOG_BASE, 9> userLed3_2; +typedef Gpio<GPIOC_BASE, 2> userLed4; +typedef Gpio<GPIOB_BASE, 2> userSwitch; + +inline void ledOn() +{ + userLed1::high(); + userLed2::high(); + userLed3_1::high(); + userLed3_2::high(); + userLed4::high(); +} + +inline void ledOff() +{ + userLed1::low(); + userLed2::low(); + userLed3_1::low(); + userLed3_2::low(); + userLed4::low(); +} + +inline void led1On() { userLed1::high(); } + +inline void led1Off() { userLed1::low(); } + +inline void led2On() { userLed2::high(); } + +inline void led2Off() { userLed2::low(); } + +inline void led3On() +{ + userLed3_1::high(); + userLed3_2::high(); +} + +inline void led3Off() +{ + userLed3_1::low(); + userLed3_2::low(); +} + +/** + * Polls the SD card sense GPIO. + * + * This board has no SD card whatsoever, but a card can be connected to the + * following GPIOs: + * TODO: never tested + * + * \return true. As there's no SD card sense switch, let's pretend that + * the card is present. + */ +inline bool sdCardSense() { return true; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/hwmapping.h b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..49e21359dc3eac86de66e8ae1381408755b0cb9b --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/interfaces-impl/hwmapping.h @@ -0,0 +1,131 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Emilio Corigliano + * + * 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. + */ + +#pragma once + +#include "interfaces/gpio.h" + +#define MIOSIX_ETHERNET_IRQ EXTI1_IRQHandlerImpl +#define MIOSIX_ETHERNET_SPI SPI4 + +namespace miosix +{ +namespace interfaces +{ +// RADIO 1 +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +// FREE SPI +namespace spi3 +{ +using sck = Gpio<GPIOB_BASE, 3>; +using miso = Gpio<GPIOB_BASE, 4>; +using mosi = Gpio<GPIOD_BASE, 6>; +} // namespace spi3 + +// ETHERNET +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +namespace can2 +{ +using rx = Gpio<GPIOB_BASE, 12>; +using tx = Gpio<GPIOB_BASE, 13>; +} // namespace can2 + +// DBG +namespace usart1 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace usart1 + +// FREE USART +namespace usart2 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace usart2 + +namespace timers +{ +using tim3ch2 = Gpio<GPIOC_BASE, 7>; // step 1 +using tim1ch4 = Gpio<GPIOA_BASE, 11>; // count 1 +using tim4ch1 = Gpio<GPIOD_BASE, 12>; // step 2 +using tim8ch4 = Gpio<GPIOC_BASE, 9>; // count 2 +} // namespace timers + +} // namespace interfaces + +namespace radio +{ +using sck = interfaces::spi1::sck; +using miso = interfaces::spi1::miso; +using mosi = interfaces::spi1::mosi; +using cs = Gpio<GPIOA_BASE, 4>; +using dio0 = Gpio<GPIOC_BASE, 6>; +using dio1 = Gpio<GPIOD_BASE, 4>; +using dio3 = Gpio<GPIOD_BASE, 5>; +using rx_enable = Gpio<GPIOB_BASE, 9>; +using tx_enable = Gpio<GPIOB_BASE, 8>; +} // namespace radio + +namespace stepper1 +{ +using enable = Gpio<GPIOA_BASE, 8>; +using direction = Gpio<GPIOA_BASE, 12>; +using pulseTimer = interfaces::timers::tim3ch2; +using countTimer = interfaces::timers::tim1ch4; +} // namespace stepper1 + +namespace stepper2 +{ +using enable = Gpio<GPIOB_BASE, 14>; +using direction = Gpio<GPIOG_BASE, 7>; +using pulseTimer = interfaces::timers::tim4ch1; +using countTimer = interfaces::timers::tim8ch4; +} // namespace stepper2 + +namespace ethernet +{ +namespace spi +{ +using sck = miosix::interfaces::spi4::sck; +using miso = miosix::interfaces::spi4::miso; +using mosi = miosix::interfaces::spi4::mosi; +} // namespace spi + +using cs = Gpio<GPIOE_BASE, 4>; +using intr = Gpio<GPIOC_BASE, 1>; +using nrst = Gpio<GPIOB_BASE, 1>; +} // namespace ethernet + +} // namespace miosix \ No newline at end of file diff --git a/src/bsps/stm32f767zi_automated_antennas/stm32_2m+16m_xram.ld b/src/bsps/stm32f767zi_automated_antennas/stm32_2m+16m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..5b3545abd6f3007072b8ff00a978242d74503d79 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/stm32_2m+16m_xram.ld @@ -0,0 +1,190 @@ +/* + * C++ enabled linker script for stm32f769ni (2M FLASH, 512K RAM, 16MB XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the external 16MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0000000 + 16M; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 16M + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to xram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to xram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_automated_antennas/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_automated_antennas/stm32_2m+384k_ram.ld new file mode 100644 index 0000000000000000000000000000000000000000..497bd5198760b9637c774bf3900fd9dfbc01a2b2 --- /dev/null +++ b/src/bsps/stm32f767zi_automated_antennas/stm32_2m+384k_ram.ld @@ -0,0 +1,189 @@ +/* + * C++ enabled linker script for stm32f767zi (2M FLASH, 512K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the internal RAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap to the end of SRAM2 */ +_heap_end = 0x20000000 + 512K; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to sram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > sram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to sram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > sram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_compute_unit/config/board_options.cmake b/src/bsps/stm32f767zi_compute_unit/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..d0bceacf53e293b9d07a8ad1d007c1ac477939b9 --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/config/board_options.cmake @@ -0,0 +1,106 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f767zi_compute_unit) +set(ARCH_NAME cortexM7_stm32f7) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file and linker script +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+16m_xram.ld) + +# Enables the initialization of the external 16MB SDRAM memory +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency (HSE_VALUE is the xtal on board, fixed) +set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM7_STM32F7 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c + ${KPATH}/arch/common/core/cache_cortexMx.cpp + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f767zi_compute_unit/config/board_settings.h b/src/bsps/stm32f767zi_compute_unit/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..2332aa30ea0f6249a56c67a56e7aacd668d29c4b --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/config/board_settings.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA +// #define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +// #define SD_ONE_BIT_DATABUS +#define SD_SDMMC 1 // Select either SDMMC1 or SDMMC2 + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_compute_unit/config/miosix_settings.h b/src/bsps/stm32f767zi_compute_unit/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..e1ca4aac6bef352c5b4d367b3ba84ff5f4445499 --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_compute_unit/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_compute_unit/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83eac53b4b0b56309c0a9c26aacb7ff4289558d0 --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/core/stage_1_boot.cpp @@ -0,0 +1,505 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#include <string.h> + +#include "core/cache_cortexMx.h" +#include "core/interrupts.h" //For the unexpected interrupt call +#include "core/interrupts_cortexMx.h" +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f767 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M7 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + miosix::IRQconfigureCache((const unsigned int *)0xd0000000, + 8 * 1024 * 1024); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + /** + * SystemInit() is called *before* initializing .data and zeroing .bss + * Despite all startup files provided by ST do the opposite, there are three + * good reasons to do so: + * 1. First, the CMSIS specifications say that SystemInit() must not access + * global variables, so it is actually possible to call it before + * 2. Second, when running Miosix with the xram linker scripts .data and + * .bss are placed in the external RAM, so we *must* call SystemInit(), + * which enables xram, before touching .data and .bss + * 3. Third, this is a performance improvement since the loops that + * initialize .data and zeros .bss now run with the CPU at full speed + * instead of 8MHz + */ + SystemInit(); + +/** + * ST does not provide code to initialize the SDRAM at boot. + * Put after SystemInit() as SDRAM is timing-sensitive and needs the full + * clock speed. + */ +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Load into the program stack pointer the heap end address and switch from + * the msp to sps. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Set the control register to use + "msr control, r0 \n\t" // the process stack + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDMMC1_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); +void __attribute__((weak)) SAI2_IRQHandler(); +void __attribute__((weak)) QUADSPI_IRQHandler(); +void __attribute__((weak)) LPTIM1_IRQHandler(); +void __attribute__((weak)) CEC_IRQHandler(); +void __attribute__((weak)) I2C4_EV_IRQHandler(); +void __attribute__((weak)) I2C4_ER_IRQHandler(); +void __attribute__((weak)) SPDIF_RX_IRQHandler(); +void __attribute__((weak)) DSIHOST_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT0_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT1_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT2_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT3_IRQHandler(); +void __attribute__((weak)) SDMMC2_IRQHandler(); +void __attribute__((weak)) CAN3_TX_IRQHandler(); +void __attribute__((weak)) CAN3_RX0_IRQHandler(); +void __attribute__((weak)) CAN3_RX1_IRQHandler(); +void __attribute__((weak)) CAN3_SCE_IRQHandler(); +void __attribute__((weak)) JPEG_IRQHandler(); +void __attribute__((weak)) MDIOS_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDMMC1_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, + SAI2_IRQHandler, + QUADSPI_IRQHandler, + LPTIM1_IRQHandler, + CEC_IRQHandler, + I2C4_EV_IRQHandler, + I2C4_ER_IRQHandler, + SPDIF_RX_IRQHandler, + DSIHOST_IRQHandler, + DFSDM1_FLT0_IRQHandler, + DFSDM1_FLT1_IRQHandler, + DFSDM1_FLT2_IRQHandler, + DFSDM1_FLT3_IRQHandler, + SDMMC2_IRQHandler, + CAN3_TX_IRQHandler, + CAN3_RX0_IRQHandler, + CAN3_RX1_IRQHandler, + CAN3_SCE_IRQHandler, + JPEG_IRQHandler, + MDIOS_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDMMC1_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler +#pragma weak SAI2_IRQHandler = Default_Handler +#pragma weak QUADSPI_IRQHandler = Default_Handler +#pragma weak LPTIM1_IRQHandler = Default_Handler +#pragma weak CEC_IRQHandler = Default_Handler +#pragma weak I2C4_EV_IRQHandler = Default_Handler +#pragma weak I2C4_ER_IRQHandler = Default_Handler +#pragma weak SPDIF_RX_IRQHandler = Default_Handler +#pragma weak DSIHOST_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT0_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT1_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT2_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT3_IRQHandler = Default_Handler +#pragma weak SDMMC2_IRQHandler = Default_Handler +#pragma weak CAN3_TX_IRQHandler = Default_Handler +#pragma weak CAN3_RX0_IRQHandler = Default_Handler +#pragma weak CAN3_RX1_IRQHandler = Default_Handler +#pragma weak CAN3_SCE_IRQHandler = Default_Handler +#pragma weak JPEG_IRQHandler = Default_Handler +#pragma weak MDIOS_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f767zi_compute_unit/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f767zi_compute_unit/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..3224edc9ea21e7d207549879bb48cac84b71defe --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// stm32f7xx.h defines a few macros like __ICACHE_PRESENT, __DCACHE_PRESENT and +// includes core_cm7.h. Do not include core_cm7.h before. +#define STM32F767xx +#include "CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h" + +#if (__ICACHE_PRESENT != 1) || (__DCACHE_PRESENT != 1) +#error "Wrong include order" +#endif + +#include "CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h" + +#define RCC_SYNC() __DSB() // TODO: can this dsb be removed? + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f767zi_compute_unit/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_compute_unit/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c1f5a0d8095fdb2a9c10b2f496caf88a5ce468be --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/interfaces-impl/bsp.cpp @@ -0,0 +1,302 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "drivers/serial_stm32.h" +#include "drivers/stm32_sgm.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable gpios used by the ram + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | + RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | + RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN; + RCC_SYNC(); + + // On the compute unit with F767ZI, the SDRAM pins are: + // - PG8: FMC_SDCLK (sdram clock) + // - PB5: FMC_SDCKE1 (sdram bank 2 clock enable) + // - PB6: FMC_SDNE1 (sdram bank 2 chip enable) + // - PF0: FMC_A0 + // - PF1: FMC_A1 + // - PF2: FMC_A2 + // - PF3: FMC_A3 + // - PF4: FMC_A4 + // - PF5: FMC_A5 + // - PF12: FMC_A6 + // - PF13: FMC_A7 + // - PF14: FMC_A8 + // - PF15: FMC_A9 + // - PG0: FMC_A10 + // - PG1: FMC_A11 + // - PG2: FMC_A12 (used only by the 32MB ram, not by the 8MB one) + // - PD14: FMC_D0 + // - PD15: FMC_D1 + // - PD0: FMC_D2 + // - PD1: FMC_D3 + // - PE7: FMC_D4 + // - PE8: FMC_D5 + // - PE9: FMC_D6 + // - PE10: FMC_D7 + // - PE11: FMC_D8 + // - PE12: FMC_D9 + // - PE13: FMC_D10 + // - PE14: FMC_D11 + // - PE15: FMC_D12 + // - PD8: FMC_D13 + // - PD9: FMC_D14 + // - PD10: FMC_D15 + + // - PG4: FMC_BA0 + // - PG5: FMC_BA1 + // - PF11: FMC_SDNRAS + // - PG15: FMC_SDNCAS + // - PC0: FMC_SDNWE + // - PE0: FMC_NBL0 + // - PE1: FMC_NBL1 + + // All SDRAM GPIOs needs to be configured with alternate function 12 and + // maximum speed + + // WARNING: The current configuration is for the 8MB ram + + // Alternate functions + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc0ccc; + GPIOG->AFR[1] = 0xc000000c; + + // Mode + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a2a; + + // Speed (high speed for all, very high speed for SDRAM pins) + GPIOB->OSPEEDR = 0x00003c00; + GPIOC->OSPEEDR = 0x00000003; + GPIOD->OSPEEDR = 0xf03f000f; + GPIOE->OSPEEDR = 0xffffc00f; + GPIOF->OSPEEDR = 0xffc00fff; + GPIOG->OSPEEDR = 0xc0030f3f; + + // Since we'we un-configured PB3 and PB4 (by default they are SWO and NJRST) + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Enable the SDRAM controller clock + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // The SDRAM is a AS4C4M16SA-6TAN + // HCLK = 216MHz -> SDRAM clock = HCLK/2 = 133MHz + + // 1. Memory device features + FMC_Bank5_6->SDCR[0] = 0 // 0 delay after CAS latency + | FMC_SDCR1_RBURST // Enable read bursts + | FMC_SDCR1_SDCLK_1; // SDCLK = HCLK / 2 + FMC_Bank5_6->SDCR[1] = 0 // Write accesses allowed + | FMC_SDCR2_CAS_1 // 2 cycles CAS latency + | FMC_SDCR2_NB // 4 internal banks + | FMC_SDCR2_MWID_0 // 16 bit data bus + | FMC_SDCR2_NR_1 // 13 bit row address + // cppcheck-suppress duplicateExpression + | 0; // 8 bit column address + +// 2. Memory device timings +#ifdef SYSCLK_FREQ_216MHz + // SDRAM timings. One clock cycle is 9.26ns + FMC_Bank5_6->SDTR[0] = + (2 - 1) << FMC_SDTR1_TRP_Pos // 2 cycles TRP (18.52ns > 18ns) + | (7 - 1) << FMC_SDTR1_TRC_Pos; // 7 cycles TRC (64.82ns > 60ns) + FMC_Bank5_6->SDTR[1] = + (2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns) + | (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (min 2cc > 12ns) + | (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns) + | (7 - 1) << FMC_SDTR1_TXSR_Pos // 7 cycles TXSR (74.08ns > 61.5ns) + | (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (min 2cc > 12ns) +#else +#error No SDRAM timings for this clock +#endif + + // 3. Enable the bank 2 clock + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 4. Wait during command execution + delayUs(100); + + // 5. Issue a "Precharge All" command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 // Precharge all + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 6. Issue Auto-Refresh commands + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh + | FMC_SDCMR_CTB2 // Bank 2 + | (8 - 1) << FMC_SDCMR_NRFS_Pos; // 2 Auto-Refresh + sdramCommandWait(); + + // 7. Issue a Load Mode Register command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_2 /// Load mode register + | FMC_SDCMR_CTB2 // Bank 2 + | 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1 + sdramCommandWait(); + +// 8. Program the refresh rate (4K / 32ms) +// 64ms / 8192 = 7.8125us +#ifdef SYSCLK_FREQ_216MHz + // 7.8125us * 133MHz = 1039 - 20 = 1019 + FMC_Bank5_6->SDRTR = 1019 << FMC_SDRTR_COUNT_Pos; +#else +#error No SDRAM refresh timings for this clock +#endif +} + +void IRQbspInit() +{ + // Enable USART1 pins port + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; + + userLed1::mode(Mode::OUTPUT); + userLed2::mode(Mode::OUTPUT); + userLed3_1::mode(Mode::OUTPUT); + userLed3_2::mode(Mode::OUTPUT); + userLed4::mode(Mode::OUTPUT); + userSwitch::mode(Mode::INPUT); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial( + defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM + +#ifdef WITH_BACKUP_SRAM + // Print the reset reason + bootlog("Reset reson: "); + switch (SGM::instance().lastResetReason()) + { + case ResetReason::RST_LOW_PWR: + bootlog("low power\n"); + break; + case ResetReason::RST_WINDOW_WDG: + bootlog("window watchdog\n"); + break; + case ResetReason::RST_INDEPENDENT_WDG: + bootlog("indeendent watchdog\n"); + break; + case ResetReason::RST_SW: + bootlog("software reset\n"); + break; + case ResetReason::RST_POWER_ON: + bootlog("power on\n"); + break; + case ResetReason::RST_PIN: + bootlog("reset pin\n"); + break; + case ResetReason::RST_UNKNOWN: + bootlog("unknown\n"); + break; + } +#endif // WITH_BACKUP_SRAM +} + +// +// Shutdown and reboot +// + +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + for (;;) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_compute_unit/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_compute_unit/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..70ed88d1536e9135d58c1ae126cb0e02d759f20d --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/interfaces-impl/bsp_impl.h @@ -0,0 +1,116 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*************************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ***************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * Board pin definition + */ +typedef Gpio<GPIOB_BASE, 7> userLed1; +typedef Gpio<GPIOE_BASE, 3> userLed2; +typedef Gpio<GPIOC_BASE, 13> userLed3_1; +typedef Gpio<GPIOG_BASE, 9> userLed3_2; +typedef Gpio<GPIOC_BASE, 2> userLed4; +typedef Gpio<GPIOB_BASE, 2> userSwitch; + +inline void ledOn() +{ + userLed1::high(); + userLed2::high(); + userLed3_1::high(); + userLed3_2::high(); + userLed4::high(); +} + +inline void ledOff() +{ + userLed1::low(); + userLed2::low(); + userLed3_1::low(); + userLed3_2::low(); + userLed4::low(); +} + +inline void led1On() { userLed1::high(); } + +inline void led1Off() { userLed1::low(); } + +inline void led2On() { userLed2::high(); } + +inline void led2Off() { userLed2::low(); } + +inline void led3On() +{ + userLed3_1::high(); + userLed3_2::high(); +} + +inline void led3Off() +{ + userLed3_1::low(); + userLed3_2::low(); +} + +/** + * Polls the SD card sense GPIO. + * + * This board has no SD card whatsoever, but a card can be connected to the + * following GPIOs: + * TODO: never tested + * + * \return true. As there's no SD card sense switch, let's pretend that + * the card is present. + */ +inline bool sdCardSense() { return true; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f767zi_compute_unit/stm32_2m+16m_xram.ld b/src/bsps/stm32f767zi_compute_unit/stm32_2m+16m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..5b3545abd6f3007072b8ff00a978242d74503d79 --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/stm32_2m+16m_xram.ld @@ -0,0 +1,190 @@ +/* + * C++ enabled linker script for stm32f769ni (2M FLASH, 512K RAM, 16MB XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the external 16MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0000000 + 16M; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 16M + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to xram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to xram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_compute_unit/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_compute_unit/stm32_2m+384k_ram.ld new file mode 100644 index 0000000000000000000000000000000000000000..497bd5198760b9637c774bf3900fd9dfbc01a2b2 --- /dev/null +++ b/src/bsps/stm32f767zi_compute_unit/stm32_2m+384k_ram.ld @@ -0,0 +1,189 @@ +/* + * C++ enabled linker script for stm32f767zi (2M FLASH, 512K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the internal RAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap to the end of SRAM2 */ +_heap_end = 0x20000000 + 512K; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to sram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > sram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to sram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > sram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_death_stack_v4/config/board_options.cmake b/src/bsps/stm32f767zi_death_stack_v4/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..9445805546567654219f69c83c2359d4304ce391 --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/config/board_options.cmake @@ -0,0 +1,106 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f767zi_death_stack_v4) +set(ARCH_NAME cortexM7_stm32f7) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file and linker script +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+16m_xram.ld) + +# Enables the initialization of the external 16MB SDRAM memory +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency (HSE_VALUE is the xtal on board, fixed) +set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM7_STM32F7 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c + ${KPATH}/arch/common/core/cache_cortexMx.cpp + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f767zi_death_stack_v4/config/board_settings.h b/src/bsps/stm32f767zi_death_stack_v4/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..0ea02bc3e37eef56048b827f54480a53f16e5d6e --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/config/board_settings.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#pragma once + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA +// #define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +#define SD_ONE_BIT_DATABUS +#define SD_SDMMC 1 // Select either SDMMC1 or SDMMC2 + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_death_stack_v4/config/miosix_settings.h b/src/bsps/stm32f767zi_death_stack_v4/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..5fe66bf6c7986666ec94c8c52588f3c5d8cfef58 --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_death_stack_v4/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_death_stack_v4/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8374c9de6bf6f2dbdfa94c9385f140e5bf82490f --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/core/stage_1_boot.cpp @@ -0,0 +1,505 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#include <string.h> + +#include "core/cache_cortexMx.h" +#include "core/interrupts.h" //For the unexpected interrupt call +#include "core/interrupts_cortexMx.h" +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f767 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M7 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + miosix::IRQconfigureCache((const unsigned int *)0xd0000000, + 8 * 1024 * 1024); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + /** + * SystemInit() is called *before* initializing .data and zeroing .bss + * Despite all startup files provided by ST do the opposite, there are three + * good reasons to do so: + * 1. First, the CMSIS specifications say that SystemInit() must not access + * global variables, so it is actually possible to call it before + * 2. Second, when running Miosix with the xram linker scripts .data and + * .bss are placed in the external RAM, so we *must* call SystemInit(), + * which enables xram, before touching .data and .bss + * 3. Third, this is a performance improvement since the loops that + * initialize .data and zeros .bss now run with the CPU at full speed + * instead of 8MHz + */ + SystemInit(); + +/** + * ST does not provide code to initialize the SDRAM at boot. + * Put after SystemInit() as SDRAM is timing-sensitive and needs the full + * clock speed. + */ +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Load into the program stack pointer the heap end address and switch from + * the msp to sps. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Set the control register to use + "msr control, r0 \n\t" // the process stack + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDMMC1_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); +void __attribute__((weak)) SAI2_IRQHandler(); +void __attribute__((weak)) QUADSPI_IRQHandler(); +void __attribute__((weak)) LPTIM1_IRQHandler(); +void __attribute__((weak)) CEC_IRQHandler(); +void __attribute__((weak)) I2C4_EV_IRQHandler(); +void __attribute__((weak)) I2C4_ER_IRQHandler(); +void __attribute__((weak)) SPDIF_RX_IRQHandler(); +void __attribute__((weak)) DSIHOST_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT0_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT1_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT2_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT3_IRQHandler(); +void __attribute__((weak)) SDMMC2_IRQHandler(); +void __attribute__((weak)) CAN3_TX_IRQHandler(); +void __attribute__((weak)) CAN3_RX0_IRQHandler(); +void __attribute__((weak)) CAN3_RX1_IRQHandler(); +void __attribute__((weak)) CAN3_SCE_IRQHandler(); +void __attribute__((weak)) JPEG_IRQHandler(); +void __attribute__((weak)) MDIOS_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDMMC1_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, + SAI2_IRQHandler, + QUADSPI_IRQHandler, + LPTIM1_IRQHandler, + CEC_IRQHandler, + I2C4_EV_IRQHandler, + I2C4_ER_IRQHandler, + SPDIF_RX_IRQHandler, + DSIHOST_IRQHandler, + DFSDM1_FLT0_IRQHandler, + DFSDM1_FLT1_IRQHandler, + DFSDM1_FLT2_IRQHandler, + DFSDM1_FLT3_IRQHandler, + SDMMC2_IRQHandler, + CAN3_TX_IRQHandler, + CAN3_RX0_IRQHandler, + CAN3_RX1_IRQHandler, + CAN3_SCE_IRQHandler, + JPEG_IRQHandler, + MDIOS_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDMMC1_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler +#pragma weak SAI2_IRQHandler = Default_Handler +#pragma weak QUADSPI_IRQHandler = Default_Handler +#pragma weak LPTIM1_IRQHandler = Default_Handler +#pragma weak CEC_IRQHandler = Default_Handler +#pragma weak I2C4_EV_IRQHandler = Default_Handler +#pragma weak I2C4_ER_IRQHandler = Default_Handler +#pragma weak SPDIF_RX_IRQHandler = Default_Handler +#pragma weak DSIHOST_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT0_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT1_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT2_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT3_IRQHandler = Default_Handler +#pragma weak SDMMC2_IRQHandler = Default_Handler +#pragma weak CAN3_TX_IRQHandler = Default_Handler +#pragma weak CAN3_RX0_IRQHandler = Default_Handler +#pragma weak CAN3_RX1_IRQHandler = Default_Handler +#pragma weak CAN3_SCE_IRQHandler = Default_Handler +#pragma weak JPEG_IRQHandler = Default_Handler +#pragma weak MDIOS_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..d2d82f50a19d084d8d41e48b04da578f14f74a5c --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// stm32f7xx.h defines a few macros like __ICACHE_PRESENT, __DCACHE_PRESENT and +// includes core_cm7.h. Do not include core_cm7.h before. +#define STM32F767xx +#include "CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h" + +#if (__ICACHE_PRESENT != 1) || (__DCACHE_PRESENT != 1) +#error "Wrong include order" +#endif + +#include "CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h" + +#define RCC_SYNC() __DSB() // TODO: can this dsb be removed? + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..557775f4156e8a38caba214bb1acb568e8f2b154 --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/bsp.cpp @@ -0,0 +1,419 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "drivers/serial_stm32.h" +#include "drivers/stm32_sgm.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable gpios used by the ram + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | + RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | + RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN; + RCC_SYNC(); + + // On the compute unit with F767ZI, the SDRAM pins are: + // - PG8: FMC_SDCLK (sdram clock) + // - PB5: FMC_SDCKE1 (sdram bank 2 clock enable) + // - PB6: FMC_SDNE1 (sdram bank 2 chip enable) + // - PF0: FMC_A0 + // - PF1: FMC_A1 + // - PF2: FMC_A2 + // - PF3: FMC_A3 + // - PF4: FMC_A4 + // - PF5: FMC_A5 + // - PF12: FMC_A6 + // - PF13: FMC_A7 + // - PF14: FMC_A8 + // - PF15: FMC_A9 + // - PG0: FMC_A10 + // - PG1: FMC_A11 + // - PG2: FMC_A12 (used only by the 32MB ram, not by the 8MB one) + // - PD14: FMC_D0 + // - PD15: FMC_D1 + // - PD0: FMC_D2 + // - PD1: FMC_D3 + // - PE7: FMC_D4 + // - PE8: FMC_D5 + // - PE9: FMC_D6 + // - PE10: FMC_D7 + // - PE11: FMC_D8 + // - PE12: FMC_D9 + // - PE13: FMC_D10 + // - PE14: FMC_D11 + // - PE15: FMC_D12 + // - PD8: FMC_D13 + // - PD9: FMC_D14 + // - PD10: FMC_D15 + + // - PG4: FMC_BA0 + // - PG5: FMC_BA1 + // - PF11: FMC_SDNRAS + // - PG15: FMC_SDNCAS + // - PC0: FMC_SDNWE + // - PE0: FMC_NBL0 + // - PE1: FMC_NBL1 + + // All SDRAM GPIOs needs to be configured with alternate function 12 and + // maximum speed + + // WARNING: The current configuration is for the 8MB ram + + // Alternate functions + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc0ccc; + GPIOG->AFR[1] = 0xc000000c; + + // Mode + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a2a; + + // Speed (high speed for all, very high speed for SDRAM pins) + GPIOB->OSPEEDR = 0x00003c00; + GPIOC->OSPEEDR = 0x00000003; + GPIOD->OSPEEDR = 0xf03f000f; + GPIOE->OSPEEDR = 0xffffc00f; + GPIOF->OSPEEDR = 0xffc00fff; + GPIOG->OSPEEDR = 0xc0030f3f; + + // Since we'we un-configured PB3 and PB4 (by default they are SWO and NJRST) + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Enable the SDRAM controller clock + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // The SDRAM is a AS4C4M16SA-6TAN + // HCLK = 216MHz -> SDRAM clock = HCLK/2 = 133MHz + + // 1. Memory device features + FMC_Bank5_6->SDCR[0] = 0 // 0 delay after CAS latency + | FMC_SDCR1_RBURST // Enable read bursts + | FMC_SDCR1_SDCLK_1; // SDCLK = HCLK / 2 + FMC_Bank5_6->SDCR[1] = 0 // Write accesses allowed + | FMC_SDCR2_CAS_1 // 2 cycles CAS latency + | FMC_SDCR2_NB // 4 internal banks + | FMC_SDCR2_MWID_0 // 16 bit data bus + | FMC_SDCR2_NR_1 // 13 bit row address + // cppcheck-suppress duplicateExpression + | 0; // 8 bit column address + +// 2. Memory device timings +#ifdef SYSCLK_FREQ_216MHz + // SDRAM timings. One clock cycle is 9.26ns + FMC_Bank5_6->SDTR[0] = + (2 - 1) << FMC_SDTR1_TRP_Pos // 2 cycles TRP (18.52ns > 18ns) + | (7 - 1) << FMC_SDTR1_TRC_Pos; // 7 cycles TRC (64.82ns > 60ns) + FMC_Bank5_6->SDTR[1] = + (2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns) + | (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (min 2cc > 12ns) + | (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns) + | (7 - 1) << FMC_SDTR1_TXSR_Pos // 7 cycles TXSR (74.08ns > 61.5ns) + | (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (min 2cc > 12ns) +#else +#error No SDRAM timings for this clock +#endif + + // 3. Enable the bank 2 clock + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 4. Wait during command execution + delayUs(100); + + // 5. Issue a "Precharge All" command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 // Precharge all + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 6. Issue Auto-Refresh commands + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh + | FMC_SDCMR_CTB2 // Bank 2 + | (8 - 1) << FMC_SDCMR_NRFS_Pos; // 2 Auto-Refresh + sdramCommandWait(); + + // 7. Issue a Load Mode Register command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_2 /// Load mode register + | FMC_SDCMR_CTB2 // Bank 2 + | 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1 + sdramCommandWait(); + +// 8. Program the refresh rate (4K / 32ms) +// 64ms / 8192 = 7.8125us +#ifdef SYSCLK_FREQ_216MHz + // 7.8125us * 133MHz = 1039 - 20 = 1019 + FMC_Bank5_6->SDRTR = 1019 << FMC_SDRTR_COUNT_Pos; +#else +#error No SDRAM refresh timings for this clock +#endif +} + +void IRQbspInit() +{ + // Enable USART1 pins port + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; + + userLed1::mode(Mode::OUTPUT); + userLed2::mode(Mode::OUTPUT); + userLed3_1::mode(Mode::OUTPUT); + userLed3_2::mode(Mode::OUTPUT); + userLed4::mode(Mode::OUTPUT); + userSwitch::mode(Mode::INPUT); + + using namespace interfaces; + spi1::sck::mode(Mode::ALTERNATE); + spi1::sck::alternateFunction(5); + spi1::miso::mode(Mode::ALTERNATE); + spi1::miso::alternateFunction(5); + spi1::mosi::mode(Mode::ALTERNATE); + spi1::mosi::alternateFunction(5); + + spi3::sck::mode(Mode::ALTERNATE); + spi3::sck::alternateFunction(6); + spi3::miso::mode(Mode::ALTERNATE); + spi3::miso::alternateFunction(6); + spi3::mosi::mode(Mode::ALTERNATE); + spi3::mosi::alternateFunction(5); + + spi4::sck::mode(Mode::ALTERNATE); + spi4::sck::alternateFunction(5); + spi4::miso::mode(Mode::ALTERNATE); + spi4::miso::alternateFunction(5); + spi4::mosi::mode(Mode::ALTERNATE); + spi4::mosi::alternateFunction(5); + + spi6::sck::mode(Mode::ALTERNATE); + spi6::sck::alternateFunction(5); + spi6::miso::mode(Mode::ALTERNATE); + spi6::miso::alternateFunction(5); + spi6::mosi::mode(Mode::ALTERNATE); + spi6::mosi::alternateFunction(5); + + i2c1::sda::mode(Mode::ALTERNATE); + i2c1::sda::alternateFunction(4); + i2c1::scl::mode(Mode::ALTERNATE); + i2c1::scl::alternateFunction(4); + + can1::rx::mode(Mode::ALTERNATE); + can1::rx::alternateFunction(9); + can1::tx::mode(Mode::ALTERNATE); + can1::tx::alternateFunction(9); + + can2::rx::mode(Mode::ALTERNATE); + can2::rx::alternateFunction(9); + can2::tx::mode(Mode::ALTERNATE); + can2::tx::alternateFunction(9); + + usart1::tx::mode(Mode::ALTERNATE); + usart1::tx::alternateFunction(7); + usart1::rx::mode(Mode::ALTERNATE); + usart1::rx::alternateFunction(7); + + usart2::tx::mode(Mode::ALTERNATE); + usart2::tx::alternateFunction(7); + usart2::rx::mode(Mode::ALTERNATE); + usart2::rx::alternateFunction(7); + + uart4::tx::mode(Mode::ALTERNATE); + uart4::tx::alternateFunction(8); + uart4::rx::mode(Mode::ALTERNATE); + uart4::rx::alternateFunction(8); + + using namespace timers; + tim3ch1::mode(Mode::ALTERNATE); + tim3ch1::alternateFunction(2); + tim3ch2::mode(Mode::ALTERNATE); + tim3ch2::alternateFunction(2); + tim1ch1::mode(Mode::ALTERNATE); + tim1ch1::alternateFunction(1); + tim12ch2::mode(Mode::ALTERNATE); + tim12ch2::alternateFunction(9); + + using namespace sensors; + LSM6DSRX::cs::mode(Mode::OUTPUT); + LSM6DSRX::cs::getPin().high(); + LSM6DSRX::interrupt1::mode(Mode::INPUT); + LSM6DSRX::interrupt2::mode(Mode::INPUT); + + H3LIS331DL::cs::mode(Mode::OUTPUT); + H3LIS331DL::cs::getPin().high(); + + LIS2MDL::cs::mode(Mode::OUTPUT); + LIS2MDL::cs::getPin().high(); + + LPS22DF::cs::mode(Mode::OUTPUT); + LPS22DF::cs::getPin().high(); + LPS22DF::interrupt::mode(Mode::INPUT); + + GPS::cs::mode(Mode::OUTPUT); + GPS::cs::getPin().high(); + + VN100::cs::mode(Mode::OUTPUT); + VN100::cs::getPin().high(); + + ADS131::cs::mode(Mode::OUTPUT); + ADS131::cs::getPin().high(); + + using namespace radio; + cs::mode(Mode::OUTPUT); + cs::getPin().high(); + dio0::mode(Mode::INPUT); + dio1::mode(Mode::INPUT); + dio3::mode(Mode::INPUT); + tx_enable::mode(Mode::OUTPUT); + rx_enable::mode(Mode::OUTPUT); + + using namespace gpios; + cut_trigger::mode(Mode::OUTPUT); + cut_sense::mode(Mode::INPUT); + exp_enable::mode(Mode::OUTPUT); + // status_led::mode(Mode::OUTPUT); + camera_enable::mode(Mode::OUTPUT); + liftoff_detach::mode(Mode::INPUT); + nosecone_detach::mode(Mode::INPUT); + exp_sense::mode(Mode::INPUT); + + using namespace actuators; + buzzer::mode(Mode::ALTERNATE_PULL_DOWN); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial( + defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM + +#ifdef WITH_BACKUP_SRAM + // Print the reset reason + bootlog("Reset reson: "); + switch (SGM::instance().lastResetReason()) + { + case ResetReason::RST_LOW_PWR: + bootlog("low power\n"); + break; + case ResetReason::RST_WINDOW_WDG: + bootlog("window watchdog\n"); + break; + case ResetReason::RST_INDEPENDENT_WDG: + bootlog("indeendent watchdog\n"); + break; + case ResetReason::RST_SW: + bootlog("software reset\n"); + break; + case ResetReason::RST_POWER_ON: + bootlog("power on\n"); + break; + case ResetReason::RST_PIN: + bootlog("reset pin\n"); + break; + case ResetReason::RST_UNKNOWN: + bootlog("unknown\n"); + break; + } +#endif // WITH_BACKUP_SRAM +} + +// +// Shutdown and reboot +// + +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + for (;;) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..f39efd8250f1cbc0a00f4150a43399d815dbe9d5 --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/bsp_impl.h @@ -0,0 +1,116 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +/*************************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ***************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * Board pin definition + */ +typedef Gpio<GPIOB_BASE, 7> userLed1; +typedef Gpio<GPIOE_BASE, 3> userLed2; +typedef Gpio<GPIOC_BASE, 13> userLed3_1; +typedef Gpio<GPIOG_BASE, 9> userLed3_2; +typedef Gpio<GPIOC_BASE, 2> userLed4; +typedef Gpio<GPIOB_BASE, 2> userSwitch; + +inline void ledOn() +{ + userLed1::high(); + userLed2::high(); + userLed3_1::high(); + userLed3_2::high(); + userLed4::high(); +} + +inline void ledOff() +{ + userLed1::low(); + userLed2::low(); + userLed3_1::low(); + userLed3_2::low(); + userLed4::low(); +} + +inline void led1On() { userLed1::high(); } + +inline void led1Off() { userLed1::low(); } + +inline void led2On() { userLed2::high(); } + +inline void led2Off() { userLed2::low(); } + +inline void led3On() +{ + userLed3_1::high(); + userLed3_2::high(); +} + +inline void led3Off() +{ + userLed3_1::low(); + userLed3_2::low(); +} + +/** + * Polls the SD card sense GPIO. + * + * This board has no SD card whatsoever, but a card can be connected to the + * following GPIOs: + * TODO: never tested + * + * \return true. As there's no SD card sense switch, let's pretend that + * the card is present. + */ +inline bool sdCardSense() { return true; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/hwmapping.h b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..8b6166f3bddc8c7bd6f119f137f48d17bb4b8d32 --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/interfaces-impl/hwmapping.h @@ -0,0 +1,221 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Matteo Pignataro + * + * 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. + */ + +#pragma once + +#include "interfaces/gpio.h" + +namespace miosix +{ +namespace interfaces +{ +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +namespace spi3 +{ +using sck = Gpio<GPIOB_BASE, 3>; +using miso = Gpio<GPIOB_BASE, 4>; +using mosi = Gpio<GPIOD_BASE, 6>; +} // namespace spi3 + +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +namespace spi6 +{ +using sck = Gpio<GPIOG_BASE, 13>; +using miso = Gpio<GPIOG_BASE, 12>; +using mosi = Gpio<GPIOG_BASE, 14>; +} // namespace spi6 + +namespace i2c1 +{ +using sda = Gpio<GPIOB_BASE, 9>; +using scl = Gpio<GPIOB_BASE, 8>; +} // namespace i2c1 + +namespace can1 +{ +using rx = Gpio<GPIOA_BASE, 11>; +using tx = Gpio<GPIOA_BASE, 12>; +} // namespace can1 + +namespace can2 +{ +using rx = Gpio<GPIOB_BASE, 12>; +using tx = Gpio<GPIOB_BASE, 13>; +} // namespace can2 + +namespace usart1 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace usart1 + +namespace usart2 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace usart2 + +namespace uart4 +{ +using tx = Gpio<GPIOA_BASE, 0>; +using rx = Gpio<GPIOA_BASE, 1>; +} // namespace uart4 + +namespace timers +{ +using tim3ch1 = Gpio<GPIOC_BASE, 6>; // Airbrakes servo - Servo1 Payload +using tim3ch2 = Gpio<GPIOC_BASE, 7>; // Auxiliary - Servo2 Payload +using tim1ch1 = Gpio<GPIOA_BASE, 8>; // Buzzer +using tim12ch2 = Gpio<GPIOB_BASE, 15>; // Expulsion +} // namespace timers + +} // namespace interfaces + +namespace sensors +{ +namespace LSM6DSRX +{ +using sck = interfaces::spi1::sck; +using miso = interfaces::spi1::miso; +using mosi = interfaces::spi1::mosi; +using cs = Gpio<GPIOC_BASE, 4>; +using interrupt1 = Gpio<GPIOD_BASE, 13>; +using interrupt2 = Gpio<GPIOG_BASE, 7>; +} // namespace LSM6DSRX + +namespace H3LIS331DL +{ +using sck = interfaces::spi3::sck; +using miso = interfaces::spi3::miso; +using mosi = interfaces::spi3::mosi; +using cs = Gpio<GPIOD_BASE, 3>; +} // namespace H3LIS331DL + +namespace LIS2MDL +{ +using sck = interfaces::spi3::sck; +using miso = interfaces::spi3::miso; +using mosi = interfaces::spi3::mosi; +using cs = Gpio<GPIOD_BASE, 5>; +} // namespace LIS2MDL + +namespace LPS22DF +{ +using sck = interfaces::spi3::sck; +using miso = interfaces::spi3::miso; +using mosi = interfaces::spi3::mosi; +using cs = Gpio<GPIOD_BASE, 7>; +using interrupt = Gpio<GPIOB_BASE, 11>; +} // namespace LPS22DF + +namespace GPS +{ +using sck = interfaces::spi4::sck; +using miso = interfaces::spi4::miso; +using mosi = interfaces::spi4::mosi; +using cs = Gpio<GPIOE_BASE, 4>; +} // namespace GPS + +namespace VN100 +{ +using sck = interfaces::spi4::sck; +using miso = interfaces::spi4::miso; +using mosi = interfaces::spi4::mosi; +using cs = Gpio<GPIOB_BASE, 14>; +} // namespace VN100 + +namespace VN100_SERIAL +{ +using tx = interfaces::uart4::tx; +using rx = interfaces::uart4::rx; +} // namespace VN100_SERIAL + +namespace ADS131 +{ +using sck = interfaces::spi4::sck; +using miso = interfaces::spi4::miso; +using mosi = interfaces::spi4::mosi; +using cs = Gpio<GPIOG_BASE, 10>; +} // namespace ADS131 + +namespace LPS28DFW_1 +{ +using sda = interfaces::i2c1::sda; +using scl = interfaces::i2c1::scl; +} // namespace LPS28DFW_1 + +namespace LPS28DFW_2 +{ +using sda = interfaces::i2c1::sda; +using scl = interfaces::i2c1::scl; +} // namespace LPS28DFW_2 + +} // namespace sensors + +namespace radio +{ +using sck = interfaces::spi6::sck; +using miso = interfaces::spi6::miso; +using mosi = interfaces::spi6::mosi; +using cs = Gpio<GPIOG_BASE, 11>; +using dio0 = Gpio<GPIOC_BASE, 3>; +using dio1 = Gpio<GPIOD_BASE, 4>; +using dio3 = Gpio<GPIOC_BASE, 5>; +using rx_enable = Gpio<GPIOB_BASE, 0>; +using tx_enable = Gpio<GPIOC_BASE, 1>; +} // namespace radio + +namespace actuators +{ +using airbrakes = interfaces::timers::tim3ch1; +using expulsion = interfaces::timers::tim12ch2; +using buzzer = interfaces::timers::tim1ch1; +using parafoil_servo1 = interfaces::timers::tim3ch1; +using parafoil_servo2 = interfaces::timers::tim3ch2; +} // namespace actuators + +namespace gpios +{ +using cut_trigger = Gpio<GPIOA_BASE, 15>; +using cut_sense = Gpio<GPIOD_BASE, 12>; +using exp_enable = Gpio<GPIOB_BASE, 1>; +using status_led = Gpio<GPIOA_BASE, 14>; +using camera_enable = Gpio<GPIOA_BASE, 12>; +using liftoff_detach = Gpio<GPIOA_BASE, 11>; +using nosecone_detach = Gpio<GPIOA_BASE, 4>; +using exp_sense = Gpio<GPIOG_BASE, 6>; + +} // namespace gpios + +} // namespace miosix \ No newline at end of file diff --git a/src/bsps/stm32f767zi_death_stack_v4/stm32_2m+16m_xram.ld b/src/bsps/stm32f767zi_death_stack_v4/stm32_2m+16m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..5b3545abd6f3007072b8ff00a978242d74503d79 --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/stm32_2m+16m_xram.ld @@ -0,0 +1,190 @@ +/* + * C++ enabled linker script for stm32f769ni (2M FLASH, 512K RAM, 16MB XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the external 16MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0000000 + 16M; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 16M + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to xram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to xram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_death_stack_v4/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_death_stack_v4/stm32_2m+384k_ram.ld new file mode 100644 index 0000000000000000000000000000000000000000..497bd5198760b9637c774bf3900fd9dfbc01a2b2 --- /dev/null +++ b/src/bsps/stm32f767zi_death_stack_v4/stm32_2m+384k_ram.ld @@ -0,0 +1,189 @@ +/* + * C++ enabled linker script for stm32f767zi (2M FLASH, 512K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the internal RAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap to the end of SRAM2 */ +_heap_end = 0x20000000 + 512K; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to sram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > sram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to sram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > sram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_gemini_gs/config/board_options.cmake b/src/bsps/stm32f767zi_gemini_gs/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..259876fc5eb9657fd18d6dc79447c394da01dd2b --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/config/board_options.cmake @@ -0,0 +1,106 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f767zi_gemini_gs) +set(ARCH_NAME cortexM7_stm32f7) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file and linker script +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+16m_xram.ld) + +# Enables the initialization of the external 16MB SDRAM memory +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency (HSE_VALUE is the xtal on board, fixed) +set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM7_STM32F7 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c + ${KPATH}/arch/common/core/cache_cortexMx.cpp + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f767zi_gemini_gs/config/board_settings.h b/src/bsps/stm32f767zi_gemini_gs/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..168493854829a416608963acfba5a7b22f644ad0 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/config/board_settings.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#pragma once + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA +// #define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +// #define SD_ONE_BIT_DATABUS +#define SD_SDMMC 1 // Select either SDMMC1 or SDMMC2 + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_gemini_gs/config/miosix_settings.h b/src/bsps/stm32f767zi_gemini_gs/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..1b49a8e7ca34bfda7db31258fda251eb142e34f1 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_gemini_gs/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_gemini_gs/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc96d3b51b35ec422f8880304fc319aaf20ab8e0 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/core/stage_1_boot.cpp @@ -0,0 +1,505 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#include <string.h> + +#include "core/cache_cortexMx.h" +#include "core/interrupts.h" //For the unexpected interrupt call +#include "core/interrupts_cortexMx.h" +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f767 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M7 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + miosix::IRQconfigureCache((const unsigned int *)0xd0000000, + 8 * 1024 * 1024); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + /** + * SystemInit() is called *before* initializing .data and zeroing .bss + * Despite all startup files provided by ST do the opposite, there are three + * good reasons to do so: + * 1. First, the CMSIS specifications say that SystemInit() must not access + * global variables, so it is actually possible to call it before + * 2. Second, when running Miosix with the xram linker scripts .data and + * .bss are placed in the external RAM, so we *must* call SystemInit(), + * which enables xram, before touching .data and .bss + * 3. Third, this is a performance improvement since the loops that + * initialize .data and zeros .bss now run with the CPU at full speed + * instead of 8MHz + */ + SystemInit(); + +/** + * ST does not provide code to initialize the SDRAM at boot. + * Put after SystemInit() as SDRAM is timing-sensitive and needs the full + * clock speed. + */ +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Load into the program stack pointer the heap end address and switch from + * the msp to sps. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Set the control register to use + "msr control, r0 \n\t" // the process stack + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDMMC1_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); +void __attribute__((weak)) SAI2_IRQHandler(); +void __attribute__((weak)) QUADSPI_IRQHandler(); +void __attribute__((weak)) LPTIM1_IRQHandler(); +void __attribute__((weak)) CEC_IRQHandler(); +void __attribute__((weak)) I2C4_EV_IRQHandler(); +void __attribute__((weak)) I2C4_ER_IRQHandler(); +void __attribute__((weak)) SPDIF_RX_IRQHandler(); +void __attribute__((weak)) DSIHOST_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT0_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT1_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT2_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT3_IRQHandler(); +void __attribute__((weak)) SDMMC2_IRQHandler(); +void __attribute__((weak)) CAN3_TX_IRQHandler(); +void __attribute__((weak)) CAN3_RX0_IRQHandler(); +void __attribute__((weak)) CAN3_RX1_IRQHandler(); +void __attribute__((weak)) CAN3_SCE_IRQHandler(); +void __attribute__((weak)) JPEG_IRQHandler(); +void __attribute__((weak)) MDIOS_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDMMC1_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, + SAI2_IRQHandler, + QUADSPI_IRQHandler, + LPTIM1_IRQHandler, + CEC_IRQHandler, + I2C4_EV_IRQHandler, + I2C4_ER_IRQHandler, + SPDIF_RX_IRQHandler, + DSIHOST_IRQHandler, + DFSDM1_FLT0_IRQHandler, + DFSDM1_FLT1_IRQHandler, + DFSDM1_FLT2_IRQHandler, + DFSDM1_FLT3_IRQHandler, + SDMMC2_IRQHandler, + CAN3_TX_IRQHandler, + CAN3_RX0_IRQHandler, + CAN3_RX1_IRQHandler, + CAN3_SCE_IRQHandler, + JPEG_IRQHandler, + MDIOS_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDMMC1_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler +#pragma weak SAI2_IRQHandler = Default_Handler +#pragma weak QUADSPI_IRQHandler = Default_Handler +#pragma weak LPTIM1_IRQHandler = Default_Handler +#pragma weak CEC_IRQHandler = Default_Handler +#pragma weak I2C4_EV_IRQHandler = Default_Handler +#pragma weak I2C4_ER_IRQHandler = Default_Handler +#pragma weak SPDIF_RX_IRQHandler = Default_Handler +#pragma weak DSIHOST_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT0_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT1_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT2_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT3_IRQHandler = Default_Handler +#pragma weak SDMMC2_IRQHandler = Default_Handler +#pragma weak CAN3_TX_IRQHandler = Default_Handler +#pragma weak CAN3_RX0_IRQHandler = Default_Handler +#pragma weak CAN3_RX1_IRQHandler = Default_Handler +#pragma weak CAN3_SCE_IRQHandler = Default_Handler +#pragma weak JPEG_IRQHandler = Default_Handler +#pragma weak MDIOS_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..662ddc6ec073e9e8839d8a97151dfeab8e67286b --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// stm32f7xx.h defines a few macros like __ICACHE_PRESENT, __DCACHE_PRESENT and +// includes core_cm7.h. Do not include core_cm7.h before. +#define STM32F767xx +#include "CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h" + +#if (__ICACHE_PRESENT != 1) || (__DCACHE_PRESENT != 1) +#error "Wrong include order" +#endif + +#include "CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h" + +#define RCC_SYNC() __DSB() // TODO: can this dsb be removed? + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f1b9d7daf7e1ef66a426246697b8eccabdb47589 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/bsp.cpp @@ -0,0 +1,355 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "drivers/serial_stm32.h" +#include "drivers/stm32_sgm.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "hwmapping.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable gpios used by the ram + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN | + RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOEEN | + RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOGEN; + RCC_SYNC(); + + // On the compute unit with F767ZI, the SDRAM pins are: + // - PG8: FMC_SDCLK (sdram clock) + // - PB5: FMC_SDCKE1 (sdram bank 2 clock enable) + // - PB6: FMC_SDNE1 (sdram bank 2 chip enable) + // - PF0: FMC_A0 + // - PF1: FMC_A1 + // - PF2: FMC_A2 + // - PF3: FMC_A3 + // - PF4: FMC_A4 + // - PF5: FMC_A5 + // - PF12: FMC_A6 + // - PF13: FMC_A7 + // - PF14: FMC_A8 + // - PF15: FMC_A9 + // - PG0: FMC_A10 + // - PG1: FMC_A11 + // - PG2: FMC_A12 (used only by the 32MB ram, not by the 8MB one) + // - PD14: FMC_D0 + // - PD15: FMC_D1 + // - PD0: FMC_D2 + // - PD1: FMC_D3 + // - PE7: FMC_D4 + // - PE8: FMC_D5 + // - PE9: FMC_D6 + // - PE10: FMC_D7 + // - PE11: FMC_D8 + // - PE12: FMC_D9 + // - PE13: FMC_D10 + // - PE14: FMC_D11 + // - PE15: FMC_D12 + // - PD8: FMC_D13 + // - PD9: FMC_D14 + // - PD10: FMC_D15 + + // - PG4: FMC_BA0 + // - PG5: FMC_BA1 + // - PF11: FMC_SDNRAS + // - PG15: FMC_SDNCAS + // - PC0: FMC_SDNWE + // - PE0: FMC_NBL0 + // - PE1: FMC_NBL1 + + // All SDRAM GPIOs needs to be configured with alternate function 12 and + // maximum speed + + // WARNING: The current configuration is for the 8MB ram + + // Alternate functions + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc0ccc; + GPIOG->AFR[1] = 0xc000000c; + + // Mode + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a2a; + + // Speed (high speed for all, very high speed for SDRAM pins) + GPIOB->OSPEEDR = 0x00003c00; + GPIOC->OSPEEDR = 0x00000003; + GPIOD->OSPEEDR = 0xf03f000f; + GPIOE->OSPEEDR = 0xffffc00f; + GPIOF->OSPEEDR = 0xffc00fff; + GPIOG->OSPEEDR = 0xc0030f3f; + + // Since we'we un-configured PB3 and PB4 (by default they are SWO and NJRST) + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Enable the SDRAM controller clock + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // The SDRAM is a AS4C4M16SA-6TAN + // HCLK = 216MHz -> SDRAM clock = HCLK/2 = 133MHz + + // 1. Memory device features + FMC_Bank5_6->SDCR[0] = 0 // 0 delay after CAS latency + | FMC_SDCR1_RBURST // Enable read bursts + | FMC_SDCR1_SDCLK_1; // SDCLK = HCLK / 2 + FMC_Bank5_6->SDCR[1] = 0 // Write accesses allowed + | FMC_SDCR2_CAS_1 // 2 cycles CAS latency + | FMC_SDCR2_NB // 4 internal banks + | FMC_SDCR2_MWID_0 // 16 bit data bus + | FMC_SDCR2_NR_1 // 13 bit row address + // cppcheck-suppress duplicateExpression + | 0; // 8 bit column address + +// 2. Memory device timings +#ifdef SYSCLK_FREQ_216MHz + // SDRAM timings. One clock cycle is 9.26ns + FMC_Bank5_6->SDTR[0] = + (2 - 1) << FMC_SDTR1_TRP_Pos // 2 cycles TRP (18.52ns > 18ns) + | (7 - 1) << FMC_SDTR1_TRC_Pos; // 7 cycles TRC (64.82ns > 60ns) + FMC_Bank5_6->SDTR[1] = + (2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns) + | (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (min 2cc > 12ns) + | (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns) + | (7 - 1) << FMC_SDTR1_TXSR_Pos // 7 cycles TXSR (74.08ns > 61.5ns) + | (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (min 2cc > 12ns) +#else +#error No SDRAM timings for this clock +#endif + + // 3. Enable the bank 2 clock + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 4. Wait during command execution + delayUs(100); + + // 5. Issue a "Precharge All" command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 // Precharge all + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 6. Issue Auto-Refresh commands + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh + | FMC_SDCMR_CTB2 // Bank 2 + | (8 - 1) << FMC_SDCMR_NRFS_Pos; // 2 Auto-Refresh + sdramCommandWait(); + + // 7. Issue a Load Mode Register command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_2 /// Load mode register + | FMC_SDCMR_CTB2 // Bank 2 + | 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1 + sdramCommandWait(); + +// 8. Program the refresh rate (4K / 32ms) +// 64ms / 8192 = 7.8125us +#ifdef SYSCLK_FREQ_216MHz + // 7.8125us * 133MHz = 1039 - 20 = 1019 + FMC_Bank5_6->SDRTR = 1019 << FMC_SDRTR_COUNT_Pos; +#else +#error No SDRAM refresh timings for this clock +#endif +} + +void IRQbspInit() +{ + // Enable USART1 pins port + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; + + userLed1::mode(Mode::OUTPUT); + userLed2::mode(Mode::OUTPUT); + userLed3_1::mode(Mode::OUTPUT); + userLed3_2::mode(Mode::OUTPUT); + userLed4::mode(Mode::OUTPUT); + userSwitch::mode(Mode::INPUT); + + interfaces::spi1::miso::mode(Mode::ALTERNATE); + interfaces::spi1::miso::alternateFunction(5); + interfaces::spi1::mosi::mode(Mode::ALTERNATE); + interfaces::spi1::mosi::alternateFunction(5); + interfaces::spi1::sck::mode(Mode::ALTERNATE); + interfaces::spi1::sck::alternateFunction(5); + + interfaces::spi3::miso::mode(Mode::ALTERNATE); + interfaces::spi3::miso::alternateFunction(6); + interfaces::spi3::mosi::mode(Mode::ALTERNATE); + interfaces::spi3::mosi::alternateFunction(5); + interfaces::spi3::sck::mode(Mode::ALTERNATE); + interfaces::spi3::sck::alternateFunction(6); + + interfaces::spi4::miso::mode(Mode::ALTERNATE); + interfaces::spi4::miso::alternateFunction(5); + interfaces::spi4::mosi::mode(Mode::ALTERNATE); + interfaces::spi4::mosi::alternateFunction(5); + interfaces::spi4::sck::mode(Mode::ALTERNATE); + interfaces::spi4::sck::alternateFunction(5); + + radio1::cs::mode(Mode::OUTPUT); + radio1::cs::high(); + radio1::nrst::mode(Mode::OUTPUT); + radio1::nrst::high(); + radio1::txen::mode(Mode::OUTPUT); + radio1::txen::low(); + radio1::rxen::mode(Mode::OUTPUT); + radio1::rxen::low(); + radio1::dio0::mode(Mode::INPUT); + radio1::dio1::mode(Mode::INPUT); + radio1::dio3::mode(Mode::INPUT); + + radio2::cs::mode(Mode::OUTPUT); + radio2::cs::high(); + radio2::nrst::mode(Mode::OUTPUT); + radio2::nrst::high(); + radio2::txen::mode(Mode::OUTPUT); + radio2::txen::low(); + radio2::rxen::mode(Mode::OUTPUT); + radio2::rxen::low(); + radio2::dio0::mode(Mode::INPUT); + radio2::dio1::mode(Mode::INPUT); + radio2::dio3::mode(Mode::INPUT); + + ethernet::cs::mode(Mode::OUTPUT); + ethernet::cs::high(); + ethernet::nrst::mode(Mode::OUTPUT); + ethernet::nrst::high(); + ethernet::intr::mode(Mode::INPUT); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial( + defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + // Init devfs with empty device + basicFilesystemSetup(intrusive_ref_ptr<Device>()); +#endif // WITH_FILESYSTEM + +#ifdef WITH_BACKUP_SRAM + // Print the reset reason + bootlog("Reset reson: "); + switch (SGM::instance().lastResetReason()) + { + case ResetReason::RST_LOW_PWR: + bootlog("low power\n"); + break; + case ResetReason::RST_WINDOW_WDG: + bootlog("window watchdog\n"); + break; + case ResetReason::RST_INDEPENDENT_WDG: + bootlog("indeendent watchdog\n"); + break; + case ResetReason::RST_SW: + bootlog("software reset\n"); + break; + case ResetReason::RST_POWER_ON: + bootlog("power on\n"); + break; + case ResetReason::RST_PIN: + bootlog("reset pin\n"); + break; + case ResetReason::RST_UNKNOWN: + bootlog("unknown\n"); + break; + } +#endif // WITH_BACKUP_SRAM +} + +// +// Shutdown and reboot +// + +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + for (;;) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..aeba49af90aac903fb41acfac60b764fd466e0ea --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/bsp_impl.h @@ -0,0 +1,116 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +/*************************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ***************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +/** + * \internal + * Board pin definition + */ +typedef Gpio<GPIOB_BASE, 7> userLed1; +typedef Gpio<GPIOE_BASE, 3> userLed2; +typedef Gpio<GPIOC_BASE, 13> userLed3_1; +typedef Gpio<GPIOG_BASE, 9> userLed3_2; +typedef Gpio<GPIOC_BASE, 2> userLed4; +typedef Gpio<GPIOB_BASE, 2> userSwitch; + +inline void ledOn() +{ + userLed1::high(); + userLed2::high(); + userLed3_1::high(); + userLed3_2::high(); + userLed4::high(); +} + +inline void ledOff() +{ + userLed1::low(); + userLed2::low(); + userLed3_1::low(); + userLed3_2::low(); + userLed4::low(); +} + +inline void led1On() { userLed1::high(); } + +inline void led1Off() { userLed1::low(); } + +inline void led2On() { userLed2::high(); } + +inline void led2Off() { userLed2::low(); } + +inline void led3On() +{ + userLed3_1::high(); + userLed3_2::high(); +} + +inline void led3Off() +{ + userLed3_1::low(); + userLed3_2::low(); +} + +/** + * Polls the SD card sense GPIO. + * + * This board has no SD card whatsoever, but a card can be connected to the + * following GPIOs: + * TODO: never tested + * + * \return true. As there's no SD card sense switch, let's pretend that + * the card is present. + */ +inline bool sdCardSense() { return true; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/hwmapping.h b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..b81a36d1ebcf9f9d306c7221ff40d2dbaea60d44 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/interfaces-impl/hwmapping.h @@ -0,0 +1,130 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Davide Mor + * + * 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. + */ + +#ifndef HWMAPPING_H +#define HWMAPPING_H + +#include "interfaces/gpio.h" + +#define MIOSIX_RADIO1_DIO0_IRQ EXTI8_IRQHandlerImpl +#define MIOSIX_RADIO1_DIO1_IRQ EXTI10_IRQHandlerImpl +#define MIOSIX_RADIO1_DIO2_IRQ EXTI11_IRQHandlerImpl +#define MIOSIX_RADIO1_DIO3_IRQ EXTI12_IRQHandlerImpl +#define MIOSIX_RADIO1_SPI SPI3 + +#define MIOSIX_RADIO2_DIO0_IRQ EXTI6_IRQHandlerImpl +#define MIOSIX_RADIO2_DIO1_IRQ EXTI4_IRQHandlerImpl +#define MIOSIX_RADIO2_DIO2_IRQ EXTI7_IRQHandlerImpl +#define MIOSIX_RADIO2_DIO3_IRQ EXTI5_IRQHandlerImpl +#define MIOSIX_RADIO2_DIO4_IRQ EXTI2_IRQHandlerImpl +#define MIOSIX_RADIO2_DIO5_IRQ EXTI3_IRQHandlerImpl +#define MIOSIX_RADIO2_SPI SPI1 + +#define MIOSIX_ETHERNET_IRQ EXTI1_IRQHandlerImpl +#define MIOSIX_ETHERNET_SPI SPI4 + +// Remember to modify pins of leds +namespace miosix +{ + +namespace interfaces +{ + +// Radio 1 +namespace spi3 +{ +using sck = Gpio<GPIOB_BASE, 3>; +using miso = Gpio<GPIOB_BASE, 4>; +using mosi = Gpio<GPIOD_BASE, 6>; +} // namespace spi3 + +// Radio 2 +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +// Ethernet module +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +} // namespace interfaces + +namespace radio1 +{ +namespace spi +{ +using sck = miosix::interfaces::spi3::sck; +using miso = miosix::interfaces::spi3::miso; +using mosi = miosix::interfaces::spi3::mosi; +} // namespace spi + +using cs = Gpio<GPIOA_BASE, 15>; +using dio0 = Gpio<GPIOC_BASE, 8>; +using dio1 = Gpio<GPIOC_BASE, 10>; +using dio3 = Gpio<GPIOC_BASE, 12>; +using txen = Gpio<GPIOG_BASE, 12>; +using rxen = Gpio<GPIOG_BASE, 14>; +using nrst = Gpio<GPIOA_BASE, 1>; +} // namespace radio1 + +namespace radio2 +{ +namespace spi +{ +using sck = miosix::interfaces::spi1::sck; +using miso = miosix::interfaces::spi1::miso; +using mosi = miosix::interfaces::spi1::mosi; +} // namespace spi + +using cs = Gpio<GPIOA_BASE, 4>; +using dio0 = Gpio<GPIOC_BASE, 6>; +using dio1 = Gpio<GPIOD_BASE, 4>; +using dio3 = Gpio<GPIOD_BASE, 5>; +using txen = Gpio<GPIOB_BASE, 8>; +using rxen = Gpio<GPIOB_BASE, 9>; +using nrst = Gpio<GPIOA_BASE, 0>; +} // namespace radio2 + +namespace ethernet +{ +namespace spi +{ +using sck = miosix::interfaces::spi4::sck; +using miso = miosix::interfaces::spi4::miso; +using mosi = miosix::interfaces::spi4::mosi; +} // namespace spi + +using cs = Gpio<GPIOE_BASE, 4>; +using intr = Gpio<GPIOC_BASE, 1>; +using nrst = Gpio<GPIOB_BASE, 1>; +} // namespace ethernet + +} // namespace miosix + +#endif // HWMAPPING_H diff --git a/src/bsps/stm32f767zi_gemini_gs/stm32_2m+16m_xram.ld b/src/bsps/stm32f767zi_gemini_gs/stm32_2m+16m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..5b3545abd6f3007072b8ff00a978242d74503d79 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/stm32_2m+16m_xram.ld @@ -0,0 +1,190 @@ +/* + * C++ enabled linker script for stm32f769ni (2M FLASH, 512K RAM, 16MB XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the external 16MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0000000 + 16M; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 16M + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to xram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to xram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_gemini_gs/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_gemini_gs/stm32_2m+384k_ram.ld new file mode 100644 index 0000000000000000000000000000000000000000..497bd5198760b9637c774bf3900fd9dfbc01a2b2 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_gs/stm32_2m+384k_ram.ld @@ -0,0 +1,189 @@ +/* + * C++ enabled linker script for stm32f767zi (2M FLASH, 512K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the internal RAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap to the end of SRAM2 */ +_heap_end = 0x20000000 + 512K; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to sram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > sram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to sram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > sram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_gemini_motor/config/board_options.cmake b/src/bsps/stm32f767zi_gemini_motor/config/board_options.cmake new file mode 100644 index 0000000000000000000000000000000000000000..5608769a118128ab55cadb93379ca6a6603a7720 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/config/board_options.cmake @@ -0,0 +1,106 @@ +# Copyright (C) 2023 by Skyward +# +# This program is free software; you can redistribute it and/or +# it under the terms of the GNU General Public License as published +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# As a special exception, if other files instantiate templates or use +# macros or inline functions from this file, or you compile this file +# and link it with other works to produce a work based on this file, +# this file does not by itself cause the resulting work to be covered +# by the GNU General Public License. However the source code for this +# file must still be made available in accordance with the GNU +# Public License. This exception does not invalidate any other +# why a work based on this file might be covered by the GNU General +# Public License. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/> + +set(BOARD_NAME stm32f767zi_gemini_motor) +set(ARCH_NAME cortexM7_stm32f7) + +# Base directories with header files for this board +set(ARCH_PATH ${KPATH}/arch/${ARCH_NAME}/common) +set(BOARD_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}) +set(BOARD_CONFIG_PATH ${BOARDCORE_PATH}/src/bsps/${BOARD_NAME}/config) + +# Specify where to find the board specific config/miosix_settings.h +set(BOARD_MIOSIX_SETTINGS_PATH ${BOARD_PATH}) + +# Specify where to find the board specific config/mxgui_settings.h +set(BOARD_MXGUI_SETTINGS_PATH ${BOARD_PATH}) + +# Optimization flags: +# -O0 do no optimization, the default if no optimization level is specified +# -O or -O1 optimize minimally +# -O2 optimize more +# -O3 optimize even more +# -Ofast optimize very aggressively to the point of breaking the standard +# -Og Optimize debugging experience, enables optimizations that do not +# interfere with debugging +# -Os Optimize for size with -O2 optimizations that do not increase code size +set(OPT_OPTIMIZATION -O2) + +# Boot file and linker script +set(BOOT_FILE ${BOARD_PATH}/core/stage_1_boot.cpp) +# set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+384k_ram.ld) +set(LINKER_SCRIPT ${BOARD_PATH}/stm32_2m+16m_xram.ld) + +# Enables the initialization of the external 16MB SDRAM memory +set(XRAM -D__ENABLE_XRAM) + +# Select clock frequency (HSE_VALUE is the xtal on board, fixed) +set(CLOCK_FREQ -DHSE_VALUE=25000000 -DSYSCLK_FREQ_216MHz=216000000) + +# C++ Exception/rtti support disable flags. +# To save code size if not using C++ exceptions (nor some STL code which +# implicitly uses it) uncomment this option. +# -D__NO_EXCEPTIONS is used by Miosix to know if exceptions are used. +# set(OPT_EXCEPT -fno-exceptions -fno-rtti -D__NO_EXCEPTIONS) + +# Specify a custom flash command +# This is the program that is invoked when the flash flag (-f or --flash) is +# used with the Miosix Build System. Use $binary or $hex as placeolders, they +# will be replaced by the build systems with the binary or hex file repectively. +# If a command is not specified, the build system will use st-flash if found +# set(PROGRAM_CMDLINE "here your custom flash command") + +# Basic flags +set(FLAGS_BASE -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16) + +# Flags for ASM and linker +set(AFLAGS_BASE ${FLAGS_BASE}) +set(LFLAGS_BASE ${FLAGS_BASE} -Wl,--gc-sections,-Map,main.map -Wl,-T${LINKER_SCRIPT} ${OPT_EXCEPT} ${OPT_OPTIMIZATION} -nostdlib) + +# Flags for C/C++ +string(TOUPPER ${BOARD_NAME} BOARD_UPPER) +set(CFLAGS_BASE + -D_BOARD_${BOARD_UPPER} -D_MIOSIX_BOARDNAME=\"${BOARD_NAME}\" + -D_DEFAULT_SOURCE=1 -ffunction-sections -Wall -Werror=return-type -g + -D_ARCH_CORTEXM7_STM32F7 + ${CLOCK_FREQ} ${XRAM} ${SRAM_BOOT} ${FLAGS_BASE} ${OPT_OPTIMIZATION} -c +) +set(CXXFLAGS_BASE ${CFLAGS_BASE} ${OPT_EXCEPT}) + +# Select architecture specific files +set(ARCH_SRC + ${ARCH_PATH}/interfaces-impl/delays.cpp + ${ARCH_PATH}/interfaces-impl/gpio_impl.cpp + ${ARCH_PATH}/interfaces-impl/portability.cpp + ${BOARD_PATH}/interfaces-impl/bsp.cpp + ${KPATH}/arch/common/CMSIS/Device/ST/STM32F7xx/Source/Templates/system_stm32f7xx.c + ${KPATH}/arch/common/core/cache_cortexMx.cpp + ${KPATH}/arch/common/core/interrupts_cortexMx.cpp + ${KPATH}/arch/common/core/mpu_cortexMx.cpp + ${KPATH}/arch/common/core/stm32f2_f4_l4_f7_h7_os_timer.cpp + ${KPATH}/arch/common/drivers/sd_stm32f2_f4_f7.cpp + ${KPATH}/arch/common/drivers/serial_stm32.cpp + ${KPATH}/arch/common/drivers/stm32_hardware_rng.cpp +) diff --git a/src/bsps/stm32f767zi_gemini_motor/config/board_settings.h b/src/bsps/stm32f767zi_gemini_motor/config/board_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..2332aa30ea0f6249a56c67a56e7aacd668d29c4b --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/config/board_settings.h @@ -0,0 +1,62 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +/** + * \internal + * Versioning for board_settings.h for out of git tree projects + */ +#define BOARD_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +/// Size of stack for main(). +/// The C standard library is stack-heavy (iprintf requires 1KB) +const unsigned int MAIN_STACK_SIZE = 16 * 1024; + +/// Serial port +const unsigned int defaultSerial = 1; +const unsigned int defaultSerialSpeed = 115200; +#define SERIAL_1_DMA +// #define SERIAL_2_DMA +// #define SERIAL_3_DMA + +// SD card driver +static const unsigned char sdVoltage = 33; // Board powered @ 3.3V +// #define SD_ONE_BIT_DATABUS +#define SD_SDMMC 1 // Select either SDMMC1 or SDMMC2 + +/// Analog supply voltage for ADC, DAC, Reset blocks, RCs and PLL +#define V_DDA_VOLTAGE 3.3f + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_gemini_motor/config/miosix_settings.h b/src/bsps/stm32f767zi_gemini_motor/config/miosix_settings.h new file mode 100644 index 0000000000000000000000000000000000000000..e1ca4aac6bef352c5b4d367b3ba84ff5f4445499 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/config/miosix_settings.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +// Before you can compile the kernel you have to configure it by editing this +// file. After that, comment out this line to disable the reminder error. +// The PARSING_FROM_IDE is because Netbeans gets confused by this, it is never +// defined when compiling the code. +#ifndef PARSING_FROM_IDE +//#error This error is a reminder that you have not edited miosix_settings.h +// yet. +#endif // PARSING_FROM_IDE + +/** + * \file miosix_settings.h + * NOTE: this file contains ONLY configuration options that are not dependent + * on architecture specific details. The other options are in the following + * files which are included here: + * miosix/arch/architecture name/common/arch_settings.h + * miosix/config/arch/architecture name/board name/board_settings.h + */ +#include "arch_settings.h" +#include "board_settings.h" +#include "util/version.h" + +/** + * \internal + * Versioning for miosix_settings.h for out of git tree projects + */ +#define MIOSIX_SETTINGS_VERSION 300 + +namespace miosix +{ + +/** + * \addtogroup Settings + * \{ + */ + +// +// Scheduler options +// + +/// \def SCHED_TYPE_PRIORITY +/// If uncommented selects the priority scheduler +/// \def SCHED_TYPE_CONTROL_BASED +/// If uncommented selects the control based scheduler +/// \def SCHED_TYPE_EDF +/// If uncommented selects the EDF scheduler +// Uncomment only *one* of those + +#define SCHED_TYPE_PRIORITY +//#define SCHED_TYPE_CONTROL_BASED +//#define SCHED_TYPE_EDF + +/// \def WITH_CPU_TIME_COUNTER +/// Allows to enable/disable CPUTimeCounter to save code size and remove its +/// overhead from the scheduling process. By default it is not defined +/// (CPUTimeCounter is disabled). +//#define WITH_CPU_TIME_COUNTER + +// +// Filesystem options +// + +/// \def WITH_FILESYSTEM +/// Allows to enable/disable filesystem support to save code size +/// By default it is defined (filesystem support is enabled) +#define WITH_FILESYSTEM + +/// \def WITH_DEVFS +/// Allows to enable/disable DevFs support to save code size +/// By default it is defined (DevFs is enabled) +#define WITH_DEVFS + +/// \def SYNC_AFTER_WRITE +/// Increases filesystem write robustness. After each write operation the +/// filesystem is synced so that a power failure happens data is not lost +/// (unless power failure happens exactly between the write and the sync) +/// Unfortunately write latency and throughput becomes twice as worse +/// By default it is defined (slow but safe) +#define SYNC_AFTER_WRITE + +/// Maximum number of open files. Trying to open more will fail. +/// Cannot be lower than 3, as the first three are stdin, stdout, stderr +const unsigned char MAX_OPEN_FILES = 8; + +/// \def WITH_PROCESSES +/// If uncommented enables support for processes as well as threads. +/// This enables the dynamic loader to load elf programs, the extended system +/// call service and, if the hardware supports it, the MPU to provide memory +/// isolation of processes +//#define WITH_PROCESSES + +#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) +#error Processes require C++ exception support +#endif // defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS) + +#if defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) +#error Processes require filesystem support +#endif // defined(WITH_PROCESSES) && !defined(WITH_FILESYSTEM) + +#if defined(WITH_PROCESSES) && !defined(WITH_DEVFS) +#error Processes require devfs support +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +// +// C/C++ standard library I/O (stdin, stdout and stderr related) +// + +/// \def WITH_BOOTLOG +/// Uncomment to print bootlogs on stdout. +/// By default it is defined (bootlogs are printed) +#define WITH_BOOTLOG + +/// \def WITH_ERRLOG +/// Uncomment for debug information on stdout. +/// By default it is defined (error information is printed) +#define WITH_ERRLOG + +// +// Kernel related options (stack sizes, priorities) +// + +/// \def WITH_DEEP_SLEEP +/// Adds interfaces and required variables to support deep sleep state switch +/// automatically when peripherals are not required +//#define WITH_DEEP_SLEEP + +/** + * \def JTAG_DISABLE_SLEEP + * JTAG debuggers lose communication with the device if it enters sleep + * mode, so to use debugging it is necessary to disable sleep in the idle + * thread. By default it is not defined (idle thread calls sleep). + */ +//#define JTAG_DISABLE_SLEEP + +#if defined(WITH_DEEP_SLEEP) && defined(JTAG_DISABLE_SLEEP) +#error Deep sleep cannot work together with jtag +#endif // defined(WITH_PROCESSES) && !defined(WITH_DEVFS) + +/// Minimum stack size (MUST be divisible by 4) +const unsigned int STACK_MIN = 256; + +/// \internal Size of idle thread stack. +/// Should be >=STACK_MIN (MUST be divisible by 4) +const unsigned int STACK_IDLE = 256; + +/// Default stack size for pthread_create. +/// The chosen value is enough to call C standard library functions +/// such as printf/fopen which are stack-heavy +const unsigned int STACK_DEFAULT_FOR_PTHREAD = 2048; + +/// Maximum size of the RAM image of a process. If a program requires more +/// the kernel will not run it (MUST be divisible by 4) +const unsigned int MAX_PROCESS_IMAGE_SIZE = 64 * 1024; + +/// Minimum size of the stack for a process. If a program specifies a lower +/// size the kernel will not run it (MUST be divisible by 4) +const unsigned int MIN_PROCESS_STACK_SIZE = STACK_MIN; + +/// Every userspace thread has two stacks, one for when it is running in +/// userspace and one for when it is running in kernelspace (that is, while it +/// is executing system calls). This is the size of the stack for when the +/// thread is running in kernelspace (MUST be divisible by 4) +const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE = 2 * 1024; + +/// Number of priorities (MUST be >1) +/// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as +/// the priority of the idle thread. +/// The meaning of a thread's priority depends on the chosen scheduler. +#ifdef SCHED_TYPE_PRIORITY +// Can be modified, but a high value makes context switches more expensive +const short int PRIORITY_MAX = 4; +#elif defined(SCHED_TYPE_CONTROL_BASED) +// Don't touch, the limit is due to the fixed point implementation +// It's not needed for if floating point is selected, but kept for consistency +const short int PRIORITY_MAX = 64; +#else // SCHED_TYPE_EDF +// Doesn't exist for this kind of scheduler +#endif + +/// Priority of main() +/// The meaning of a thread's priority depends on the chosen scheduler. +const unsigned char MAIN_PRIORITY = 1; + +#ifdef SCHED_TYPE_PRIORITY +/// Maximum thread time slice in nanoseconds, after which preemption occurs +const unsigned int MAX_TIME_SLICE = 1000000; +#endif // SCHED_TYPE_PRIORITY + +// +// Other low level kernel options. There is usually no need to modify these. +// + +/// \internal Length of wartermark (in bytes) to check stack overflow. +/// MUST be divisible by 4 and can also be zero. +/// A high value increases context switch time. +const unsigned int WATERMARK_LEN = 16; + +/// \internal Used to fill watermark +const unsigned int WATERMARK_FILL = 0xaaaaaaaa; + +/// \internal Used to fill stack (for checking stack usage) +const unsigned int STACK_FILL = 0xbbbbbbbb; + +// Compiler version checks +#if !defined(_MIOSIX_GCC_PATCH_MAJOR) || _MIOSIX_GCC_PATCH_MAJOR < 3 +#error \ + "You are using a too old or unsupported compiler. Get the latest one from https://miosix.org/wiki/index.php?title=Miosix_Toolchain" +#endif +#if _MIOSIX_GCC_PATCH_MAJOR > 3 +#warning "You are using a too new compiler, which may not be supported" +#endif + +/** + * \} + */ + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_gemini_motor/core/stage_1_boot.cpp b/src/bsps/stm32f767zi_gemini_motor/core/stage_1_boot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..83eac53b4b0b56309c0a9c26aacb7ff4289558d0 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/core/stage_1_boot.cpp @@ -0,0 +1,505 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#include <string.h> + +#include "core/cache_cortexMx.h" +#include "core/interrupts.h" //For the unexpected interrupt call +#include "core/interrupts_cortexMx.h" +#include "interfaces/arch_registers.h" +#include "interfaces/bsp.h" +#include "kernel/stage_2_boot.h" + +/* + * startup.cpp + * STM32 C++ startup. + * NOTE: for stm32f767 devices ONLY. + * Supports interrupt handlers in C++ without extern "C" + * Developed by Terraneo Federico, based on ST startup code. + * Additionally modified to boot Miosix. + */ + +/** + * Called by Reset_Handler, performs initialization and calls main. + * Never returns. + */ +void program_startup() __attribute__((noreturn)); +void program_startup() +{ + // Cortex M7 core appears to get out of reset with interrupts already + // enabled + __disable_irq(); + + miosix::IRQconfigureCache((const unsigned int *)0xd0000000, + 8 * 1024 * 1024); + + // These are defined in the linker script + extern unsigned char _etext asm("_etext"); + extern unsigned char _data asm("_data"); + extern unsigned char _edata asm("_edata"); + extern unsigned char _bss_start asm("_bss_start"); + extern unsigned char _bss_end asm("_bss_end"); + + // Initialize .data section, clear .bss section + unsigned char *etext = &_etext; + unsigned char *data = &_data; + unsigned char *edata = &_edata; + unsigned char *bss_start = &_bss_start; + unsigned char *bss_end = &_bss_end; + memcpy(data, etext, edata - data); + memset(bss_start, 0, bss_end - bss_start); + + // Move on to stage 2 + _init(); + + // If main returns, reboot + NVIC_SystemReset(); + for (;;) + ; +} + +/** + * Reset handler, called by hardware immediately after reset + */ +void Reset_Handler() __attribute__((__interrupt__, noreturn)); +void Reset_Handler() +{ + /** + * SystemInit() is called *before* initializing .data and zeroing .bss + * Despite all startup files provided by ST do the opposite, there are three + * good reasons to do so: + * 1. First, the CMSIS specifications say that SystemInit() must not access + * global variables, so it is actually possible to call it before + * 2. Second, when running Miosix with the xram linker scripts .data and + * .bss are placed in the external RAM, so we *must* call SystemInit(), + * which enables xram, before touching .data and .bss + * 3. Third, this is a performance improvement since the loops that + * initialize .data and zeros .bss now run with the CPU at full speed + * instead of 8MHz + */ + SystemInit(); + +/** + * ST does not provide code to initialize the SDRAM at boot. + * Put after SystemInit() as SDRAM is timing-sensitive and needs the full + * clock speed. + */ +#ifdef __ENABLE_XRAM + miosix::configureSdram(); +#endif //__ENABLE_XRAM + + /* + * Load into the program stack pointer the heap end address and switch from + * the msp to sps. + * This is required for booting Miosix, a small portion of the top of the + * heap area will be used as stack until the first thread starts. After, + * this stack will be abandoned and the process stack will point to the + * current thread's stack. + */ + asm volatile( + "ldr r0, =_heap_end \n\t" + "msr psp, r0 \n\t" + "movw r0, #2 \n\n" // Set the control register to use + "msr control, r0 \n\t" // the process stack + "isb \n\t" :: + : "r0"); + + program_startup(); +} + +/** + * All unused interrupts call this function. + */ +extern "C" void Default_Handler() { unexpectedInterrupt(); } + +// System handlers +void /*__attribute__((weak))*/ Reset_Handler(); // These interrupts are not +void /*__attribute__((weak))*/ NMI_Handler(); // weak because they are +void /*__attribute__((weak))*/ HardFault_Handler(); // surely defined by Miosix +void /*__attribute__((weak))*/ MemManage_Handler(); +void /*__attribute__((weak))*/ BusFault_Handler(); +void /*__attribute__((weak))*/ UsageFault_Handler(); +void /*__attribute__((weak))*/ SVC_Handler(); +void /*__attribute__((weak))*/ DebugMon_Handler(); +void /*__attribute__((weak))*/ PendSV_Handler(); +void __attribute__((weak)) SysTick_Handler(); + +// Interrupt handlers +void __attribute__((weak)) WWDG_IRQHandler(); +void __attribute__((weak)) PVD_IRQHandler(); +void __attribute__((weak)) TAMP_STAMP_IRQHandler(); +void __attribute__((weak)) RTC_WKUP_IRQHandler(); +void __attribute__((weak)) FLASH_IRQHandler(); +void __attribute__((weak)) RCC_IRQHandler(); +void __attribute__((weak)) EXTI0_IRQHandler(); +void __attribute__((weak)) EXTI1_IRQHandler(); +void __attribute__((weak)) EXTI2_IRQHandler(); +void __attribute__((weak)) EXTI3_IRQHandler(); +void __attribute__((weak)) EXTI4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream0_IRQHandler(); +void __attribute__((weak)) DMA1_Stream1_IRQHandler(); +void __attribute__((weak)) DMA1_Stream2_IRQHandler(); +void __attribute__((weak)) DMA1_Stream3_IRQHandler(); +void __attribute__((weak)) DMA1_Stream4_IRQHandler(); +void __attribute__((weak)) DMA1_Stream5_IRQHandler(); +void __attribute__((weak)) DMA1_Stream6_IRQHandler(); +void __attribute__((weak)) ADC_IRQHandler(); +void __attribute__((weak)) CAN1_TX_IRQHandler(); +void __attribute__((weak)) CAN1_RX0_IRQHandler(); +void __attribute__((weak)) CAN1_RX1_IRQHandler(); +void __attribute__((weak)) CAN1_SCE_IRQHandler(); +void __attribute__((weak)) EXTI9_5_IRQHandler(); +void __attribute__((weak)) TIM1_BRK_TIM9_IRQHandler(); +void __attribute__((weak)) TIM1_UP_TIM10_IRQHandler(); +void __attribute__((weak)) TIM1_TRG_COM_TIM11_IRQHandler(); +void __attribute__((weak)) TIM1_CC_IRQHandler(); +void __attribute__((weak)) TIM2_IRQHandler(); +void __attribute__((weak)) TIM3_IRQHandler(); +void __attribute__((weak)) TIM4_IRQHandler(); +void __attribute__((weak)) I2C1_EV_IRQHandler(); +void __attribute__((weak)) I2C1_ER_IRQHandler(); +void __attribute__((weak)) I2C2_EV_IRQHandler(); +void __attribute__((weak)) I2C2_ER_IRQHandler(); +void __attribute__((weak)) SPI1_IRQHandler(); +void __attribute__((weak)) SPI2_IRQHandler(); +void __attribute__((weak)) USART1_IRQHandler(); +void __attribute__((weak)) USART2_IRQHandler(); +void __attribute__((weak)) USART3_IRQHandler(); +void __attribute__((weak)) EXTI15_10_IRQHandler(); +void __attribute__((weak)) RTC_Alarm_IRQHandler(); +void __attribute__((weak)) OTG_FS_WKUP_IRQHandler(); +void __attribute__((weak)) TIM8_BRK_TIM12_IRQHandler(); +void __attribute__((weak)) TIM8_UP_TIM13_IRQHandler(); +void __attribute__((weak)) TIM8_TRG_COM_TIM14_IRQHandler(); +void __attribute__((weak)) TIM8_CC_IRQHandler(); +void __attribute__((weak)) DMA1_Stream7_IRQHandler(); +void __attribute__((weak)) FMC_IRQHandler(); +void __attribute__((weak)) SDMMC1_IRQHandler(); +void __attribute__((weak)) TIM5_IRQHandler(); +void __attribute__((weak)) SPI3_IRQHandler(); +void __attribute__((weak)) UART4_IRQHandler(); +void __attribute__((weak)) UART5_IRQHandler(); +void __attribute__((weak)) TIM6_DAC_IRQHandler(); +void __attribute__((weak)) TIM7_IRQHandler(); +void __attribute__((weak)) DMA2_Stream0_IRQHandler(); +void __attribute__((weak)) DMA2_Stream1_IRQHandler(); +void __attribute__((weak)) DMA2_Stream2_IRQHandler(); +void __attribute__((weak)) DMA2_Stream3_IRQHandler(); +void __attribute__((weak)) DMA2_Stream4_IRQHandler(); +void __attribute__((weak)) ETH_IRQHandler(); +void __attribute__((weak)) ETH_WKUP_IRQHandler(); +void __attribute__((weak)) CAN2_TX_IRQHandler(); +void __attribute__((weak)) CAN2_RX0_IRQHandler(); +void __attribute__((weak)) CAN2_RX1_IRQHandler(); +void __attribute__((weak)) CAN2_SCE_IRQHandler(); +void __attribute__((weak)) OTG_FS_IRQHandler(); +void __attribute__((weak)) DMA2_Stream5_IRQHandler(); +void __attribute__((weak)) DMA2_Stream6_IRQHandler(); +void __attribute__((weak)) DMA2_Stream7_IRQHandler(); +void __attribute__((weak)) USART6_IRQHandler(); +void __attribute__((weak)) I2C3_EV_IRQHandler(); +void __attribute__((weak)) I2C3_ER_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_OUT_IRQHandler(); +void __attribute__((weak)) OTG_HS_EP1_IN_IRQHandler(); +void __attribute__((weak)) OTG_HS_WKUP_IRQHandler(); +void __attribute__((weak)) OTG_HS_IRQHandler(); +void __attribute__((weak)) DCMI_IRQHandler(); +void __attribute__((weak)) CRYP_IRQHandler(); +void __attribute__((weak)) RNG_IRQHandler(); +void __attribute__((weak)) FPU_IRQHandler(); +void __attribute__((weak)) UART7_IRQHandler(); +void __attribute__((weak)) UART8_IRQHandler(); +void __attribute__((weak)) SPI4_IRQHandler(); +void __attribute__((weak)) SPI5_IRQHandler(); +void __attribute__((weak)) SPI6_IRQHandler(); +void __attribute__((weak)) SAI1_IRQHandler(); +void __attribute__((weak)) LTDC_IRQHandler(); +void __attribute__((weak)) LTDC_ER_IRQHandler(); +void __attribute__((weak)) DMA2D_IRQHandler(); +void __attribute__((weak)) SAI2_IRQHandler(); +void __attribute__((weak)) QUADSPI_IRQHandler(); +void __attribute__((weak)) LPTIM1_IRQHandler(); +void __attribute__((weak)) CEC_IRQHandler(); +void __attribute__((weak)) I2C4_EV_IRQHandler(); +void __attribute__((weak)) I2C4_ER_IRQHandler(); +void __attribute__((weak)) SPDIF_RX_IRQHandler(); +void __attribute__((weak)) DSIHOST_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT0_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT1_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT2_IRQHandler(); +void __attribute__((weak)) DFSDM1_FLT3_IRQHandler(); +void __attribute__((weak)) SDMMC2_IRQHandler(); +void __attribute__((weak)) CAN3_TX_IRQHandler(); +void __attribute__((weak)) CAN3_RX0_IRQHandler(); +void __attribute__((weak)) CAN3_RX1_IRQHandler(); +void __attribute__((weak)) CAN3_SCE_IRQHandler(); +void __attribute__((weak)) JPEG_IRQHandler(); +void __attribute__((weak)) MDIOS_IRQHandler(); + +// Stack top, defined in the linker script +extern char _main_stack_top asm("_main_stack_top"); + +// Interrupt vectors, must be placed @ address 0x00000000 +// The extern declaration is required otherwise g++ optimizes it out +extern void (*const __Vectors[])(); +void (*const __Vectors[])() __attribute__((section(".isr_vector"))) = { + reinterpret_cast<void (*)()>(&_main_stack_top), /* Stack pointer*/ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* NMI Handler */ + HardFault_Handler, /* Hard Fault Handler */ + MemManage_Handler, /* MPU Fault Handler */ + BusFault_Handler, /* Bus Fault Handler */ + UsageFault_Handler, /* Usage Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* SVCall Handler */ + DebugMon_Handler, /* Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* PendSV Handler */ + SysTick_Handler, /* SysTick Handler */ + + /* External Interrupts */ + WWDG_IRQHandler, + PVD_IRQHandler, + TAMP_STAMP_IRQHandler, + RTC_WKUP_IRQHandler, + FLASH_IRQHandler, + RCC_IRQHandler, + EXTI0_IRQHandler, + EXTI1_IRQHandler, + EXTI2_IRQHandler, + EXTI3_IRQHandler, + EXTI4_IRQHandler, + DMA1_Stream0_IRQHandler, + DMA1_Stream1_IRQHandler, + DMA1_Stream2_IRQHandler, + DMA1_Stream3_IRQHandler, + DMA1_Stream4_IRQHandler, + DMA1_Stream5_IRQHandler, + DMA1_Stream6_IRQHandler, + ADC_IRQHandler, + CAN1_TX_IRQHandler, + CAN1_RX0_IRQHandler, + CAN1_RX1_IRQHandler, + CAN1_SCE_IRQHandler, + EXTI9_5_IRQHandler, + TIM1_BRK_TIM9_IRQHandler, + TIM1_UP_TIM10_IRQHandler, + TIM1_TRG_COM_TIM11_IRQHandler, + TIM1_CC_IRQHandler, + TIM2_IRQHandler, + TIM3_IRQHandler, + TIM4_IRQHandler, + I2C1_EV_IRQHandler, + I2C1_ER_IRQHandler, + I2C2_EV_IRQHandler, + I2C2_ER_IRQHandler, + SPI1_IRQHandler, + SPI2_IRQHandler, + USART1_IRQHandler, + USART2_IRQHandler, + USART3_IRQHandler, + EXTI15_10_IRQHandler, + RTC_Alarm_IRQHandler, + OTG_FS_WKUP_IRQHandler, + TIM8_BRK_TIM12_IRQHandler, + TIM8_UP_TIM13_IRQHandler, + TIM8_TRG_COM_TIM14_IRQHandler, + TIM8_CC_IRQHandler, + DMA1_Stream7_IRQHandler, + FMC_IRQHandler, + SDMMC1_IRQHandler, + TIM5_IRQHandler, + SPI3_IRQHandler, + UART4_IRQHandler, + UART5_IRQHandler, + TIM6_DAC_IRQHandler, + TIM7_IRQHandler, + DMA2_Stream0_IRQHandler, + DMA2_Stream1_IRQHandler, + DMA2_Stream2_IRQHandler, + DMA2_Stream3_IRQHandler, + DMA2_Stream4_IRQHandler, + ETH_IRQHandler, + ETH_WKUP_IRQHandler, + CAN2_TX_IRQHandler, + CAN2_RX0_IRQHandler, + CAN2_RX1_IRQHandler, + CAN2_SCE_IRQHandler, + OTG_FS_IRQHandler, + DMA2_Stream5_IRQHandler, + DMA2_Stream6_IRQHandler, + DMA2_Stream7_IRQHandler, + USART6_IRQHandler, + I2C3_EV_IRQHandler, + I2C3_ER_IRQHandler, + OTG_HS_EP1_OUT_IRQHandler, + OTG_HS_EP1_IN_IRQHandler, + OTG_HS_WKUP_IRQHandler, + OTG_HS_IRQHandler, + DCMI_IRQHandler, + CRYP_IRQHandler, + RNG_IRQHandler, + FPU_IRQHandler, + UART7_IRQHandler, + UART8_IRQHandler, + SPI4_IRQHandler, + SPI5_IRQHandler, + SPI6_IRQHandler, + SAI1_IRQHandler, + LTDC_IRQHandler, + LTDC_ER_IRQHandler, + DMA2D_IRQHandler, + SAI2_IRQHandler, + QUADSPI_IRQHandler, + LPTIM1_IRQHandler, + CEC_IRQHandler, + I2C4_EV_IRQHandler, + I2C4_ER_IRQHandler, + SPDIF_RX_IRQHandler, + DSIHOST_IRQHandler, + DFSDM1_FLT0_IRQHandler, + DFSDM1_FLT1_IRQHandler, + DFSDM1_FLT2_IRQHandler, + DFSDM1_FLT3_IRQHandler, + SDMMC2_IRQHandler, + CAN3_TX_IRQHandler, + CAN3_RX0_IRQHandler, + CAN3_RX1_IRQHandler, + CAN3_SCE_IRQHandler, + JPEG_IRQHandler, + MDIOS_IRQHandler, +}; + +#pragma weak SysTick_IRQHandler = Default_Handler +#pragma weak WWDG_IRQHandler = Default_Handler +#pragma weak PVD_IRQHandler = Default_Handler +#pragma weak TAMP_STAMP_IRQHandler = Default_Handler +#pragma weak RTC_WKUP_IRQHandler = Default_Handler +#pragma weak FLASH_IRQHandler = Default_Handler +#pragma weak RCC_IRQHandler = Default_Handler +#pragma weak EXTI0_IRQHandler = Default_Handler +#pragma weak EXTI1_IRQHandler = Default_Handler +#pragma weak EXTI2_IRQHandler = Default_Handler +#pragma weak EXTI3_IRQHandler = Default_Handler +#pragma weak EXTI4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream0_IRQHandler = Default_Handler +#pragma weak DMA1_Stream1_IRQHandler = Default_Handler +#pragma weak DMA1_Stream2_IRQHandler = Default_Handler +#pragma weak DMA1_Stream3_IRQHandler = Default_Handler +#pragma weak DMA1_Stream4_IRQHandler = Default_Handler +#pragma weak DMA1_Stream5_IRQHandler = Default_Handler +#pragma weak DMA1_Stream6_IRQHandler = Default_Handler +#pragma weak ADC_IRQHandler = Default_Handler +#pragma weak CAN1_TX_IRQHandler = Default_Handler +#pragma weak CAN1_RX0_IRQHandler = Default_Handler +#pragma weak CAN1_RX1_IRQHandler = Default_Handler +#pragma weak CAN1_SCE_IRQHandler = Default_Handler +#pragma weak EXTI9_5_IRQHandler = Default_Handler +#pragma weak TIM1_BRK_TIM9_IRQHandler = Default_Handler +#pragma weak TIM1_UP_TIM10_IRQHandler = Default_Handler +#pragma weak TIM1_TRG_COM_TIM11_IRQHandler = Default_Handler +#pragma weak TIM1_CC_IRQHandler = Default_Handler +#pragma weak TIM2_IRQHandler = Default_Handler +#pragma weak TIM3_IRQHandler = Default_Handler +#pragma weak TIM4_IRQHandler = Default_Handler +#pragma weak I2C1_EV_IRQHandler = Default_Handler +#pragma weak I2C1_ER_IRQHandler = Default_Handler +#pragma weak I2C2_EV_IRQHandler = Default_Handler +#pragma weak I2C2_ER_IRQHandler = Default_Handler +#pragma weak SPI1_IRQHandler = Default_Handler +#pragma weak SPI2_IRQHandler = Default_Handler +// #pragma weak USART1_IRQHandler = Default_Handler +// #pragma weak USART2_IRQHandler = Default_Handler +// #pragma weak USART3_IRQHandler = Default_Handler +#pragma weak EXTI15_10_IRQHandler = Default_Handler +#pragma weak RTC_Alarm_IRQHandler = Default_Handler +#pragma weak OTG_FS_WKUP_IRQHandler = Default_Handler +#pragma weak TIM8_BRK_TIM12_IRQHandler = Default_Handler +#pragma weak TIM8_UP_TIM13_IRQHandler = Default_Handler +#pragma weak TIM8_TRG_COM_TIM14_IRQHandler = Default_Handler +#pragma weak TIM8_CC_IRQHandler = Default_Handler +#pragma weak DMA1_Stream7_IRQHandler = Default_Handler +#pragma weak FMC_IRQHandler = Default_Handler +#pragma weak SDMMC1_IRQHandler = Default_Handler +#pragma weak TIM5_IRQHandler = Default_Handler +#pragma weak SPI3_IRQHandler = Default_Handler +// #pragma weak UART4_IRQHandler = Default_Handler +// #pragma weak UART5_IRQHandler = Default_Handler +#pragma weak TIM6_DAC_IRQHandler = Default_Handler +#pragma weak TIM7_IRQHandler = Default_Handler +#pragma weak DMA2_Stream0_IRQHandler = Default_Handler +#pragma weak DMA2_Stream1_IRQHandler = Default_Handler +#pragma weak DMA2_Stream2_IRQHandler = Default_Handler +#pragma weak DMA2_Stream3_IRQHandler = Default_Handler +#pragma weak DMA2_Stream4_IRQHandler = Default_Handler +#pragma weak ETH_IRQHandler = Default_Handler +#pragma weak ETH_WKUP_IRQHandler = Default_Handler +#pragma weak CAN2_TX_IRQHandler = Default_Handler +#pragma weak CAN2_RX0_IRQHandler = Default_Handler +#pragma weak CAN2_RX1_IRQHandler = Default_Handler +#pragma weak CAN2_SCE_IRQHandler = Default_Handler +#pragma weak OTG_FS_IRQHandler = Default_Handler +#pragma weak DMA2_Stream5_IRQHandler = Default_Handler +#pragma weak DMA2_Stream6_IRQHandler = Default_Handler +#pragma weak DMA2_Stream7_IRQHandler = Default_Handler +// #pragma weak USART6_IRQHandler = Default_Handler +#pragma weak I2C3_EV_IRQHandler = Default_Handler +#pragma weak I2C3_ER_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_OUT_IRQHandler = Default_Handler +#pragma weak OTG_HS_EP1_IN_IRQHandler = Default_Handler +#pragma weak OTG_HS_WKUP_IRQHandler = Default_Handler +#pragma weak OTG_HS_IRQHandler = Default_Handler +#pragma weak DCMI_IRQHandler = Default_Handler +#pragma weak CRYP_IRQHandler = Default_Handler +#pragma weak RNG_IRQHandler = Default_Handler +#pragma weak FPU_IRQHandler = Default_Handler +// #pragma weak UART7_IRQHandler = Default_Handler +// #pragma weak UART8_IRQHandler = Default_Handler +#pragma weak SPI4_IRQHandler = Default_Handler +#pragma weak SPI5_IRQHandler = Default_Handler +#pragma weak SPI6_IRQHandler = Default_Handler +#pragma weak SAI1_IRQHandler = Default_Handler +#pragma weak LTDC_IRQHandler = Default_Handler +#pragma weak LTDC_ER_IRQHandler = Default_Handler +#pragma weak DMA2D_IRQHandler = Default_Handler +#pragma weak SAI2_IRQHandler = Default_Handler +#pragma weak QUADSPI_IRQHandler = Default_Handler +#pragma weak LPTIM1_IRQHandler = Default_Handler +#pragma weak CEC_IRQHandler = Default_Handler +#pragma weak I2C4_EV_IRQHandler = Default_Handler +#pragma weak I2C4_ER_IRQHandler = Default_Handler +#pragma weak SPDIF_RX_IRQHandler = Default_Handler +#pragma weak DSIHOST_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT0_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT1_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT2_IRQHandler = Default_Handler +#pragma weak DFSDM1_FLT3_IRQHandler = Default_Handler +#pragma weak SDMMC2_IRQHandler = Default_Handler +#pragma weak CAN3_TX_IRQHandler = Default_Handler +#pragma weak CAN3_RX0_IRQHandler = Default_Handler +#pragma weak CAN3_RX1_IRQHandler = Default_Handler +#pragma weak CAN3_SCE_IRQHandler = Default_Handler +#pragma weak JPEG_IRQHandler = Default_Handler +#pragma weak MDIOS_IRQHandler = Default_Handler diff --git a/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/arch_registers_impl.h b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/arch_registers_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..3224edc9ea21e7d207549879bb48cac84b71defe --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/arch_registers_impl.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#ifndef ARCH_REGISTERS_IMPL_H +#define ARCH_REGISTERS_IMPL_H + +// stm32f7xx.h defines a few macros like __ICACHE_PRESENT, __DCACHE_PRESENT and +// includes core_cm7.h. Do not include core_cm7.h before. +#define STM32F767xx +#include "CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h" + +#if (__ICACHE_PRESENT != 1) || (__DCACHE_PRESENT != 1) +#error "Wrong include order" +#endif + +#include "CMSIS/Device/ST/STM32F7xx/Include/system_stm32f7xx.h" + +#define RCC_SYNC() __DSB() // TODO: can this dsb be removed? + +#endif // ARCH_REGISTERS_IMPL_H diff --git a/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/bsp.cpp b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/bsp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..12303cae3b797c729cba634123b21caabee0afb1 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/bsp.cpp @@ -0,0 +1,370 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*********************************************************************** + * bsp.cpp Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ************************************************************************/ + +#include "interfaces/bsp.h" + +#include <inttypes.h> +#include <sys/ioctl.h> + +#include <cstdlib> + +#include "board_settings.h" +#include "config/miosix_settings.h" +#include "drivers/sd_stm32f2_f4_f7.h" +#include "drivers/serial.h" +#include "drivers/serial_stm32.h" +#include "drivers/stm32_sgm.h" +#include "filesystem/console/console_device.h" +#include "filesystem/file_access.h" +#include "interfaces/arch_registers.h" +#include "interfaces/delays.h" +#include "interfaces/portability.h" +#include "kernel/kernel.h" +#include "kernel/logging.h" +#include "kernel/sync.h" + +namespace miosix +{ + +// +// Initialization +// + +static void sdramCommandWait() +{ + for (int i = 0; i < 0xffff; i++) + if ((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) == 0) + return; +} + +void configureSdram() +{ + // Enable all gpios + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN | RCC_AHB1ENR_GPIOBEN | + RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN | + RCC_AHB1ENR_GPIOEEN | RCC_AHB1ENR_GPIOFEN | + RCC_AHB1ENR_GPIOGEN; + RCC_SYNC(); + + // On the compute unit with F767ZI, the SDRAM pins are: + // - PG8: FMC_SDCLK (sdram clock) + // - PB5: FMC_SDCKE1 (sdram bank 2 clock enable) + // - PB6: FMC_SDNE1 (sdram bank 2 chip enable) + // - PF0: FMC_A0 + // - PF1: FMC_A1 + // - PF2: FMC_A2 + // - PF3: FMC_A3 + // - PF4: FMC_A4 + // - PF5: FMC_A5 + // - PF12: FMC_A6 + // - PF13: FMC_A7 + // - PF14: FMC_A8 + // - PF15: FMC_A9 + // - PG0: FMC_A10 + // - PG1: FMC_A11 + // - PG2: FMC_A12 (used only by the 32MB ram, not by the 8MB one) + // - PD14: FMC_D0 + // - PD15: FMC_D1 + // - PD0: FMC_D2 + // - PD1: FMC_D3 + // - PE7: FMC_D4 + // - PE8: FMC_D5 + // - PE9: FMC_D6 + // - PE10: FMC_D7 + // - PE11: FMC_D8 + // - PE12: FMC_D9 + // - PE13: FMC_D10 + // - PE14: FMC_D11 + // - PE15: FMC_D12 + // - PD8: FMC_D13 + // - PD9: FMC_D14 + // - PD10: FMC_D15 + + // - PG4: FMC_BA0 + // - PG5: FMC_BA1 + // - PF11: FMC_SDNRAS + // - PG15: FMC_SDNCAS + // - PC0: FMC_SDNWE + // - PE0: FMC_NBL0 + // - PE1: FMC_NBL1 + + // All SDRAM GPIOs needs to be configured with alternate function 12 and + // maximum speed + + // WARNING: The current configuration is for the 8MB ram + + // Alternate functions + GPIOB->AFR[0] = 0x0cc00000; + GPIOC->AFR[0] = 0x0000000c; + GPIOD->AFR[0] = 0x000000cc; + GPIOD->AFR[1] = 0xcc000ccc; + GPIOE->AFR[0] = 0xc00000cc; + GPIOE->AFR[1] = 0xcccccccc; + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xccccc000; + GPIOG->AFR[0] = 0x00cc0ccc; + GPIOG->AFR[1] = 0xc000000c; + + // Mode + GPIOB->MODER = 0x00002800; + GPIOC->MODER = 0x00000002; + GPIOD->MODER = 0xa02a000a; + GPIOE->MODER = 0xaaaa800a; + GPIOF->MODER = 0xaa800aaa; + GPIOG->MODER = 0x80020a2a; + + // Speed (high speed for all, very high speed for SDRAM pins) + GPIOB->OSPEEDR = 0x00003c00; + GPIOC->OSPEEDR = 0x00000003; + GPIOD->OSPEEDR = 0xf03f000f; + GPIOE->OSPEEDR = 0xffffc00f; + GPIOF->OSPEEDR = 0xffc00fff; + GPIOG->OSPEEDR = 0xc0030f3f; + + // Since we'we un-configured PB3 and PB4 (by default they are SWO and NJRST) + // finish the job and remove the default pull-up + GPIOB->PUPDR = 0; + + // Enable the SDRAM controller clock + RCC->AHB3ENR |= RCC_AHB3ENR_FMCEN; + RCC_SYNC(); + + // The SDRAM is a AS4C4M16SA-6TAN + // HCLK = 216MHz -> SDRAM clock = HCLK/2 = 133MHz + + // 1. Memory device features + FMC_Bank5_6->SDCR[0] = 0 // 0 delay after CAS latency + | FMC_SDCR1_RBURST // Enable read bursts + | FMC_SDCR1_SDCLK_1; // SDCLK = HCLK / 2 + FMC_Bank5_6->SDCR[1] = 0 // Write accesses allowed + | FMC_SDCR2_CAS_1 // 2 cycles CAS latency + | FMC_SDCR2_NB // 4 internal banks + | FMC_SDCR2_MWID_0 // 16 bit data bus + | FMC_SDCR2_NR_1 // 13 bit row address + // cppcheck-suppress duplicateExpression + | 0; // 8 bit column address + +// 2. Memory device timings +#ifdef SYSCLK_FREQ_216MHz + // SDRAM timings. One clock cycle is 9.26ns + FMC_Bank5_6->SDTR[0] = + (2 - 1) << FMC_SDTR1_TRP_Pos // 2 cycles TRP (18.52ns > 18ns) + | (7 - 1) << FMC_SDTR1_TRC_Pos; // 7 cycles TRC (64.82ns > 60ns) + FMC_Bank5_6->SDTR[1] = + (2 - 1) << FMC_SDTR1_TRCD_Pos // 2 cycles TRCD (18.52ns > 18ns) + | (2 - 1) << FMC_SDTR1_TWR_Pos // 2 cycles TWR (min 2cc > 12ns) + | (5 - 1) << FMC_SDTR1_TRAS_Pos // 5 cycles TRAS (46.3ns > 42ns) + | (7 - 1) << FMC_SDTR1_TXSR_Pos // 7 cycles TXSR (74.08ns > 61.5ns) + | (2 - 1) << FMC_SDTR1_TMRD_Pos; // 2 cycles TMRD (min 2cc > 12ns) +#else +#error No SDRAM timings for this clock +#endif + + // 3. Enable the bank 2 clock + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_0 // Clock Configuration Enable + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 4. Wait during command execution + delayUs(100); + + // 5. Issue a "Precharge All" command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 // Precharge all + | FMC_SDCMR_CTB2; // Bank 2 + sdramCommandWait(); + + // 6. Issue Auto-Refresh commands + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_1 | FMC_SDCMR_MODE_0 // Auto-Refresh + | FMC_SDCMR_CTB2 // Bank 2 + | (8 - 1) << FMC_SDCMR_NRFS_Pos; // 2 Auto-Refresh + sdramCommandWait(); + + // 7. Issue a Load Mode Register command + FMC_Bank5_6->SDCMR = FMC_SDCMR_MODE_2 /// Load mode register + | FMC_SDCMR_CTB2 // Bank 2 + | 0x220 << FMC_SDCMR_MRD_Pos; // CAS = 2, burst = 1 + sdramCommandWait(); + +// 8. Program the refresh rate (4K / 32ms) +// 64ms / 8192 = 7.8125us +#ifdef SYSCLK_FREQ_216MHz + // 7.8125us * 133MHz = 1039 - 20 = 1019 + FMC_Bank5_6->SDRTR = 1019 << FMC_SDRTR_COUNT_Pos; +#else +#error No SDRAM refresh timings for this clock +#endif +} + +void IRQbspInit() +{ + // Enable USART1 pins port + RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; + + interfaces::spi1::sck::mode(Mode::ALTERNATE); + interfaces::spi1::sck::alternateFunction(5); + interfaces::spi1::miso::mode(Mode::ALTERNATE); + interfaces::spi1::miso::alternateFunction(5); + interfaces::spi1::mosi::mode(Mode::ALTERNATE); + interfaces::spi1::mosi::alternateFunction(5); + + interfaces::spi3::sck::mode(Mode::ALTERNATE); + interfaces::spi3::sck::alternateFunction(6); + interfaces::spi3::miso::mode(Mode::ALTERNATE); + interfaces::spi3::miso::alternateFunction(6); + interfaces::spi3::mosi::mode(Mode::ALTERNATE); + interfaces::spi3::mosi::alternateFunction(5); + + interfaces::spi4::sck::mode(Mode::ALTERNATE); + interfaces::spi4::sck::alternateFunction(5); + interfaces::spi4::miso::mode(Mode::ALTERNATE); + interfaces::spi4::miso::alternateFunction(5); + interfaces::spi4::mosi::mode(Mode::ALTERNATE); + interfaces::spi4::mosi::alternateFunction(5); + + // USART1 configured by the miosix serial driver + + interfaces::usart2::tx::mode(Mode::ALTERNATE); + interfaces::usart2::tx::alternateFunction(7); + interfaces::usart2::rx::mode(Mode::ALTERNATE); + interfaces::usart2::rx::alternateFunction(7); + + interfaces::can2::tx::mode(Mode::ALTERNATE); + interfaces::can2::tx::alternateFunction(9); + interfaces::can2::rx::mode(Mode::ALTERNATE); + interfaces::can2::rx::alternateFunction(9); + + peripherals::leds::userLed1::mode(Mode::OUTPUT); + peripherals::leds::userLed2::mode(Mode::OUTPUT); + peripherals::leds::userLed3_1::mode(Mode::OUTPUT); + peripherals::leds::userLed3_2::mode(Mode::OUTPUT); + peripherals::leds::userLed4::mode(Mode::OUTPUT); + + peripherals::switches::userSwitch1::mode(Mode::INPUT); + + peripherals::lsm6dsrx::cs::mode(Mode::OUTPUT); + peripherals::lsm6dsrx::cs::high(); + peripherals::lsm6dsrx::int1::mode(Mode::INPUT); + peripherals::lsm6dsrx::int2::mode(Mode::INPUT); + + peripherals::h3lis331dl::cs::mode(Mode::OUTPUT); + peripherals::h3lis331dl::cs::high(); + peripherals::h3lis331dl::int1::mode(Mode::INPUT); + + peripherals::lis2mdl::cs::mode(Mode::OUTPUT); + peripherals::lis2mdl::cs::high(); + + peripherals::lps22df::cs::mode(Mode::OUTPUT); + peripherals::lps22df::cs::high(); + peripherals::lps22df::int1::mode(Mode::INPUT); + + peripherals::ads131m08::cs::mode(Mode::OUTPUT); + peripherals::ads131m08::cs::high(); + + peripherals::max31856::cs::mode(Mode::OUTPUT); + peripherals::max31856::cs::high(); + + peripherals::servos::servo1::mode(Mode::ALTERNATE); + peripherals::servos::servo1::alternateFunction(3); + peripherals::servos::servo2::mode(Mode::ALTERNATE); + peripherals::servos::servo2::alternateFunction(3); + + peripherals::tank_level::lvl1::mode(Mode::INPUT); + peripherals::tank_level::lvl2::mode(Mode::INPUT); + peripherals::tank_level::lvl3::mode(Mode::INPUT); + + peripherals::battery_voltage::ch15::mode(Mode::INPUT_ANALOG); + + DefaultConsole::instance().IRQset(intrusive_ref_ptr<Device>(new STM32Serial( + defaultSerial, defaultSerialSpeed, STM32Serial::NOFLOWCTRL))); +} + +void bspInit2() +{ +#ifdef WITH_FILESYSTEM + basicFilesystemSetup(SDIODriver::instance()); +#endif // WITH_FILESYSTEM + +#ifdef WITH_BACKUP_SRAM + // Print the reset reason + bootlog("Reset reson: "); + switch (SGM::instance().lastResetReason()) + { + case ResetReason::RST_LOW_PWR: + bootlog("low power\n"); + break; + case ResetReason::RST_WINDOW_WDG: + bootlog("window watchdog\n"); + break; + case ResetReason::RST_INDEPENDENT_WDG: + bootlog("indeendent watchdog\n"); + break; + case ResetReason::RST_SW: + bootlog("software reset\n"); + break; + case ResetReason::RST_POWER_ON: + bootlog("power on\n"); + break; + case ResetReason::RST_PIN: + bootlog("reset pin\n"); + break; + case ResetReason::RST_UNKNOWN: + bootlog("unknown\n"); + break; + } +#endif // WITH_BACKUP_SRAM +} + +// +// Shutdown and reboot +// + +void shutdown() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + for (;;) + ; +} + +void reboot() +{ + ioctl(STDOUT_FILENO, IOCTL_SYNC, 0); + +#ifdef WITH_FILESYSTEM + FilesystemManager::instance().umountAll(); +#endif // WITH_FILESYSTEM + + disableInterrupts(); + miosix_private::IRQsystemReboot(); +} + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/bsp_impl.h b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/bsp_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..5c82116ba88d1de2ae3aec23c73f5389905a5337 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/bsp_impl.h @@ -0,0 +1,106 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +/*************************************************************************** + * bsp_impl.h Part of the Miosix Embedded OS. + * Board support package, this file initializes hardware. + ***************************************************************************/ + +#ifndef BSP_IMPL_H +#define BSP_IMPL_H + +#include "config/miosix_settings.h" +#include "hwmapping.h" +#include "interfaces/gpio.h" + +namespace miosix +{ + +/** +\addtogroup Hardware +\{ +*/ + +/** + * \internal + * Called by stage_1_boot.cpp to enable the SDRAM before initializing .data/.bss + * Requires the CPU clock to be already configured (running from the PLL) + */ +void configureSdram(); + +inline void ledOn() +{ + peripherals::leds::userLed1::high(); + peripherals::leds::userLed2::high(); + peripherals::leds::userLed3_1::high(); + peripherals::leds::userLed3_2::high(); + peripherals::leds::userLed4::high(); +} + +inline void ledOff() +{ + peripherals::leds::userLed1::low(); + peripherals::leds::userLed2::low(); + peripherals::leds::userLed3_1::low(); + peripherals::leds::userLed3_2::low(); + peripherals::leds::userLed4::low(); +} + +inline void led1On() { peripherals::leds::userLed1::high(); } + +inline void led1Off() { peripherals::leds::userLed1::low(); } + +inline void led2On() { peripherals::leds::userLed2::high(); } + +inline void led2Off() { peripherals::leds::userLed2::low(); } + +inline void led3On() +{ + peripherals::leds::userLed3_1::high(); + peripherals::leds::userLed3_2::high(); +} + +inline void led3Off() +{ + peripherals::leds::userLed3_1::low(); + peripherals::leds::userLed3_2::low(); +} + +/** + * Polls the SD card sense GPIO. + * + * This board has no SD card whatsoever, but a card can be connected to the + * following GPIOs: + * TODO: never tested + * + * \return true. As there's no SD card sense switch, let's pretend that + * the card is present. + */ +inline bool sdCardSense() { return true; } + +/** +\} +*/ + +} // namespace miosix + +#endif // BSP_IMPL_H diff --git a/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/hwmapping.h b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/hwmapping.h new file mode 100644 index 0000000000000000000000000000000000000000..5916f30a471a58ffed9d422c1e4a630fc6da2461 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/interfaces-impl/hwmapping.h @@ -0,0 +1,145 @@ +/* Copyright (c) 2023 Skyward Experimental Rocketry + * Author: Alberto Nidasio + * + * 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. + */ + +#pragma once + +#include "interfaces/gpio.h" + +namespace miosix +{ + +namespace interfaces +{ + +namespace spi1 +{ +using sck = Gpio<GPIOA_BASE, 5>; +using miso = Gpio<GPIOA_BASE, 6>; +using mosi = Gpio<GPIOA_BASE, 7>; +} // namespace spi1 + +namespace spi3 +{ +using sck = Gpio<GPIOB_BASE, 3>; +using miso = Gpio<GPIOB_BASE, 4>; +using mosi = Gpio<GPIOD_BASE, 6>; +} // namespace spi3 + +namespace spi4 +{ +using sck = Gpio<GPIOE_BASE, 2>; +using miso = Gpio<GPIOE_BASE, 5>; +using mosi = Gpio<GPIOE_BASE, 6>; +} // namespace spi4 + +namespace usart1 +{ +using tx = Gpio<GPIOA_BASE, 2>; +using rx = Gpio<GPIOA_BASE, 3>; +} // namespace usart1 + +namespace usart2 +{ +using tx = Gpio<GPIOA_BASE, 9>; +using rx = Gpio<GPIOA_BASE, 10>; +} // namespace usart2 + +namespace can2 +{ +using tx = Gpio<GPIOB_BASE, 12>; +using rx = Gpio<GPIOB_BASE, 13>; +} // namespace can2 + +} // namespace interfaces + +namespace peripherals +{ + +namespace leds +{ +using userLed1 = Gpio<GPIOB_BASE, 7>; +using userLed2 = Gpio<GPIOE_BASE, 3>; +using userLed3_1 = Gpio<GPIOC_BASE, 13>; // On MCU rev 2 +using userLed3_2 = Gpio<GPIOG_BASE, 9>; // On MCU rev 3 +using userLed4 = Gpio<GPIOC_BASE, 2>; +} // namespace leds + +namespace switches +{ +using userSwitch1 = Gpio<GPIOB_BASE, 2>; +} + +namespace lsm6dsrx +{ +using cs = Gpio<GPIOC_BASE, 4>; +using int1 = Gpio<GPIOD_BASE, 13>; +using int2 = Gpio<GPIOG_BASE, 7>; +} // namespace lsm6dsrx + +namespace h3lis331dl +{ +using cs = Gpio<GPIOD_BASE, 3>; +using int1 = Gpio<GPIOC_BASE, 3>; +} // namespace h3lis331dl + +namespace lis2mdl +{ +using cs = Gpio<GPIOD_BASE, 5>; +} // namespace lis2mdl + +namespace lps22df +{ +using cs = Gpio<GPIOD_BASE, 7>; +using int1 = Gpio<GPIOB_BASE, 11>; +} // namespace lps22df + +namespace ads131m08 +{ +using cs = Gpio<GPIOG_BASE, 10>; +} // namespace ads131m08 + +namespace max31856 +{ +using cs = Gpio<GPIOD_BASE, 4>; +} // namespace max31856 + +namespace servos +{ +using servo1 = Gpio<GPIOC_BASE, 6>; // TIM8 CH1 +using servo2 = Gpio<GPIOC_BASE, 7>; // TIM8 CH2 +} // namespace servos + +namespace tank_level +{ +using lvl1 = Gpio<GPIOB_BASE, 1>; +using lvl2 = Gpio<GPIOG_BASE, 6>; +using lvl3 = Gpio<GPIOB_BASE, 14>; +} // namespace tank_level + +namespace battery_voltage +{ +using ch15 = Gpio<GPIOC_BASE, 5>; +} + +} // namespace peripherals + +} // namespace miosix diff --git a/src/bsps/stm32f767zi_gemini_motor/stm32_2m+16m_xram.ld b/src/bsps/stm32f767zi_gemini_motor/stm32_2m+16m_xram.ld new file mode 100644 index 0000000000000000000000000000000000000000..5b3545abd6f3007072b8ff00a978242d74503d79 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/stm32_2m+16m_xram.ld @@ -0,0 +1,190 @@ +/* + * C++ enabled linker script for stm32f769ni (2M FLASH, 512K RAM, 16MB XRAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the external 16MB SDRAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap into XRAM */ +_heap_end = 0xd0000000 + 16M; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + xram(wx) : ORIGIN = 0xd0000000, LENGTH = 16M + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to xram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > xram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to xram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > xram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/bsps/stm32f767zi_gemini_motor/stm32_2m+384k_ram.ld b/src/bsps/stm32f767zi_gemini_motor/stm32_2m+384k_ram.ld new file mode 100644 index 0000000000000000000000000000000000000000..497bd5198760b9637c774bf3900fd9dfbc01a2b2 --- /dev/null +++ b/src/bsps/stm32f767zi_gemini_motor/stm32_2m+384k_ram.ld @@ -0,0 +1,189 @@ +/* + * C++ enabled linker script for stm32f767zi (2M FLASH, 512K RAM) + * Developed by TFT: Terraneo Federico Technologies + * Optimized for use with the Miosix kernel + */ + +/* + * This linker script puts: + * - read only data and code (.text, .rodata, .eh_*) in FLASH + * - the 512Byte main (IRQ) stack, .data and .bss in the DTCM 128KB RAM + * - .data, .bss, stacks and heap in the internal RAM. + */ + +/* + * The main stack is used for interrupt handling by the kernel. + * + * *** Readme *** + * This linker script places the main stack (used by the kernel for interrupts) + * at the bottom of the ram, instead of the top. This is done for two reasons: + * + * - as an optimization for microcontrollers with little ram memory. In fact + * the implementation of malloc from newlib requests memory to the OS in 4KB + * block (except the first block that can be smaller). This is probably done + * for compatibility with OSes with an MMU and paged memory. To see why this + * is bad, consider a microcontroller with 8KB of ram: when malloc finishes + * up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will + * fail because the top part of the ram is used by the main stack. As a + * result, the top part of the memory will not be used by malloc, even if + * available (and it is nearly *half* the ram on an 8KB mcu). By placing the + * main stack at the bottom of the ram, the upper 4KB block will be entirely + * free and available as heap space. + * + * - In case of main stack overflow the cpu will fault because access to memory + * before the beginning of the ram faults. Instead with the default stack + * placement the main stack will silently collide with the heap. + * Note: if increasing the main stack size also increase the ORIGIN value in + * the MEMORY definitions below accordingly. + */ + +_main_stack_size = 512; /* main stack = 512Bytes */ +_main_stack_top = 0x20000000 + _main_stack_size; +ASSERT(_main_stack_size % 8 == 0, "MAIN stack size error"); + +/* Mapping the heap to the end of SRAM2 */ +_heap_end = 0x20000000 + 512K; /* end of available ram */ + +/* Identify the Entry Point */ +ENTRY(_Z13Reset_Handlerv) + +/* + * Specify the memory areas + * + * NOTE: starting at 0x20000000 there's 128KB of DTCM (Data Tightly Coupled + * Memory). Technically, we could use this as normal RAM as there's a way for + * the DMA to access it, but the datasheet is unclear about performance + * penalties for doing so. To avoid nonuniform DMA memory access latencies, + * we leave this 128KB DTCM unused except for the first 512Bytes which are for + * the interrupt stack. This leaves us with 384KB of RAM + */ +MEMORY +{ + sram(wx) : ORIGIN = 0x20020000, LENGTH = 384K + dtcm(wx) : ORIGIN = 0x20000000, LENGTH = 128K /* Used for main stack */ + bram(rw) : ORIGIN = 0x40024000, LENGTH = 4K /* Bakup SRAM */ + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2M +} + +/* now define the output sections */ +SECTIONS +{ + . = 0; + + /* .text section: code goes to flash */ + .text : + { + /* Startup code must go at address 0 */ + KEEP(*(.isr_vector)) + + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + /* these sections for thumb interwork? */ + *(.glue_7) + *(.glue_7t) + /* these sections for C++? */ + *(.gcc_except_table) + *(.gcc_except_table.*) + *(.ARM.extab*) + *(.gnu.linkonce.armextab.*) + + . = ALIGN(4); + /* .rodata: constant data */ + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + + /* C++ Static constructors/destructors (eabi) */ + . = ALIGN(4); + KEEP(*(.init)) + + . = ALIGN(4); + __miosix_init_array_start = .; + KEEP (*(SORT(.miosix_init_array.*))) + KEEP (*(.miosix_init_array)) + __miosix_init_array_end = .; + + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + /* C++ Static constructors/destructors (elf) */ + . = ALIGN(4); + _ctor_start = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + _ctor_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + } > flash + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash + __exidx_end = .; + + /* + * .data section: global variables go to sram, but also store a copy to + * flash to initialize them + */ + .data : ALIGN(8) + { + _data = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + _edata = .; + } > sram AT > flash + _etext = LOADADDR(.data); + + /* .bss section: uninitialized global variables go to sram */ + _bss_start = .; + .bss : + { + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + . = ALIGN(8); + } > sram + _bss_end = .; + + _end = .; + PROVIDE(end = .); + + .preserve(NOLOAD) : ALIGN(4) + { + _preserve_start = .; + . = ALIGN(4); + *(.preserve); + *(.preserve*); + . = ALIGN(4); + _preserve_end = .; + } > bram +} diff --git a/src/entrypoints/bmx160-calibration-entry.cpp b/src/entrypoints/bmx160-calibration-entry.cpp index 40e57dc55447ef5165bfebdb252643d6c366125d..2d36db1e9760a947bfff29dbd324c7a0647c8bcb 100644 --- a/src/entrypoints/bmx160-calibration-entry.cpp +++ b/src/entrypoints/bmx160-calibration-entry.cpp @@ -78,12 +78,12 @@ constexpr const char* testHumanFriendlyDirection[]{ "Z up", "X up", "Y up", "Z down", "X down", "Y down", }; -#if defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) +#if defined(_BOARD_STM32F429ZI_DEATH_STACK_V2) SPIBus bus(SPI1); void __attribute__((used)) EXTI5_IRQHandlerImpl() { -#elif defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) +#elif defined(_BOARD_STM32F429ZI_DEATH_STACK_V3) SPIBus bus(SPI4); void __attribute__((used)) EXTI3_IRQHandlerImpl() @@ -105,11 +105,11 @@ void calibrateGyroscope(); int main() { // Enable interrupt from BMX pin -#if defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_X) +#if defined(_BOARD_STM32F429ZI_DEATH_STACK_V2) enableExternalInterrupt(miosix::sensors::bmx160::intr::getPin().getPort(), miosix::sensors::bmx160::intr::getPin().getNumber(), InterruptTrigger::FALLING_EDGE); -#elif defined(_BOARD_STM32F429ZI_SKYWARD_DEATHST_V3) +#elif defined(_BOARD_STM32F429ZI_DEATH_STACK_V3) enableExternalInterrupt(miosix::sensors::bmx160::intr::getPin().getPort(), miosix::sensors::bmx160::intr::getPin().getNumber(), InterruptTrigger::FALLING_EDGE); diff --git a/src/entrypoints/sx1278-serial.cpp b/src/entrypoints/sx1278-serial.cpp index ae0e6f41ae36a2b43fec40d02a6cbc7232e1d1d5..ede273cb243c0f8d76512966177fcbb85aa5698b 100644 --- a/src/entrypoints/sx1278-serial.cpp +++ b/src/entrypoints/sx1278-serial.cpp @@ -36,7 +36,7 @@ using namespace miosix; // Or use SBS to define it for you // #define SX1278_IS_LORA -#if defined _BOARD_STM32F429ZI_SKYWARD_GS_V2 +#if defined _BOARD_STM32F429ZI_NOKIA #include "interfaces-impl/hwmapping.h" // Uncomment the following line to enable Ebyte module @@ -64,7 +64,7 @@ using rxen = Gpio<GPIOD_BASE, 4>; #define SX1278_IRQ_DIO1 EXTI4_IRQHandlerImpl #define SX1278_IRQ_DIO3 EXTI11_IRQHandlerImpl -#elif defined _BOARD_STM32F429ZI_SKYWARD_RIG +#elif defined _BOARD_STM32F429ZI_RIG #include "interfaces-impl/hwmapping.h" #define SX1278_IS_EBYTE diff --git a/src/tests/drivers/xbee/test-xbee-bidir.cpp b/src/tests/drivers/xbee/test-xbee-bidir.cpp index 27a1af9e77be308f06b9ee63e20ceb8c0c887367..def6764fda67deaf5aa1bae13881ea50e9ccdf03 100644 --- a/src/tests/drivers/xbee/test-xbee-bidir.cpp +++ b/src/tests/drivers/xbee/test-xbee-bidir.cpp @@ -43,7 +43,7 @@ using namespace Boardcore; using namespace miosix; -#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X +#ifdef _BOARD_STM32F429ZI_DEATH_STACK_V2 #include "interfaces-impl/hwmapping.h" using GpioMiso = miosix::interfaces::spi2::miso; using GpioMosi = miosix::interfaces::spi2::mosi; @@ -74,7 +74,7 @@ using GpioUserBtn = Gpio<GPIOA_BASE, 0>; Xbee::Xbee* xbeeDriver = nullptr; Logger& logger = Logger::getInstance(); -#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X +#ifdef _BOARD_STM32F429ZI_DEATH_STACK_V2 void __attribute__((used)) EXTI10_IRQHandlerImpl() #else void __attribute__((used)) EXTI5_IRQHandlerImpl() @@ -88,7 +88,7 @@ void __attribute__((used)) EXTI5_IRQHandlerImpl() int getUserBtnValue() { -#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X +#ifdef _BOARD_STM32F429ZI_DEATH_STACK_V2 return 0; #else return GpioUserBtn::value(); @@ -97,7 +97,7 @@ int getUserBtnValue() void configure() { -#ifndef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X +#ifndef _BOARD_STM32F429ZI_DEATH_STACK_V2 { FastInterruptDisableLock dLock; @@ -123,7 +123,7 @@ void configure() GpioLedLog::low(); #endif -#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X +#ifdef _BOARD_STM32F429ZI_DEATH_STACK_V2 enableExternalInterrupt(GPIOF_BASE, 10, InterruptTrigger::FALLING_EDGE); #else enableExternalInterrupt(GPIOE_BASE, 5, InterruptTrigger::FALLING_EDGE); diff --git a/src/tests/radio/sx1278/fsk/test-sx1278-bidir.cpp b/src/tests/radio/sx1278/fsk/test-sx1278-bidir.cpp index 19de226e5b3e822e6759ef16a99acfb1e39e762d..1d3670053458c12ae4860f08338503fa1892afc3 100644 --- a/src/tests/radio/sx1278/fsk/test-sx1278-bidir.cpp +++ b/src/tests/radio/sx1278/fsk/test-sx1278-bidir.cpp @@ -33,7 +33,7 @@ using namespace Boardcore; using namespace miosix; -#if defined _BOARD_STM32F429ZI_SKYWARD_GS_V2 +#if defined _BOARD_STM32F429ZI_NOKIA #include "interfaces-impl/hwmapping.h" using cs = peripherals::ra01::pc13::cs; diff --git a/src/tests/radio/sx1278/fsk/test-sx1278-mavlink.cpp b/src/tests/radio/sx1278/fsk/test-sx1278-mavlink.cpp index 2ea4330776a25051354534ef0c85aa25fe5b15ef..794a7378cbfa51eb08e0afd0f2ff19040e215d9b 100644 --- a/src/tests/radio/sx1278/fsk/test-sx1278-mavlink.cpp +++ b/src/tests/radio/sx1278/fsk/test-sx1278-mavlink.cpp @@ -53,7 +53,7 @@ constexpr uint32_t FLIGHT_TM_PERIOD = 250; using Mav = MavlinkDriver<RADIO_PKT_LENGTH, RADIO_OUT_QUEUE_SIZE, RADIO_MAV_MSG_LENGTH>; -#if defined _BOARD_STM32F429ZI_SKYWARD_GS_V2 +#if defined _BOARD_STM32F429ZI_NOKIA #include "interfaces-impl/hwmapping.h" using cs = peripherals::ra01::pc13::cs; @@ -176,7 +176,7 @@ void flightTmLoop() while (1) { - long long start = miosix::getTick(); + long long start = miosix::getTick; { Lock<FastMutex> l(mutex); diff --git a/src/tests/radio/sx1278/lora/test-sx1278-bidir.cpp b/src/tests/radio/sx1278/lora/test-sx1278-bidir.cpp index a08f009cb9c699e49e0bf0df69217d6d5a3056c2..673354430f52513ad1261ef651d7ada2ab2f2cae 100644 --- a/src/tests/radio/sx1278/lora/test-sx1278-bidir.cpp +++ b/src/tests/radio/sx1278/lora/test-sx1278-bidir.cpp @@ -31,7 +31,7 @@ using namespace Boardcore; using namespace miosix; -#if defined _BOARD_STM32F429ZI_SKYWARD_GS_V2 +#if defined _BOARD_STM32F429ZI_NOKIA #include "interfaces-impl/hwmapping.h" // Uncomment the following line to enable Ebyte module diff --git a/src/tests/radio/sx1278/lora/test-sx1278-mavlink.cpp b/src/tests/radio/sx1278/lora/test-sx1278-mavlink.cpp index 4bf32e6ba58c3719140a1e7a6d38e3071b434ce7..38398038442bab4e9df06774eef23d7be96ca75b 100644 --- a/src/tests/radio/sx1278/lora/test-sx1278-mavlink.cpp +++ b/src/tests/radio/sx1278/lora/test-sx1278-mavlink.cpp @@ -51,7 +51,7 @@ constexpr uint32_t STATS_TM_PERIOD = 1000; using Mav = MavlinkDriver<RADIO_PKT_LENGTH, RADIO_OUT_QUEUE_SIZE, RADIO_MAV_MSG_LENGTH>; -#if defined _BOARD_STM32F429ZI_SKYWARD_GS_V2 +#if defined _BOARD_STM32F429ZI_NOKIA #include "interfaces-impl/hwmapping.h" // Uncomment the following line to enable Ebyte module diff --git a/src/tests/radio/sx1278/lora/test-sx1278-simple.cpp b/src/tests/radio/sx1278/lora/test-sx1278-simple.cpp index 2d4bdc75b62f457aa44bc77104d7c53df3ab1a5d..efca424cc8a07f76edcdb594708465dce18aef01 100644 --- a/src/tests/radio/sx1278/lora/test-sx1278-simple.cpp +++ b/src/tests/radio/sx1278/lora/test-sx1278-simple.cpp @@ -27,7 +27,7 @@ using namespace Boardcore; using namespace miosix; -#if defined _BOARD_STM32F429ZI_SKYWARD_GS_V2 +#if defined _BOARD_STM32F429ZI_NOKIA #include "interfaces-impl/hwmapping.h" // Uncomment the following line to enable Ebyte module diff --git a/src/tests/radio/sx1278/sx1278-init.h b/src/tests/radio/sx1278/sx1278-init.h index f304948729a401b0045b907b2d971592d5c03742..068d7eb2861cebae47f831591a7f11c3767680aa 100644 --- a/src/tests/radio/sx1278/sx1278-init.h +++ b/src/tests/radio/sx1278/sx1278-init.h @@ -34,7 +34,7 @@ // Or use SBS to define it for you // #define SX1278_IS_LORA -#if defined _BOARD_STM32F429ZI_SKYWARD_GS_V2 +#if defined _BOARD_STM32F429ZI_NOKIA #include "interfaces-impl/hwmapping.h" // Uncomment the following line to enable Ebyte module @@ -62,7 +62,7 @@ using rxen = miosix::Gpio<GPIOD_BASE, 4>; #define SX1278_IRQ_DIO1 EXTI4_IRQHandlerImpl #define SX1278_IRQ_DIO3 EXTI11_IRQHandlerImpl -#elif defined _BOARD_STM32F429ZI_SKYWARD_RIG +#elif defined _BOARD_STM32F429ZI_RIG #include "interfaces-impl/hwmapping.h" #define SX1278_IS_EBYTE @@ -76,8 +76,8 @@ using sck = miosix::radio::sck; using miso = miosix::radio::miso; using mosi = miosix::radio::mosi; -using txen = miosix::radio::txEn; -using rxen = miosix::radio::rxEn; +using txen = miosix::radio::txEn; +using rxen = miosix::radio::rxEn; #define SX1278_SPI SPI4 @@ -208,11 +208,11 @@ bool initRadio() #elif defined SX1278_IS_SKYWARD433 printf("[sx1278] Confuring Skyward 433 frontend...\n"); std::unique_ptr<Boardcore::SX1278::ISX1278Frontend> frontend( - new Boardcore::Skyward433Frontend()); + new Boardcore::Skyward433Frontend()); #else printf("[sx1278] Confuring RA01 frontend...\n"); std::unique_ptr<Boardcore::SX1278::ISX1278Frontend> frontend( - new Boardcore::RA01Frontend()); + new Boardcore::RA01Frontend()); #endif // Initialize actual radio driver @@ -240,14 +240,14 @@ bool initRadio() Boardcore::SX1278Fsk::Error err; sx1278 = new Boardcore::SX1278Fsk(sx1278_bus, cs::getPin(), dio0::getPin(), - dio1::getPin(), dio3::getPin(), - Boardcore::SPI::ClockDivider::DIV_256, - std::move(frontend)); + dio1::getPin(), dio3::getPin(), + Boardcore::SPI::ClockDivider::DIV_256, + std::move(frontend)); printf("\n[sx1278] Configuring sx1278 fsk...\n"); if ((err = sx1278->init(config)) != Boardcore::SX1278Fsk::Error::NONE) { - // FIXME: Why does clang-format put this line up here? + // FIXME: Why does clang-format put this line up here? printf("[sx1278] sx1278->init error\n"); return false; } diff --git a/src/tests/sensors/test-ubxgps-spi.cpp b/src/tests/sensors/test-ubxgps-spi.cpp index 3fcecde01e161e98c8e01a1aa2021d8e4e4775dc..bb60e2342f0b77f3ebbb5052b2d83fbcba1f9834 100644 --- a/src/tests/sensors/test-ubxgps-spi.cpp +++ b/src/tests/sensors/test-ubxgps-spi.cpp @@ -28,7 +28,7 @@ using namespace Boardcore; int main() { -#ifdef _BOARD_STM32F429ZI_SKYWARD_DEATHST_X +#ifdef _BOARD_STM32F429ZI_DEATH_STACK_V2 SPIBus spiBus(SPI2); GpioPin spiCs(GPIOG_BASE, 3); GpioPin spiSck(GPIOB_BASE, 13);