From 4ee13ec44babae5d89f3e5abce60a9c1df857667 Mon Sep 17 00:00:00 2001 From: Alecks Date: Fri, 1 Aug 2025 14:35:49 +0800 Subject: [PATCH] Base Firmware --- .gitignore | 5 + .mxproject | 33 + .vscode/iar-vsc.json | 32 + .vscode/settings.json | 7 + Core/Inc/eg91.h | 334 +++ Core/Inc/eg91_conf.h | 80 + Core/Inc/gpio.h | 52 + Core/Inc/icache.h | 50 + Core/Inc/lte_comms.h | 132 ++ Core/Inc/main.h | 88 + Core/Inc/rtc.h | 52 + Core/Inc/stm32wbaxx_hal_conf.h | 353 ++++ Core/Inc/stm32wbaxx_it.h | 68 + Core/Inc/usart.h | 115 ++ Core/Src/eg91.c | 1801 +++++++++++++++++ Core/Src/gpio.c | 136 ++ Core/Src/icache.c | 57 + Core/Src/lte_comms.c | 586 ++++++ Core/Src/main.c | 212 ++ Core/Src/rtc.c | 125 ++ Core/Src/stm32wbaxx_hal_msp.c | 87 + Core/Src/stm32wbaxx_it.c | 232 +++ Core/Src/system_stm32wbaxx.c | 390 ++++ Core/Src/usart.c | 394 ++++ EWARM/Backup of WiseEye-LTE.ewd | 1534 ++++++++++++++ EWARM/Backup of WiseEye-LTE.ewp | 1166 +++++++++++ EWARM/Backup of WiseEye-LTE.ewt | 1519 ++++++++++++++ EWARM/Project.eww | 7 + EWARM/WiseEye-LTE.ewd | 1615 +++++++++++++++ EWARM/WiseEye-LTE.ewp | 1206 +++++++++++ EWARM/WiseEye-LTE.ewt | 1537 ++++++++++++++ EWARM/WiseEye-LTE/.WiseEye-LTE_build_cache | 12 + EWARM/WiseEye-LTE/.ninja_deps | Bin 0 -> 21224 bytes EWARM/WiseEye-LTE/.ninja_log | 94 + EWARM/WiseEye-LTE/Exe/WiseEye-LTE.hex | 1553 ++++++++++++++ EWARM/WiseEye-LTE/Exe/WiseEye-LTE.out | Bin 0 -> 473368 bytes EWARM/WiseEye-LTE/Exe/WiseEye-LTE.sim | Bin 0 -> 24827 bytes EWARM/WiseEye-LTE/List/WiseEye-LTE.map | 822 ++++++++ EWARM/settings/Project.wsdt | 517 +++++ EWARM/settings/Project_EditorBookmarks.xml | 2 + .../settings/WiseEye-LTE.WiseEye-LTE.cspy.bat | 40 + .../settings/WiseEye-LTE.WiseEye-LTE.cspy.ps1 | 31 + .../WiseEye-LTE.WiseEye-LTE.driver.xcl | 31 + .../WiseEye-LTE.WiseEye-LTE.general.xcl | 17 + EWARM/settings/WiseEye-LTE.crun | 13 + EWARM/settings/WiseEye-LTE.dbgdt | 4 + EWARM/settings/WiseEye-LTE.dnx | 124 ++ EWARM/settings/WiseEye_LTE.wsdt | 506 +++++ .../settings/WiseEye_LTE_EditorBookmarks.xml | 2 + EWARM/startup_stm32wba52xx.s | 562 +++++ EWARM/stm32wba52xx_flash.icf | 35 + EWARM/stm32wba52xx_sram.icf | 36 + WiseEye-LTE-2.ioc | 194 ++ WiseEye-LTE.ioc | 249 +++ 54 files changed, 18849 insertions(+) create mode 100644 .mxproject create mode 100644 .vscode/iar-vsc.json create mode 100644 .vscode/settings.json create mode 100644 Core/Inc/eg91.h create mode 100644 Core/Inc/eg91_conf.h create mode 100644 Core/Inc/gpio.h create mode 100644 Core/Inc/icache.h create mode 100644 Core/Inc/lte_comms.h create mode 100644 Core/Inc/main.h create mode 100644 Core/Inc/rtc.h create mode 100644 Core/Inc/stm32wbaxx_hal_conf.h create mode 100644 Core/Inc/stm32wbaxx_it.h create mode 100644 Core/Inc/usart.h create mode 100644 Core/Src/eg91.c create mode 100644 Core/Src/gpio.c create mode 100644 Core/Src/icache.c create mode 100644 Core/Src/lte_comms.c create mode 100644 Core/Src/main.c create mode 100644 Core/Src/rtc.c create mode 100644 Core/Src/stm32wbaxx_hal_msp.c create mode 100644 Core/Src/stm32wbaxx_it.c create mode 100644 Core/Src/system_stm32wbaxx.c create mode 100644 Core/Src/usart.c create mode 100644 EWARM/Backup of WiseEye-LTE.ewd create mode 100644 EWARM/Backup of WiseEye-LTE.ewp create mode 100644 EWARM/Backup of WiseEye-LTE.ewt create mode 100644 EWARM/Project.eww create mode 100644 EWARM/WiseEye-LTE.ewd create mode 100644 EWARM/WiseEye-LTE.ewp create mode 100644 EWARM/WiseEye-LTE.ewt create mode 100644 EWARM/WiseEye-LTE/.WiseEye-LTE_build_cache create mode 100644 EWARM/WiseEye-LTE/.ninja_deps create mode 100644 EWARM/WiseEye-LTE/.ninja_log create mode 100644 EWARM/WiseEye-LTE/Exe/WiseEye-LTE.hex create mode 100644 EWARM/WiseEye-LTE/Exe/WiseEye-LTE.out create mode 100644 EWARM/WiseEye-LTE/Exe/WiseEye-LTE.sim create mode 100644 EWARM/WiseEye-LTE/List/WiseEye-LTE.map create mode 100644 EWARM/settings/Project.wsdt create mode 100644 EWARM/settings/Project_EditorBookmarks.xml create mode 100644 EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.bat create mode 100644 EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.ps1 create mode 100644 EWARM/settings/WiseEye-LTE.WiseEye-LTE.driver.xcl create mode 100644 EWARM/settings/WiseEye-LTE.WiseEye-LTE.general.xcl create mode 100644 EWARM/settings/WiseEye-LTE.crun create mode 100644 EWARM/settings/WiseEye-LTE.dbgdt create mode 100644 EWARM/settings/WiseEye-LTE.dnx create mode 100644 EWARM/settings/WiseEye_LTE.wsdt create mode 100644 EWARM/settings/WiseEye_LTE_EditorBookmarks.xml create mode 100644 EWARM/startup_stm32wba52xx.s create mode 100644 EWARM/stm32wba52xx_flash.icf create mode 100644 EWARM/stm32wba52xx_sram.icf create mode 100644 WiseEye-LTE-2.ioc create mode 100644 WiseEye-LTE.ioc diff --git a/.gitignore b/.gitignore index 4a1f5a5..1e6b36c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,8 @@ compile_commands.json CTestTestfile.cmake _deps +# ---> Output +*.o + +# ---> Folder +/EWARM/WiseEye-LTE/BrowseInfo \ No newline at end of file diff --git a/.mxproject b/.mxproject new file mode 100644 index 0000000..df5567b --- /dev/null +++ b/.mxproject @@ -0,0 +1,33 @@ +[PreviousLibFiles] +LibFiles=Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_cortex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_cortex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_def.h;Drivers\STM32WBAxx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_bus.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_system.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rcc.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rcc_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_rcc.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_utils.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_flash.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_flash_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_gpio.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_gpio_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_gpio.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_dma.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_dma.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_dma_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_exti.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_exti.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_pwr.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_pwr.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_pwr_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_hsem.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_icache.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_icache.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_uart.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_usart.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_lpuart.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_uart_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rtc.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rtc_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_rtc.h;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_cortex.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc_ex.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash_ex.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_gpio.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma_ex.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_exti.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr_ex.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_hsem.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_icache.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart_ex.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc.c;Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc_ex.c;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_cortex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_cortex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_def.h;Drivers\STM32WBAxx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_bus.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_system.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rcc.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rcc_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_rcc.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_utils.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_flash.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_flash_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_gpio.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_gpio_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_gpio.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_dma.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_dma.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_dma_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_exti.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_exti.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_pwr.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_pwr.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_pwr_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_hsem.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_icache.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_icache.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_uart.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_usart.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_lpuart.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_uart_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rtc.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_hal_rtc_ex.h;Drivers\STM32WBAxx_HAL_Driver\Inc\stm32wbaxx_ll_rtc.h;Drivers\CMSIS\Device\ST\STM32WBAxx\Include\stm32wba52xx.h;Drivers\CMSIS\Device\ST\STM32WBAxx\Include\stm32wbaxx.h;Drivers\CMSIS\Device\ST\STM32WBAxx\Include\system_stm32wbaxx.h;Drivers\CMSIS\Device\ST\STM32WBAxx\Include\system_stm32wbaxx.h;Drivers\CMSIS\Device\ST\STM32WBAxx\Source\Templates\system_stm32wbaxx.c;Drivers\CMSIS\Include\cachel1_armv7.h;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm55.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_cm85.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\core_starmc1.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\pac_armv81.h;Drivers\CMSIS\Include\pmu_armv8.h;Drivers\CMSIS\Include\tz_context.h; + +[PreviousUsedIarFiles] +SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\icache.c;..\Core\Src\usart.c;..\Core\Src\rtc.c;..\Core\Src\stm32wbaxx_it.c;..\Core\Src\stm32wbaxx_hal_msp.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_cortex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_gpio.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_exti.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_hsem.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_icache.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\CMSIS\Device\ST\STM32WBAxx\Source\Templates\system_stm32wbaxx.c;..\Core\Src\system_stm32wbaxx.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_cortex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_gpio.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_exti.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_hsem.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_icache.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc_ex.c;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\CMSIS\Device\ST\STM32WBAxx\Source\Templates\system_stm32wbaxx.c;..\Core\Src\system_stm32wbaxx.c;;; +HeaderPath=C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Inc;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Inc\Legacy;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\CMSIS\Device\ST\STM32WBAxx\Include;C:\Users\Admin\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\CMSIS\Include;..\Core\Inc; +CDefines=USE_HAL_DRIVER;STM32WBA52xx;USE_HAL_DRIVER;USE_HAL_DRIVER; + +[PreviousGenFiles] +AdvancedFolderStructure=true +HeaderFileListSize=7 +HeaderFiles#0=..\Core\Inc\gpio.h +HeaderFiles#1=..\Core\Inc\icache.h +HeaderFiles#2=..\Core\Inc\usart.h +HeaderFiles#3=..\Core\Inc\rtc.h +HeaderFiles#4=..\Core\Inc\stm32wbaxx_it.h +HeaderFiles#5=..\Core\Inc\stm32wbaxx_hal_conf.h +HeaderFiles#6=..\Core\Inc\main.h +HeaderFolderListSize=1 +HeaderPath#0=..\Core\Inc +HeaderFiles=; +SourceFileListSize=7 +SourceFiles#0=..\Core\Src\gpio.c +SourceFiles#1=..\Core\Src\icache.c +SourceFiles#2=..\Core\Src\usart.c +SourceFiles#3=..\Core\Src\rtc.c +SourceFiles#4=..\Core\Src\stm32wbaxx_it.c +SourceFiles#5=..\Core\Src\stm32wbaxx_hal_msp.c +SourceFiles#6=..\Core\Src\main.c +SourceFolderListSize=1 +SourcePath#0=..\Core\Src +SourceFiles=; + diff --git a/.vscode/iar-vsc.json b/.vscode/iar-vsc.json new file mode 100644 index 0000000..0a4cab4 --- /dev/null +++ b/.vscode/iar-vsc.json @@ -0,0 +1,32 @@ +{ + "workspace": { + "path": "${workspaceFolder}\\EWARM\\Project.eww" + }, + "workspaces": { + "${workspaceFolder}\\EWARM\\Project.eww": { + "configs": { + "${workspaceFolder}\\EWARM\\WiseEye-LTE.ewp": "WiseEye-LTE" + }, + "selected": { + "path": "${workspaceFolder}\\EWARM\\WiseEye-LTE.ewp" + } + }, + "${workspaceFolder}\\EWARM\\WiseEye_LTE.eww": { + "configs": { + "${workspaceFolder}\\EWARM\\WiseEye-LTE.ewp": "WiseEye-LTE" + }, + "selected": { + "path": "${workspaceFolder}\\EWARM\\WiseEye-LTE.ewp" + } + } + }, + "workbench": { + "path": "C:\\Program Files\\IAR Systems\\Embedded Workbench 9.2" + }, + "configs": { + "${workspaceFolder}\\EWARM\\WiseEye-LTE.ewp": "WiseEye-LTE" + }, + "project": { + "path": "${workspaceFolder}\\EWARM\\WiseEye-LTE.ewp" + } +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f1fde13 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "C_Cpp.default.configurationProvider": "iarsystems.iar-build", + "files.associations": { + "eg91.h": "c", + "lte_comms.h": "c" + } +} \ No newline at end of file diff --git a/Core/Inc/eg91.h b/Core/Inc/eg91.h new file mode 100644 index 0000000..d0c8f6d --- /dev/null +++ b/Core/Inc/eg91.h @@ -0,0 +1,334 @@ +#ifndef EG91_H +#define EG91_H + +#include +#include +#include +#include +#include "eg91_conf.h" + +/* Private Constants --------------------------------------------------------*/ +#define RET_NONE 0x0000 /* RET_NONE shall be 0x0: don't change this value! */ +#define RET_CRLF 0x0001 +#define RET_OK 0x0002 /* do not change this value */ +#define RET_SIM_READY 0x0004 +#define RET_ARROW 0x0008 +#define RET_SENT 0x0010 /* do not change this value */ +#define RET_OPEN 0x0020 +#define RET_ERROR 0x0040 /* do not change this value */ +#define RET_URC_CLOSED 0x0080 +#define RET_URC_RECV 0x0100 +#define RET_URC_IN_FULL 0x0200 +#define RET_URC_INCOM 0x0400 +#define RET_URC_PDPDEACT 0x0800 +#define RET_URC_DNS 0x1000 +#define RET_BUF_FULL 0x2000 /* do not change this value */ +#define RET_READ 0x4000 +#define RET_CME_ERROR 0x8000 /* do not change this value */ +#define RET_CMS_ERROR 0x10000 +#define RET_POWERED_DOWN 0x20000 +#define RET_SEND 0x40000 +#define RET_RESP 0x80000 +#define RET_NETCLOSE 0x80010 +#define RET_UART_READY 0x90000 +#define NUM_RESPONSES 23 + +/* Timeouts modem dependent */ +#define EG91_TOUT_SHORT 1000 /* 50 ms 1000 */ +#define EG91_TOUT_100 100 /* 100 ms */ +#define EG91_TOUT_300 350 /* 0,3 sec + margin */ +#define EG91_TOUT_ATSYNC 500 +/* Timeouts network dependent */ +#define EG91_TOUT_5000 5500 /* 5 sec + margin */ +#define EG91_TOUT_15000 16500 /* 15 sec + margin */ +#define EG91_TOUT_40000 42000 /* 40 sec + margin */ +#define EG91_TOUT_60000 64000 /* 1 min + margin */ +#define EG91_TOUT_75000 78000 /* 75 sec + margin */ +#define EG91_TOUT_150000 156000 /* 2,5 min + margin */ +#define EG91_TOUT_180000 186000 /* 3 min + margin */ + +/* Exported constants---------------------------------------------------------*/ + +#define EG91_MAX_APN_NAME_SIZE 32 +#define EG91_MAX_USER_NAME_SIZE 32 +#define EG91_MAX_PSW_NAME_SIZE 32 + +#define EG91_ERROR_STRING_SIZE 40 + +#define EG91_MFC_SIZE 10 +#define EG91_PROD_ID_SIZE 50 +#define EG91_FW_REV_SIZE 100 +#define EG91_IMEI_SIZE 50 +#define EG91_ICCID_SIZE 50 +#define EG91_IMSI_SIZE 50 + +/* Exported macro-------------------------------------------------------------*/ +#ifdef MIN +#undef MIN +#endif +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +/* Exported typedef ----------------------------------------------------------*/ +typedef int8_t (*IO_Init_Func)(void); +typedef int8_t (*IO_DeInit_Func)(void); +typedef int8_t (*IO_Baudrate_Func)(uint32_t BaudRate); +typedef void (*IO_Flush_Func)(void); +typedef int16_t (*IO_Send_Func)(uint8_t*, uint16_t); +typedef int16_t (*IO_ReceiveOne_Func)(uint8_t *pSingleData); +typedef uint32_t (*App_GetTickCb_Func)(void); + +typedef struct +{ + uint32_t retVal; + char retStr[100]; +} EG91_RetKeywords_t; + +typedef enum +{ + EG91_RETURN_OK = RET_OK, /* shall be aligned with above definitions */ + EG91_RETURN_ERROR = RET_ERROR, /* shall be aligned with above definitions */ + EG91_RETURN_CME_ERROR = RET_CME_ERROR, /* shall be aligned with above definitions */ + EG91_RETURN_RETRIEVE_ERROR = -1, + EG91_RETURN_SEND_ERROR = -2 +} EG91_Return_t; + +typedef enum +{ + /* See CME Error Codes */ + EG91_SIM_ERROR = 0, + EG91_SIM_NOT_INSERTED = 10, + EG91_SIM_PIN_REQUIRED = 11, + EG91_SIM_PUK_REQUIRED = 12, + EG91_SIM_FAILURE = 13, + EG91_SIM_BUSY = 14, + EG91_SIM_WRONG = 15, + EG91_INCORRECT_PSW = 16, + EG91_SIM_PIN2_REQUIRED = 17, + EG91_SIM_PUK2_REQUIRED = 18, + EG91_OPERATION_NOT_ALLOW = 3, + EG91_SIM_READY = 0xFF +} EG91_SIMState_t; + + +typedef enum +{ + EG91_NRS_NOT_REGISTERED = 0x00, + EG91_NRS_HOME_NETWORK = 0x01, + EG91_NRS_TRYING = 0x02, + EG91_NRS_REG_DENIED = 0x03, + EG91_NRS_UNKNOWN = 0x04, + EG91_NRS_ROAMING = 0x05, + EG91_NRS_ERROR = 0xFF +} EG91_NetworkRegistrationState_t; + +typedef enum +{ + EG91_AP_NOT_CONFIG = 0x00, + EG91_AP_CONFIGURED = 0x01, + EG91_AP_ACVTIVATED = 0x02, + EG91_AP_ERROR = 0xFF +} EG91_APState_t; + +typedef enum +{ + EG91_INIT_RET_OK = RET_OK, /*shall be aligned with above definitions */ + EG91_INIT_RET_AT_ERR = 0x04, + EG91_INIT_RET_SIM_ERR = 0x08, + EG91_INIT_RET_IO_ERR = 0x10, + EG91_INIT_OTHER_ERR = 0x20 +} EG91_InitRet_t; + +typedef enum +{ + EG91_SEND_RET_UART_FAIL = 0x1, + EG91_SEND_RET_SENT = RET_SENT, /*shall be aligned with above definitions */ + EG91_SEND_RET_BUF_FULL = RET_BUF_FULL, /*shall be aligned with above definitions */ + EG91_SEND_RET_CONN_ERR = RET_ERROR /*shall be aligned with above definitions */ +} EG91_SendRet_t; + + +typedef enum +{ + EG91_RECEIVE_RET_INCOMPLETE = 0x01, + EG91_RECEIVE_RET_OK = RET_OK, /*shall be aligned with above definitions */ + EG91_RECEIVE_RET_PARAM_ERR = 0x04, + EG91_RECEIVE_RET_COM_ERR = 0x08 +} EG91_ReceiveRet_t; + +typedef enum +{ + EG91_TCP_CONNECTION = 0, + EG91_UDP_CONNECTION = 1, + EG91_TCP_LISTENER_CONNECTION = 2, + EG91_UDP_SERVER_CONNECTION = 3 +} EG91_ConnType_t; + +typedef enum +{ + EG91_BUFFER_MODE = 0, + EG91_DIRECT_PUSH = 1, + EG91_TRANSPARENT_MODE = 2 +} EG91_AccessMode_t; + +/** + * \brief Authentication settings for C2C network + */ +typedef enum +{ + EG91_AUTHENT_NONE = 0x00, + EG91_AUTHENT_PAP = 0x01, + EG91_AUTHENT_CHAP = 0x02, + EG91_AUTHENT_PAP_CHAP = 0x03 +} EG91_Authent_t; + +typedef enum +{ + EG91_UART_FLW_CTL_NONE = 0x00, + EG91_UART_FLW_CTL_RTS = 0x01, + EG91_UART_FLW_CTL_CTS = 0x02, + EG91_UART_FLW_CTL_RTS_CTS = 0x03, +} EG91_UART_FLW_CTL_t; + +typedef struct +{ + uint32_t BaudRate; + uint32_t FlowControl; +} EG91_UARTConfig_t; + +typedef struct +{ + uint8_t ContextID; /*!< range is 1-20 */ + uint8_t ContextType; /*!< shall be 1 (IpV */ + uint8_t ApnString[32]; /*!< access point name, string of chars */ + uint8_t Username[32]; /*!< user name, string of chars */ + uint8_t Password[32]; /*!< password, string of chars */ + EG91_Authent_t Authentication; +} EG91_APConfig_t; + +typedef struct +{ + EG91_ConnType_t Type; + EG91_AccessMode_t AccessMode; + uint8_t ConnectID; + uint16_t RemotePort; + uint16_t LocalPort; + char *Url; +} EG91_Conn_t; + +typedef struct +{ + EG91_ConnType_t Type; + EG91_AccessMode_t AccessMode; + uint16_t ComulatedQirdData; + uint16_t HaveReadLength; + uint16_t UnreadLength; + int16_t UartRemaining; /* if Timeout respects UART speed this should always be 0 */ +} EG91_Socket_t; + +typedef struct +{ + IO_Init_Func IO_Init; + IO_DeInit_Func IO_DeInit; + IO_Baudrate_Func IO_Baudrate; + IO_Flush_Func IO_FlushBuffer; + IO_Send_Func IO_Send; + IO_ReceiveOne_Func IO_ReceiveOne; +} EG91_IO_t; + +typedef struct +{ + EG91_SIMState_t SimStatus; + uint8_t RegistStatusString[3]; + uint8_t IMSI[EG91_IMSI_SIZE]; + uint8_t ICCID[EG91_ICCID_SIZE + 1]; +} EG91_SIMInfo_t; + +typedef struct +{ + uint8_t Manufacturer[EG91_MFC_SIZE]; + uint8_t ProductID[EG91_PROD_ID_SIZE]; + uint8_t FW_Rev[EG91_FW_REV_SIZE]; + uint8_t Imei[EG91_IMEI_SIZE]; /*International Mobile Equipment Identity*/ + EG91_SIMInfo_t SimInfo; + uint8_t APsActive; + uint8_t APContextState[EG91_MAX_CONTEXTS]; /* to decide if keeping all EG91_APConfig_t info. maybe at c2c SW level*/ + EG91_Socket_t SocketInfo[EG91_MAX_SOCKETS]; /* to decide if keeping all EG91_Conn_t info. maybe at c2c SW level*/ + EG91_UARTConfig_t UART_Config; + EG91_IO_t fops; + App_GetTickCb_Func GetTickCb; + uint8_t CmdResp[EG91_CMD_SIZE]; + uint32_t RemainRxData; +} EG91Object_t; + +/* Exported functions --------------------------------------------------------*/ + +/* ==== Init and status ==== */ + +EG91_Return_t EG91_RegisterBusIO(EG91Object_t *Obj, IO_Init_Func IO_Init, + IO_DeInit_Func IO_DeInit, IO_Baudrate_Func IO_Baudrate, + IO_Send_Func IO_Send, IO_ReceiveOne_Func IO_ReceiveOne, + IO_Flush_Func IO_Flush); + +EG91_InitRet_t EG91_Init(EG91Object_t *Obj); + +EG91_Return_t EG91_PowerDown(EG91Object_t *Obj); + +/* ==== Registration and network selection ==== */ + +EG91_Return_t EG91_GetSignalQualityStatus(EG91Object_t *Obj, int32_t *Qvalue); +EG91_Return_t EG91_PSAttach(EG91Object_t *Obj); +EG91_Return_t EG91_AutomaticPlmnSelection(EG91Object_t *Obj); +EG91_Return_t EG91_SetFullFunctionality(EG91Object_t *Obj); +EG91_Return_t EG91_SetGSMLTE(EG91Object_t *Obj); +EG91_NetworkRegistrationState_t EG91_GetCsNetworkRegistrationStatus(EG91Object_t *Obj); +EG91_NetworkRegistrationState_t EG91_GetPsNetworkRegistrationStatus(EG91Object_t *Obj); + +EG91_Return_t EG91_ListOperators(EG91Object_t *Obj, char *Operators); +EG91_Return_t EG91_GetCurrentOperator(EG91Object_t *Obj, char *Operator, uint8_t Bufsize); +EG91_Return_t EG91_ForceOperator(EG91Object_t *Obj, int32_t OperatorCode); + +/* ==== AP Connection ==== */ + +EG91_Return_t EG91_ConfigureAP(EG91Object_t *Obj, EG91_APConfig_t *ApConfig); +EG91_Return_t EG91_Activate(EG91Object_t *Obj, uint8_t ContextID); +EG91_Return_t EG91_Deactivate(EG91Object_t *Obj, uint8_t ContextID); +EG91_APState_t EG91_IsActivated(EG91Object_t *Obj, uint8_t ContextID); + +/* ====IP Addr ==== */ + +EG91_Return_t EG91_GetActiveIpAddresses(EG91Object_t *Obj, char *IPaddr_string, uint8_t *IPaddr_int); + +/* ==== Ping ==== */ + +#if (EG91_USE_PING == 1) +EG91_Return_t EG91_Ping(EG91Object_t *Obj, uint8_t ContextID, char *host_addr_string, uint16_t count, uint16_t rep_delay_sec); +#endif + +/* ==== Client connection ==== */ + +EG91_Return_t EG91_DNS_LookUp(EG91Object_t *Obj, uint8_t ContextID, const char *IPaddr_string, uint8_t *IPaddr_int); +EG91_Return_t EG91_OpenClientConnection(EG91Object_t *Obj, uint8_t ContextID, EG91_Conn_t *conn); +EG91_Return_t EG91_CloseClientConnection(EG91Object_t *Obj, EG91_Conn_t *conn); + +EG91_SendRet_t EG91_SendData(EG91Object_t *Obj, uint8_t Socket, uint8_t *pdata, uint16_t Reqlen, uint16_t *SentLen, uint32_t Timeout); +EG91_ReceiveRet_t EG91_ReceiveData(EG91Object_t *Obj, uint8_t Socket, uint8_t *pdata, uint16_t Reqlen, uint16_t *Receivedlen, uint32_t Timeout); + +/* ==== Miscellaneus ==== */ + +EG91_Return_t EG91_ResetToFactoryDefault(EG91Object_t *Obj); +EG91_Return_t EG91_SetUARTBaudrate(EG91Object_t *Obj, EG91_UARTConfig_t *pconf); +EG91_Return_t EG91_GetUARTConfig(EG91Object_t *Obj, EG91_UARTConfig_t *pconf); + +void EG91_GetManufacturer(EG91Object_t *Obj, uint8_t *Manufacturer); +void EG91_GetProductID(EG91Object_t *Obj, uint8_t *ProductID); +void EG91_GetFWRevID(EG91Object_t *Obj, uint8_t *Fw_ver); + +EG91_Return_t EG91_RetrieveLastErrorDetails(EG91Object_t *Obj, char *error_string); + +/* Application must provide callback function that gives a Timer Tick in ms (e.g. HAL_GetTick())*/ +EG91_Return_t EG91_RegisterTickCb(EG91Object_t *Obj, App_GetTickCb_Func GetTickCb); +#ifdef __cplusplus +} +#endif + +#endif // EG91_H \ No newline at end of file diff --git a/Core/Inc/eg91_conf.h b/Core/Inc/eg91_conf.h new file mode 100644 index 0000000..9d88dc1 --- /dev/null +++ b/Core/Inc/eg91_conf.h @@ -0,0 +1,80 @@ +/** + ****************************************************************************** + * @file EG91_conf.h + * @author MCD Application Team + * @brief EG91 configuration file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +#ifndef __EG91_CONF_H +#define __EG91_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* --------------------------------------------------------------------------- */ +/* EG91 static parameter that can be configured by the user before compilation */ +/* --------------------------------------------------------------------------- */ + +/* Max sockets allowed by modem is 12 but beter use max 9 (sw not tested above) */ +#define EG91_MAX_SOCKETS 1 +/* Max context allowed by modem is 20 but beter use max 9 (sw not tested above) */ +#define EG91_MAX_CONTEXTS 1 + +/* 256 is normally sufficient, but if some params like URL are very long string it can be increased*/ +#define EG91_CMD_SIZE 256 + +/* EG91 and STM32 shall have same baudrate to communicate */ +#define EG91_DEFAULT_BAUDRATE 115200 + +/* Rx and Tx buffer size, depend as the applic handles the buffer */ +#define EG91_TX_DATABUF_SIZE 1460 /* mbedTLS needs at least 1460 */ +#define EG91_RX_DATABUF_SIZE 1500 + +/* 0 to disable, 1 to enable PING feature */ +#define EG91_USE_PING 1 + +#ifdef __cplusplus +} +#endif +#endif /* __EG91_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Core/Inc/gpio.h b/Core/Inc/gpio.h new file mode 100644 index 0000000..c758db6 --- /dev/null +++ b/Core/Inc/gpio.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.h + * @brief This file contains all the function prototypes for + * the gpio.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_GPIO_Init(void); + +/* USER CODE BEGIN Prototypes */ +void LEDStatus_Active(void); +void LEDStatus_Inactive(void); +void LTE_HardwarePowerUp(void); +void LTE_HardwarePowerDown(void); +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif +#endif /*__ GPIO_H__ */ + diff --git a/Core/Inc/icache.h b/Core/Inc/icache.h new file mode 100644 index 0000000..e686d12 --- /dev/null +++ b/Core/Inc/icache.h @@ -0,0 +1,50 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file icache.h + * @brief This file contains all the function prototypes for + * the icache.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ICACHE_H__ +#define __ICACHE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_ICACHE_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ICACHE_H__ */ + diff --git a/Core/Inc/lte_comms.h b/Core/Inc/lte_comms.h new file mode 100644 index 0000000..87da1a2 --- /dev/null +++ b/Core/Inc/lte_comms.h @@ -0,0 +1,132 @@ +#ifndef __LTE_COMMS_H_ +#define __LTE_COMMS_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "eg91.h" +#include "eg91_conf.h" + +#define LTE_COMMS_MAX_DELAY 0xFFFFU + +#define LTE_OPERATOR_STRING 30 +#define LTE_OPERATORS_LIST 6 * LTE_OPERATOR_STRING +#define LTE_IPADDR_STRING 35 +#define LTE_IPADDR_LIST 3 * LTE_IPADDR_STRING +#define LTE_ERROR_STRING 40 + +#define LTE_MAN_SIZE 16 +#define LTE_PROD_ID_SIZE 16 +#define LTE_FW_REV_SIZE 100 +#define LTE_IMEI_SIZE 16 +#define LTE_ICCID_SIZE 20 + +#define LTE_MAX_NOS 100 /* Network Operators */ +#define LTE_MAX_CONNECTION EG91_MAX_SOCKETS +#define LTE_PAYLOAD_SIZE 1500 /* Should be = or > than EG91_RX_DATABUF_SIZE */ + +typedef enum +{ + LTE_IPV4 = 0x01, + LTE_IPV6 = 0x02 +} LTE_IPVer_t; + +typedef enum +{ + LTE_AUTHENT_NONE = 0x00, + LTE_AUTHENT_PAP = 0x01, + LTE_AUTHENT_CHAP = 0x02, + LTE_AUTHENT_PAP_CHAP = 0x03 +} LTE_Authent_t; + +typedef enum +{ + LTE_TCP_PROTOCOL = 0, + LTE_UDP_PROTOCOL = 1, + LTE_TCP_LISTENER_PROTOCOL = 2, + LTE_UDP_SERVICE_PROTOCOL = 3 +} LTE_Protocol_t; + +typedef enum +{ + /* Registration Status */ + LTE_REGISTATUS_NOT_REGISTERED = 0x00, + LTE_REGISTATUS_HOME_NETWORK = 0x01, + LTE_REGISTATUS_TRYING = 0x02, + LTE_REGISTATUS_REG_DENIED = 0x03, + LTE_REGISTATUS_UNKNOWN = 0x04, + LTE_REGISTATUS_ROAMING = 0x05, + LTE_REGISTATUS_SIM_NOT_INSERTED = 0x0A, + LTE_REGISTATUS_SIM_PIN_REQUIRED = 0x0B, + LTE_REGISTATUS_SIM_PUK_REGUIRED = 0x0C, + LTE_REGISTATUS_SIM_FAILURE = 0x0D, + LTE_REGISTATUS_SIM_BUSY = 0x0E, + LTE_REGISTATUS_SIM_WRONG = 0x0F, + LTE_REGISTATUS_INCORRECT_PSW = 0x10, + LTE_REGISTATUS_SIM_PIN2_REQUIRED = 0x11, + LTE_REGISTATUS_SIM_PUK2_REQUIRED = 0x12, + LTE_REGISTATUS_OP_NOT_ALLOWED = 0x13, + LTE_REGISTATUS_ERROR = 0xFF +} LTE_Registatus_t; + +typedef enum +{ + LTE_AP_NOT_CONFIG = 0x00, + LTE_AP_CONFIGURED = 0x01, + LTE_AP_ACTIVATED = 0x02, + LTE_AP_ERROR = 0xFF +} LTE_APState_t; + +typedef enum +{ + LTE_RET_OK = 0x00, + LTE_RET_NOT_SUPPORTED = 0x01, + LTE_RET_ERROR = 0x02 +} LTE_Ret_t; + +typedef enum +{ + LTE_SEND_OK = 0x00, + LTE_SEND_BUF_FULL = 0x01, + LTE_SEND_ERROR = 0xFF +} LTE_SendStatus_t; + +int Network_Init(void); + +void LTE_ConvertIpAddrToString(const uint8_t * ipArray, char *returnStr); +LTE_Registatus_t LTE_Init(uint16_t registration_timeout_sec); +LTE_Ret_t LTE_GetSignalQualityStatus(int32_t *qValue); +LTE_Ret_t LTE_ListOperators(char *operator); +LTE_Ret_t LTE_GetCurrentOperator (char *operator, int32_t bufSize); +LTE_Ret_t LTE_ForceOperator(int32_t code); +LTE_Ret_t LTE_ConfigureAP(uint8_t contextType, const char *apn, const char *username, + const char *password, uint8_t authenticationMode); +LTE_Ret_t LTE_Connect(void); +LTE_Ret_t LTE_Disconnect(void); +LTE_APState_t LTE_isConnected(void); +LTE_Ret_t LTE_GetActiveIpAddress(char * ipAddrStr, uint8_t *ipAddrInt); +LTE_Ret_t LTE_Ping(char *address, uint16_t count, uint16_t timeout); +LTE_Ret_t LTE_GetHostAddress(const char *address, uint8_t *ipaddr); +LTE_Ret_t LTE_StartClientConnection(uint32_t socket, LTE_Protocol_t type, const char *url, + uint8_t *ipaddr, uint16_t port, uint16_t local_port); +LTE_Ret_t LTE_StopClientConnection(uint32_t socket); +LTE_Ret_t LTE_StartServerConnection(uint32_t socket, LTE_Protocol_t type, uint16_t port, uint16_t local_port); +LTE_Ret_t LTE_StopServerConnection(uint32_t socket); +LTE_SendStatus_t LTE_SendData(uint32_t socket, uint8_t *pdata, uint16_t reqLen, uint16_t *sentDataLen, uint32_t timeout); +LTE_Ret_t LTE_ReceiveData(uint32_t socket, uint8_t *pdata, uint16_t reqLen, uint16_t *rcvDataLen, uint32_t timeout); +LTE_Ret_t LTE_RetrieveLastErrorDetails(char *errorStr); +LTE_Ret_t LTE_PowerOff(void); +LTE_Ret_t LTE_GetModuleFirmwareRevision(char *rev); +LTE_Ret_t LTE_GetModuleID(char *productId); +LTE_Ret_t LTE_GetModuleName(char *moduleName); +LTE_Ret_t LTE_GetSimId(char *simId); +LTE_Ret_t LTE_GetIMEI(char *imei); + + + +#ifdef __cplusplus +} +#endif + +#endif /* __LTE_COMMS_H_ */ \ No newline at end of file diff --git a/Core/Inc/main.h b/Core/Inc/main.h new file mode 100644 index 0000000..45dbec6 --- /dev/null +++ b/Core/Inc/main.h @@ -0,0 +1,88 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbaxx_hal.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ +#undef MIN +#define MIN(a,b) ( ((a)<(b)) ? (a) : (b) ) +#define MAX(a,b) ( ((a)<(b)) ? (b) : (a) ) +#define ROUND_DOWN(a,b) ( ((a) / (b)) * (b) ) +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define LTE_TX_Pin GPIO_PIN_12 +#define LTE_TX_GPIO_Port GPIOB +#define DEBUG_TX_Pin GPIO_PIN_11 +#define DEBUG_TX_GPIO_Port GPIOB +#define LTE_RX_Pin GPIO_PIN_8 +#define LTE_RX_GPIO_Port GPIOA +#define STATUS_LED_Pin GPIO_PIN_7 +#define STATUS_LED_GPIO_Port GPIOB +#define LTE_EN_Pin GPIO_PIN_4 +#define LTE_EN_GPIO_Port GPIOB +#define LTE_RST_Pin GPIO_PIN_0 +#define LTE_RST_GPIO_Port GPIOB +#define LTE_PWRKEY_Pin GPIO_PIN_15 +#define LTE_PWRKEY_GPIO_Port GPIOB +#define DEBUG_RX_Pin GPIO_PIN_10 +#define DEBUG_RX_GPIO_Port GPIOA + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/Core/Inc/rtc.h b/Core/Inc/rtc.h new file mode 100644 index 0000000..2b87ae5 --- /dev/null +++ b/Core/Inc/rtc.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file rtc.h + * @brief This file contains all the function prototypes for + * the rtc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __RTC_H__ +#define __RTC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern RTC_HandleTypeDef hrtc; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_RTC_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __RTC_H__ */ + diff --git a/Core/Inc/stm32wbaxx_hal_conf.h b/Core/Inc/stm32wbaxx_hal_conf.h new file mode 100644 index 0000000..1a73913 --- /dev/null +++ b/Core/Inc/stm32wbaxx_hal_conf.h @@ -0,0 +1,353 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbaxx_hal_conf.h + * @author MCD Application Team + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WBAxx_HAL_CONF_H +#define STM32WBAxx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_GTZC_MODULE_ENABLED */ +/*#define HAL_HASH_MODULE_ENABLED */ +#define HAL_HSEM_MODULE_ENABLED +/*#define HAL_I2C_MODULE_ENABLED */ +#define HAL_ICACHE_MODULE_ENABLED +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_PKA_MODULE_ENABLED */ +/*#define HAL_RAMCFG_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_EXTI_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE 32000000UL /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations in voltage + and temperature.*/ + +#if defined (RCC_LSI2_SUPPORT) +#if !defined (LSI2_VALUE) +#define LSI2_VALUE 32000UL /*!< LSI2 Typical Value in Hz*/ +#endif /* LSI2_VALUE */ +#endif + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) +#define EXTERNAL_SAI1_CLOCK_VALUE 48000UL /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (15UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U /*!< Enable prefetch */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Register callback feature configuration ############### */ +/** + * @brief Set below the peripheral configuration to "1U" to add the support + * of HAL callback registration/unregistration feature for the HAL + * driver(s). This allows user application to provide specific callback + * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting + * the default weak callback functions (see each stm32wbaxx_hal_ppp.h file + * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef + * for each PPP peripheral). + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ + +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ + +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ +#define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ +#define USE_SPI_CRC 0U + +/* ################## CRYP peripheral configuration ########################## */ + +#define USE_HAL_CRYP_SUSPEND_RESUME 0U + +/* ################## HASH peripheral configuration ########################## */ + +#define USE_HAL_HASH_SUSPEND_RESUME 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32wbaxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32wbaxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32wbaxx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32wbaxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32wbaxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32wbaxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32wbaxx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32wbaxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32wbaxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED +#include "stm32wbaxx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED +#include "stm32wbaxx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED +#include "stm32wbaxx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32wbaxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED +#include "stm32wbaxx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32wbaxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32wbaxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32wbaxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED +#include "stm32wbaxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32wbaxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RAMCFG_MODULE_ENABLED +#include "stm32wbaxx_hal_ramcfg.h" +#endif /* HAL_RAMCFG_MODULE_ENABLED */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32wbaxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32wbaxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32wbaxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32wbaxx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32wbaxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32wbaxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32wbaxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32wbaxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED +#include "stm32wbaxx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32wbaxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32wbaxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32wbaxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WBAxx_HAL_CONF_H */ + diff --git a/Core/Inc/stm32wbaxx_it.h b/Core/Inc/stm32wbaxx_it.h new file mode 100644 index 0000000..5484f41 --- /dev/null +++ b/Core/Inc/stm32wbaxx_it.h @@ -0,0 +1,68 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbaxx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32WBAxx_IT_H +#define __STM32WBAxx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); +void USART1_IRQHandler(void); +void HSEM_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32WBAxx_IT_H */ diff --git a/Core/Inc/usart.h b/Core/Inc/usart.h new file mode 100644 index 0000000..db698cf --- /dev/null +++ b/Core/Inc/usart.h @@ -0,0 +1,115 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.h + * @brief This file contains all the function prototypes for + * the usart.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USART_H__ +#define __USART_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ +#include +#include +#include +/* USER CODE END Includes */ + +extern UART_HandleTypeDef hlpuart1; + +extern UART_HandleTypeDef huart1; + +/* USER CODE BEGIN Private defines */ + +// #define LOG_APP_DEBUG +#define LOG_APP_ERROR +#define LOG_APP_LOG +#define LOG_APP_LTE + +/** + * @brief Application general debug messages + * + * Enable by defining `LOG_APP_DEBUG` in config.h. + */ +#ifdef LOG_APP_DEBUG +# define APP_DEBUG_MSG(a, ...) printf(("DEBUG: " a), ##__VA_ARGS__) +#else +# define APP_DEBUG_MSG(...) ((void)0) +#endif + +/** + * @brief Application error messages + * + * Enable by defining `LOG_APP_ERROR` in config.h. + */ +#ifdef LOG_APP_ERROR +# define APP_ERROR_MSG(a, ...) printf(("ERROR: "a), ##__VA_ARGS__) +#else +# define APP_ERROR_MSG(...) ((void)0) +#endif + +/** + * @brief Application logging messages + * + * Enable by defining `LOG_APP_LOG` in config.h. + */ +#ifdef LOG_APP_LOG +# define APP_LOG_MSG(a, ...) printf((a), ##__VA_ARGS__) +#else +# define APP_LOG_MSG(...) ((void)0) +#endif + +/** + * @brief Application logging lte messages + * + * Enable by defining `LOG_APP_LTE` in config.h. + */ +#ifdef LOG_APP_LTE +# define APP_LTE_MSG(a, ...) printf(("AT RSP:" a), ##__VA_ARGS__) +#else +# define APP_LTE_MSG(...) ((void)0) +#endif + +/* USER CODE END Private defines */ + +void MX_LPUART1_UART_Init(void); +void MX_USART1_UART_Init(void); + +/* USER CODE BEGIN Prototypes */ +void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle); + +void LTE_ATSendCommand(const char *cmd); +void LTE_SendATCommand_Test(void); + +int8_t LTE_UART_SetBaudrate(uint32_t baudrate); +void LTE_UART_FlushBuffer(void); +int16_t LTE_UART_SendData(uint8_t *pData, uint16_t length); +int16_t LTE_UART_ReceiveSingleData(uint8_t *pSingleData); + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USART_H__ */ + diff --git a/Core/Src/eg91.c b/Core/Src/eg91.c new file mode 100644 index 0000000..dae94f9 --- /dev/null +++ b/Core/Src/eg91.c @@ -0,0 +1,1801 @@ +/** + ****************************************************************************** + * @file EG91.c + * @author MCD Application Team + * @version V0.0.1 + * @date 11-08-2017 + * @brief Functions to manage the EG91 module (C2C cellular modem). + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ + +#include "eg91.h" +#include "main.h" + +#define CHARISHEXNUM(x) (((x) >= '0' && (x) <= '9') || \ + ((x) >= 'a' && (x) <= 'f') || \ + ((x) >= 'A' && (x) <= 'F')) + +#define CHARISNUM(x) ((x) >= '0' && (x) <= '9') +#define CHAR2NUM(x) ((x) - '0') + +#define CTRL_Z 26 + +/* Private variable ---------------------------------------------------------*/ +char CmdString[EG91_CMD_SIZE]; + +/* Exported variable ---------------------------------------------------------*/ + +/* This should be reworked, _IO should not depend on component */ +const EG91_RetKeywords_t ReturnKeywords[] = +{ +/* send receive related keywords */ +{ RET_SENT, "OK\r\n" }, +{ RET_ARROW, ">" }, +{ RET_READ, "CIPRXGET" }, +{ RET_SEND, "CIPSEND" }, +{ RET_POWERED_DOWN, "POWERED DOWN\r\n" }, +{ RET_UART_READY, "RDY\r\n"}, +{ RET_URC_CLOSED, "closed\"" }, +{ RET_URC_RECV, "CIPRXGET:SUCCESS" }, +{ RET_URC_IN_FULL, "incoming full\"" }, +{ RET_URC_INCOM, "incoming\"" }, +{ RET_URC_PDPDEACT, "pdpdeact\"" }, +{ RET_URC_DNS, "+MDNSGIP:" }, +/* errors keywords */ +{ RET_ERROR, "ERROR\r\n" }, +{ RET_CME_ERROR, "CME ERROR:" }, +//{ RET_CMS_ERROR, "CMS ERROR:" }, +{ RET_BUF_FULL, "ERROR\r\n" }, +/* set-up keywords */ +{ RET_OK, "OK\r\n" }, +{ RET_OPEN, "OPEN:" }, +{ RET_SIM_READY, "ready\r\n" }, +{ RET_RESP, "\r\n\r\nOK" }, +{ RET_NETCLOSE, "\r\n\r\n" }, +{ RET_CRLF, "\r\n" }, /* keep RET_CRLF last !!! */ +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief Parses and returns number from string. + * @param ptr: pointer to string + * @param cnt: pointer to the number of parsed digit + * @retval integer value. + */ +static int32_t ParseNumber(char *ptr, uint8_t *cnt) +{ + uint8_t minus = 0, i = 0; + int32_t sum = 0; + + if (*ptr == '-') + { /* Check for minus character */ + minus = 1; + ptr++; + i++; + } + while (CHARISNUM(*ptr)) + { /* Parse number */ + sum = 10 * sum + CHAR2NUM(*ptr); + ptr++; + i++; + } + if (cnt != NULL) + { /* Save number of characters used for number */ + *cnt = i; + } + if (minus) + { /* Minus detected */ + return 0 - sum; + } + return sum; /* Return number */ +} + +/** + * @brief Parses and returns QIRQ query response. + * @param ptr: pointer to string + * @param arr: pointer to IP array + * @retval None. + */ +static void ParseQIRD(char *ptr, uint16_t *arr) +{ + uint8_t hexnum = 0, hexcnt; + + while (*ptr) + { + hexcnt = 1; + if (*ptr != ',') + { + arr[hexnum++] = (uint16_t) ParseNumber(ptr, &hexcnt); + } + ptr = ptr + hexcnt; + if ((*ptr == '\r') || (hexnum == 3)) + { + return; + } + } +} + +/** + * @brief Parses and returns . + * @param ptr: pointer to string + * @retval The number of unread data in modem TX buffer. + */ +//static void ParseQISEND(char *ptr, uint32_t *unackedbytes) +//{ +// uint8_t hexnum = 0, hexcnt; +// uint32_t temp = 0; +// +// /* QISEND Response contains 3 kind of information +// * ,, +// * we're only interested to the 3rd one, unackedbytes for now */ +// while (*ptr) +// { +// hexcnt = 1; +// if (*ptr != ',') +// { +// temp = (uint32_t) ParseNumber(ptr, &hexcnt); +// /* Count up the number we've retrieved */ +// hexnum++; +// if (hexnum == 3) +// { +// *unackedbytes = temp; +// } +// } +// ptr = ptr + hexcnt; +// if ((*ptr == '\r') || (hexnum == 3)) +// { +// return; +// } +// } +//} + +/** + * @brief Parses and returns IP address. + * @param ptr: pointer to string + * @param arr: pointer to IP array + * @retval None. + */ +static void ParseIP(char *ptr, uint8_t *arr) +{ + uint8_t hexnum = 0, hexcnt; + + while (*ptr) + { + hexcnt = 1; + if (*ptr != '.') + { + arr[hexnum++] = ParseNumber(ptr, &hexcnt); + } + ptr = ptr + hexcnt; + if (*ptr == '"') + { + return; + } + } +} + +/** + * @brief Return the integer difference between 'init + timeout' and 'now'. + * The implementation is robust to uint32_t overflows. + * @param In: init Reference index. + * @param In: now Current index. + * @param In: timeout Target index. + * @retval Number of ms from now to target (init + timeout). + */ +static int32_t TimeLeftFromExpiration(uint32_t init, uint32_t now, + uint32_t timeout) +{ + int32_t ret = 0; + uint32_t wrap_end = 0; + + if (now < init) + { /* Timer wrap-around detected */ + wrap_end = UINT32_MAX - init; + } + ret = wrap_end - (now - init) + timeout; + + return ret; +} + +/** + * @brief Retrieve Data from the C2C module over the UART interface. + * This function receives data from the C2C module, the + * data is fetched from a ring buffer that is asynchronously and continuously + filled with the received data. + * @param Obj: pointer to module handle + * @param pData: a buffer inside which the data will be read. + * @param Length: Size of the data to receive. + * @param ScanVals: when param Length = 0 : values to be retrieved in the coming data in order to exit. + * @retval int32_t: if param Length = 0 : the actual RET_CODE found, + if param Length > 0 : the actual data size that has been received + if error (timeout): return -1 (EG91_RETURN_RETRIEVE_ERROR). + */ +static int32_t AT_RetrieveData(EG91Object_t *Obj, uint8_t *pData, + uint16_t Length, uint32_t ScanVals, uint32_t Timeout) +{ + uint32_t tickstart = Obj->GetTickCb(); + int16_t ReadData = 0; + uint16_t x; + uint16_t index[NUM_RESPONSES]; + uint16_t lens[NUM_RESPONSES]; + uint16_t pos; + uint8_t c; + int32_t min_requested_time; + + min_requested_time = 2 * (Length + 15) * 8 * 1000 / EG91_DEFAULT_BAUDRATE; /* 15 is the max length of the return keyword */ + if (Timeout < min_requested_time) /* UART speed 115200 bits per sec */ + { + Timeout = min_requested_time; + } + + for (x = 0; x < NUM_RESPONSES; x++) + { + index[x] = 0; + lens[x] = strlen(ReturnKeywords[x].retStr); + } + + if ((Length == 0) && (ScanVals == RET_NONE)) + { + return 0; /* to avoid waiting a RET_VAL in case the parsed_lenth of payload is zero */ + /* but no code needs to be retrieved */ + } + + memset(Obj->CmdResp, 0, EG91_CMD_SIZE); + + while (TimeLeftFromExpiration(tickstart, Obj->GetTickCb(), Timeout) > 0) + { + if (Obj->fops.IO_ReceiveOne(&c) == 0) /* Receive one sample from UART */ + { + /* serial data available, so return data to user */ + pData[ReadData++] = c; + + if (Length == 0) + { + /* Check whether we hit an ESP return values */ + for (x = 0; x < NUM_RESPONSES; x++) + { + if (c != ReturnKeywords[x].retStr[index[x]]) + { + index[x] = 0; + } + + if (c == ReturnKeywords[x].retStr[index[x]]) + { + pos = ++(index[x]); + if (pos >= lens[x]) + { + if (ScanVals & ReturnKeywords[x].retVal) + { + return ReturnKeywords[x].retVal; + } + } + } + } + } + else /* end (Length > 0) */ + { + if (ReadData < Length) + { + /* nothing to do except keep reading in the while loop */ + } + else /* ReadData >= Length */ + { + return ReadData; + } + } /* end (Length == 0) */ + } + } + + if ((Length > 0) && (ReadData > 0)) + { + return ReadData; + } + return EG91_RETURN_RETRIEVE_ERROR; +} + +/** + * @brief Execute AT command. + * @param Obj: pointer to module handle + * @param cmd: pointer to command string + * @param resp: expected response + * @retval Operation Status: OK or ERROR. + */ +static int32_t AT_ExecuteCommand(EG91Object_t *Obj, uint32_t timeout, + uint8_t *cmd, uint32_t resp) +{ + int32_t ret = EG91_RETURN_SEND_ERROR; + + if (timeout == 0) + { + timeout = EG91_TOUT_300; + } +#ifdef EG91_DBG_AT //alecks + printf("AT Request: %s \n", cmd); +#endif + if (Obj->fops.IO_Send(cmd, strlen((char*) cmd)) >= 0) + { + HAL_Delay(200); //return to 200 + ret = (AT_RetrieveData(Obj, Obj->CmdResp, 0, resp, timeout)); + if (ret < 0) + { +#ifdef EG91_DBG + printf("EG91 AT_ExecuteCommand() rcv TIMEOUT ret=%ld: %s \r\n", ret, cmd); +#endif + } +#ifdef EG91_DBG_AT + else + { + printf("AT Response: %s \n", Obj->CmdResp); + } +#endif + } + else + { +#ifdef EG91_DBG + printf("EG91 AT_ExecuteCommand() send ERROR: %s \r\n", cmd); +#endif + } + return ret; +} + +/** + * @brief Execute AT command with data. + * @param Obj: pointer to module handle + * @param pdata: pointer to returned data + * @param len: binary data length + * @param timeout: waiting that the modem confirms confirm that send command has been executed (SEND OK) + * @retval Operation Status. + */ +static EG91_SendRet_t AT_RequestSendData(EG91Object_t *Obj, uint8_t *pdata, + uint16_t len, uint32_t timeout) +{ + int32_t confirm; + + if (Obj->fops.IO_Send(pdata, len) >= 0) + { + confirm = AT_RetrieveData(Obj, Obj->CmdResp, 0, + (RET_SENT | RET_BUF_FULL | RET_ERROR), timeout); + return (EG91_SendRet_t) confirm; + } + return EG91_SEND_RET_UART_FAIL; /* UART error to transmit */ +} + +/** + * @brief Retrieve URC header and decode it + * @param Obj: pointer to module handle + * @param Timeout : ms + * @param ParseLength : pointer to return the length parsed from URC info + * @param AccMode : currently only EG91_BUFFER_MODE is used and tested + * @retval Operation Status. + */ +static int32_t AT_RetrieveUrc(EG91Object_t *Obj, uint32_t Timeout, + uint16_t *ParseLength, EG91_AccessMode_t AccMode) +{ + int32_t check_resp, ret; + uint32_t expected_resp; + uint8_t parse_ret; + uint8_t parse_count, ip_count; + uint32_t count = 0; + + expected_resp = RET_URC_CLOSED | RET_URC_RECV | RET_URC_IN_FULL + | RET_URC_INCOM | RET_URC_PDPDEACT | RET_URC_DNS; + check_resp = AT_RetrieveData(Obj, Obj->CmdResp, 0, expected_resp, Timeout); + switch (check_resp) + { + case RET_URC_CLOSED: + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_SHORT); + parse_ret = ParseNumber((char*) Obj->CmdResp + 1, &parse_count); + break; + case RET_URC_RECV: + /* retrieve contextID */ + ret = AT_RetrieveData(Obj, Obj->CmdResp, 3, RET_NONE, EG91_TOUT_SHORT); + if (ret > 0) + { + parse_ret = ParseNumber((char*) Obj->CmdResp + 1, &parse_count); + if (parse_count == 2) + { /* read next comma */ + AT_RetrieveData(Obj, Obj->CmdResp, 1, RET_NONE, EG91_TOUT_SHORT); + } + } + if (AccMode == EG91_BUFFER_MODE) + { + AT_RetrieveData(Obj, Obj->CmdResp, 1, RET_NONE, EG91_TOUT_SHORT); + } + else + { + for (; count < 6; count++) + { + if (ret < 0) + { + break; + } + ret = AT_RetrieveData(Obj, &Obj->CmdResp[count], 1, RET_NONE,EG91_TOUT_SHORT); + if (ret == 1) + { + if (Obj->CmdResp[count] == '\n') + { + *ParseLength = (uint16_t) ParseNumber((char*) Obj->CmdResp, &parse_count); + break; + } + } + } + } + break; + + case RET_URC_IN_FULL: + /* nothing to be done */ + break; + + case RET_URC_INCOM: + /* TBD: to be implemented for SERVER MODE*/ + break; + + case RET_URC_PDPDEACT: + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_SHORT); + parse_ret = ParseNumber((char*) Obj->CmdResp + 1, &parse_count); + break; + + case RET_URC_DNS: + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, Timeout); + parse_ret = ParseNumber((char*) Obj->CmdResp + 1, &parse_count); + if (parse_ret == 0) /* means no errors */ + { + ip_count = ParseNumber((char*) Obj->CmdResp + 3, &parse_count); + for (count = 0; count < ip_count; count++) + { + expected_resp = RET_URC_DNS; + check_resp = AT_RetrieveData(Obj, Obj->CmdResp, 0, + expected_resp, Timeout); + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, Timeout); + } + } + else + { + check_resp = -1; + } + break; + + default: + check_resp = -1; + break; + } + + return check_resp; +} + +/** + * @brief Synchronize the modem uart with the STM32 uart (autobauding) + * @param Obj: pointer to module handle + * @retval Operation status. + */ +static int32_t AT_Synchro(EG91Object_t *Obj) +{ + int32_t ret = RET_ERROR; + int8_t atSync = 0; + uint32_t tickstart; + + /* Init tickstart for timeout management */ + tickstart = Obj->GetTickCb(); + + /* Start AT SYNC: Send AT every 500ms, + if receive OK, SYNC success, + if no OK return after sending AT 10 times, SYNC fail */ + do + { + if (TimeLeftFromExpiration(tickstart, Obj->GetTickCb(), EG91_TOUT_ATSYNC) < 0) + { + ret = AT_ExecuteCommand(Obj, EG91_TOUT_100, (uint8_t*) "AT\r\n", RET_OK | RET_ERROR); + atSync++; + tickstart = Obj->GetTickCb(); + } + } while ((atSync < 10) && (ret != RET_OK)); + + return ret; +} + +/* --------------------------------------------------------------------------*/ +/* --- Public functions -----------------------------------------------------*/ +/* --------------------------------------------------------------------------*/ + +/** + * @brief Register EG91 BusIO external functions. + * @param Obj: pointer to module handle + * @retval Operation Status. + */ +EG91_Return_t EG91_RegisterBusIO(EG91Object_t *Obj, IO_Init_Func IO_Init, + IO_DeInit_Func IO_DeInit, IO_Baudrate_Func IO_Baudrate, + IO_Send_Func IO_Send, IO_ReceiveOne_Func IO_ReceiveOne, + IO_Flush_Func IO_Flush) +{ + if (!Obj || !IO_Init || !IO_DeInit || !IO_Baudrate || !IO_Send + || !IO_ReceiveOne || !IO_Flush) + { + return EG91_RETURN_ERROR; + } + + Obj->fops.IO_Init = IO_Init; + Obj->fops.IO_DeInit = IO_DeInit; + Obj->fops.IO_Baudrate = IO_Baudrate; + Obj->fops.IO_Send = IO_Send; + Obj->fops.IO_ReceiveOne = IO_ReceiveOne; + Obj->fops.IO_FlushBuffer = IO_Flush; + + return EG91_RETURN_OK; +} + +/** + * @brief Shut down the module. + * @retval Operation Status. + */ +EG91_Return_t EG91_PowerDown(EG91Object_t *Obj) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + + if ( RET_OK == (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+POWEROFF\r\n", + RET_OK | RET_ERROR | RET_CME_ERROR)) + { +// printf("Please wait, disconnecting and saving data. It may last until 60 s\n"); + /* expect for the "POWERED DOWN" */ + /* The maximum time for network log-off is 60 seconds */ + if (AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_POWERED_DOWN, EG91_TOUT_60000) > 0) + { + printf("Modem is entered in power down\n"); + ret = EG91_RETURN_OK; + } + } + return ret; +} + +/** + * @brief Initialize EG91 module. + * @param Obj: pointer to module handle + * @retval Operation Status. + */ +EG91_InitRet_t EG91_Init(EG91Object_t *Obj) +{ + EG91_InitRet_t fret = EG91_INIT_OTHER_ERR; + int32_t ret = RET_ERROR; + int8_t i; + char *align_ptr, *token; + uint8_t parse_count; + uint32_t tickstart; + + Obj->APsActive = 0; + for (i = 0; i < EG91_MAX_SOCKETS; i++) + { + Obj->SocketInfo[i].Type = EG91_TCP_CONNECTION; + Obj->SocketInfo[i].AccessMode = EG91_BUFFER_MODE; + Obj->SocketInfo[i].ComulatedQirdData = 0; + Obj->SocketInfo[i].HaveReadLength = 0; + Obj->SocketInfo[i].UnreadLength = 0; + } + + Obj->fops.IO_FlushBuffer(); /* Flush Uart intermediate buffer */ + + if (Obj->fops.IO_Init() == 0) /* configure and initialize UART */ + { + ret = AT_Synchro(Obj); + + if (ret != RET_OK) + { + printf("Fail to AT SYNC, after several attempts\r\n"); + fret = EG91_INIT_RET_AT_ERR; /* if does not respond to AT command set specific return status */ + } + else + { + /* Retrieve Quectel Factory Default values */ + ret = EG91_ResetToFactoryDefault(Obj); + + /* Retrieve Quectel UART baud rate and flow control*/ + /* If not aligned to the UART of MCU (_io.h), already previous AT command will fail */ + ret = ret | EG91_GetUARTConfig(Obj, &Obj->UART_Config); + /* Use ATV1 to set the response format */ + ret = ret | AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) "ATV1\r\n", RET_OK | RET_ERROR); + /* Use ATE1 to enable or ATE0 to disable echo mode */ + ret = ret | AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) "ATE0\r\n", RET_OK | RET_ERROR); + /* Use AT+CMEE=1 to enable result code and use "integer" values */ + ret = ret | AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+CMEE=1\r\n", RET_OK | RET_ERROR); + } + + /* retrieve module info */ + if (ret == RET_OK) + { + ret = AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) "AT+CGMI\r\n", RET_OK | RET_ERROR); + if (ret == RET_OK) + { + align_ptr = strtok((char *)Obj->CmdResp, "\r\n"); + strncpy((char*) Obj->Manufacturer, align_ptr, EG91_MFC_SIZE); + } + + ret = AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) "AT+CGMM\r\n", RET_OK | RET_ERROR); + if (ret == RET_OK) + { + align_ptr = strtok((char *)Obj->CmdResp, "\r\n"); + strncpy((char*) Obj->ProductID, align_ptr, EG91_PROD_ID_SIZE); + } + + ret = AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) "AT+CGMR\r\n", RET_OK | RET_ERROR); + if (ret == RET_OK) + { + align_ptr = strtok((char *)Obj->CmdResp, "\r\n"); + strncpy((char*) Obj->FW_Rev, align_ptr, EG91_FW_REV_SIZE); + } + + /* Use AT+GSN to query the IMEI (International Mobile Equipment Identity) of module */ + ret = AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+CGSN\r\n", RET_OK | RET_ERROR); + if (ret == RET_OK) + { + align_ptr = strtok((char *)Obj->CmdResp, "\r\n"); + strncpy((char*) Obj->Imei, align_ptr, EG91_IMEI_SIZE); + } + } + + /* retrieve SIM info */ + if (ret == RET_OK) + { + + /* A tempo is required to get the SIM ready. Set to 2000 ms */ + tickstart = Obj->GetTickCb(); + while ((Obj->GetTickCb() - tickstart) < 2000) + { + } + + ret = AT_ExecuteCommand(Obj, EG91_TOUT_5000, (uint8_t*) "AT+CPIN?\r\n", RET_OK | RET_ERROR | RET_CME_ERROR); + + if (RET_OK == ret) + { + align_ptr = strstr((char*) Obj->CmdResp, "+CPIN: READY"); + if ( NULL != align_ptr) + { + Obj->SimInfo.SimStatus = EG91_SIM_READY; + + if (RET_OK == AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+CIMI\r\n", RET_OK | RET_ERROR | RET_CME_ERROR)) + { + align_ptr = strtok((char *)Obj->CmdResp, "\r\n"); + strncpy((char*) Obj->SimInfo.IMSI, align_ptr, EG91_IMSI_SIZE); + } + + if (RET_OK == AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+ICCID\r\n", RET_OK | RET_ERROR)) + { + align_ptr = strtok((char *)Obj->CmdResp, "\r\n"); + token = strchr(align_ptr, ':'); + + if (token != NULL) + { + token++; + while(*token == ' ') + { + token++; + } + } + strncpy((char*) Obj->SimInfo.ICCID, token, EG91_ICCID_SIZE); + } + + fret = EG91_INIT_RET_OK; + } + } + else + { + if (RET_CME_ERROR == ret) + { + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_SHORT); + Obj->SimInfo.SimStatus = (EG91_SIMState_t) ParseNumber( (char*) Obj->CmdResp + 1, &parse_count); + fret = EG91_INIT_RET_SIM_ERR; + } + } + } + + /* Set the radio ON with the full functionality in the modem */ + ret = AT_ExecuteCommand(Obj, EG91_TOUT_15000, (uint8_t*) "AT+CFUN=1\r\n", RET_OK | RET_ERROR | RET_CME_ERROR); + if (RET_OK != ret) + { + fret = EG91_INIT_OTHER_ERR; + } + + for (int i = 0; i < 30; i++) + { + HAL_Delay(30); + } + /* Set the modem to GSM and LTE enable */ +// ret = AT_ExecuteCommand(Obj, EG91_TOUT_15000, (uint8_t*) "AT+CNMP=4\r\n", RET_OK | RET_ERROR | RET_CME_ERROR); +// if (RET_OK != ret) +// { +// fret = EG91_INIT_OTHER_ERR; +// } + } + else + { + fret = EG91_INIT_RET_IO_ERR; + } + + return fret; +} + +/** + * @brief Get Signal Quality value + * @param Obj: pointer to module handle + * @retval Operation status. + */ +EG91_Return_t EG91_GetSignalQualityStatus(EG91Object_t *Obj, int32_t *Qvalue) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + uint8_t parse_count; + char *align_ptr; + + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_300, + (uint8_t*) "AT+CSQ\r\n", + RET_OK | RET_ERROR | RET_CME_ERROR); + if (RET_OK == ret) + { + align_ptr = strstr((char*) Obj->CmdResp, "+CSQ:") + sizeof("+CSQ:"); + *Qvalue = ParseNumber(align_ptr, &parse_count); + } + return ret; +} + +/** + * @brief Attach the MT to the packet domain service + * @param Obj: pointer to module handle + * @retval Operation status. + */ +EG91_Return_t EG91_PSAttach(EG91Object_t *Obj) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + + if (Obj->SimInfo.SimStatus == EG91_SIM_READY) + { + if (RET_OK != AT_ExecuteCommand(Obj, EG91_TOUT_75000, (uint8_t*) "AT+CGATT=1\r\n", RET_OK | RET_ERROR | RET_CME_ERROR)) + { + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_SHORT); + ret = EG91_RETURN_ERROR; + } + else + { + ret = EG91_RETURN_OK; + } + } + return ret; +} + +/** + * @brief Force an automatic PLMN selection + * @param Obj: pointer to module handle + * @retval Operation status. + */ +EG91_Return_t EG91_AutomaticPlmnSelection(EG91Object_t *Obj) +{ + EG91_Return_t ret; + + if (RET_OK != AT_ExecuteCommand(Obj, EG91_TOUT_180000, (uint8_t*) "AT+COPS=0\r\n", RET_OK | RET_ERROR | RET_CME_ERROR)) + { + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_SHORT); + ret = EG91_RETURN_ERROR; + } + else + { + ret = EG91_RETURN_OK; + } + return ret; +} + +EG91_Return_t EG91_SetFullFunctionality(EG91Object_t *Obj) +{ + EG91_Return_t ret; + + if (RET_OK != AT_ExecuteCommand(Obj, EG91_TOUT_15000, (uint8_t*) "AT+CFUN=1\r\n", RET_OK | RET_ERROR | RET_CME_ERROR)) + { + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_SHORT); + ret = EG91_RETURN_ERROR; + } + else + { + ret = EG91_RETURN_OK; + } + return ret; +} + +EG91_Return_t EG91_SetGSMLTE(EG91Object_t *Obj) +{ + EG91_Return_t ret; + + if (RET_OK != AT_ExecuteCommand(Obj, EG91_TOUT_15000, (uint8_t*) "AT+CNMP=4\r\n", RET_OK | RET_ERROR | RET_CME_ERROR)) + { + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_SHORT); + ret = EG91_RETURN_ERROR; + } + else + { + ret = EG91_RETURN_OK; + } + return ret; +} + +/** + * @brief Get Circuit Switch Registration Status + * @param Obj: pointer to module handle + * @retval Registration Status. + */ +EG91_NetworkRegistrationState_t EG91_GetCsNetworkRegistrationStatus(EG91Object_t *Obj) +{ + int8_t received_string[3]; + int16_t val; + EG91_NetworkRegistrationState_t ret = EG91_NRS_ERROR; + char *align_ptr; + char *creg_ptr; + + if (Obj->SimInfo.SimStatus == EG91_SIM_READY) + { + if (RET_OK == AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+CEREG?\r\n", RET_OK | RET_ERROR | RET_CME_ERROR)) + { + creg_ptr = strstr((char*) Obj->CmdResp, "+CEREG:"); + + /* +CREG: is in the response*/ + if (NULL != creg_ptr) + { + /* search for is in the response */ + align_ptr = creg_ptr + sizeof("+CEREG:"); + strncpy((char*) received_string, align_ptr + 2, 1); + strncpy((char*) received_string + 1, "\r\n", 2); + val = atoi((char*) received_string); + ret = (EG91_NetworkRegistrationState_t) val; + } + } + } + return ret; +} + +/** + * @brief Get Packet Switch Registration Status + * @param Obj: pointer to module handle + * @retval Registration Status. + */ +EG91_NetworkRegistrationState_t EG91_GetPsNetworkRegistrationStatus(EG91Object_t *Obj) +{ + int8_t received_string[3]; + int16_t val; + EG91_NetworkRegistrationState_t ret = EG91_NRS_ERROR; + char *align_ptr; + char *cgreg_ptr; + + if (Obj->SimInfo.SimStatus == EG91_SIM_READY) + { + if (RET_OK == AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+CREG?\r\n", RET_OK | RET_ERROR | RET_CME_ERROR)) + { + cgreg_ptr = strstr((char*) Obj->CmdResp, "+CREG:"); + + /* +CGREG: is in the response*/ + if (NULL != cgreg_ptr) + { + align_ptr = cgreg_ptr + sizeof("+CREG:"); + strncpy((char*) received_string, align_ptr + 2, 1); + strncpy((char*) received_string + 1, "\r\n", 2); + val = atoi((char*) received_string); + ret = (EG91_NetworkRegistrationState_t) val; + } + } + } + return ret; +} + +/** + * @brief Get the list of Network Operator available in the area + * @param Obj: pointer to module handle + * @param Operator: pointer to a string + * @retval Operation Status. + */ +EG91_Return_t EG91_ListOperators(EG91Object_t *Obj, char *Operators) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + char *align_ptr; + + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_180000, (uint8_t*) "AT+COPS=?\r\n", RET_OK | RET_ERROR | RET_CME_ERROR); + if (RET_OK == ret) + { + align_ptr = strstr((char*) Obj->CmdResp, "+COPS:") + sizeof("+COPS:"); + strncpy((char*) Operators, align_ptr, 100); + } + return ret; +} + +/** + * @brief Get current Network Operator (by string descriptor). + * @param Obj: pointer to module handle + * @param Operator: pointer to a string + * @param bufsize: max string buffer length + * @retval Operation Status. + */ +EG91_Return_t EG91_GetCurrentOperator(EG91Object_t *Obj, char *Operator, + uint8_t Bufsize) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + char *align_ptr; + const char s[2] = ","; + char *token; + int i; + + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_180000, (uint8_t*) "AT+COPS?\r\n", RET_OK | RET_ERROR | RET_CME_ERROR); + + if (RET_OK == ret) + { + align_ptr = strstr((char*) Obj->CmdResp, "+COPS:") + sizeof("+COPS:"); + + strncpy((char*) Operator, align_ptr, Bufsize); + + /* get the first token */ + token = strtok(Operator, s); + + /* walk through tokens until operator info */ + i = 0; + while (token != NULL && i < 2) + { + token = strtok(NULL, s); + i++; + } + + if (token != NULL) + { + strncpy((char*) (Operator), token, Bufsize); + } + else + { + ret = EG91_RETURN_ERROR; + } + } + return ret; +} + +/** + * @brief Force registration to specific Network Operator (by operator code). + * @param Obj: pointer to module handle + * @param OperatorCode: http://www.imei.info/operator-codes/ + * @retval Operation Status. + */ +EG91_Return_t EG91_ForceOperator(EG91Object_t *Obj, int32_t OperatorCode) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + + snprintf(CmdString, 24, "AT+COPS=1,2,\"%ld\"\r\n", OperatorCode); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_180000, (uint8_t*) CmdString, RET_OK | RET_ERROR | RET_CME_ERROR); + return ret; +} + +/** + * @brief Reset To factory defaults. + * @param Obj: pointer to module handle + * @retval Operation Status. + */ +EG91_Return_t EG91_ResetToFactoryDefault(EG91Object_t *Obj) +{ + EG91_Return_t ret; + + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT&F\r\n", RET_OK | RET_ERROR); + return ret; +} + +/** + * @brief Set UART Configuration on the Quectel modem and on STM32. + * @param Obj: pointer to module handle + * @param pconf: pointer to UART config structure + * @retval Operation Status. + */ +EG91_Return_t EG91_SetUARTBaudrate(EG91Object_t *Obj, EG91_UARTConfig_t *pconf) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + + /* change the UART baudrate on EG91 module */ + snprintf(CmdString, 17, "AT+IPR=%lu\r\n", pconf->BaudRate); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) CmdString, RET_OK | RET_ERROR); + + /* change the UART baudrate on STM32 microcontroller accordingly */ + Obj->fops.IO_Baudrate(pconf->BaudRate); + + return ret; +} + +/** + * @brief Get UART Configuration. + * @param Obj: pointer to module handle + * @param pconf: pointer to UART config structure + * @retval Operation Status. + */ +EG91_Return_t EG91_GetUARTConfig(EG91Object_t *Obj, EG91_UARTConfig_t *pconf) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + char *align_ptr; + uint8_t rts, cts; + + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+IPR?\r\n", RET_OK | RET_ERROR); + if (ret == RET_OK) + { + align_ptr = strstr((char*) Obj->CmdResp, "+IPR:") + sizeof("+IPR:"); + Obj->UART_Config.BaudRate = ParseNumber(align_ptr, NULL); + } + + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) "AT+IFC?\r\n", RET_OK | RET_ERROR); + if (ret == RET_OK) + { + align_ptr = strstr((char*) Obj->CmdResp, "+IFC:") + sizeof("+IPR:"); + rts = ParseNumber(align_ptr, NULL); + cts = ParseNumber(align_ptr + 2, NULL); + + if (rts == 2) + { + if (cts == 2) + { + pconf->FlowControl = EG91_UART_FLW_CTL_RTS_CTS; + } + else + { + pconf->FlowControl = EG91_UART_FLW_CTL_RTS; + } + } + else + { + if (cts == 2) + { + pconf->FlowControl = EG91_UART_FLW_CTL_CTS; + } + else + { + pconf->FlowControl = EG91_UART_FLW_CTL_NONE; + } + } + } + + return ret; +} + +/** + * @brief Return Manufacturer. + * @param Obj: pointer to module handle + * @param Manufacturer: pointer to Manufacturer + * @retval None. + */ +void EG91_GetManufacturer(EG91Object_t *Obj, uint8_t *Manufacturer) +{ + strncpy((char*) Manufacturer, (char*) Obj->Manufacturer, EG91_MFC_SIZE); +} + +/** + * @brief Return Model. + * @param Obj: pointer to module handle + * @param Model: pointer to Model + * @retval None. + */ +void EG91_GetProductID(EG91Object_t *Obj, uint8_t *ProductID) +{ + strncpy((char*) ProductID, (char*) Obj->ProductID, EG91_PROD_ID_SIZE); +} + +/** + * @brief Return FW revision. + * @param Obj: pointer to module handle + * @param Model: pointer to FW revision + * @retval None. + */ +void EG91_GetFWRevID(EG91Object_t *Obj, uint8_t *Fw_ver) +{ + strncpy((char*) Fw_ver, (char*) Obj->FW_Rev, EG91_FW_REV_SIZE); +} + +/** + * @brief Retrieve last IP error code + * @param Obj: pointer to module handle + * @param error_string: + * @param error_code + * @retval Operation Status. + */ +EG91_Return_t EG91_RetrieveLastErrorDetails(EG91Object_t *Obj, + char *error_string) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + char *align_ptr; + + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) "AT+QIGETERROR\r\n", RET_OK | RET_ERROR); + align_ptr = strstr((char*) Obj->CmdResp, "+QIGETERROR:") + sizeof("+QIGETERROR:"); + strncpy((char*) error_string, align_ptr, EG91_ERROR_STRING_SIZE); + return ret; +} + +/** + * @brief Register EG91 Tick external cb functions to be provided by application (e.g. HAL_GetTick) + * @param Obj: pointer to module handle + * @param GetTickCb: pointer to callback function that should provide a Timer Tick in ms + * @retval Operation Status. + */ +EG91_Return_t EG91_RegisterTickCb(EG91Object_t *Obj, + App_GetTickCb_Func GetTickCb) +{ + if (!Obj || !GetTickCb) + { + return EG91_RETURN_ERROR; + } + + Obj->GetTickCb = GetTickCb; + + return EG91_RETURN_OK; +} + +/* ==== AP Connection ==== */ + +/** + * @brief Configure a PDP Access point. + * @param Obj: pointer to module handle + * @param ContextID : range is 1-20 + * @param Apn : access point name + * @param Username : Got IP Address + * @param Password : Network IP mask + * @param AuthenticationMode : 0: none, 1: PAP + * @retval Operation Status. + */ +EG91_Return_t EG91_ConfigureAP(EG91Object_t *Obj, EG91_APConfig_t *ApConfig) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + + snprintf(CmdString, EG91_CMD_SIZE, "AT+QICSGP=%d,1,\"%s\",\"%s\",\"%s\",%d\r\n", + ApConfig->ContextID, ApConfig->ApnString, ApConfig->Username, ApConfig->Password, ApConfig->Authentication); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) CmdString, RET_OK | RET_ERROR); + if (ret == EG91_RETURN_OK) + { + Obj->APContextState[ApConfig->ContextID - 1] = EG91_AP_CONFIGURED; + } + return ret; +} + +/** + * @brief Join a PDP Access point. + * @param Obj: pointer to module handle + * @param ContextID : range is 1-20 (max three can be connected simultaneously) + * @retval Operation Status. + */ +EG91_Return_t EG91_Activate(EG91Object_t *Obj, uint8_t ContextID) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + + snprintf(CmdString, strlen("AT+QICSGP=1, 1, \"%s\", \"\", \"\", 0\r\n") + 20, "AT+QICSGP=1, 1, \"%s\", \"\", \"\", 0\r\n", "testingAPN"); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) CmdString, RET_OK | RET_ERROR); + if (ret == EG91_RETURN_OK) + { + Obj->APContextState[ContextID - 1] = EG91_AP_CONFIGURED; + } + + HAL_Delay(1000); + + if (Obj->APContextState[ContextID - 1] == EG91_AP_CONFIGURED) + { + if (Obj->APsActive < 3) + { +// snprintf(CmdString, 24, "AT+QIACT=%d\r\n", ContextID); + snprintf(CmdString, 24, "AT+CGACT=1,%d\r\n", ContextID); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_150000, (uint8_t*) CmdString, RET_OK | RET_ERROR); + HAL_Delay(10); + if (ret == EG91_RETURN_OK) + { + Obj->APContextState[ContextID - 1] = EG91_AP_ACVTIVATED; + Obj->APsActive++; + } + } + + snprintf(CmdString, EG91_CMD_SIZE, "AT+NETOPEN?\r\n"); + AT_ExecuteCommand(Obj, EG91_TOUT_150000 / 2, (uint8_t*) CmdString, RET_OPEN | RET_ERROR); + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_OK, EG91_TOUT_300); + if(strstr((char*)Obj->CmdResp, "0") != NULL) + { + snprintf(CmdString, EG91_CMD_SIZE, "AT+NETOPEN\r\n"); + AT_ExecuteCommand(Obj, EG91_TOUT_150000 / 2, (uint8_t*) CmdString, RET_OPEN | RET_ERROR); + } + else + { + //do nothing + } + HAL_Delay(500); + } +#ifdef EG91_DBG + printf(" EG91_Activate() PDP Access point, ret value: %d \n", ret); +#endif + return ret; +} + +/** + * @brief Leave a PDP Access point. + * @param Obj: pointer to module handle + * @param ContextID : range is 1-20 (max three are connected simultaneously) + * @retval Operation Status. + */ +EG91_Return_t EG91_Deactivate(EG91Object_t *Obj, uint8_t ContextID) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + +// snprintf(CmdString, 24, "AT+QIDEACT=%d\r\n", ContextID); + snprintf(CmdString, 24, "AT+CGACT=0,%d\r\n", ContextID); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_40000, (uint8_t*) CmdString, RET_OK | RET_ERROR); + if (ret == EG91_RETURN_OK) + { + Obj->APContextState[ContextID - 1] = EG91_AP_CONFIGURED; + Obj->APsActive--; + } +#ifdef EG91_DBG + printf(" EG91_Deactivate() PDP Access point, ret value: %d \n", ret); +#endif + return ret; +} + +/** + * @brief Check whether the contextID is connected to an access point. + * @retval Operation Status. + */ +EG91_APState_t EG91_IsActivated(EG91Object_t *Obj, uint8_t ContextID) +{ + return (EG91_APState_t) Obj->APContextState[ContextID - 1]; +} + +/** + * @brief Get the list of the current activated context and its IP addresses + * @param Obj: pointer to module handle + * @param IPaddr_string: pointer where to retrieve the string with all active IP info + * @param IPaddr_int: pointer where to retrieve the first active IP address in int_array[] format + * @retval Operation Status. + */ +EG91_Return_t EG91_GetActiveIpAddresses(EG91Object_t *Obj, char *IPaddr_string, + uint8_t *IPaddr_int) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + int32_t cmdret; + char *align_ptr; + + /* Remove this if it is not working - Alecks*/ + snprintf(CmdString, EG91_CMD_SIZE, "AT+NETOPEN?\r\n"); + AT_ExecuteCommand(Obj, EG91_TOUT_150000 / 2, (uint8_t*) CmdString, RET_OPEN | RET_ERROR); + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_OK, EG91_TOUT_300); + + if(strstr((char*)Obj->CmdResp, "0") != NULL) + { + snprintf(CmdString, EG91_CMD_SIZE, "AT+NETOPEN\r\n"); + AT_ExecuteCommand(Obj, EG91_TOUT_150000 / 2, (uint8_t*) CmdString, RET_OPEN | RET_ERROR); + } + + cmdret = AT_ExecuteCommand(Obj, EG91_TOUT_150000, (uint8_t*) "AT+IPADDR\r\n", RET_OK | RET_ERROR); + if (cmdret == RET_OK) + { + align_ptr = strtok((char*)Obj->CmdResp, ","); + // loop through the string to extract all other tokens + for (int i = 0; i < 1; i++) + { + align_ptr = strtok(NULL, "\r\n"); + } + align_ptr = strtok(align_ptr, "\r\n\r\n"); + ParseIP(align_ptr, IPaddr_int); + ret = EG91_RETURN_OK; + } + return ret; +} + +#if (EG91_USE_PING == 1) +/** + * @brief Test the Internet Protocol reachability of a host + * @param Obj: pointer to module handle + * @param ContextID : range is 1-20 (max three are connected simultaneously) + * @param host_addr_string: domain name (e.g. www.amazon.com) or dotted decimal IP addr + * @param count: PING repetitions (default 4) (max 10) + * @param rep_delay_sec: timeout for each repetition in seconds + * @retval Operation Status. + */ +EG91_Return_t EG91_Ping(EG91Object_t *Obj, uint8_t ContextID, + char *host_addr_string, uint16_t count, uint16_t rep_delay_sec) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + char *align_ptr; + char *token; +// char *packetReceived; + + if (count > 10) + { + count = 10; + } + snprintf(CmdString, EG91_CMD_SIZE, "AT+MPING=%s, 1, %d, 32, %d\r\n", host_addr_string, count, rep_delay_sec ); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_150000, (uint8_t*) CmdString, RET_OK | RET_ERROR); + + if(ret == EG91_RETURN_OK) + { + for(int i = 0; i < 11; i++) + { + memset(Obj->CmdResp, 0, sizeof(Obj->CmdResp)); + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_NETCLOSE, EG91_TOUT_SHORT); +// printf("Ping: %s\r\n", Obj->CmdResp); + HAL_Delay(1000); + } + + align_ptr = strtok((char*)Obj->CmdResp, "+MPING:"); + if (align_ptr != NULL) + { + for (int j = 0; j < 2; j++) + { + token = strtok_r(align_ptr, ",", &align_ptr); + } + + if (atoi(token) >= (count * 0.7)) + { + ret = EG91_RETURN_OK; + } + else + { + ret = EG91_RETURN_ERROR; + } + } + else + { + ret = EG91_RETURN_ERROR; + } + } + return ret; +} +#endif + +/* ==== Client connection and communication ==== */ + +/** + * @brief Get the last IP addresses associated to the host name via Google DNS service + * @param Obj: pointer to module handle + * @param ContextID : range is 1-20 (max three are connected simultaneously) + * @param IPaddr_string: host name (e.g. www.host.com) + * @param IPaddr_int: pointer where to retrieve the first active IP address in int_array[] format + * @retval Operation Status. + */ +EG91_Return_t EG91_DNS_LookUp(EG91Object_t *Obj, uint8_t ContextID, + const char *IPaddr_string, uint8_t *IPaddr_int) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; +// int32_t urc_retval = 0; +// uint16_t parsedlen = 0; + int32_t cmdret; + char *align_ptr; + + /* force to use google DNS service : "8.8.8.8" */ + // Need to revisit + snprintf(CmdString, 255, "AT+MDNSGIP=\"%s\"\r\n", IPaddr_string); + cmdret = AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) CmdString, RET_OK | RET_ERROR); + + if (cmdret == RET_OK) + { + align_ptr = strtok((char*)Obj->CmdResp, ","); + // loop through the string to extract all other tokens + for (int i = 0; i < 1; i++) + { + align_ptr = strtok(NULL, " "); + } + align_ptr = strtok(align_ptr, "\r\n\r\n"); + ParseIP(align_ptr, IPaddr_int); + ret = EG91_RETURN_OK; + } + +#ifdef EG91_DBG + char error_string[40]; + if (ret == EG91_RETURN_OK) + { + printf("Host addr from DNS: %d.%d.%d.%d \n", IPaddr_int[0],IPaddr_int[1],IPaddr_int[2],IPaddr_int[3]); + } + else + { + EG91_RetrieveLastErrorDetails(Obj, error_string); + printf("EG91_DNS_LookUp error: %s\n", error_string); + } +#endif + return ret; +} + +/** + * @brief Configure and Start a Client connection. + * @param Obj: pointer to module handle + * @param ContextID : range is 1-20 (max three are connected simultaneously) + * @param conn: pointer to the connection structure + * @retval Operation Status. + */ +EG91_Return_t EG91_OpenClientConnection(EG91Object_t *Obj, uint8_t ContextID, + EG91_Conn_t *conn) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + char type_string[13]; + int16_t recv; + int32_t cmdret, retr_errcode; + + Obj->fops.IO_FlushBuffer(); + Obj->SocketInfo[conn->ConnectID].Type = conn->Type; + Obj->SocketInfo[conn->ConnectID].AccessMode = conn->AccessMode; + Obj->SocketInfo[conn->ConnectID].ComulatedQirdData = 0; + Obj->SocketInfo[conn->ConnectID].HaveReadLength = 0; + Obj->SocketInfo[conn->ConnectID].UnreadLength = 0; + + if (conn->Type == EG91_TCP_CONNECTION) + { + strcpy(type_string, "TCP"); + } + else if (conn->Type == EG91_UDP_CONNECTION) + { + strcpy(type_string, "UDP"); + } + else if (conn->Type == EG91_TCP_LISTENER_CONNECTION) + { + strcpy(type_string, "TCP_LISTENER"); + } + else if (conn->Type == EG91_UDP_SERVER_CONNECTION) + { + strcpy(type_string, "UDP_SERVER"); + } + +#ifdef EG91_DBG + printf(" EG91_OpenClientConnection() \n"); +#endif + + + snprintf(CmdString, EG91_CMD_SIZE, "AT+CIPOPEN=%d,\"%s\",\"%s\",%u,%u\r\n", + conn->ConnectID, type_string, conn->Url, conn->RemotePort, conn->LocalPort); +// snprintf(CmdString, EG91_CMD_SIZE, "AT+CIPOPEN=%d,\"%s\",\"%s\",%u\r\n", +// conn->ConnectID, type_string, conn->Url, conn->RemotePort); + /* The maximum timeout of TCP connect is 75 seconds, hence EG91_TOUT_150000/2 */ + cmdret = AT_ExecuteCommand(Obj, EG91_TOUT_150000 / 2, (uint8_t*) CmdString, + RET_OPEN | RET_ERROR); + if (cmdret == RET_OPEN) + { + recv = AT_RetrieveData(Obj, Obj->CmdResp, 6, RET_NONE, EG91_TOUT_SHORT); + if (recv > 0) + { + retr_errcode = ParseNumber((char*) Obj->CmdResp + 3, NULL); + if (retr_errcode != 0) /* read the remaining 2 characters if error nr 3 chiphers*/ + { + recv = AT_RetrieveData(Obj, Obj->CmdResp, 2, RET_NONE, + EG91_TOUT_SHORT); +#ifdef EG91_DBG + printf(" EG91_OpenClientConnection() retr_errcode: %ld \n", retr_errcode); +#endif + } + else + { +#ifdef EG91_DBG + snprintf(CmdString, EG91_CMD_SIZE, "AT+QISTATE=1,%d\r\n", conn->ConnectID); + cmdret = AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t *)CmdString, RET_OK | RET_ERROR); +#endif + ret = EG91_RETURN_OK; + } + } + else + { +#ifdef EG91_DBG + printf(" EG91_OpenClientConnection() missing part of the response \n"); +#endif + } + } + + return ret; +} + +/** + * @brief Stop Client connection. + * @param Obj: pointer to module handle + * @param conn: pointer to the connection structure + * @retval Operation Status. + */ +EG91_Return_t EG91_CloseClientConnection(EG91Object_t *Obj, EG91_Conn_t *conn) +{ + EG91_Return_t ret = EG91_RETURN_ERROR; + Obj->fops.IO_FlushBuffer(); + + snprintf(CmdString, 24, "AT+CIPCLOSE=%d\r\n", conn->ConnectID); + ret = (EG91_Return_t) AT_ExecuteCommand(Obj, EG91_TOUT_5000, (uint8_t*) CmdString, RET_ERROR | RET_OK); + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_NETCLOSE, EG91_TOUT_300); +#ifdef EG91_DBG + printf(" EG91_CloseClientConnection(), ret value: %d \n", ret); +#endif + return ret; +} + +/** + * @brief Send an amount data over C2C. + * @param Obj: pointer to module handle + * @param Socket: number of the socket + * @param pdata: pointer to data + * @param Reqlen : (IN) nr of bytes to be sent + * @param SentLen : (OUT) ptr to return the nr of bytes actually sent + * @param Timeout : time (ms) for the modem to confirm the data was sent. Function can take twice to return. + * @retval Operation Status. + */ +EG91_SendRet_t EG91_SendData(EG91Object_t *Obj, uint8_t Socket, uint8_t *pdata, + uint16_t Reqlen, uint16_t *SentLen, uint32_t Timeout) +{ + EG91_SendRet_t ret = EG91_SEND_RET_CONN_ERR; + int32_t cmdret = 0; + + *SentLen = 0; + if (Reqlen <= EG91_TX_DATABUF_SIZE) + { + snprintf(CmdString, 24, "AT+CIPRXGET=1,%d\r\n", Socket); + AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) CmdString, RET_ERROR | RET_READ); + + snprintf(CmdString, 24, "AT+CIPSEND=%d,%d\r\n", Socket, Reqlen); + cmdret = AT_ExecuteCommand(Obj, Timeout, (uint8_t*) CmdString, RET_ERROR | RET_ARROW); + if (cmdret == RET_ARROW) + { + ret = AT_RequestSendData(Obj, pdata, Reqlen, Timeout); + if (ret == RET_SENT) + { + *SentLen = Reqlen; + } + } + else + { +#ifdef EG91_DBG + printf("AT_ExecuteCommand() failed: %ld.\n", cmdret); +#endif + } + } +#ifdef EG91_DBG + if(ret == RET_SENT) + { + printf("EG91_SendData() OK sending from STM32 to EG91: length: %u \n", Reqlen); + } + else + { + printf("EG91_SendData() FAIL sending: length: %u, ret error: %d\n", Reqlen, ret); + } +#endif + return ret; +} + +/** + * @brief Receive an amount data over C2C. + * @param Obj: pointer to module handle + * @param Socket: number of the socket + * @param pdata: pointer to data + * @param Requestedlen (IN) : in EG91_BUFFER_MODE the req len, in EG91_DIRECT_PUSH is the max leng available in pdata[] buffer + * @param Receivedlen (OUT) : pointer to return the length of the data received + * @param Timeout : timeout (ms) used by each internal exchange Mcu<-->modem; hence function could take much longer to return + * @retval Operation Status. + */ +EG91_ReceiveRet_t EG91_ReceiveData(EG91Object_t *Obj, uint8_t Socket, + uint8_t *pdata, uint16_t Requestedlen, uint16_t *Receivedlen, + uint32_t Timeout) +{ + + EG91_ReceiveRet_t ret = EG91_RECEIVE_RET_COM_ERR; + int32_t urc_retval = 0, rcvlen = 0; + uint8_t *ptr = pdata; + uint16_t parsedlen = 0; + uint8_t parse_count; + int16_t qird_retval = 0; + + *Receivedlen = 0; + + if (Obj->SocketInfo[Socket].Type != EG91_TCP_CONNECTION) + { + return EG91_RECEIVE_RET_PARAM_ERR; /* currently only TCP connection is implemented */ + } + + if (Requestedlen <= EG91_RX_DATABUF_SIZE) + { + switch (Obj->SocketInfo[Socket].AccessMode) + { + case EG91_BUFFER_MODE: +#ifdef EG91_DBG + printf(" EG91_ReceiveData() Requestedlen: %d \n", Requestedlen); + printf(" EG91_ReceiveData() UnreadLength: %d \n", Obj->SocketInfo[Socket].UnreadLength); + printf(" EG91_ReceiveData() ComulatedQirdData: %d \n", Obj->SocketInfo[Socket].ComulatedQirdData); +#endif + + if (Obj->SocketInfo[Socket].UartRemaining > 0) /* if Timeout respects UART speed this should never happen*/ + { +#ifdef EG91_DBG + printf(" **** EG91_ReceiveData() UartRemaining %d \n", Obj->SocketInfo[Socket].UartRemaining); +#endif + rcvlen = AT_RetrieveData(Obj, ptr, Obj->SocketInfo[Socket].UartRemaining, RET_NONE, Timeout); + Obj->SocketInfo[Socket].UartRemaining -= rcvlen; + *Receivedlen = rcvlen; + if (Obj->SocketInfo[Socket].UartRemaining == 0) + { + /* update Obj->SocketInfo[Socket] and exit */ + snprintf(CmdString, 24, "AT+CIPRXGET=0,%d\r\n", Socket); + AT_ExecuteCommand(Obj, EG91_TOUT_300, (uint8_t*) CmdString, RET_ERROR | RET_READ ); + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_300); + ParseQIRD((char*) Obj->CmdResp, &Obj->SocketInfo[Socket].ComulatedQirdData); + ret = EG91_RECEIVE_RET_OK; + } + else + { + ret = EG91_RECEIVE_RET_INCOMPLETE; /* even this iteration was not sufficient to get all data from modem */ + } + break; + } + + + if (Obj->SocketInfo[Socket].UnreadLength > 0) /* some data remaining from previous operation */ + { + if (Requestedlen > Obj->SocketInfo[Socket].UnreadLength) + { + Requestedlen = Obj->SocketInfo[Socket].UnreadLength; /* Just take the one to end remaining data */ + } + } + else + { + /* Wait for parsing URC */ + urc_retval = AT_RetrieveUrc(Obj, Timeout, &parsedlen, EG91_BUFFER_MODE); +#ifdef EG91_DBG + if (urc_retval < 0) + { + printf(" EG91_ReceiveData() URC not received\n"); + } + else + { + printf(" EG91_ReceiveData() URC OK\n"); + } +#endif + } + + snprintf(CmdString, 24, "AT+CIPRXGET=2,%d,%u\r\n", Socket, Requestedlen); + qird_retval = AT_ExecuteCommand(Obj, EG91_TOUT_SHORT, (uint8_t*) CmdString, RET_ERROR | RET_READ); + if ((qird_retval < 0) || (qird_retval == RET_ERROR)) + { +#ifdef EG91_DBG + printf(" EG91_ReceiveData() QIRD issue\n"); +#endif + return EG91_RECEIVE_RET_COM_ERR; + } + /* length parsing */ + AT_RetrieveData(Obj, Obj->CmdResp, 0, RET_CRLF, EG91_TOUT_300); + char *token = strtok((char*)Obj->CmdResp, ","); + for(int i = 0; i < 3; i++) + { + token = strtok(NULL, ","); + } + parsedlen = (uint16_t) ParseNumber(token, &parse_count); + +#ifdef EG91_DBG + if ((Obj->SocketInfo[Socket].UnreadLength > 0) && (parsedlen != Requestedlen)) + { + printf(" EG91_ReceiveData() unexpected behaviour parsedlen != Requestedlen (%u)\n", Requestedlen); + } + printf(" EG91_ReceiveData() parsedlen is %u\n", parsedlen); +#endif + /* Retrieving data */ + rcvlen = AT_RetrieveData(Obj, ptr, parsedlen, RET_NONE, Timeout); + if (rcvlen < 0) + { + *Receivedlen = 0; + break; /* return EG91_RECEIVE_RET_COM_ERR */ + } + if (rcvlen != parsedlen) /* uart has not retrieved all data from modem yet*/ + { +#ifdef EG91_DBG + printf(" EG91_ReceiveData() Received length mismatch!!!\n"); +#endif + Obj->SocketInfo[Socket].UartRemaining = parsedlen - rcvlen; + Obj->SocketInfo[Socket].UnreadLength -= rcvlen; + *Receivedlen = rcvlen; + ret = EG91_RECEIVE_RET_INCOMPLETE; /* if Timeout respects UART speed this should never happen*/ + } + else + { +#ifdef EG91_DBG + printf(" EG91_ReceiveData() Received OK %ld \n", rcvlen); +#endif + *Receivedlen = rcvlen; + Obj->SocketInfo[Socket].UartRemaining = 0; + ret = EG91_RECEIVE_RET_OK; + } + + break; + + case EG91_DIRECT_PUSH: /* ******** Careful: NOT fully TESTED ******** */ + + if (Obj->RemainRxData > 0) /* some data remaining from previous operation */ + { + if (Requestedlen <= Obj->RemainRxData) /* in EG91_DIRECT_PUSH Requestedlen is the max the applic can receive */ + { + Obj->RemainRxData -= Requestedlen; + if (AT_RetrieveData(Obj, ptr, Requestedlen, RET_NONE, + Timeout) != Requestedlen) + { + return EG91_RECEIVE_RET_COM_ERR; + } + else + { + return EG91_RECEIVE_RET_OK; + } + } + else /* all remaining data can be retried */ + { + Requestedlen -= Obj->RemainRxData; + + if (AT_RetrieveData(Obj, ptr, Obj->RemainRxData, RET_NONE, + Timeout) == Obj->RemainRxData) + { + ptr += Obj->RemainRxData; + Obj->RemainRxData = 0; + } + else + { + /* error */ + return EG91_RECEIVE_RET_COM_ERR; + } + } + } + + urc_retval = AT_RetrieveUrc(Obj, Timeout, &parsedlen, + EG91_DIRECT_PUSH); + + if (urc_retval == RET_URC_RECV) + { + if (parsedlen > 0) + { + if (Requestedlen > parsedlen) /* retrieve all data */ + { + Obj->RemainRxData = 0; + Requestedlen = parsedlen; + } + else /* not enough space in the applic buffer */ + { + Obj->RemainRxData = parsedlen - Requestedlen; + } + + *Receivedlen = AT_RetrieveData(Obj, ptr, Requestedlen, + RET_NONE, Timeout); + if (*Receivedlen == Requestedlen) + { + ret = EG91_RECEIVE_RET_OK; + } + } + } + break; + + case EG91_TRANSPARENT_MODE: + /* TBD */ + ret = EG91_RECEIVE_RET_PARAM_ERR; + break; + + } /*end switch case */ + } + else + { + ret = EG91_RECEIVE_RET_PARAM_ERR; + } + return ret; +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/Core/Src/gpio.c b/Core/Src/gpio.c new file mode 100644 index 0000000..62bfaa1 --- /dev/null +++ b/Core/Src/gpio.c @@ -0,0 +1,136 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file gpio.c + * @brief This file provides code for the configuration + * of all used GPIO pins. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "gpio.h" + +/* USER CODE BEGIN 0 */ +#include "usart.h" +/* USER CODE END 0 */ + +/*----------------------------------------------------------------------------*/ +/* Configure GPIO */ +/*----------------------------------------------------------------------------*/ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** Configure pins + PC15-OSC32_OUT ------> RCC_OSC32_OUT + PC14-OSC32_IN ------> RCC_OSC32_IN + PA14 (JTCK/SWCLK) ------> DEBUG_JTCK-SWCLK + PA13 (JTMS/SWDIO) ------> DEBUG_JTMS-SWDIO + OSC_OUT ------> RCC_OSC_OUT + OSC_IN ------> RCC_OSC_IN +*/ +void MX_GPIO_Init(void) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOB, STATUS_LED_Pin|LTE_EN_Pin|LTE_RST_Pin|LTE_PWRKEY_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pins : STATUS_LED_Pin LTE_EN_Pin LTE_RST_Pin LTE_PWRKEY_Pin */ + GPIO_InitStruct.Pin = STATUS_LED_Pin|LTE_EN_Pin|LTE_RST_Pin|LTE_PWRKEY_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + +} + +/* USER CODE BEGIN 2 */ +void LEDStatus_Active(void) +{ + HAL_GPIO_WritePin(STATUS_LED_GPIO_Port, STATUS_LED_Pin, GPIO_PIN_SET); +} + +void LEDStatus_Inactive(void) +{ + HAL_GPIO_WritePin(STATUS_LED_GPIO_Port, STATUS_LED_Pin, GPIO_PIN_RESET); +} + +/** + * @brief Powers up the LTE module (Quectel EG91) using GPIO toggling. + * + * This function simulates pressing the PWRKEY and enables the level translator. + * A wait period is included to allow UART stabilization. + */ +void LTE_HardwarePowerUp(void) +{ + HAL_GPIO_WritePin(LTE_EN_GPIO_Port, LTE_EN_Pin, GPIO_PIN_SET); + + APP_LOG_MSG(" --- QUECTEL EG91 Power Up ---\r\n"); + + /* Power up the LTE Module Using Power Key */ + HAL_GPIO_WritePin(LTE_PWRKEY_GPIO_Port, LTE_PWRKEY_Pin, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LTE_RST_GPIO_Port, LTE_RST_Pin, GPIO_PIN_RESET); + HAL_Delay(100); + HAL_GPIO_WritePin(LTE_RST_GPIO_Port, LTE_RST_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(LTE_PWRKEY_GPIO_Port, LTE_PWRKEY_Pin, GPIO_PIN_SET); + HAL_Delay(200); + HAL_GPIO_WritePin(LTE_RST_GPIO_Port, LTE_RST_Pin, GPIO_PIN_RESET); + HAL_Delay(350); + HAL_GPIO_WritePin(LTE_PWRKEY_GPIO_Port, LTE_PWRKEY_Pin, GPIO_PIN_RESET); + + HAL_Delay(100); + + for (uint8_t wait = 0; wait < 12; wait++) { + LEDStatus_Active(); + HAL_Delay(500); + LEDStatus_Inactive(); + HAL_Delay(500); + // APP_LOG_MSG("."); + } + // APP_LOG_MSG(" Done\r\n"); +} + +/** + * @brief Powers down the LTE module (Quectel EG91) via GPIO toggling. + * + * This simulates a long-press of the PWRKEY, then waits 30 seconds to allow the module to shut down safely. + */ +void LTE_HardwarePowerDown(void) +{ + APP_LOG_MSG(" --- QUECTEL EG91 Shut Down --- \r\n"); + + HAL_GPIO_WritePin(LTE_PWRKEY_GPIO_Port, LTE_PWRKEY_Pin, GPIO_PIN_RESET); + HAL_Delay(100); + HAL_GPIO_WritePin(LTE_PWRKEY_GPIO_Port, LTE_PWRKEY_Pin, GPIO_PIN_SET); + HAL_Delay(700); + HAL_GPIO_WritePin(LTE_PWRKEY_GPIO_Port, LTE_PWRKEY_Pin, GPIO_PIN_RESET); + + LEDStatus_Active(); + // APP_LOG_MSG("Shutting off "); + for (uint8_t wait = 0; wait < 30; wait++) + { + // APP_LOG_MSG("."); + HAL_Delay(1000); + } + // APP_LOG_MSG(" Done\r\n"); + LEDStatus_Inactive(); +} +/* USER CODE END 2 */ diff --git a/Core/Src/icache.c b/Core/Src/icache.c new file mode 100644 index 0000000..63795c3 --- /dev/null +++ b/Core/Src/icache.c @@ -0,0 +1,57 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file icache.c + * @brief This file provides code for the configuration + * of the ICACHE instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "icache.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* ICACHE init function */ +void MX_ICACHE_Init(void) +{ + + /* USER CODE BEGIN ICACHE_Init 0 */ + + /* USER CODE END ICACHE_Init 0 */ + + /* USER CODE BEGIN ICACHE_Init 1 */ + + /* USER CODE END ICACHE_Init 1 */ + + /** Enable instruction cache in 1-way (direct mapped cache) + */ + if (HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) != HAL_OK) + { + Error_Handler(); + } + if (HAL_ICACHE_Enable() != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ICACHE_Init 2 */ + + /* USER CODE END ICACHE_Init 2 */ + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Core/Src/lte_comms.c b/Core/Src/lte_comms.c new file mode 100644 index 0000000..ce66777 --- /dev/null +++ b/Core/Src/lte_comms.c @@ -0,0 +1,586 @@ +#include +#include + +#include "main.h" +#include "usart.h" +#include "gpio.h" + +#include "eg91.h" +#include "lte_comms.h" + +#define LTE_CONTEXT_1 1 + +EG91Object_t Eg91Obj; +static uint16_t rnglocalport = 0; + +int Network_Init(void) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + LTE_Registatus_t reg_status = LTE_REGISTATUS_UNKNOWN; + int32_t quality_level = 0; + int8_t quality_level_db = 0; + int try_counter = 0; + + char moduleInfo[MAX(MAX(MAX(MAX(LTE_FW_REV_SIZE, LTE_MAN_SIZE), LTE_PROD_ID_SIZE), LTE_IMEI_SIZE), LTE_ICCID_SIZE) + 1]; + while (ret != LTE_RET_OK) + { + if (try_counter >= 3) + { + ret = LTE_RET_ERROR; + break; + } + else + { + try_counter++; + HAL_Delay(50); + + LTE_HardwarePowerUp(); + reg_status = LTE_Init(120); + + LTE_GetModuleName(moduleInfo); + APP_LOG_MSG("Module Name: %s\r\n", moduleInfo); + memset(moduleInfo, 0, sizeof(moduleInfo)); + + LTE_GetModuleID(moduleInfo); + APP_LOG_MSG("Product ID: %s\r\n", moduleInfo); + memset(moduleInfo, 0, sizeof(moduleInfo)); + + LTE_GetModuleFirmwareRevision(moduleInfo); + APP_LOG_MSG("FW Version: %s\r\n", moduleInfo); + memset(moduleInfo, 0, sizeof(moduleInfo)); + + LTE_GetIMEI(moduleInfo); + APP_LOG_MSG("IMEI: %s\r\n", moduleInfo); + memset(moduleInfo, 0, sizeof(moduleInfo)); + + LTE_GetSimId(moduleInfo); + APP_LOG_MSG("ICCID: %s\r\n", moduleInfo); + memset(moduleInfo, 0, sizeof(moduleInfo)); + + + if ((reg_status != LTE_REGISTATUS_ERROR) && (reg_status != LTE_REGISTATUS_SIM_NOT_INSERTED) && (reg_status == LTE_REGISTATUS_NOT_REGISTERED)) + { + APP_LOG_MSG("Successful Initialization of the Module\r\n\r\n"); + memset(moduleInfo, 0, sizeof(moduleInfo)); + + + /* Retrieve the Quality Level of the Connection */ + LTE_GetSignalQualityStatus(&quality_level); + if (quality_level != 99) + { + quality_level_db = (int8_t)(-113 + 2 * quality_level); + APP_LOG_MSG("Signal Quality Level %d dBm (GSM Format: %ld)\r\n", quality_level_db, quality_level); + } + else + { + APP_LOG_MSG("Signal Quality Level not detectable\r\n"); + } + APP_LOG_MSG("\r\n"); + } + switch (reg_status) + { + case LTE_REGISTATUS_HOME_NETWORK: + case LTE_REGISTATUS_ROAMING: + case LTE_REGISTATUS_UNKNOWN: + { + HAL_Delay(1000); + ret = LTE_RET_OK; + APP_LOG_MSG("\r\n >>> Module Registration Successful\r\n\r\n"); + break; + } + + case LTE_REGISTATUS_TRYING: + { + APP_LOG_MSG("\r\n >>> Module Registration Trying\r\n\r\n"); + break; + } + + case LTE_REGISTATUS_REG_DENIED: + { + APP_LOG_MSG("\r\n >>> Module Registration Denied\r\n\r\n"); + break; + } + + case LTE_REGISTATUS_NOT_REGISTERED: + { + APP_LOG_MSG("\r\n >>> Module Registration Failed\r\n\r\n"); + break; + } + + case LTE_REGISTATUS_ERROR: + { + APP_LOG_MSG("\r\n >>> Module AT Communication Error with the Device\r\n"); + APP_LOG_MSG(" >>> Device might be disconnected or wrongly connected\r\n\r\n"); + break; + } + + case LTE_REGISTATUS_SIM_NOT_INSERTED: + { + APP_LOG_MSG("\r\n >>> SIM is not INSERTED\r\n\r\n"); + break; + } + + default: + { + APP_LOG_MSG("\r\n >>> Module SIM Error: %d\r\n", reg_status); + APP_LOG_MSG(" >>> Please check if the SIM is inserted and valid, if credentials are ok, etc.\r\n\r\n"); + break; + } + + } + } + } + return (ret == LTE_RET_OK) ? 0 : -1; +} + + +void LTE_ConvertIpAddrToString(const uint8_t * ipArray, char *returnStr) +{ + snprintf((char*) returnStr, 16, "%d.%d.%d.%d", ipArray[0], ipArray[1], ipArray[2], ipArray[3]); +} + +LTE_Registatus_t LTE_Init(uint16_t registration_timeout_sec) +{ + EG91_InitRet_t init_status; + EG91_SIMState_t sim_tmp; + LTE_Registatus_t ret = LTE_REGISTATUS_ERROR; + + bool signalMsg = false; + + /* Channel Signal Quality */ + int32_t quality_level = 0; + int8_t quality_level_db = 0; + + /* Counter for PS Attachement */ + int8_t attRetry = 0; + + /* Init for timeout management */ + uint32_t tickstart; + uint32_t tickcurrent; + uint32_t registration_timeout_msec = registration_timeout_sec * 1000; + + tickstart = HAL_GetTick(); + + EG91_RegisterTickCb(&Eg91Obj, HAL_GetTick); + + if (EG91_RegisterBusIO(&Eg91Obj, (IO_Init_Func)MX_USART1_UART_Init, + (IO_DeInit_Func)HAL_UART_DeInit, (IO_Baudrate_Func)LTE_UART_SetBaudrate, + (IO_Send_Func)LTE_UART_SendData, (IO_ReceiveOne_Func)LTE_UART_ReceiveSingleData, + (IO_Flush_Func)LTE_UART_FlushBuffer) == EG91_RETURN_OK) + { + init_status = EG91_Init(&Eg91Obj); + if (init_status == EG91_INIT_RET_OK) + { + tickcurrent = HAL_GetTick() - tickstart; + while ((tickcurrent < registration_timeout_msec) || (registration_timeout_sec == LTE_COMMS_MAX_DELAY)) + { + /* Check Signal Quality*/ + if (EG91_GetSignalQualityStatus(&Eg91Obj, &quality_level) == EG91_RETURN_OK) + { + if (quality_level == 99) + { + if (signalMsg == false) + { + APP_LOG_MSG("Signal is not known or not detectable yet... "); + signalMsg = true; + } + else + { + APP_LOG_MSG("."); + } + HAL_Delay(1000); + } + else + { + quality_level_db = (int8_t)(-113 + 2 * quality_level); + APP_LOG_MSG("\r\nSignal Level: %d dBm\r\n", quality_level_db); + HAL_Delay(1000); + break; + } + } + tickcurrent = HAL_GetTick() - tickstart; + } + tickcurrent = HAL_GetTick() - tickstart; + while( (tickcurrent < registration_timeout_msec) || (registration_timeout_sec == LTE_COMMS_MAX_DELAY) ) + { + /* Attach the MT to the backet domain service */ + if (EG91_PSAttach(&Eg91Obj) == EG91_RETURN_OK) + { + APP_DEBUG_MSG("Packet Switched attachement succeeded\r\n"); + break; + } + else + { + /* Start an Automatic PLMN selection */ + attRetry++; + if (attRetry == 1) + { + APP_DEBUG_MSG("Trying an automatic registration. It may take until 3 minutes, please wait ...\r\n"); + if (EG91_RETURN_OK != EG91_AutomaticPlmnSelection(&Eg91Obj)) + { + break; + } + else + { + if (attRetry > 4) + { + APP_DEBUG_MSG("Unrecoverable Error, PS attachement failed\r\n"); + break; + } + } + } + HAL_Delay(1000); + } + tickcurrent = HAL_GetTick() - tickstart; + } + /* Check Packet Switched Registration */ + ret = (LTE_Registatus_t) EG91_GetPsNetworkRegistrationStatus(&Eg91Obj); + APP_DEBUG_MSG("Packet Switch Registration: %d\r\n", ret); + if ( (ret == LTE_REGISTATUS_HOME_NETWORK) || (ret == LTE_REGISTATUS_ROAMING) ) + { + tickcurrent = HAL_GetTick() - tickstart; + APP_DEBUG_MSG("Registation done in %lu ms\r\n", tickcurrent); + } + } + else + { + if (init_status == EG91_INIT_RET_SIM_ERR) + { + sim_tmp = Eg91Obj.SimInfo.SimStatus; + if (sim_tmp == EG91_OPERATION_NOT_ALLOW) + { + ret = LTE_REGISTATUS_OP_NOT_ALLOWED; + } + else + { + ret = (LTE_Registatus_t) Eg91Obj.SimInfo.SimStatus; + } + } + else + { + ret = LTE_REGISTATUS_ERROR; /* Generic e.g. module does not respond to AT command */ + } + } + } + return ret; +} + +LTE_Ret_t LTE_GetSignalQualityStatus(int32_t *qValue) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_GetSignalQualityStatus(&Eg91Obj, qValue) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_ListOperators(char *operator) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_ListOperators(&Eg91Obj, operator) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_GetCurrentOperator (char *operator, int32_t bufSize) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_GetCurrentOperator(&Eg91Obj, operator, bufSize) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_ForceOperator(int32_t code) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_ForceOperator(&Eg91Obj, code) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_ConfigureAP(uint8_t contextType, const char *apn, const char *username, + const char *password, uint8_t authenticationMode) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + EG91_APConfig_t apConfig; + + apConfig.ContextID = LTE_CONTEXT_1; + strncpy((char *)apConfig.ApnString, (char *)apn, EG91_MAX_APN_NAME_SIZE); + strncpy((char *)apConfig.Username, (char *)username, EG91_MAX_USER_NAME_SIZE); + strncpy((char *)apConfig.Password, (char *)password, EG91_MAX_PSW_NAME_SIZE); + apConfig.Authentication = (EG91_Authent_t)authenticationMode; + + if (EG91_ConfigureAP(&Eg91Obj, &apConfig) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_Connect(void) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_Activate(&Eg91Obj, LTE_CONTEXT_1) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_Disconnect(void) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_Deactivate(&Eg91Obj, LTE_CONTEXT_1) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_APState_t LTE_isConnected(void) +{ + return (LTE_APState_t) EG91_IsActivated(&Eg91Obj, LTE_CONTEXT_1); +} + +LTE_Ret_t LTE_GetActiveIpAddress(char * ipAddrStr, uint8_t *ipAddrInt) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_GetActiveIpAddresses(&Eg91Obj, ipAddrStr, ipAddrInt) == LTE_RET_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_Ping(char *address, uint16_t count, uint16_t timeout) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_Ping(&Eg91Obj,LTE_CONTEXT_1, address, count, timeout) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_GetHostAddress(const char *address, uint8_t *ipaddr) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_DNS_LookUp(&Eg91Obj, LTE_CONTEXT_1, address, ipaddr) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_StartClientConnection(uint32_t socket, LTE_Protocol_t type, const char *url, + uint8_t *ipaddr, uint16_t port, uint16_t local_port) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + char converted_ipaddr[16] = { 0 }; + EG91_Conn_t conn; + int random_number = 0; + + conn.ConnectID = socket; + conn.RemotePort = port; + +#ifdef ACCESS_MODE_DIRECT_PUSH + conn.AccessMode = EG91_DIRECT_PUSH; +#else + conn.AccessMode = EG91_BUFFER_MODE; +#endif + + if (local_port != 0) + { + conn.LocalPort = local_port; + } + else + { + if(rnglocalport == 0) + { + random_number = rand(); + rnglocalport = ((uint16_t)(random_number & 0xFFFF) >> 2) + 49152; + } + else + { + rnglocalport += 1; + } + + if (rnglocalport < 49152) /* Wrap around */ + { + rnglocalport = 49152; + } + conn.LocalPort = rnglocalport; + } + + switch (type) + { + case LTE_TCP_PROTOCOL: + conn.Type = EG91_TCP_CONNECTION; + break; + + case LTE_UDP_PROTOCOL: + conn.Type = EG91_UDP_CONNECTION; + break; + + default: + conn.Type = LTE_RET_NOT_SUPPORTED; + break; + } + + if (ret != LTE_RET_NOT_SUPPORTED) + { + if (url == NULL) + { + LTE_ConvertIpAddrToString(ipaddr, converted_ipaddr); + conn.Url = converted_ipaddr; + } + else + { + conn.Url = (char*)url; + } + + if (EG91_OpenClientConnection(&Eg91Obj, LTE_CONTEXT_1, &conn) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + } + return ret; +} + +LTE_Ret_t LTE_StopClientConnection(uint32_t socket) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + EG91_Conn_t conn; + + conn.ConnectID = socket; + if (EG91_CloseClientConnection(&Eg91Obj, &conn) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_StartServerConnection(uint32_t socket, LTE_Protocol_t type, uint16_t port, uint16_t local_port) +{ + return LTE_RET_NOT_SUPPORTED; +} + +LTE_Ret_t LTE_StopServerConnection(uint32_t socket) +{ + return LTE_RET_NOT_SUPPORTED; +} + +LTE_SendStatus_t LTE_SendData(uint32_t socket, uint8_t *pdata, uint16_t reqLen, uint16_t *sentDataLen, uint32_t timeout) +{ + LTE_SendStatus_t ret = LTE_SEND_ERROR; + EG91_SendRet_t status; + + status = EG91_SendData(&Eg91Obj, socket, pdata, reqLen, sentDataLen, timeout); + if (status == EG91_SEND_RET_SENT) + { + ret = LTE_SEND_OK; + } else if (status == EG91_SEND_RET_BUF_FULL) + { + ret = LTE_SEND_BUF_FULL; + } + return ret; +} + +LTE_Ret_t LTE_ReceiveData(uint32_t socket, uint8_t *pdata, uint16_t reqLen, uint16_t *rcvDataLen, uint32_t timeout) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + EG91_ReceiveRet_t result; + + result = EG91_ReceiveData(&Eg91Obj, socket, pdata, reqLen, rcvDataLen, timeout); + if ((result == EG91_RECEIVE_RET_OK) || (result == EG91_RECEIVE_RET_INCOMPLETE)) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_RetrieveLastErrorDetails(char *errorStr) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + char errStr[EG91_ERROR_STRING_SIZE]; + + memset(errStr, 0, EG91_ERROR_STRING_SIZE); + if (EG91_RetrieveLastErrorDetails(&Eg91Obj, errStr) == EG91_RETURN_OK) + { + strncpy(errorStr, errStr, MIN(LTE_ERROR_STRING, EG91_ERROR_STRING_SIZE)); + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_PowerOff(void) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (EG91_PowerDown(&Eg91Obj) == EG91_RETURN_OK) + { + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_GetModuleFirmwareRevision(char *rev) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (Eg91Obj.FW_Rev != NULL) + { + strncpy(rev, (char*)Eg91Obj.FW_Rev, MIN(LTE_FW_REV_SIZE, EG91_FW_REV_SIZE)); + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_GetModuleID(char *productId) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (Eg91Obj.ProductID != NULL) + { + strncpy(productId, (char*)Eg91Obj.ProductID, MIN(LTE_PROD_ID_SIZE, EG91_PROD_ID_SIZE)); + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_GetModuleName(char *moduleName) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (Eg91Obj.Manufacturer != NULL) + { + strncpy(moduleName, (char*)Eg91Obj.Manufacturer, MIN(LTE_MAN_SIZE, EG91_MFC_SIZE)); + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_GetSimId(char *simId) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (Eg91Obj.SimInfo.ICCID != NULL) + { + strncpy(simId, (char*)Eg91Obj.SimInfo.ICCID, MIN(LTE_ICCID_SIZE, EG91_ICCID_SIZE)); + ret = LTE_RET_OK; + } + return ret; +} + +LTE_Ret_t LTE_GetIMEI(char *imei) +{ + LTE_Ret_t ret = LTE_RET_ERROR; + if (Eg91Obj.Imei != NULL) + { + strncpy(imei, (char*)Eg91Obj.Imei, MIN(LTE_IMEI_SIZE, EG91_IMEI_SIZE)); + ret = LTE_RET_OK; + } + return ret; +} diff --git a/Core/Src/main.c b/Core/Src/main.c new file mode 100644 index 0000000..bd1e740 --- /dev/null +++ b/Core/Src/main.c @@ -0,0 +1,212 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "icache.h" +#include "usart.h" +#include "rtc.h" +#include "gpio.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include +#include "lte_comms.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_LPUART1_UART_Init(); + MX_USART1_UART_Init(); + MX_RTC_Init(); + MX_ICACHE_Init(); + /* USER CODE BEGIN 2 */ + + Network_Init(); + + /* USER CODE END 2 */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + uint8_t counter = 0; + uint8_t shut_lte_off = 1; + while (1) + { + if (shut_lte_off == 1) + { + LTE_HardwarePowerDown(); + APP_LOG_MSG("LTE TEST DONE\r\n"); + shut_lte_off = 0; + } + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSEDiv = RCC_HSE_DIV1; + RCC_OscInitStruct.LSIState = RCC_LSI1_ON; + RCC_OscInitStruct.LSIDiv = RCC_LSI_DIV1; + RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL1.PLLM = 2; + RCC_OscInitStruct.PLL1.PLLN = 8; + RCC_OscInitStruct.PLL1.PLLP = 2; + RCC_OscInitStruct.PLL1.PLLQ = 2; + RCC_OscInitStruct.PLL1.PLLR = 2; + RCC_OscInitStruct.PLL1.PLLFractional = 0; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 + |RCC_CLOCKTYPE_PCLK7|RCC_CLOCKTYPE_HCLK5; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB7CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.AHB5_PLL1_CLKDivider = RCC_SYSCLK_PLL1_DIV2; + RCC_ClkInitStruct.AHB5_HSEHSI_CLKDivider = RCC_SYSCLK_HSEHSI_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + { + Error_Handler(); + } +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) + { + } + /* USER CODE END Error_Handler_Debug */ +} +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/Core/Src/rtc.c b/Core/Src/rtc.c new file mode 100644 index 0000000..4bf92d1 --- /dev/null +++ b/Core/Src/rtc.c @@ -0,0 +1,125 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file rtc.c + * @brief This file provides code for the configuration + * of the RTC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "rtc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +RTC_HandleTypeDef hrtc; + +/* RTC init function */ +void MX_RTC_Init(void) +{ + + /* USER CODE BEGIN RTC_Init 0 */ + + /* USER CODE END RTC_Init 0 */ + + RTC_PrivilegeStateTypeDef privilegeState = {0}; + + /* USER CODE BEGIN RTC_Init 1 */ + + /* USER CODE END RTC_Init 1 */ + + /** Initialize RTC Only + */ + hrtc.Instance = RTC; + hrtc.Init.HourFormat = RTC_HOURFORMAT_24; + hrtc.Init.AsynchPrediv = 127; + hrtc.Init.SynchPrediv = 255; + hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; + hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; + hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE; + hrtc.Init.BinMode = RTC_BINARY_NONE; + if (HAL_RTC_Init(&hrtc) != HAL_OK) + { + Error_Handler(); + } + privilegeState.rtcPrivilegeFull = RTC_PRIVILEGE_FULL_NO; + privilegeState.backupRegisterPrivZone = RTC_PRIVILEGE_BKUP_ZONE_NONE; + privilegeState.backupRegisterStartZone2 = RTC_BKP_DR0; + privilegeState.backupRegisterStartZone3 = RTC_BKP_DR0; + if (HAL_RTCEx_PrivilegeModeSet(&hrtc, &privilegeState) != HAL_OK) + { + Error_Handler(); + } + + /** Enable the WakeUp + */ + if (HAL_RTCEx_SetWakeUpTimer(&hrtc, 0, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN RTC_Init 2 */ + + /* USER CODE END RTC_Init 2 */ + +} + +void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle) +{ + + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(rtcHandle->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspInit 0 */ + + /* USER CODE END RTC_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /* RTC clock enable */ + __HAL_RCC_RTCAPB_CLK_ENABLE(); + /* USER CODE BEGIN RTC_MspInit 1 */ + + /* USER CODE END RTC_MspInit 1 */ + } +} + +void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle) +{ + + if(rtcHandle->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspDeInit 0 */ + + /* USER CODE END RTC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RTCAPB_CLK_DISABLE(); + /* USER CODE BEGIN RTC_MspDeInit 1 */ + + /* USER CODE END RTC_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Core/Src/stm32wbaxx_hal_msp.c b/Core/Src/stm32wbaxx_hal_msp.c new file mode 100644 index 0000000..4fc6fcd --- /dev/null +++ b/Core/Src/stm32wbaxx_hal_msp.c @@ -0,0 +1,87 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbaxx_hal_msp.c + * @brief This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN Define */ + +/* USER CODE END Define */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN Macro */ + +/* USER CODE END Macro */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* External functions --------------------------------------------------------*/ +/* USER CODE BEGIN ExternalFunctions */ + +/* USER CODE END ExternalFunctions */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_RCC_HSEM_CLK_ENABLE(); + + /* System interrupt init*/ + + /* Peripheral interrupt init */ + /* HSEM_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(HSEM_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(HSEM_IRQn); + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Core/Src/stm32wbaxx_it.c b/Core/Src/stm32wbaxx_it.c new file mode 100644 index 0000000..2d6da87 --- /dev/null +++ b/Core/Src/stm32wbaxx_it.c @@ -0,0 +1,232 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32wbaxx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32wbaxx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "gpio.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +extern UART_HandleTypeDef huart1; +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) + { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Prefetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles System service call via SWI instruction. + */ +void SVC_Handler(void) +{ + /* USER CODE BEGIN SVCall_IRQn 0 */ + + /* USER CODE END SVCall_IRQn 0 */ + /* USER CODE BEGIN SVCall_IRQn 1 */ + + /* USER CODE END SVCall_IRQn 1 */ +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/** + * @brief This function handles Pendable request for system service. + */ +void PendSV_Handler(void) +{ + /* USER CODE BEGIN PendSV_IRQn 0 */ + + /* USER CODE END PendSV_IRQn 0 */ + /* USER CODE BEGIN PendSV_IRQn 1 */ + + /* USER CODE END PendSV_IRQn 1 */ +} + +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + HAL_IncTick(); + /* USER CODE BEGIN SysTick_IRQn 1 */ + + /* USER CODE END SysTick_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32WBAxx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32wbaxx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles USART1 global interrupt. + */ +void USART1_IRQHandler(void) +{ + /* USER CODE BEGIN USART1_IRQn 0 */ + HAL_GPIO_TogglePin(STATUS_LED_GPIO_Port, STATUS_LED_Pin); + /* USER CODE END USART1_IRQn 0 */ + HAL_UART_IRQHandler(&huart1); + /* USER CODE BEGIN USART1_IRQn 1 */ + + /* USER CODE END USART1_IRQn 1 */ +} + +/** + * @brief This function handles HSEM non-secure global interrupt. + */ +void HSEM_IRQHandler(void) +{ + /* USER CODE BEGIN HSEM_IRQn 0 */ + + /* USER CODE END HSEM_IRQn 0 */ + HAL_HSEM_IRQHandler(); + /* USER CODE BEGIN HSEM_IRQn 1 */ + + /* USER CODE END HSEM_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ diff --git a/Core/Src/system_stm32wbaxx.c b/Core/Src/system_stm32wbaxx.c new file mode 100644 index 0000000..ede3f75 --- /dev/null +++ b/Core/Src/system_stm32wbaxx.c @@ -0,0 +1,390 @@ +/** + ****************************************************************************** + * @file system_stm32wbaxx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M33 Device Peripheral Access Layer System Source File + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32wbaxx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the HSI (16 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32wbaxx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | HSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 16000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL1_SRC | No clock + *----------------------------------------------------------------------------- + * PLL1_M | 1 + *----------------------------------------------------------------------------- + * PLL1_N | 128 + *----------------------------------------------------------------------------- + * PLL1_P | 1 + *----------------------------------------------------------------------------- + * PLL1_Q | 1 + *----------------------------------------------------------------------------- + * PLL1_R | 1 + *----------------------------------------------------------------------------- + * Require 48MHz for | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup STM32WBAxx_system + * @{ + */ + +/** @addtogroup STM32WBAxx_System_Private_Includes + * @{ + */ + +#include "stm32wbaxx.h" +#include + +/** + * @} + */ + +/** @addtogroup STM32WBAxx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32WBAxx_System_Private_Defines + * @{ + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE (32000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSI_VALUE) +#define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/*!< The VTOR location information is based on information from the linker with a dependency + on the IDE, the cortex register is updated using the INTVECT_START. +*/ +#if defined(__ICCARM__) +extern uint32_t __vector_table; +#define INTVECT_START ((uint32_t)& __vector_table) +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +extern void * __Vectors; +#define INTVECT_START ((uint32_t) & __Vectors) +#elif defined(__GNUC__) +extern void * g_pfnVectors; +#define INTVECT_START ((uint32_t)& g_pfnVectors) +#endif /* __ICCARM__*/ + +/******************************************************************************/ + +/** + * @} + */ + +/** @addtogroup STM32WBAxx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32WBAxx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 16000000U; /* The HSI16 is used as system clock source after startup from reset, configured at 16 MHz. */ + + const uint8_t AHBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + const uint8_t AHB5PrescTable[8] = {1U, 1U, 1U, 1U, 2U, 3U, 4U, 6U}; +/** + * @} + */ + +/** @addtogroup STM32WBAxx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32WBAxx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ +#if defined(STM32WBAXX_SI_CUT1_0) + __IO uint32_t timeout_cpu_cycles; +#endif +#if defined(STM32WBAXX_SI_CUT1_0) || defined (VREFBUF) + __IO uint32_t tmpreg; +#endif + + /* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */ +#endif + + /* Configure the Vector Table location -------------------------------------*/ + SCB->VTOR = INTVECT_START; + +#if defined(STM32WBAXX_SI_CUT1_0) + /* Work-around for ADC peripheral issue possibly impacting system + power consumption. + Refer to STM32WBA errata sheet item "HSI16 clock cannot be stopped when + used as kernel clock by ADC". + Actions: Perform a ADC activation sequence in order to update state + of internal signals. + */ + /* Enable ADC kernel clock */ + SET_BIT(RCC->AHB4ENR, RCC_AHB4ENR_ADC4EN); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->AHB4ENR, RCC_AHB4ENR_ADC4EN); + (void)tmpreg; + + /* Enable ADC */ + SET_BIT(ADC4->CR, ADC_CR_ADEN); + + /* Poll for ADC ready */ + /* Set timeout 2 ADC clock cycles */ + /* Note: Approximative computation and timeout execution not taking into + account processing CPU cycles */ + timeout_cpu_cycles = 2; + while (READ_BIT(ADC4->ISR, ADC_ISR_ADRDY) == 0U) + { + timeout_cpu_cycles--; + if(timeout_cpu_cycles == 0U) + { + break; + } + } + + /* Disable ADC */ + SET_BIT(ADC4->CR, ADC_CR_ADDIS); + + /* Poll for ADC disable is effective */ + /* Set timeout 6 ADC clock cycles */ + /* Note: Approximative computation and timeout execution not taking into + account processing CPU cycles */ + timeout_cpu_cycles = 6; + while (READ_BIT(ADC4->CR, ADC_CR_ADEN) != 0U) + { + timeout_cpu_cycles--; + if(timeout_cpu_cycles == 0U) + { + break; + } + } + + /* Disable ADC internal voltage regulator */ + CLEAR_BIT(ADC4->CR, ADC_CR_ADVREGEN); + + /* Disable ADC kernel clock */ + CLEAR_BIT(RCC->AHB4ENR, RCC_AHB4ENR_ADC4EN); +#endif + +#if defined (VREFBUF) + /* Work-around for VREFBUF peripheral issue. + Refer to STM32WBA errata sheet item "VREF BUFF cannot be trimmed by EngiBit". + Actions: Our SW copies the TRIM V11 (R1) in VREFBUF CCR (to guarantee the correct start + trim instead the current bad value 111111). + */ + /* Enable VREFBUF kernel clock */ + SET_BIT(RCC->APB7ENR, RCC_APB7ENR_VREFEN); + /* Delay after an RCC peripheral clock enabling */ + tmpreg = READ_BIT(RCC->APB7ENR, RCC_APB7ENR_VREFEN); + (void)tmpreg; + + /* Set TRIM V11 (R1) value */ + MODIFY_REG(VREFBUF->CCR, VREFBUF_CCR_TRIM, ((*(uint32_t *)(FLASH_ENGY_BASE + 0x2ABUL)) & 0x3FUL)); + + /* Disable VREFBUF kernel clock */ + CLEAR_BIT(RCC->APB7ENR, RCC_APB7ENR_VREFEN); +#endif /* VREFBUF */ +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL1, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(*) multiplied/divided by the PLL1 factors. + * + * (**) HSI_VALUE is a constant defined in STM32WBAxx_hal.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in STM32WBAxx_hal.h file (default value + * 32 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp1; + uint32_t tmp2; + uint32_t pllsource; + uint32_t pllr; + uint32_t pllm; + uint32_t plln; + float_t fracn; + float_t pllvco; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR1 & RCC_CFGR1_SWS) + { + case RCC_CFGR1_SWS_1: /* HSE used as system clock source */ + SystemCoreClock = (HSE_VALUE >> ((RCC->CR & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos)); + break; + + case (RCC_CFGR1_SWS_0 | RCC_CFGR1_SWS_1): /* PLL1 used as system clock source */ + /* PLL_VCO = (PLLsource / PLLM) * PLLN * FractionnalPart + SYSCLK = PLL_VCO / PLLR */ + /* Get PLL1 CFGR and DIVR register values */ + tmp1 = RCC->PLL1CFGR; + tmp2 = RCC->PLL1DIVR; + + /* Retrieve PLL1 multiplication factor and divider */ + pllm = ((tmp1 & RCC_PLL1CFGR_PLL1M) >> RCC_PLL1CFGR_PLL1M_Pos) + 1U; + plln = (tmp2 & RCC_PLL1DIVR_PLL1N) + 1U; + pllr = ((tmp2 & RCC_PLL1DIVR_PLL1R) >> RCC_PLL1DIVR_PLL1R_Pos) + 1U; + + /* Check if fractional part is enable */ + if ((tmp1 & RCC_PLL1CFGR_PLL1FRACEN) != 0x00u) + { + fracn = (float_t)((uint32_t)((RCC->PLL1FRACR & RCC_PLL1FRACR_PLL1FRACN) >> RCC_PLL1FRACR_PLL1FRACN_Pos)); + } + else + { + fracn = (float_t)0U; + } + + /* determine PLL source */ + pllsource = (tmp1 & RCC_PLL1CFGR_PLL1SRC); + switch (pllsource) + { + /* HSI used as PLL1 clock source */ + case RCC_PLL1CFGR_PLL1SRC_1: + tmp1 = HSI_VALUE; + break; + + /* HSE used as PLL1 clock source */ + case (RCC_PLL1CFGR_PLL1SRC_0 | RCC_PLL1CFGR_PLL1SRC_1): + tmp1 = (HSE_VALUE >> ((RCC->CR & RCC_CR_HSEPRE) >> RCC_CR_HSEPRE_Pos)); + break; + + default: + tmp1 = 0U; + break; + } + + /* Compute VCO output frequency */ + pllvco = ((float_t) tmp1 / (float_t)pllm) * (((float_t)plln + (float_t)(fracn / (float_t)0x2000U))); + SystemCoreClock = (uint32_t)((float_t)(pllvco / (float_t)pllr)); + break; + + case 0x00u: /* HSI used as system clock source */ + default: + SystemCoreClock = HSI_VALUE; + break; + } + + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp1 = AHBPrescTable[(RCC->CFGR2 & RCC_CFGR2_HPRE)]; + + /* HCLK clock frequency */ + SystemCoreClock >>= tmp1; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/Core/Src/usart.c b/Core/Src/usart.c new file mode 100644 index 0000000..f724cc4 --- /dev/null +++ b/Core/Src/usart.c @@ -0,0 +1,394 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file usart.c + * @brief This file provides code for the configuration + * of the USART instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "usart.h" + +/* USER CODE BEGIN 0 */ +#include + +#define RING_BUFFER_SIZE 1500 +#define UART_RX_BUF_SIZE 128 + +typedef struct +{ + uint8_t data[RING_BUFFER_SIZE]; + uint16_t tail; + uint16_t head; +} ringbuffer_t; + +ringbuffer_t UART_RxData; + +uint8_t UART1_RxByte; // For single-byte interrupt reception +uint8_t UART1_RxBuffer[UART_RX_BUF_SIZE]; // Circular or linear buffer +volatile uint16_t uart1_rx_index = 0; +volatile bool uart1_msg_ready = false; +/* USER CODE END 0 */ + +UART_HandleTypeDef hlpuart1; +UART_HandleTypeDef huart1; + +/* LPUART1 init function */ + +void MX_LPUART1_UART_Init(void) +{ + + /* USER CODE BEGIN LPUART1_Init 0 */ + + /* USER CODE END LPUART1_Init 0 */ + + /* USER CODE BEGIN LPUART1_Init 1 */ + + /* USER CODE END LPUART1_Init 1 */ + hlpuart1.Instance = LPUART1; + hlpuart1.Init.BaudRate = 115200; + hlpuart1.Init.WordLength = UART_WORDLENGTH_8B; + hlpuart1.Init.StopBits = UART_STOPBITS_1; + hlpuart1.Init.Parity = UART_PARITY_NONE; + hlpuart1.Init.Mode = UART_MODE_TX_RX; + hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1; + hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + hlpuart1.FifoMode = UART_FIFOMODE_DISABLE; + if (HAL_UART_Init(&hlpuart1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN LPUART1_Init 2 */ + + /* USER CODE END LPUART1_Init 2 */ + +} +/* USART1 init function */ + +void MX_USART1_UART_Init(void) +{ + + /* USER CODE BEGIN USART1_Init 0 */ + + /* USER CODE END USART1_Init 0 */ + + /* USER CODE BEGIN USART1_Init 1 */ + + /* USER CODE END USART1_Init 1 */ + huart1.Instance = USART1; + huart1.Init.BaudRate = 115200; + huart1.Init.WordLength = UART_WORDLENGTH_8B; + huart1.Init.StopBits = UART_STOPBITS_1; + huart1.Init.Parity = UART_PARITY_NONE; + huart1.Init.Mode = UART_MODE_TX_RX; + huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart1.Init.OverSampling = UART_OVERSAMPLING_16; + huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1; + huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + if (HAL_UART_Init(&huart1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) + { + Error_Handler(); + } + if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART1_Init 2 */ + + UART_RxData.head = 0; + UART_RxData.tail = 0; + + HAL_UART_Receive_IT(&huart1, (uint8_t*)&UART_RxData.data[UART_RxData.tail], 1); + /* USER CODE END USART1_Init 2 */ + +} + +void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; + if(uartHandle->Instance==LPUART1) + { + /* USER CODE BEGIN LPUART1_MspInit 0 */ + + /* USER CODE END LPUART1_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1; + PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK7; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /* LPUART1 clock enable */ + __HAL_RCC_LPUART1_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**LPUART1 GPIO Configuration + PB11 ------> LPUART1_TX + PA10 ------> LPUART1_RX + */ + GPIO_InitStruct.Pin = DEBUG_TX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1; + HAL_GPIO_Init(DEBUG_TX_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = DEBUG_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1; + HAL_GPIO_Init(DEBUG_RX_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN LPUART1_MspInit 1 */ + + /* USER CODE END LPUART1_MspInit 1 */ + } + else if(uartHandle->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspInit 0 */ + + /* USER CODE END USART1_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1; + PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } + + /* USART1 clock enable */ + __HAL_RCC_USART1_CLK_ENABLE(); + + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART1 GPIO Configuration + PB12 ------> USART1_TX + PA8 ------> USART1_RX + */ + GPIO_InitStruct.Pin = LTE_TX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(LTE_TX_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = LTE_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(LTE_RX_GPIO_Port, &GPIO_InitStruct); + + /* USART1 interrupt Init */ + HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(USART1_IRQn); + /* USER CODE BEGIN USART1_MspInit 1 */ + + /* USER CODE END USART1_MspInit 1 */ + } +} + +void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) +{ + + if(uartHandle->Instance==LPUART1) + { + /* USER CODE BEGIN LPUART1_MspDeInit 0 */ + + /* USER CODE END LPUART1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_LPUART1_CLK_DISABLE(); + + /**LPUART1 GPIO Configuration + PB11 ------> LPUART1_TX + PA10 ------> LPUART1_RX + */ + HAL_GPIO_DeInit(DEBUG_TX_GPIO_Port, DEBUG_TX_Pin); + + HAL_GPIO_DeInit(DEBUG_RX_GPIO_Port, DEBUG_RX_Pin); + + /* USER CODE BEGIN LPUART1_MspDeInit 1 */ + + /* USER CODE END LPUART1_MspDeInit 1 */ + } + else if(uartHandle->Instance==USART1) + { + /* USER CODE BEGIN USART1_MspDeInit 0 */ + + /* USER CODE END USART1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART1_CLK_DISABLE(); + + /**USART1 GPIO Configuration + PB12 ------> USART1_TX + PA8 ------> USART1_RX + */ + HAL_GPIO_DeInit(LTE_TX_GPIO_Port, LTE_TX_Pin); + + HAL_GPIO_DeInit(LTE_RX_GPIO_Port, LTE_RX_Pin); + + /* USART1 interrupt Deinit */ + HAL_NVIC_DisableIRQ(USART1_IRQn); + /* USER CODE BEGIN USART1_MspDeInit 1 */ + + /* USER CODE END USART1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ +int8_t LTE_UART_SetBaudrate(uint32_t baudrate) +{ + HAL_UART_DeInit(&huart1); + huart1.Init.BaudRate = baudrate; + if (HAL_UART_Init(&huart1) != HAL_OK) + { + return -1; + } + + UART_RxData.head = 0; + UART_RxData.tail = 0; + + HAL_UART_Receive_IT(&huart1, (uint8_t *)&UART_RxData.data[UART_RxData.tail], 1); + return 0; +} + +void LTE_UART_FlushBuffer(void) +{ + memset(UART_RxData.data, 0, RING_BUFFER_SIZE); + UART_RxData.head = 0; + UART_RxData.tail = 0; +} + +int16_t LTE_UART_SendData(uint8_t *pData, uint16_t length) +{ + if(HAL_UART_Transmit(&huart1, (uint8_t*)pData, length, HAL_MAX_DELAY) != HAL_OK) + { + return -1; + } + return 0; +} + +int16_t LTE_UART_ReceiveSingleData(uint8_t *pSingleData) +{ + if (UART_RxData.head != UART_RxData.tail) + { + *pSingleData = UART_RxData.data[UART_RxData.head++]; + + if (UART_RxData.head >= RING_BUFFER_SIZE) + { + UART_RxData.head = 0; + } + } else + { + return -1; + } + + return 0; +} + +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if (++UART_RxData.tail >= RING_BUFFER_SIZE) + { + UART_RxData.tail = 0; + } + HAL_UART_Receive_IT(huart, (uint8_t*) &UART_RxData.data[UART_RxData.tail], 1); +} + +#pragma module_name = "?__write" + +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) + return _LLIO_ERROR; + + for (size_t i = 0; i < size; ++i) + { + HAL_UART_Transmit(&hlpuart1, (uint8_t *)&buffer[i], 1, HAL_MAX_DELAY); + } + + return size; +} + +void LTE_ATSendCommand(const char *cmd) +{ + HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), 1000); +} + +/* For Testing Purposes ONLY */ +void LTE_SendATCommand_Test(void) +{ + const char *cmd = "AT\r\n"; + uint8_t rx_byte; + uint8_t rx_buff[100] = {0}; + int idx = 0; + uint32_t startTick; + + // Transmit AT Command + if (HAL_UART_Transmit(&huart1, (uint8_t *)cmd, strlen(cmd), 1000) != HAL_OK) + { + APP_ERROR_MSG("UART TX Failed\r\n"); + return; + } + + // Wait and read each byte until timeout or buffer full + startTick = HAL_GetTick(); + while ((HAL_GetTick() - startTick) < 1000 && idx < sizeof(rx_buff) - 1) + { + if (HAL_UART_Receive(&huart1, &rx_byte, 1, 10) == HAL_OK) + { + rx_buff[idx++] = rx_byte; + + // Reset timeout if still receiving + startTick = HAL_GetTick(); + } + } + + rx_buff[idx] = '\0'; // Null-terminate the received string + + APP_LTE_MSG(" %s\r\n", rx_buff); +} +/* USER CODE END 1 */ diff --git a/EWARM/Backup of WiseEye-LTE.ewd b/EWARM/Backup of WiseEye-LTE.ewd new file mode 100644 index 0000000..85f1b3c --- /dev/null +++ b/EWARM/Backup of WiseEye-LTE.ewd @@ -0,0 +1,1534 @@ + + + 3 + + WiseEye-LTE + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9BE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/EWARM/Backup of WiseEye-LTE.ewp b/EWARM/Backup of WiseEye-LTE.ewp new file mode 100644 index 0000000..92e3aec --- /dev/null +++ b/EWARM/Backup of WiseEye-LTE.ewp @@ -0,0 +1,1166 @@ + + + 3 + + WiseEye-LTE + + ARM + + 1 + + General + 3 + + 34 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 37 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 11 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 26 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + Coder + 0 + + + + + Application + + EWARM + + $PROJ_DIR$/startup_stm32wba52xx.s + + + + User + + Core + + $PROJ_DIR$/../Core/Src/main.c + + + $PROJ_DIR$/../Core/Src/gpio.c + + + $PROJ_DIR$/../Core/Src/icache.c + + + $PROJ_DIR$/../Core/Src/usart.c + + + $PROJ_DIR$/../Core/Src/stm32wbaxx_it.c + + + $PROJ_DIR$/../Core/Src/stm32wbaxx_hal_msp.c + + + + + + Drivers + + STM32WBAxx_HAL_Driver + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_cortex.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_icache.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_rcc.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_rcc_ex.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_flash.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_flash_ex.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_gpio.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_dma.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_dma_ex.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_exti.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_pwr.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_pwr_ex.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_uart.c + + + C:/Users/Admin/STM32Cube/Repository/STM32Cube_FW_WBA_V1.7.0/Drivers/STM32WBAxx_HAL_Driver/Src/stm32wbaxx_hal_uart_ex.c + + + + CMSIS + + $PROJ_DIR$/../Core/Src/system_stm32wbaxx.c + + + + + diff --git a/EWARM/Backup of WiseEye-LTE.ewt b/EWARM/Backup of WiseEye-LTE.ewt new file mode 100644 index 0000000..16fa6ce --- /dev/null +++ b/EWARM/Backup of WiseEye-LTE.ewt @@ -0,0 +1,1519 @@ + + + 4 + + WiseEye-LTE + + ARM + + 1 + + C-STAT + 517 + + 517 + + 0 + + 1 + 600 + 1 + 10 + 0 + 1 + 100 + WiseEye-LTE/C-STAT + + + 2.5.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + Application + + EWARM + + $PROJ_DIR$\startup_stm32wba52xx.s + + + + User + + Core + + $PROJ_DIR$\..\Core\Src\gpio.c + + + $PROJ_DIR$\..\Core\Src\icache.c + + + $PROJ_DIR$\..\Core\Src\main.c + + + $PROJ_DIR$\..\Core\Src\stm32wbaxx_hal_msp.c + + + $PROJ_DIR$\..\Core\Src\stm32wbaxx_it.c + + + $PROJ_DIR$\..\Core\Src\usart.c + + + + + + Drivers + + CMSIS + + $PROJ_DIR$\..\Core\Src\system_stm32wbaxx.c + + + + STM32WBAxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_cortex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_exti.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_icache.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart_ex.c + + + + diff --git a/EWARM/Project.eww b/EWARM/Project.eww new file mode 100644 index 0000000..54f196f --- /dev/null +++ b/EWARM/Project.eww @@ -0,0 +1,7 @@ + + + + $WS_DIR$\WiseEye-LTE.ewp + + + diff --git a/EWARM/WiseEye-LTE.ewd b/EWARM/WiseEye-LTE.ewd new file mode 100644 index 0000000..226b4c4 --- /dev/null +++ b/EWARM/WiseEye-LTE.ewd @@ -0,0 +1,1615 @@ + + + 4 + + WiseEye-LTE + + ARM + + 1 + + C-SPY + 2 + + 33 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + E2_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 3 + 1 + 1 + + + + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 9 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm9a.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/EWARM/WiseEye-LTE.ewp b/EWARM/WiseEye-LTE.ewp new file mode 100644 index 0000000..7f50d78 --- /dev/null +++ b/EWARM/WiseEye-LTE.ewp @@ -0,0 +1,1206 @@ + + + 4 + + WiseEye-LTE + + ARM + + 1 + + General + 3 + + 36 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 38 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 12 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + inputOutputBased + + + + ILINK + 0 + + 27 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BUILDACTION + 2 + + + + Coder + 0 + + + + + Application + + EWARM + + $PROJ_DIR$\startup_stm32wba52xx.s + + + + User + + Core + + $PROJ_DIR$\..\Core\Src\eg91.c + + + $PROJ_DIR$\..\Core\Src\gpio.c + + + $PROJ_DIR$\..\Core\Src\icache.c + + + $PROJ_DIR$\..\Core\Src\lte_comms.c + + + $PROJ_DIR$\..\Core\Src\main.c + + + $PROJ_DIR$\..\Core\Src\rtc.c + + + $PROJ_DIR$\..\Core\Src\stm32wbaxx_hal_msp.c + + + $PROJ_DIR$\..\Core\Src\stm32wbaxx_it.c + + + $PROJ_DIR$\..\Core\Src\usart.c + + + + + + Drivers + + CMSIS + + $PROJ_DIR$\..\Core\Src\system_stm32wbaxx.c + + + + STM32WBAxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_cortex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_exti.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_hsem.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_icache.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart_ex.c + + + + diff --git a/EWARM/WiseEye-LTE.ewt b/EWARM/WiseEye-LTE.ewt new file mode 100644 index 0000000..fdd0820 --- /dev/null +++ b/EWARM/WiseEye-LTE.ewt @@ -0,0 +1,1537 @@ + + + 4 + + WiseEye-LTE + + ARM + + 1 + + C-STAT + 517 + + 517 + + 0 + + 1 + 600 + 1 + 10 + 0 + 1 + 100 + WiseEye-LTE/C-STAT + + + 2.5.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + Application + + EWARM + + $PROJ_DIR$\startup_stm32wba52xx.s + + + + User + + Core + + $PROJ_DIR$\..\Core\Src\eg91.c + + + $PROJ_DIR$\..\Core\Src\gpio.c + + + $PROJ_DIR$\..\Core\Src\icache.c + + + $PROJ_DIR$\..\Core\Src\lte_comms.c + + + $PROJ_DIR$\..\Core\Src\main.c + + + $PROJ_DIR$\..\Core\Src\rtc.c + + + $PROJ_DIR$\..\Core\Src\stm32wbaxx_hal_msp.c + + + $PROJ_DIR$\..\Core\Src\stm32wbaxx_it.c + + + $PROJ_DIR$\..\Core\Src\usart.c + + + + + + Drivers + + CMSIS + + $PROJ_DIR$\..\Core\Src\system_stm32wbaxx.c + + + + STM32WBAxx_HAL_Driver + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_cortex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_dma_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_exti.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_flash_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_gpio.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_hsem.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_icache.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_pwr_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rcc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_rtc_ex.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart.c + + + $PROJ_DIR$\..\..\..\..\..\..\STM32Cube\Repository\STM32Cube_FW_WBA_V1.7.0\Drivers\STM32WBAxx_HAL_Driver\Src\stm32wbaxx_hal_uart_ex.c + + + + diff --git a/EWARM/WiseEye-LTE/.WiseEye-LTE_build_cache b/EWARM/WiseEye-LTE/.WiseEye-LTE_build_cache new file mode 100644 index 0000000..45adb10 --- /dev/null +++ b/EWARM/WiseEye-LTE/.WiseEye-LTE_build_cache @@ -0,0 +1,12 @@ + + + + linker + + C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Exe\WiseEye-LTE.out + + C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\List\WiseEye-LTE.map + + + + diff --git a/EWARM/WiseEye-LTE/.ninja_deps b/EWARM/WiseEye-LTE/.ninja_deps new file mode 100644 index 0000000000000000000000000000000000000000..016ac7cc0175a7590e93984c3475c7a4f5aefec0 GIT binary patch literal 21224 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�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 + - 0x800'60dc 0x5f80 + +"P2", part 1 of 3: 0xd8 + P2-1 0x2000'0000 0xd8 + .data inited 0x2000'0000 0xc stm32wbaxx_hal.o [4] + .data inited 0x2000'000c 0x4 system_stm32wbaxx.o [1] + .data inited 0x2000'0010 0x38 xlocale_c.o [5] + .data inited 0x2000'0048 0x48 xlocale_c.o [5] + .data inited 0x2000'0090 0x48 xfiles.o [5] + - 0x2000'00d8 0xd8 + +"P2", part 2 of 3: 0xa00 + .bss zero 0x2000'00d8 0x5e0 usart.o [2] + .bss zero 0x2000'06b8 0x270 lte_comms.o [2] + .bss zero 0x2000'0928 0x94 usart.o [2] + .bss zero 0x2000'09bc 0x94 usart.o [2] + .bss zero 0x2000'0a50 0x50 xfiles.o [5] + .bss zero 0x2000'0aa0 0x30 rtc.o [2] + .bss zero 0x2000'0ad0 0x4 strtok.o [5] + .bss zero 0x2000'0ad4 0x4 xfail_s.o [5] + - 0x2000'0ad8 0xa00 + +"P2", part 3 of 3: 0x400 + CSTACK 0x2000'0ad8 0x400 + CSTACK uninit 0x2000'0ad8 0x400 + - 0x2000'0ed8 0x400 + +Unused ranges: + + From To Size + ---- -- ---- + 0x800'60dc 0x80f'ffff 0xf'9f24 + 0x2000'0ed8 0x2000'ffff 0xf128 + + +******************************************************************************* +*** INIT TABLE +*** + + Address Size + ------- ---- +Zero (__iar_zero_init3) + 1 destination range, total size 0xa00: + 0x2000'00d8 0xa00 + +Copy/lz77 (__iar_lz77_init_single3) + 1 source range, total size 0x54 (38% of destination): + 0x800'6088 0x54 + 1 destination range, total size 0xd8: + 0x2000'0000 0xd8 + + + +******************************************************************************* +*** MODULE SUMMARY +*** + + Module ro code ro data rw data + ------ ------- ------- ------- +command line/config: + --------------------------------------------------- + Total: + +C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\CMSIS_6603591812247902717.dir: [1] + system_stm32wbaxx.o 260 10 4 + --------------------------------------------------- + Total: 260 10 4 + +C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\Core_13247989168731456611.dir: [2] + eg91.o 1'856 2'228 + gpio.o 324 72 + icache.o 30 + lte_comms.o 956 544 624 + main.o 204 + rtc.o 188 48 + stm32wbaxx_hal_msp.o 64 + stm32wbaxx_it.o 52 + usart.o 848 1'800 + --------------------------------------------------- + Total: 4'522 2'844 2'472 + +C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\EWARM_18443280873093131863.dir: [3] + startup_stm32wba52xx.o 636 + --------------------------------------------------- + Total: 636 + +C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\STM32WBAxx_HAL_Driver_814230103969653557.dir: [4] + stm32wbaxx_hal.o 268 4 12 + stm32wbaxx_hal_cortex.o 296 + stm32wbaxx_hal_dma.o 190 + stm32wbaxx_hal_gpio.o 612 + stm32wbaxx_hal_hsem.o 22 + stm32wbaxx_hal_icache.o 56 + stm32wbaxx_hal_pwr_ex.o 92 + stm32wbaxx_hal_rcc.o 1'888 + stm32wbaxx_hal_rcc_ex.o 520 + stm32wbaxx_hal_rtc.o 380 + stm32wbaxx_hal_rtc_ex.o 196 + stm32wbaxx_hal_uart.o 3'734 + stm32wbaxx_hal_uart_ex.o 252 + --------------------------------------------------- + Total: 8'506 4 12 + +dl7M_tlf.a: [5] + abort.o 6 + exit.o 4 + iar_Stoulx.o 338 80 + isspace.o 20 + low_level_init.o 4 + printf.o 40 + putchar.o 68 + strcspn.o 34 + strspn.o 34 + strstr.o 44 + strtok.o 76 4 + tolower.o 20 + xfail_s.o 64 4 + xfiles.o 28 152 + xlocale_c.o 60 55 128 + xprintffull_nomb.o 3'786 + xprout.o 22 + --------------------------------------------------- + Total: 4'620 163 288 + +m7M_tls.a: [6] + DblAddSub.o 590 + DblCmpGe.o 52 + DblCmpLe.o 52 + DblDiv.o 582 + DblMul.o 426 + DblToS32.o 54 + DblToU32.o 34 + S32ToDbl.o 34 + U32ToDbl.o 28 + fpinit_M.o 34 + frexp.o 112 + ldexp.o 314 + --------------------------------------------------- + Total: 2'312 + +rt7M_tl.a: [7] + ABImemclr4.o 6 + ABImemcpy_small.o 24 + ABImemset48.o 50 + ABImemset_small.o 18 + I64DivMod_small.o 262 + I64DivZer.o 2 + cexit.o 10 + cmain.o 30 + cstartup_M.o 28 + data_init.o 40 + lz77_init_single.o 126 + memchr.o 88 + memset.o 20 + strchr.o 22 + strlen_small.o 20 + strncpy_small.o 30 + zero_init3.o 56 + --------------------------------------------------- + Total: 832 + +shb_l.a: [8] + exit.o 20 + --------------------------------------------------- + Total: 20 + + Gaps 29 6 + Linker created 32 1'024 +------------------------------------------------------- + Grand Total: 21'737 3'059 3'800 + + +******************************************************************************* +*** ENTRY LIST +*** + +Entry Address Size Type Object +----- ------- ---- ---- ------ +.iar.init_table$$Base 0x800'5ed8 -- Gb - Linker created - +.iar.init_table$$Limit 0x800'5ef8 -- Gb - Linker created - +?main 0x800'5ef9 Code Gb cmain.o [7] +ADC4_IRQHandler 0x800'6075 Code Wk startup_stm32wba52xx.o [3] +AES_IRQHandler 0x800'6059 Code Wk startup_stm32wba52xx.o [3] +AHBPrescTable 0x800'45a0 0x8 Data Gb system_stm32wbaxx.o [1] +APBPrescTable 0x800'5f70 0x8 Data Gb system_stm32wbaxx.o [1] +AT_ExecuteCommand 0x800'4a21 0x48 Code Lc eg91.o [2] +AT_RetrieveData 0x800'4909 0x118 Code Lc eg91.o [2] +BusFault_Handler 0x800'5d93 0x2 Code Gb stm32wbaxx_it.o [2] +CSTACK$$Base 0x2000'0ad8 -- Gb - Linker created - +CSTACK$$Limit 0x2000'0ed8 -- Gb - Linker created - +DebugMon_Handler 0x800'5d99 0x2 Code Gb stm32wbaxx_it.o [2] +EG91_AutomaticPlmnSelection + 0x800'4d87 0x10 Code Gb eg91.o [2] +EG91_GetPsNetworkRegistrationStatus + 0x800'4dc5 0x3e Code Gb eg91.o [2] +EG91_GetSignalQualityStatus + 0x800'4d1d 0x2e Code Gb eg91.o [2] +EG91_GetUARTConfig 0x800'4e2d 0x82 Code Gb eg91.o [2] +EG91_Init 0x800'4ab1 0x254 Code Gb eg91.o [2] +EG91_PSAttach 0x800'4d4b 0x34 Code Gb eg91.o [2] +EG91_RegisterBusIO 0x800'4a69 0x3a Code Gb eg91.o [2] +EG91_RegisterTickCb 0x800'4ebb 0x12 Code Gb eg91.o [2] +EG91_ResetToFactoryDefault + 0x800'4e21 0xc Code Gb eg91.o [2] +EXTI0_IRQHandler 0x800'5fa9 Code Wk startup_stm32wba52xx.o [3] +EXTI10_IRQHandler 0x800'5fd1 Code Wk startup_stm32wba52xx.o [3] +EXTI11_IRQHandler 0x800'5fd5 Code Wk startup_stm32wba52xx.o [3] +EXTI12_IRQHandler 0x800'5fd9 Code Wk startup_stm32wba52xx.o [3] +EXTI13_IRQHandler 0x800'5fdd Code Wk startup_stm32wba52xx.o [3] +EXTI14_IRQHandler 0x800'5fe1 Code Wk startup_stm32wba52xx.o [3] +EXTI15_IRQHandler 0x800'5fe5 Code Wk startup_stm32wba52xx.o [3] +EXTI1_IRQHandler 0x800'5fad Code Wk startup_stm32wba52xx.o [3] +EXTI2_IRQHandler 0x800'5fb1 Code Wk startup_stm32wba52xx.o [3] +EXTI3_IRQHandler 0x800'5fb5 Code Wk startup_stm32wba52xx.o [3] +EXTI4_IRQHandler 0x800'5fb9 Code Wk startup_stm32wba52xx.o [3] +EXTI5_IRQHandler 0x800'5fbd Code Wk startup_stm32wba52xx.o [3] +EXTI6_IRQHandler 0x800'5fc1 Code Wk startup_stm32wba52xx.o [3] +EXTI7_IRQHandler 0x800'5fc5 Code Wk startup_stm32wba52xx.o [3] +EXTI8_IRQHandler 0x800'5fc9 Code Wk startup_stm32wba52xx.o [3] +EXTI9_IRQHandler 0x800'5fcd Code Wk startup_stm32wba52xx.o [3] +Eg91Obj 0x2000'06b8 0x270 Data Gb lte_comms.o [2] +Error_Handler 0x800'36a1 0x4 Code Gb main.o [2] +FLASH_IRQHandler 0x800'5f95 Code Wk startup_stm32wba52xx.o [3] +FLASH_S_IRQHandler 0x800'5f99 Code Wk startup_stm32wba52xx.o [3] +FPU_IRQHandler 0x800'6061 Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel0_IRQHandler + 0x800'5ff1 Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel1_IRQHandler + 0x800'5ff5 Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel2_IRQHandler + 0x800'5ff9 Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel3_IRQHandler + 0x800'5ffd Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel4_IRQHandler + 0x800'6001 Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel5_IRQHandler + 0x800'6005 Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel6_IRQHandler + 0x800'6009 Code Wk startup_stm32wba52xx.o [3] +GPDMA1_Channel7_IRQHandler + 0x800'600d Code Wk startup_stm32wba52xx.o [3] +GTZC_IRQHandler 0x800'5f9d Code Wk startup_stm32wba52xx.o [3] +HAL_DMA_Abort 0x800'2dc1 0x7c Code Gb stm32wbaxx_hal_dma.o [4] +HAL_DMA_Abort_IT 0x800'2e3d 0x2a Code Gb stm32wbaxx_hal_dma.o [4] +HAL_Delay 0x800'45e9 0x28 Code Wk stm32wbaxx_hal.o [4] +HAL_GPIO_DeInit 0x800'3c53 0xca Code Gb stm32wbaxx_hal_gpio.o [4] +HAL_GPIO_Init 0x800'3ae5 0x16e Code Gb stm32wbaxx_hal_gpio.o [4] +HAL_GPIO_TogglePin 0x800'3d27 0x10 Code Gb stm32wbaxx_hal_gpio.o [4] +HAL_GPIO_WritePin 0x800'3d1d 0xa Code Gb stm32wbaxx_hal_gpio.o [4] +HAL_GetTick 0x800'2db5 0xc Code Wk stm32wbaxx_hal.o [4] +HAL_HSEM_FreeCallback 0x800'5de5 0x2 Code Wk stm32wbaxx_hal_hsem.o [4] +HAL_HSEM_IRQHandler 0x800'5dd1 0x10 Code Gb stm32wbaxx_hal_hsem.o [4] +HAL_ICACHE_ConfigAssociativityMode + 0x800'4865 0x18 Code Gb stm32wbaxx_hal_icache.o [4] +HAL_ICACHE_Enable 0x800'487d 0xe Code Gb stm32wbaxx_hal_icache.o [4] +HAL_IncTick 0x800'5dc1 0x10 Code Wk stm32wbaxx_hal.o [4] +HAL_Init 0x800'3ddd 0x30 Code Gb stm32wbaxx_hal.o [4] +HAL_InitTick 0x800'3d49 0x94 Code Wk stm32wbaxx_hal.o [4] +HAL_MspInit 0x800'45a9 0x40 Code Gb stm32wbaxx_hal_msp.o [2] +HAL_NVIC_DisableIRQ 0x800'3a3b 0x1e Code Gb stm32wbaxx_hal_cortex.o [4] +HAL_NVIC_EnableIRQ 0x800'3a25 0x16 Code Gb stm32wbaxx_hal_cortex.o [4] +HAL_NVIC_SetPriority 0x800'39d7 0x4e Code Gb stm32wbaxx_hal_cortex.o [4] +HAL_NVIC_SetPriorityGrouping + 0x800'39bd 0x1a Code Gb stm32wbaxx_hal_cortex.o [4] +HAL_PWREx_ControlVoltageScaling + 0x800'4415 0x4e Code Gb stm32wbaxx_hal_pwr_ex.o [4] +HAL_RCCEx_PeriphCLKConfig + 0x800'37b5 0x1f8 Code Gb stm32wbaxx_hal_rcc_ex.o [4] +HAL_RCC_ClockConfig 0x800'3333 0x15c Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RCC_GetHCLKFreq 0x800'34b3 0x1a Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RCC_GetPCLK1Freq 0x800'34cd 0xa Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RCC_GetPCLK2Freq 0x800'34d7 0x12 Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RCC_GetPCLK7Freq 0x800'34e9 0x8 Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RCC_GetPLL1RFreq 0x800'3511 0x10 Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RCC_GetSysClockFreq + 0x800'348f 0x24 Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RCC_OscConfig 0x800'2e89 0x478 Code Gb stm32wbaxx_hal_rcc.o [4] +HAL_RTCEx_PrivilegeModeSet + 0x800'4827 0x30 Code Gb stm32wbaxx_hal_rtc_ex.o [4] +HAL_RTCEx_SetWakeUpTimer + 0x800'47a1 0x7a Code Gb stm32wbaxx_hal_rtc_ex.o [4] +HAL_RTC_Init 0x800'4625 0xa0 Code Gb stm32wbaxx_hal_rtc.o [4] +HAL_RTC_MspInit 0x800'3fbd 0x48 Code Gb rtc.o [2] +HAL_RTC_WaitForSynchro 0x800'46cb 0x36 Code Gb stm32wbaxx_hal_rtc.o [4] +HAL_SYSTICK_CLKSourceConfig + 0x800'3a7d 0x48 Code Gb stm32wbaxx_hal_cortex.o [4] +HAL_SYSTICK_Config 0x800'3a59 0x24 Code Gb stm32wbaxx_hal_cortex.o [4] +HAL_UARTEx_DisableFifoMode + 0x800'36b5 0x3c Code Gb stm32wbaxx_hal_uart_ex.o [4] +HAL_UARTEx_RxEventCallback + 0x800'2e81 0x2 Code Wk stm32wbaxx_hal_uart.o [4] +HAL_UARTEx_RxFifoFullCallback + 0x800'2e87 0x2 Code Wk stm32wbaxx_hal_uart_ex.o [4] +HAL_UARTEx_SetRxFifoThreshold + 0x800'3707 0x14 Code Gb stm32wbaxx_hal_uart_ex.o [4] +HAL_UARTEx_SetTxFifoThreshold + 0x800'36f1 0x16 Code Gb stm32wbaxx_hal_uart_ex.o [4] +HAL_UARTEx_TxFifoEmptyCallback + 0x800'2e85 0x2 Code Wk stm32wbaxx_hal_uart_ex.o [4] +HAL_UART_DeInit 0x800'1c5d 0x3e Code Gb stm32wbaxx_hal_uart.o [4] +HAL_UART_ErrorCallback 0x800'2e7f 0x2 Code Wk stm32wbaxx_hal_uart.o [4] +HAL_UART_IRQHandler 0x800'1da1 0x29e Code Gb stm32wbaxx_hal_uart.o [4] +HAL_UART_Init 0x800'1bd5 0x34 Code Gb stm32wbaxx_hal_uart.o [4] +HAL_UART_MspDeInit 0x800'2c43 0x5a Code Gb usart.o [2] +HAL_UART_MspInit 0x800'2b21 0xca Code Gb usart.o [2] +HAL_UART_Receive_IT 0x800'1d47 0x26 Code Gb stm32wbaxx_hal_uart.o [4] +HAL_UART_RxCpltCallback + 0x800'2d35 0x20 Code Gb usart.o [2] +HAL_UART_Transmit 0x800'1ca7 0x9a Code Gb stm32wbaxx_hal_uart.o [4] +HAL_UART_TxCpltCallback + 0x800'2e83 0x2 Code Wk stm32wbaxx_hal_uart.o [4] +HASH_IRQHandler 0x800'6065 Code Wk startup_stm32wba52xx.o [3] +HSEM_IRQHandler 0x800'5dbd 0x4 Code Gb stm32wbaxx_it.o [2] +HSEM_S_IRQHandler 0x800'6081 Code Wk startup_stm32wba52xx.o [3] +HardFault_Handler 0x800'5d8f 0x2 Code Gb stm32wbaxx_it.o [2] +I2C1_ER_IRQHandler 0x800'602d Code Wk startup_stm32wba52xx.o [3] +I2C1_EV_IRQHandler 0x800'6029 Code Wk startup_stm32wba52xx.o [3] +I2C3_ER_IRQHandler 0x800'6051 Code Wk startup_stm32wba52xx.o [3] +I2C3_EV_IRQHandler 0x800'604d Code Wk startup_stm32wba52xx.o [3] +ICACHE_IRQHandler 0x800'6071 Code Wk startup_stm32wba52xx.o [3] +IWDG_IRQHandler 0x800'5fe9 Code Wk startup_stm32wba52xx.o [3] +LEDStatus_Active 0x800'3e7b 0x4 Code Gb gpio.o [2] +LEDStatus_Inactive 0x800'3e7f 0x2 Code Gb gpio.o [2] +LPTIM1_IRQHandler 0x800'603d Code Wk startup_stm32wba52xx.o [3] +LPTIM2_IRQHandler 0x800'6041 Code Wk startup_stm32wba52xx.o [3] +LPUART1_IRQHandler 0x800'6039 Code Wk startup_stm32wba52xx.o [3] +LTE_GetIMEI 0x800'42fb 0x8 Code Gb lte_comms.o [2] +LTE_GetModuleFirmwareRevision + 0x800'42dd 0x8 Code Gb lte_comms.o [2] +LTE_GetModuleID 0x800'42e5 0x6 Code Gb lte_comms.o [2] +LTE_GetSignalQualityStatus + 0x800'42b5 0x16 Code Gb lte_comms.o [2] +LTE_GetSimId 0x800'42f3 0x8 Code Gb lte_comms.o [2] +LTE_HardwarePowerDown 0x800'3efb 0x3e Code Gb gpio.o [2] +LTE_HardwarePowerUp 0x800'3e89 0x68 Code Gb gpio.o [2] +LTE_Init 0x800'418d 0x120 Code Gb lte_comms.o [2] +LTE_UART_FlushBuffer 0x800'2cd5 0x18 Code Gb usart.o [2] +LTE_UART_ReceiveSingleData + 0x800'2d05 0x30 Code Gb usart.o [2] +LTE_UART_SendData 0x800'2ced 0x18 Code Gb usart.o [2] +LTE_UART_SetBaudrate 0x800'2c9d 0x2c Code Gb usart.o [2] +MX_GPIO_Init 0x800'3e11 0x6a Code Gb gpio.o [2] +MX_ICACHE_Init 0x800'4011 0x1e Code Gb icache.o [2] +MX_LPUART1_UART_Init 0x800'2a65 0x50 Code Gb usart.o [2] +MX_RTC_Init 0x800'3f55 0x68 Code Gb rtc.o [2] +MX_USART1_UART_Init 0x800'2ab5 0x54 Code Gb usart.o [2] +MemManage_Handler 0x800'5d91 0x2 Code Gb stm32wbaxx_it.o [2] +NMI_Handler 0x800'5d8d 0x2 Code Gb stm32wbaxx_it.o [2] +Network_Init 0x800'4031 0x154 Code Gb lte_comms.o [2] +PKA_IRQHandler 0x800'6069 Code Wk startup_stm32wba52xx.o [3] +PVD_IRQHandler 0x800'5f81 Code Wk startup_stm32wba52xx.o [3] +ParseNumber 0x800'48bd 0x38 Code Lc eg91.o [2] +PendSV_Handler 0x800'5d9b 0x2 Code Gb stm32wbaxx_it.o [2] +RADIO_IRQHandler 0x800'6079 Code Wk startup_stm32wba52xx.o [3] +RAMCFG_IRQHandler 0x800'5f91 Code Wk startup_stm32wba52xx.o [3] +RCC_IRQHandler 0x800'5fa1 Code Wk startup_stm32wba52xx.o [3] +RCC_PLL1_GetVCOOutputFreq + 0x800'3521 0x78 Code Lc stm32wbaxx_hal_rcc.o [4] +RCC_S_IRQHandler 0x800'5fa5 Code Wk startup_stm32wba52xx.o [3] +RNG_IRQHandler 0x800'605d Code Wk startup_stm32wba52xx.o [3] +RTC_EnterInitMode 0x800'4701 0x48 Code Gb stm32wbaxx_hal_rtc.o [4] +RTC_ExitInitMode 0x800'4749 0x4c Code Gb stm32wbaxx_hal_rtc.o [4] +RTC_IRQHandler 0x800'5f85 Code Wk startup_stm32wba52xx.o [3] +RTC_S_IRQHandler 0x800'5f89 Code Wk startup_stm32wba52xx.o [3] +Region$$Table$$Base 0x800'5ed8 -- Gb - Linker created - +Region$$Table$$Limit 0x800'5ef8 -- Gb - Linker created - +Reset_Handler 0x800'5f61 Code Wk startup_stm32wba52xx.o [3] +ReturnKeywords 0x800'5248 0x888 Data Gb eg91.o [2] +SAES_IRQHandler 0x800'5fed Code Wk startup_stm32wba52xx.o [3] +SPI1_IRQHandler 0x800'6031 Code Wk startup_stm32wba52xx.o [3] +SPI3_IRQHandler 0x800'606d Code Wk startup_stm32wba52xx.o [3] +SVC_Handler 0x800'5d97 0x2 Code Gb stm32wbaxx_it.o [2] +SecureFault_Handler 0x800'5f79 Code Wk startup_stm32wba52xx.o [3] +SysTick_Handler 0x800'5d9d 0x4 Code Gb stm32wbaxx_it.o [2] +SystemClock_Config 0x800'3619 0x88 Code Gb main.o [2] +SystemCoreClock 0x2000'000c 0x4 Data Gb system_stm32wbaxx.o [1] +SystemCoreClockUpdate 0x800'44b9 0xc6 Code Gb system_stm32wbaxx.o [1] +SystemInit 0x800'44a5 0x12 Code Gb system_stm32wbaxx.o [1] +TAMP_IRQHandler 0x800'5f8d Code Wk startup_stm32wba52xx.o [3] +TIM16_IRQHandler 0x800'6045 Code Wk startup_stm32wba52xx.o [3] +TIM17_IRQHandler 0x800'6049 Code Wk startup_stm32wba52xx.o [3] +TIM1_BRK_IRQHandler 0x800'6011 Code Wk startup_stm32wba52xx.o [3] +TIM1_CC_IRQHandler 0x800'601d Code Wk startup_stm32wba52xx.o [3] +TIM1_TRG_COM_IRQHandler + 0x800'6019 Code Wk startup_stm32wba52xx.o [3] +TIM1_UP_IRQHandler 0x800'6015 Code Wk startup_stm32wba52xx.o [3] +TIM2_IRQHandler 0x800'6021 Code Wk startup_stm32wba52xx.o [3] +TIM3_IRQHandler 0x800'6025 Code Wk startup_stm32wba52xx.o [3] +TSC_IRQHandler 0x800'6055 Code Wk startup_stm32wba52xx.o [3] +TimeLeftFromExpiration 0x800'48f5 0x14 Code Lc eg91.o [2] +UARTEx_SetNbDataToProcess + 0x800'375d 0x3e Code Lc stm32wbaxx_hal_uart_ex.o [4] +UARTEx_SetNbDataToProcess::denominator + 0x800'37a4 0x8 Data Lc stm32wbaxx_hal_uart_ex.o [4] +UARTEx_SetNbDataToProcess::numerator + 0x800'379c 0x8 Data Lc stm32wbaxx_hal_uart_ex.o [4] +UARTPrescTable 0x800'2660 0x18 Data Gb stm32wbaxx_hal_uart.o [4] +UART_AdvFeatureConfig 0x800'22db 0xc6 Code Gb stm32wbaxx_hal_uart.o [4] +UART_CheckIdleState 0x800'23a1 0x8e Code Gb stm32wbaxx_hal_uart.o [4] +UART_DMAAbortOnError 0x800'2655 0xc Code Lc stm32wbaxx_hal_uart.o [4] +UART_EndRxTransfer 0x800'25cb 0x22 Code Lc stm32wbaxx_hal_uart.o [4] +UART_RxData 0x2000'00d8 0x5e0 Data Gb usart.o [2] +UART_RxISR_16BIT 0x800'26c9 0x50 Code Lc stm32wbaxx_hal_uart.o [4] +UART_RxISR_16BIT_FIFOEN + 0x800'2899 0xa0 Code Lc stm32wbaxx_hal_uart.o [4] +UART_RxISR_8BIT 0x800'2679 0x50 Code Lc stm32wbaxx_hal_uart.o [4] +UART_RxISR_8BIT_FIFOEN 0x800'27c5 0xa0 Code Lc stm32wbaxx_hal_uart.o [4] +UART_SetConfig 0x800'20b1 0x218 Code Gb stm32wbaxx_hal_uart.o [4] +UART_Start_Receive_IT 0x800'24bf 0xf2 Code Gb stm32wbaxx_hal_uart.o [4] +UART_WaitOnFlagUntilTimeout + 0x800'242f 0x90 Code Gb stm32wbaxx_hal_uart.o [4] +USART1_IRQHandler 0x800'5da1 0x14 Code Gb stm32wbaxx_it.o [2] +USART2_IRQHandler 0x800'6035 Code Wk startup_stm32wba52xx.o [3] +UsageFault_Handler 0x800'5d95 0x2 Code Gb stm32wbaxx_it.o [2] +WKUP_IRQHandler 0x800'607d Code Wk startup_stm32wba52xx.o [3] +WKUP_S_IRQHandler 0x800'6085 Code Wk startup_stm32wba52xx.o [3] +WWDG_IRQHandler 0x800'5f7d Code Wk startup_stm32wba52xx.o [3] +_LC 0x800'015d 0x6 Code Lc xprintffull_nomb.o [5] +_LitobFullNoMb 0x800'0e45 0x114 Code Lc xprintffull_nomb.o [5] +_LocaleC_isspace 0x800'1a81 0x14 Code Gb xlocale_c.o [5] +_LocaleC_isupper 0x800'1a75 0x2 Code Gb xlocale_c.o [5] +_LocaleC_tolower 0x800'1a95 0xc Code Gb xlocale_c.o [5] +_Locale_lconv 0x2000'0010 0x38 Data Lc xlocale_c.o [5] +_PrintfFullNoMb 0x800'0163 0xcb2 Code Gb xprintffull_nomb.o [5] +_Prout 0x800'5f49 0x16 Code Gb xprout.o [5] +_PutcharsFullNoMb 0x800'0fb1 0x2e Code Lc xprintffull_nomb.o [5] +_Strtok_ssave 0x2000'0ad0 0x4 Data Lc strtok.o [5] +__Vectors 0x800'0000 -- Gb startup_stm32wba52xx.o [3] +__Vectors_End 0x800'015c Data Gb startup_stm32wba52xx.o [3] +__Vectors_Size {Abs} 0x15c -- Gb startup_stm32wba52xx.o [3] +__aeabi_cdcmple 0x800'11f1 Code Gb DblCmpLe.o [6] +__aeabi_cdrcmple 0x800'1225 Code Gb DblCmpGe.o [6] +__aeabi_d2iz 0x800'1395 Code Gb DblToS32.o [6] +__aeabi_d2uiz 0x800'1889 Code Gb DblToU32.o [6] +__aeabi_ddiv 0x800'1641 Code Gb DblDiv.o [6] +__aeabi_dmul 0x800'18c9 Code Gb DblMul.o [6] +__aeabi_dsub 0x800'155d Code Gb DblAddSub.o [6] +__aeabi_i2d 0x800'13cd Code Gb S32ToDbl.o [6] +__aeabi_ldiv0 0x800'1bbd Code Gb I64DivZer.o [7] +__aeabi_memclr4 0x800'37ad Code Gb ABImemclr4.o [7] +__aeabi_ui2d 0x800'18ad Code Gb U32ToDbl.o [6] +__cmain 0x800'5ef9 Code Gb cmain.o [7] +__exit 0x800'1bc1 0x14 Code Gb exit.o [8] +__iar_Fail_s 0x800'10bd 0x1c Code Gb xfail_s.o [5] +__iar_Memchr 0x800'1111 Code Gb memchr.o [7] +__iar_Memset4_word 0x800'4471 Code Gb ABImemset48.o [7] +__iar_Memset8_word 0x800'4471 Code Gb ABImemset48.o [7] +__iar_Stdout 0x2000'0090 0x48 Data Gb xfiles.o [5] +__iar_Stoul 0x800'51cb 0x2 Code Gb iar_Stoulx.o [5] +__iar_Stoulx 0x800'5089 0x13c Code Gb iar_Stoulx.o [5] +__iar_Strchr 0x800'10a5 Code Gb strchr.o [7] +__iar_data_init3 0x800'5e45 0x28 Code Gb data_init.o [7] +__iar_frexp 0x800'118d Code Gb frexp.o [6] +__iar_frexpl 0x800'118d Code Gb frexp.o [6] +__iar_globLocale 0x2000'0048 0x48 Data Lc xlocale_c.o [5] +__iar_global_Locale 0x800'1aa1 0x4 Code Gb xlocale_c.o [5] +__iar_init_vfp 0x800'5eb5 Code Gb fpinit_M.o [6] +__iar_ldexp64 0x800'1259 Code Gb ldexp.o [6] +__iar_lz77_init_single3 + 0x800'1027 0x7e Code Gb lz77_init_single.o [7] +__iar_program_start 0x800'5f2d Code Gb cstartup_M.o [7] +__iar_scalbln64 0x800'1259 Code Gb ldexp.o [6] +__iar_scalbn64 0x800'1259 Code Gb ldexp.o [6] +__iar_small_Memcpy 0x800'116d Code Gb ABImemcpy_small.o [7] +__iar_small_Memset 0x800'4ffd Code Gb ABImemset_small.o [7] +__iar_small_Memset_word + 0x800'4ffd Code Gb ABImemset_small.o [7] +__iar_small_memcpy 0x800'1169 Code Gb ABImemcpy_small.o [7] +__iar_small_memcpy4 0x800'1169 Code Gb ABImemcpy_small.o [7] +__iar_small_memcpy8 0x800'1169 Code Gb ABImemcpy_small.o [7] +__iar_small_memset 0x800'4ffd Code Gb ABImemset_small.o [7] +__iar_small_strlen 0x800'10fd Code Gb strlen_small.o [7] +__iar_small_strncpy 0x800'489d Code Gb strncpy_small.o [7] +__iar_small_uldivmod 0x800'1ab1 Code Gb I64DivMod_small.o [7] +__iar_softfp___iar_frexp64 + 0x800'1181 Code Gb frexp.o [6] +__iar_softfp_frexp 0x800'1181 Code Gb frexp.o [6] +__iar_softfp_frexpl 0x800'1181 Code Gb frexp.o [6] +__iar_zero_init3 0x800'5d55 0x38 Code Gb zero_init3.o [7] +__low_level_init 0x800'5f17 0x4 Code Gb low_level_init.o [5] +__vector_table 0x800'0000 Data Gb startup_stm32wba52xx.o [3] +__write 0x800'2d5d 0x32 Code Gb usart.o [2] +_call_main 0x800'5f05 Code Gb cmain.o [7] +_exit 0x800'5f21 Code Gb cexit.o [7] +abort 0x800'1bb7 0x6 Code Gb abort.o [5] +atoi 0x800'51cd 0x2 Code Gb iar_Stoulx.o [5] +digits 0x800'5ce8 0x28 Data Lc iar_Stoulx.o [5] +exit 0x800'5f1b 0x4 Code Gb exit.o [5] +hlpuart1 0x2000'0928 0x94 Data Gb usart.o [2] +hrtc 0x2000'0aa0 0x30 Data Gb rtc.o [2] +huart1 0x2000'09bc 0x94 Data Gb usart.o [2] +isspace 0x800'521f 0x14 Code Gb isspace.o [5] +ldexp 0x800'1259 Code Gb ldexp.o [6] +ldexpl 0x800'1259 Code Gb ldexp.o [6] +localeconv 0x800'1aa5 0x4 Code Gb xlocale_c.o [5] +main 0x800'35e9 0x30 Code Gb main.o [2] +memchr 0x800'1111 Code Gb memchr.o [7] +memset 0x800'4611 0x14 Code Gb memset.o [7] +ndigs 0x800'5cc0 0x28 Data Lc iar_Stoulx.o [5] +obuf 0x2000'0a50 0x50 Data Lc xfiles.o [5] +printf 0x800'43ed 0x28 Code Gb printf.o [5] +putchar 0x800'5d11 0x44 Code Gb putchar.o [5] +scalbln 0x800'1259 Code Gb ldexp.o [6] +scalblnl 0x800'1259 Code Gb ldexp.o [6] +scalbn 0x800'1259 Code Gb ldexp.o [6] +scalbnl 0x800'1259 Code Gb ldexp.o [6] +scale 0x800'0f59 0x46 Code Lc xprintffull_nomb.o [5] +sec_hand 0x2000'0ad4 0x4 Data Lc xfail_s.o [5] +strchr 0x800'10a5 Code Gb strchr.o [7] +strcspn 0x800'51fd 0x22 Code Gb strcspn.o [5] +strspn 0x800'51db 0x22 Code Gb strspn.o [5] +strstr 0x800'500f 0x2c Code Gb strstr.o [5] +strtok 0x800'503d 0x4c Code Gb strtok.o [5] +tolower 0x800'5233 0x14 Code Gb tolower.o [5] +uwTick 0x2000'0004 0x4 Data Gb stm32wbaxx_hal.o [4] +uwTickFreq 0x2000'0000 0x1 Data Gb stm32wbaxx_hal.o [4] +uwTickPrio 0x2000'0008 0x4 Data Gb stm32wbaxx_hal.o [4] + + +[1] = C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\CMSIS_6603591812247902717.dir +[2] = C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\Core_13247989168731456611.dir +[3] = C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\EWARM_18443280873093131863.dir +[4] = C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Obj\STM32WBAxx_HAL_Driver_814230103969653557.dir +[5] = dl7M_tlf.a +[6] = m7M_tls.a +[7] = rt7M_tl.a +[8] = shb_l.a + + 21'737 bytes of readonly code memory + 3'059 bytes of readonly data memory + 3'800 bytes of readwrite data memory + +Errors: none +Warnings: none diff --git a/EWARM/settings/Project.wsdt b/EWARM/settings/Project.wsdt new file mode 100644 index 0000000..7fe45eb --- /dev/null +++ b/EWARM/settings/Project.wsdt @@ -0,0 +1,517 @@ + + + + + WiseEye-LTE/WiseEye-LTE + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + + + + + 34001 + 0 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33037 + 34399 + 0 + 33038 + 33039 + 33877 + 0 + + + + + Log + _I0 + + + 250 + 20 + + 2 + $PROJ_DIR$\DebugLog.log + 0 + 0 + + + + WiseEye-LTE + WiseEye-LTE/Drivers + + + + 14 + 44 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 5B000000050059840000010000004881000001000000558400001F0000000584000001000000108400003A000000 + + + 0F007784000007840000FFFFFFFF86840000808C000044D500004D970000488100000D8400000F8400000884000054840000328100001C81000009840000 + 1400048400004D000000318400005400000020810000590300000F810000510300000C8100004E030000068400004F000000038400004C00000000840000490000000E8400005100000030840000530000001F810000580300000E810000500300000B8100004D030000D18400003E030000058400004E000000028400004B000000108400005200000032840000550000000A840000500000000D8100004F030000 + + + 0 + 0A0000000A0000006E0000006E000000 + 00000000D70300003B040000E8030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34050 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 4294967295 + A1FBFFFFEE010000BCFCFFFF93050000 + 20030000320000003B040000D7030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34051 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 1 + + + + File + Line + Messages + _I0 + + + 54 + 40 + 138 + 20 + + 2 + $WS_DIR$\BuildLog.log + 0 + 0 + + + 34055 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 1 + + + 34056 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + 93 + 13 + 159 + 2 + + 0 + -1 + + + 34057 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + 93 + 13 + 159 + 2 + + 0 + -1 + + + 34058 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 1 + + + + Line + Matched + Path + String + + + 67 + 100 + 444 + 246 + + + + 34059 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + 93 + 13 + 159 + 2 + + 0 + -1 + + + 34060 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + $WS_DIR/SourceBrowseLog.log + 0 + -1 + + + 34062 + 73F9FFFFB8030000E1FDFFFF69040000 + 240300004A00000037040000BD030000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + + 0 + -1 + + + 34052 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + + + + + + + <Right-click on a symbol in the editor to show a call graph> + + + + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + File + Function + Line + + + 200 + 700 + 100 + + + + 34053 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34054 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + + Check + File + Line + Message + Severity + + + 200 + 200 + 100 + 500 + 100 + + + + 34061 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + 0 + + + C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\BrowseInfo\WiseEye-LTE.pbw + + + File + Name + Scope + Symbol type + + + 300 + 300 + 300 + 300 + + + + 34063 + 00000000170000000601000078010000 + 0000000032000000A7000000D7030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 000000000E000000000000000010000001000000FFFFFFFFFFFFFFFFA700000032000000AB000000D70300000100000002000010040000000100000091FFFFFF0D0200000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000028500000000000000000000000000000000000001000000028500000100000002850000000000000040000001000000FFFFFFFFFFFFFFFF1C0300003200000020030000D703000001000000020000100400000001000000D6FEFFFFF201000000000000000000000000000001000000FFFFFFFF08000000038500000785000008850000098500000A8500000B8500000C8500000E850000FFFF02000B004354616262656450616E650040000001000000A1FBFFFFEE010000BCFCFFFF9305000020030000320000003B040000D7030000000000004080005608000000FFFEFF054200750069006C006400010000000385000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000785000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300010000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF1153006F0075007200630065002000420072006F0077007300650020004C006F006700000000000C85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000001000000FFFFFFFF0385000001000000FFFFFFFF03850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED1840000020000003E030000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + D603000000000000040400001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000068030000FFFEFF000000000000000000000000000100000001000000018001E100000000000069030000FFFEFF000000000000000000000000000100000001000000018003E10000000000006B030000FFFEFF0000000000000000000000000001000000010000000180008100000000000048030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000000006E030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E100000000040070030000FFFEFF000000000000000000000000000100000001000000018022E10000000004006F030000FFFEFF000000000000000000000000000100000001000000018025E100000000040071030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040072030000FFFEFF00000000000000000000000000010000000100000001802CE100000000040073030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000000FFFFFFFFFFFEFF000100000000000000010000000000000001000000B400000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004005A030000FFFEFF000000000000000000000000000100000001000000018024E100000000000063030000FFFEFF000000000000000000000000000100000001000000018028E100000000040062030000FFFEFF000000000000000000000000000100000001000000018029E100000000000064030000FFFEFF0000000000000000000000000001000000010000000180028100000000000049030000FFFEFF000000000000000000000000000100000001000000018029810000000000005E030000FFFEFF000000000000000000000000000100000001000000018027810000000000005C030000FFFEFF000000000000000000000000000100000001000000018028810000000000005D030000FFFEFF00000000000000000000000000010000000100000001801D8100000000000056030000FFFEFF00000000000000000000000000010000000100000001801E8100000000040057030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000020000004D030000FFFEFF00000000000000000000000000010000000100000001800D810000020000004F030000FFFEFF00000000000000000000000000010000000100000001805F8600000200000061030000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000200000050030000FFFEFF00000000000000000000000000010000000100000001800F8100000200000051030000FFFEFF00000000000000000000000000010000000100000001805584000002000200FFFFFFFFFFFEFF1B44006F0077006E006C006F0061006400200061006300740069007600650020006100700070006C00690063006100740069006F006E00010000000000000001000000000000000100000000000000FFFEFF044D00610069006E00E9010000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 0000000000000000D60300001A000000 + 8192 + 0 + 0 + 489 + 0 + + + 1 + + + + + 010000000300000001000000000000000000000001000000010000000200000000000000010000000100000000000000280000002800000001000000050000000200000001000000FFFEFF1C2400570053005F0044004900520024005C002E002E005C0043006F00720065005C005300720063005C00750073006100720074002E00630001000000FFFF010017004966436F6E74656E7453746F726167654D6663496D706CFFFEFF00FFFEFFFF22013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003300310031003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF07750073006100720074002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1B2400570053005F0044004900520024005C002E002E005C0043006F00720065005C0049006E0063005C0065006700390031002E006800010000000180FFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003200330030003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0037003300390038003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0037003300390038003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0665006700390031002E00680000000000FFFFFFFFFFFFFFFFFFFEFF1B2400570053005F0044004900520024005C002E002E005C0043006F00720065005C005300720063005C0065006700390031002E006300010000000180FFFEFF00FFFEFFFF2A013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003600370032003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E00320031003000350033003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E00320031003000350033003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0665006700390031002E00630000000000FFFFFFFFFFFFFFFFFFFEFF202400570053005F0044004900520024005C002E002E005C0043006F00720065005C005300720063005C006C00740065005F0063006F006D006D0073002E006300010000000180FFFEFF00FFFEFFFF22013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003300330034003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF0B6C00740065005F0063006F006D006D0073002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1B2400570053005F0044004900520024005C002E002E005C0043006F00720065005C005300720063005C006D00610069006E002E006300010000000180FFFEFF00FFFEFFFF27013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00370039003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0032003400300033003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0032003400300033003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF066D00610069006E002E00630000000000FFFFFFFFFFFFFFFF0000000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD5000100000001000000020000002CF9FFFFEE0100009DFBFFFF93050000 + + + + diff --git a/EWARM/settings/Project_EditorBookmarks.xml b/EWARM/settings/Project_EditorBookmarks.xml new file mode 100644 index 0000000..38c3485 --- /dev/null +++ b/EWARM/settings/Project_EditorBookmarks.xml @@ -0,0 +1,2 @@ + + diff --git a/EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.bat b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.bat new file mode 100644 index 0000000..1ab988d --- /dev/null +++ b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.bat @@ -0,0 +1,40 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM +@REM Read about available command line parameters in the C-SPY Debugging +@REM Guide. Hints about additional command line parameters that may be +@REM useful in specific cases: +@REM --download_only Downloads a code image without starting a debug +@REM session afterwards. +@REM --silent Omits the sign-on message. +@REM --timeout Limits the maximum allowed execution time. +@REM + + +@echo off + +if not "%~1" == "" goto debugFile + +@echo on + +"C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.general.xcl" --backend -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.driver.xcl" + +@echo off +goto end + +:debugFile + +@echo on + +"C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.driver.xcl" + +@echo off +:end \ No newline at end of file diff --git a/EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.ps1 b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.ps1 new file mode 100644 index 0000000..b4a35f4 --- /dev/null +++ b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.cspy.ps1 @@ -0,0 +1,31 @@ +param([String]$debugfile = ""); + +# This powershell file has been generated by the IAR Embedded Workbench +# C - SPY Debugger, as an aid to preparing a command line for running +# the cspybat command line utility using the appropriate settings. +# +# Note that this file is generated every time a new debug session +# is initialized, so you may want to move or rename the file before +# making changes. +# +# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed +# by the name of the debug file (usually an ELF / DWARF or UBROF file). +# +# Read about available command line parameters in the C - SPY Debugging +# Guide. Hints about additional command line parameters that may be +# useful in specific cases : +# --download_only Downloads a code image without starting a debug +# session afterwards. +# --silent Omits the sign - on message. +# --timeout Limits the maximum allowed execution time. +# + + +if ($debugfile -eq "") +{ +& "C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.general.xcl" --backend -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.driver.xcl" +} +else +{ +& "C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\settings\WiseEye-LTE.WiseEye-LTE.driver.xcl" +} diff --git a/EWARM/settings/WiseEye-LTE.WiseEye-LTE.driver.xcl b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.driver.xcl new file mode 100644 index 0000000..3a48dfe --- /dev/null +++ b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.driver.xcl @@ -0,0 +1,31 @@ +"--endian=little" + +"--cpu=Cortex-M33.no_se" + +"--fpu=VFPv5_SP" + +"-p" + +"C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\config\debugger\ST\STM32WBA52CG.ddf" + +"--drv_verify_download" + +"--semihosting" + +"--device=STM32WBA52CG" + +"--drv_interface=SWD" + +"--stlink_reset_strategy=0,2" + +"--drv_swo_clock_setup=64000000,0,2000000" + +"--drv_catch_exceptions=0x000" + +"--drv_debug_ap=1" + +"--stlink_probe_supplied_power=3.3" + + + + diff --git a/EWARM/settings/WiseEye-LTE.WiseEye-LTE.general.xcl b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.general.xcl new file mode 100644 index 0000000..d839950 --- /dev/null +++ b/EWARM/settings/WiseEye-LTE.WiseEye-LTE.general.xcl @@ -0,0 +1,17 @@ +"C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin\armPROC.dll" + +"C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin\armSTLINK.dll" + +"C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\Exe\WiseEye-LTE.out" + +--plugin="C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin\armbat.dll" + +--device_macro="C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm/config/debugger/ST/STM32WBAxx.dmac" + +--device_macro="C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm/config/debugger/ST/STM32WBAxx_DBG.dmac" + +--flash_loader="C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm/config/flashloader/ST/FlashSTM32WBAxxxG.board" + + + + diff --git a/EWARM/settings/WiseEye-LTE.crun b/EWARM/settings/WiseEye-LTE.crun new file mode 100644 index 0000000..d71ea55 --- /dev/null +++ b/EWARM/settings/WiseEye-LTE.crun @@ -0,0 +1,13 @@ + + + 1 + + + * + * + * + 0 + 1 + + + diff --git a/EWARM/settings/WiseEye-LTE.dbgdt b/EWARM/settings/WiseEye-LTE.dbgdt new file mode 100644 index 0000000..73e71f6 --- /dev/null +++ b/EWARM/settings/WiseEye-LTE.dbgdt @@ -0,0 +1,4 @@ + + + + diff --git a/EWARM/settings/WiseEye-LTE.dnx b/EWARM/settings/WiseEye-LTE.dnx new file mode 100644 index 0000000..cdf8292 --- /dev/null +++ b/EWARM/settings/WiseEye-LTE.dnx @@ -0,0 +1,124 @@ + + + + 0 + 1 + 90 + 1 + 1 + 1 + main + 0 + 50 + + + 0 + C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\config\debugger\ST\STM32WBA52CG.ddf + + + 0 + 1 + + + 0670FF343636574D43054237 + + _ 0 + _ 0 + 0 + 2 + + + 0 + 1 + + + 1 + 10 + $PROJ_DIR$\TermIOInput.txt + 1 + 0 + 2 + 2 + + + _ 0 + _ 0 + + + 0 + 64000000 + 0 + 2000000 + 2000000 + 32 + 0 + 0 + 1 + 15 + 0 + 0 + 0 + 0 + 0 + $PROJ_DIR$\ITM.log + + + 0 + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0 + 1 + 0 + 1 + + + 0 + 0 + 1 + 0 + 1 + 0 + + + 0 + 0 + 1 + Ch3 + 0 0 1 + Ch2 + 0 0 1 + Ch1 + 0 0 1 + Ch0 + 0 0 1 + 0 + 1 + 0 + + + 0 + + + 0 + + + _ 0 + _ "" + + + 0 + 0 + + diff --git a/EWARM/settings/WiseEye_LTE.wsdt b/EWARM/settings/WiseEye_LTE.wsdt new file mode 100644 index 0000000..fd71c40 --- /dev/null +++ b/EWARM/settings/WiseEye_LTE.wsdt @@ -0,0 +1,506 @@ + + + + + WiseEye-LTE/WiseEye-LTE + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + + + + + 34001 + 0 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33038 + 33039 + 33877 + 0 + + + + + Log + _I0 + + + 249 + 20 + + 2 + $PROJ_DIR$\DebugLog.log + 0 + 0 + + + + WiseEye-LTE + WiseEye-LTE/Application + WiseEye-LTE/Application/User + WiseEye-LTE/Application/User/Core + + + + 14 + 44 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 160000000400598400000100000048810000010000005584000006000000108400000F000000 + + + 0A007784000007840000FFFFFFFF86840000808C000044D5000055840000568400005984000048810000 + 1300048400004D000000318400005400000020810000910100000F810000890100000C81000086010000068400004F000000038400004C0000000E8400005100000030840000530000001F810000900100000E810000880100000B81000085010000D184000076010000058400004E000000028400004B000000108400005200000032840000550000000A840000500000000D81000087010000 + + + 0 + 0A0000000A0000006E0000006E000000 + 000000002C030000A00500003D030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34050 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 4294967295 + 8604000049000000A005000043030000 + 8604000032000000A00500002C030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34051 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + + File + Line + Messages + _I0 + + + 65 + 40 + 143 + 20 + + 2 + $WS_DIR$\BuildLog.log + 0 + 0 + + + 34055 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 34056 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 93 + 13 + 159 + 2 + + 0 + -1 + + + 34057 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 93 + 13 + 159 + 2 + + 0 + -1 + + + 34058 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 93 + 13 + 159 + 2 + + 0 + -1 + + + 34060 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 2 + $WS_DIR/SourceBrowseLog.log + 0 + -1 + + + 34062 + D8040000B3010000FA05000064020000 + 8A0400004A0000009C05000012030000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + + 0 + -1 + + + 34052 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + + + + + + + <Right-click on a symbol in the editor to show a call graph> + + + + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + File + Function + Line + + + 200 + 700 + 100 + + + + 34053 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34054 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + + Check + File + Line + Message + Severity + + + 200 + 200 + 100 + 500 + 100 + + + + 34061 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + 0 + + + C:\Users\Admin\Documents\.Projects\7. Cellular Relay Controller\LTE-Code\WiseEye-LTE\EWARM\WiseEye-LTE\BrowseInfo\WiseEye-LTE.pbw + + + File + Name + Scope + Symbol type + + + 300 + 300 + 300 + 300 + + + + 34063 + 00000000170000000601000078010000 + 0000000032000000F50000002C030000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 000000000E000000000000000010000001000000FFFFFFFFFFFFFFFFF500000032000000F90000002C03000001000000020000100400000001000000D0FEFFFFD00300000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000028500000000000000000000000000000000000001000000028500000100000002850000000000000040000001000000FFFFFFFFFFFFFFFF8204000032000000860400002C03000001000000020000100400000001000000000000000000000000000000000000000000000001000000FFFFFFFF08000000038500000785000008850000098500000A8500000B8500000C8500000E850000FFFF02000B004354616262656450616E6500400000010000008604000049000000A0050000430300008604000032000000A00500002C030000000000004080005608000000FFFEFF054200750069006C006400010000000385000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000785000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF1153006F0075007200630065002000420072006F0077007300650020004C006F006700010000000C85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF0600000000000000000000000000000000000000000000000000000001000000FFFFFFFF0385000001000000FFFFFFFF03850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED184000002000000AF010000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + CB03000000000000F90300001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000D9010000FFFEFF000000000000000000000000000100000001000000018001E1000000000000DA010000FFFEFF000000000000000000000000000100000001000000018003E1000000000400DC010000FFFEFF00000000000000000000000000010000000100000001800081000000000000B9010000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E1000000000400DF010000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E1000000000400E1010000FFFEFF000000000000000000000000000100000001000000018022E1000000000400E0010000FFFEFF000000000000000000000000000100000001000000018025E1000000000400E2010000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE1000000000400E3010000FFFEFF00000000000000000000000000010000000100000001802CE1000000000400E4010000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000400FFFFFFFFFFFEFF000100000000000000010000000000000001000000B400000002002050FFFFFFFFFFFEFF009600000000000000000001802181000000000400CB010000FFFEFF000000000000000000000000000100000001000000018024E1000000000400D4010000FFFEFF000000000000000000000000000100000001000000018028E1000000000400D3010000FFFEFF000000000000000000000000000100000001000000018029E1000000000400D5010000FFFEFF00000000000000000000000000010000000100000001800281000000000400BA010000FFFEFF00000000000000000000000000010000000100000001802981000000000400CF010000FFFEFF00000000000000000000000000010000000100000001802781000000000400CD010000FFFEFF00000000000000000000000000010000000100000001802881000000000400CE010000FFFEFF00000000000000000000000000010000000100000001801D81000000000000C7010000FFFEFF00000000000000000000000000010000000100000001801E81000000000400C8010000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B81000002000400BE010000FFFEFF00000000000000000000000000010000000100000001800C81000002000000BF010000FFFEFF00000000000000000000000000010000000100000001805F86000002000000D2010000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E81000002000000C1010000FFFEFF00000000000000000000000000010000000100000001800F81000002000000C2010000FFFEFF00000000000000000000000000010000000100000001805584000002000000FFFFFFFFFFFEFF1B44006F0077006E006C006F0061006400200061006300740069007600650020006100700070006C00690063006100740069006F006E00000000000000000001000000000000000100000000000000FFFEFF044D00610069006E00E4010000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 0000000000000000CB0300001A000000 + 8192 + 0 + 0 + 484 + 0 + + + 1 + + + + + 01000000030000000100000000000000000000000100000001000000FFFFFFFF00000000010000000100000000000000280000002800000001000000030000000200000001000000FFFEFF1B2400570053005F0044004900520024005C002E002E005C0043006F00720065005C005300720063005C006700700069006F002E00630001000000FFFF010017004966436F6E74656E7453746F726167654D6663496D706CFFFEFF00FFFEFFFF26013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E0038003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0031003000370034003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0031003000370034003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF066700700069006F002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1B2400570053005F0044004900520024005C002E002E005C0043006F00720065005C005300720063005C006D00610069006E002E006300010000000180FFFEFF00FFFEFFFF21013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E00370033003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0030003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0030003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF066D00610069006E002E00630000000000FFFFFFFFFFFFFFFFFFFEFF1C2400570053005F0044004900520024005C002E002E005C0043006F00720065005C005300720063005C00750073006100720074002E006300010000000180FFFEFF00FFFEFFFF28013C003F0078006D006C002000760065007200730069006F006E003D00220031002E0030002200200065006E0063006F00640069006E0067003D0022005500540046002D00380022003F003E000A003C0052006F006F0074003E000A0020002000200020003C004E0075006D0052006F00770073003E0031003C002F004E0075006D0052006F00770073003E000A0020002000200020003C004E0075006D0043006F006C0073003E0031003C002F004E0075006D0043006F006C0073003E000A0020002000200020003C00580050006F0073003E0030003C002F00580050006F0073003E000A0020002000200020003C00590050006F0073003E0030003C002F00590050006F0073003E000A0020002000200020003C00530065006C00530074006100720074003E0030003C002F00530065006C00530074006100720074003E000A0020002000200020003C00530065006C0045006E0064003E0030003C002F00530065006C0045006E0064003E000A0020002000200020003C00580050006F00730032003E0030003C002F00580050006F00730032003E000A0020002000200020003C00590050006F00730032003E003200330035003C002F00590050006F00730032003E000A0020002000200020003C00530065006C005300740061007200740032003E0037003700320039003C002F00530065006C005300740061007200740032003E000A0020002000200020003C00530065006C0045006E00640032003E0037003700320039003C002F00530065006C0045006E00640032003E000A003C002F0052006F006F0074003E000A00FFFEFF07750073006100720074002E00630000000000FFFFFFFFFFFFFFFF0000000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000100000002000000F9000000490000008204000043030000 + + + + diff --git a/EWARM/settings/WiseEye_LTE_EditorBookmarks.xml b/EWARM/settings/WiseEye_LTE_EditorBookmarks.xml new file mode 100644 index 0000000..38c3485 --- /dev/null +++ b/EWARM/settings/WiseEye_LTE_EditorBookmarks.xml @@ -0,0 +1,2 @@ + + diff --git a/EWARM/startup_stm32wba52xx.s b/EWARM/startup_stm32wba52xx.s new file mode 100644 index 0000000..ea2e30a --- /dev/null +++ b/EWARM/startup_stm32wba52xx.s @@ -0,0 +1,562 @@ +;******************************************************************************** +;* File Name : startup_stm32wba52xx.s +;* Author : MCD Application Team +;* Description : STM32WBA5xx Ultra Low Power Devices vector +;* This module performs: +;* - Set the initial SP +;* - Set the initial PC == _iar_program_start, +;* - Set the vector table entries with the exceptions ISR +;* address. +;* - Branches to main in the C library (which eventually +;* calls main()). +;* After Reset the Cortex-M33 processor is in Thread mode, +;* priority is Privileged, and the Stack is set to Main. +;******************************************************************************** +;* @attention +;* +;* Copyright (c) 2022 STMicroelectronics. +;* All rights reserved. +;* +;* This software is licensed under terms that can be found in the LICENSE file +;* in the root directory of this software component. +;* If no LICENSE file comes with this software, it is provided AS-IS. +;* +;******************************************************************************* +; +; +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. +; +; Cortex-M version +; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler ; Reset Handler + + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD MemManage_Handler ; MPU Fault Handler + DCD BusFault_Handler ; Bus Fault Handler + DCD UsageFault_Handler ; Usage Fault Handler + DCD SecureFault_Handler ; Secure Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD DebugMon_Handler ; Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + + ; External Interrupts + DCD WWDG_IRQHandler ; Window WatchDog + DCD PVD_IRQHandler ; PVD through EXTI Line detection Interrupt + DCD RTC_IRQHandler ; RTC non-secure interrupt + DCD RTC_S_IRQHandler ; RTC secure interrupt + DCD TAMP_IRQHandler ; Tamper non-secure interrupt + DCD RAMCFG_IRQHandler ; RAMCFG global + DCD FLASH_IRQHandler ; FLASH non-secure global interrupt + DCD FLASH_S_IRQHandler ; FLASH secure global interrupt + DCD GTZC_IRQHandler ; Global TrustZone Controller interrupt + DCD RCC_IRQHandler ; RCC non-secure global interrupt + DCD RCC_S_IRQHandler ; RCC secure global interrupt + DCD EXTI0_IRQHandler ; EXTI Line0 interrupt + DCD EXTI1_IRQHandler ; EXTI Line1 interrupt + DCD EXTI2_IRQHandler ; EXTI Line2 interrupt + DCD EXTI3_IRQHandler ; EXTI Line3 interrupt + DCD EXTI4_IRQHandler ; EXTI Line4 interrupt + DCD EXTI5_IRQHandler ; EXTI Line5 interrupt + DCD EXTI6_IRQHandler ; EXTI Line6 interrupt + DCD EXTI7_IRQHandler ; EXTI Line7 interrupt + DCD EXTI8_IRQHandler ; EXTI Line8 interrupt + DCD EXTI9_IRQHandler ; EXTI Line9 interrupt + DCD EXTI10_IRQHandler ; EXTI Line10 interrupt + DCD EXTI11_IRQHandler ; EXTI Line11 interrupt + DCD EXTI12_IRQHandler ; EXTI Line12 interrupt + DCD EXTI13_IRQHandler ; EXTI Line13 interrupt + DCD EXTI14_IRQHandler ; EXTI Line14 interrupt + DCD EXTI15_IRQHandler ; EXTI Line15 interrupt + DCD IWDG_IRQHandler ; IWDG global interrupt + DCD SAES_IRQHandler ; Secure AES global interrupt + DCD GPDMA1_Channel0_IRQHandler ; GPDMA1 Channel 0 global interrupt + DCD GPDMA1_Channel1_IRQHandler ; GPDMA1 Channel 1 global interrupt + DCD GPDMA1_Channel2_IRQHandler ; GPDMA1 Channel 2 global interrupt + DCD GPDMA1_Channel3_IRQHandler ; GPDMA1 Channel 3 global interrupt + DCD GPDMA1_Channel4_IRQHandler ; GPDMA1 Channel 4 global interrupt + DCD GPDMA1_Channel5_IRQHandler ; GPDMA1 Channel 5 global interrupt + DCD GPDMA1_Channel6_IRQHandler ; GPDMA1 Channel 6 global interrupt + DCD GPDMA1_Channel7_IRQHandler ; GPDMA1 Channel 7 global interrupt + DCD TIM1_BRK_IRQHandler ; TIM1 Break interrupt + DCD TIM1_UP_IRQHandler ; TIM1 Update interrupt + DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation interrupt + DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare interrupt + DCD TIM2_IRQHandler ; TIM2 global interrupt + DCD TIM3_IRQHandler ; TIM3 global interrupt + DCD I2C1_EV_IRQHandler ; I2C1 Event interrupt + DCD I2C1_ER_IRQHandler ; I2C1 Error interrupt + DCD SPI1_IRQHandler ; SPI1 global interrupt + DCD USART1_IRQHandler ; USART1 global interrupt + DCD USART2_IRQHandler ; USART2 global interrupt + DCD LPUART1_IRQHandler ; LPUART1 global interrupt + DCD LPTIM1_IRQHandler ; LPTIM1 global interrupt + DCD LPTIM2_IRQHandler ; LPTIM2 global interrupt + DCD TIM16_IRQHandler ; TIM16 global interrupt + DCD TIM17_IRQHandler ; TIM17 global interrupt + DCD 0 ; Reserved + DCD I2C3_EV_IRQHandler ; I2C3 event interrupt + DCD I2C3_ER_IRQHandler ; I2C3 error interrupt + DCD 0 ; Reserved + DCD TSC_IRQHandler ; Touch Sense Controller global interrupt + DCD AES_IRQHandler ; AES global interrupt + DCD RNG_IRQHandler ; RNG global interrupt + DCD FPU_IRQHandler ; FPU global interrupt + DCD HASH_IRQHandler ; HASH global interrupt + DCD PKA_IRQHandler ; PKA global interrupt + DCD SPI3_IRQHandler ; SPI3 global interrupt + DCD ICACHE_IRQHandler ; Instruction cache global interrupt + DCD ADC4_IRQHandler ; LP ADC (12bits) global interrupt + DCD RADIO_IRQHandler ; 2.4GHz RADIO global interrupt + DCD WKUP_IRQHandler ; PWR global WKUP pin interrupt + DCD HSEM_IRQHandler ; HSEM non-secure global interrupt + DCD HSEM_S_IRQHandler ; HSEM secure global interrupt + DCD WKUP_S_IRQHandler ; PWR secure global WKUP pin interrupt + +__Vectors_End + +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + PUBWEAK NMI_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +NMI_Handler + B NMI_Handler + + PUBWEAK HardFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +HardFault_Handler + B HardFault_Handler + + PUBWEAK MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SecureFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SecureFault_Handler + B SecureFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_Handler + + PUBWEAK PendSV_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +PendSV_Handler + B PendSV_Handler + + PUBWEAK SysTick_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SysTick_Handler + B SysTick_Handler + + PUBWEAK WWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDG_IRQHandler + B WWDG_IRQHandler + + PUBWEAK PVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PVD_IRQHandler + B PVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK RTC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_S_IRQHandler + B RTC_S_IRQHandler + + PUBWEAK TAMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TAMP_IRQHandler + B TAMP_IRQHandler + + PUBWEAK RAMCFG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RAMCFG_IRQHandler + B RAMCFG_IRQHandler + + PUBWEAK FLASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_IRQHandler + B FLASH_IRQHandler + + PUBWEAK FLASH_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FLASH_S_IRQHandler + B FLASH_S_IRQHandler + + PUBWEAK GTZC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GTZC_IRQHandler + B GTZC_IRQHandler + + PUBWEAK RCC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_IRQHandler + B RCC_IRQHandler + + PUBWEAK RCC_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCC_S_IRQHandler + B RCC_S_IRQHandler + + PUBWEAK EXTI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI0_IRQHandler + B EXTI0_IRQHandler + + PUBWEAK EXTI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI1_IRQHandler + B EXTI1_IRQHandler + + PUBWEAK EXTI2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI2_IRQHandler + B EXTI2_IRQHandler + + PUBWEAK EXTI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI3_IRQHandler + B EXTI3_IRQHandler + + PUBWEAK EXTI4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI4_IRQHandler + B EXTI4_IRQHandler + + PUBWEAK EXTI5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI5_IRQHandler + B EXTI5_IRQHandler + + PUBWEAK EXTI6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI6_IRQHandler + B EXTI6_IRQHandler + + PUBWEAK EXTI7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI7_IRQHandler + B EXTI7_IRQHandler + + PUBWEAK EXTI8_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI8_IRQHandler + B EXTI8_IRQHandler + + PUBWEAK EXTI9_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI9_IRQHandler + B EXTI9_IRQHandler + + PUBWEAK EXTI10_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI10_IRQHandler + B EXTI10_IRQHandler + + PUBWEAK EXTI11_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI11_IRQHandler + B EXTI11_IRQHandler + + PUBWEAK EXTI12_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI12_IRQHandler + B EXTI12_IRQHandler + + PUBWEAK EXTI13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI13_IRQHandler + B EXTI13_IRQHandler + + PUBWEAK EXTI14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI14_IRQHandler + B EXTI14_IRQHandler + + PUBWEAK EXTI15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +EXTI15_IRQHandler + B EXTI15_IRQHandler + + PUBWEAK IWDG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +IWDG_IRQHandler + B IWDG_IRQHandler + + PUBWEAK SAES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SAES_IRQHandler + B SAES_IRQHandler + + PUBWEAK GPDMA1_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel0_IRQHandler + B GPDMA1_Channel0_IRQHandler + + PUBWEAK GPDMA1_Channel1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel1_IRQHandler + B GPDMA1_Channel1_IRQHandler + + PUBWEAK GPDMA1_Channel2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel2_IRQHandler + B GPDMA1_Channel2_IRQHandler + + PUBWEAK GPDMA1_Channel3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel3_IRQHandler + B GPDMA1_Channel3_IRQHandler + + PUBWEAK GPDMA1_Channel4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel4_IRQHandler + B GPDMA1_Channel4_IRQHandler + + PUBWEAK GPDMA1_Channel5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel5_IRQHandler + B GPDMA1_Channel5_IRQHandler + + PUBWEAK GPDMA1_Channel6_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel6_IRQHandler + B GPDMA1_Channel6_IRQHandler + + PUBWEAK GPDMA1_Channel7_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +GPDMA1_Channel7_IRQHandler + B GPDMA1_Channel7_IRQHandler + + PUBWEAK TIM1_BRK_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_BRK_IRQHandler + B TIM1_BRK_IRQHandler + + PUBWEAK TIM1_UP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_UP_IRQHandler + B TIM1_UP_IRQHandler + + PUBWEAK TIM1_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_TRG_COM_IRQHandler + B TIM1_TRG_COM_IRQHandler + + PUBWEAK TIM1_CC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM1_CC_IRQHandler + B TIM1_CC_IRQHandler + + PUBWEAK TIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM2_IRQHandler + B TIM2_IRQHandler + + PUBWEAK TIM3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM3_IRQHandler + B TIM3_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK USART2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART2_IRQHandler + B USART2_IRQHandler + + PUBWEAK LPUART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPUART1_IRQHandler + B LPUART1_IRQHandler + + PUBWEAK LPTIM1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM1_IRQHandler + B LPTIM1_IRQHandler + + PUBWEAK LPTIM2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LPTIM2_IRQHandler + B LPTIM2_IRQHandler + + PUBWEAK TIM16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM16_IRQHandler + B TIM16_IRQHandler + + PUBWEAK TIM17_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIM17_IRQHandler + B TIM17_IRQHandler + + PUBWEAK I2C3_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_EV_IRQHandler + B I2C3_EV_IRQHandler + + PUBWEAK I2C3_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C3_ER_IRQHandler + B I2C3_ER_IRQHandler + + PUBWEAK TSC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TSC_IRQHandler + B TSC_IRQHandler + + PUBWEAK AES_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +AES_IRQHandler + B AES_IRQHandler + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RNG_IRQHandler + B RNG_IRQHandler + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FPU_IRQHandler + B FPU_IRQHandler + + PUBWEAK HASH_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HASH_IRQHandler + B HASH_IRQHandler + + PUBWEAK PKA_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +PKA_IRQHandler + B PKA_IRQHandler + + PUBWEAK SPI3_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI3_IRQHandler + B SPI3_IRQHandler + + PUBWEAK ICACHE_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ICACHE_IRQHandler + B ICACHE_IRQHandler + + PUBWEAK ADC4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC4_IRQHandler + B ADC4_IRQHandler + + PUBWEAK RADIO_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RADIO_IRQHandler + B RADIO_IRQHandler + + PUBWEAK WKUP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WKUP_IRQHandler + B WKUP_IRQHandler + + PUBWEAK HSEM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HSEM_IRQHandler + B HSEM_IRQHandler + + PUBWEAK HSEM_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +HSEM_S_IRQHandler + B HSEM_S_IRQHandler + + PUBWEAK WKUP_S_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WKUP_S_IRQHandler + B WKUP_S_IRQHandler + + END diff --git a/EWARM/stm32wba52xx_flash.icf b/EWARM/stm32wba52xx_flash.icf new file mode 100644 index 0000000..12eae9f --- /dev/null +++ b/EWARM/stm32wba52xx_flash.icf @@ -0,0 +1,35 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x080FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF; +define symbol __region_SRAM2_start__ = 0x20010000; +define symbol __region_SRAM2_end__ = 0x2001FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region SRAM2_region = mem:[from __region_SRAM2_start__ to __region_SRAM2_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in SRAM2_region { }; diff --git a/EWARM/stm32wba52xx_sram.icf b/EWARM/stm32wba52xx_sram.icf new file mode 100644 index 0000000..b384d48 --- /dev/null +++ b/EWARM/stm32wba52xx_sram.icf @@ -0,0 +1,36 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x20000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x20007FFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20008000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF; +define symbol __region_SRAM2_start__ = 0x20010000; +define symbol __region_SRAM2_end__ = 0x2001FFFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x400; +define symbol __ICFEDIT_size_heap__ = 0x200; +/**** End of ICF editor section. ###ICF###*/ + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region SRAM2_region = mem:[from __region_SRAM2_start__ to __region_SRAM2_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in SRAM2_region { }; diff --git a/WiseEye-LTE-2.ioc b/WiseEye-LTE-2.ioc new file mode 100644 index 0000000..2dfda16 --- /dev/null +++ b/WiseEye-LTE-2.ioc @@ -0,0 +1,194 @@ +#MicroXplorer Configuration settings - do not modify +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M33_NS.userName=CORTEX_M33 +File.Version=6 +GPIO.groupedBy= +KeepUserPlacement=false +LPUART1.BaudRate=115200 +LPUART1.IPParameters=BaudRate +MMTAppRegionsCount=0 +MMTConfigApplied=false +Mcu.CPN=STM32WBA52CGU6 +Mcu.ContextProject=TrustZoneDisabled +Mcu.Family=STM32WBA +Mcu.IP0=CORTEX_M33_NS +Mcu.IP1=ICACHE +Mcu.IP2=LPUART1 +Mcu.IP3=MEMORYMAP +Mcu.IP4=NVIC +Mcu.IP5=PWR +Mcu.IP6=RCC +Mcu.IP7=SYS +Mcu.IP8=USART1 +Mcu.IPNb=9 +Mcu.Name=STM32WBA52CGUx +Mcu.Package=UFQFPN48 +Mcu.Pin0=PB12 +Mcu.Pin1=PB11 +Mcu.Pin10=OSC_IN +Mcu.Pin11=PA10 +Mcu.Pin12=VP_CORTEX_M33_NS_VS_Hclk +Mcu.Pin13=VP_ICACHE_VS_ICACHE +Mcu.Pin14=VP_PWR_VS_SECSignals +Mcu.Pin15=VP_SYS_VS_Systick +Mcu.Pin16=VP_MEMORYMAP_VS_MEMORYMAP +Mcu.Pin2=PA8 +Mcu.Pin3=PC15-OSC32_OUT +Mcu.Pin4=PC14-OSC32_IN +Mcu.Pin5=PB7 +Mcu.Pin6=PB4 (NJTRST) +Mcu.Pin7=PA15 (JTDI) +Mcu.Pin8=PB0 +Mcu.Pin9=OSC_OUT +Mcu.PinsNb=17 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32WBA52CGUx +MxCube.Version=6.15.0 +MxDb.Version=DB.6.0.150 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +OSC_IN.Mode=HSE-External-Oscillator +OSC_IN.Signal=RCC_OSC_IN +OSC_OUT.Mode=HSE-External-Oscillator +OSC_OUT.Signal=RCC_OSC_OUT +PA10.GPIOParameters=GPIO_Label +PA10.GPIO_Label=DEBUG_RX +PA10.Locked=true +PA10.Mode=Asynchronous +PA10.Signal=LPUART1_RX +PA15\ (JTDI).GPIOParameters=GPIO_Label +PA15\ (JTDI).GPIO_Label=LTE_PWRKEY +PA15\ (JTDI).Locked=true +PA15\ (JTDI).Signal=GPIO_Output +PA8.GPIOParameters=GPIO_Label +PA8.GPIO_Label=LTE_RX +PA8.Mode=Asynchronous +PA8.Signal=USART1_RX +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=LTE_RST +PB0.Locked=true +PB0.Signal=GPIO_Output +PB11.GPIOParameters=GPIO_Label +PB11.GPIO_Label=DEBUG_TX +PB11.Mode=Asynchronous +PB11.Signal=LPUART1_TX +PB12.GPIOParameters=GPIO_Label +PB12.GPIO_Label=LTE_TX +PB12.Mode=Asynchronous +PB12.Signal=USART1_TX +PB4\ (NJTRST).GPIOParameters=GPIO_Label +PB4\ (NJTRST).GPIO_Label=LTE_EN +PB4\ (NJTRST).Locked=true +PB4\ (NJTRST).Signal=GPIO_Output +PB7.GPIOParameters=GPIO_Label +PB7.GPIO_Label=STATUS_LED +PB7.Locked=true +PB7.Signal=GPIO_Output +PC14-OSC32_IN.Mode=LSE-External-Oscillator +PC14-OSC32_IN.Signal=RCC_OSC32_IN +PC15-OSC32_OUT.Mode=LSE-External-Oscillator +PC15-OSC32_OUT.Signal=RCC_OSC32_OUT +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=true +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=true +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=false +ProjectManager.DeviceId=STM32WBA52CGUx +ProjectManager.FirmwarePackage=STM32Cube FW_WBA V1.7.0 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=2 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=WiseEye-LTE.ioc +ProjectManager.ProjectName=WiseEye-LTE +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=EWARM V9.20 +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-SystemPower_Config-PWR-false-HAL-true,4-MX_LPUART1_UART_Init-LPUART1-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_ICACHE_Init-ICACHE-false-HAL-true,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true +RCC.ADCFreq_Value=64000000 +RCC.AHB4Freq_Value=64000000 +RCC.AHB5CLKDivider=DIV2 +RCC.AHB5Freq_Value=32000000 +RCC.AHBFreq_Value=64000000 +RCC.APB1Freq_Value=64000000 +RCC.APB1TimFreq_Value=64000000 +RCC.APB2Freq_Value=64000000 +RCC.APB2TimFreq_Value=64000000 +RCC.APB7Freq_Value=64000000 +RCC.ASFreq_Value=64000000 +RCC.CortexFreq_Value=8000000 +RCC.FCLKCortexFreq_Value=64000000 +RCC.HCLKFreq_Value=64000000 +RCC.HSESYSFreq_VALUE=32000000 +RCC.HSE_VALUE=32000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=64000000 +RCC.I2C3Freq_Value=64000000 +RCC.IPParameters=ADCFreq_Value,AHB4Freq_Value,AHB5CLKDivider,AHB5Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB7Freq_Value,ASFreq_Value,CortexFreq_Value,FCLKCortexFreq_Value,HCLKFreq_Value,HSESYSFreq_VALUE,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,PLLFRACN,PLLM,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSourceVirtual,RNGFreq_Value,RSTFreq_Value,RSTRFFreq_Value,SAESFreq_Value,SPI1Freq_Value,SPI3Freq_Value,SYSCLKFreq_VALUE,SYSCLKSourceVirtual,USART1Freq_Value,USART2Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value +RCC.LPTIM1Freq_Value=64000000 +RCC.LPTIM2Freq_Value=64000000 +RCC.LPUART1Freq_Value=64000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=64000000 +RCC.PLLFRACN=0 +RCC.PLLM=2 +RCC.PLLN=8 +RCC.PLLPoutputFreq_Value=64000000 +RCC.PLLQoutputFreq_Value=64000000 +RCC.PLLRCLKFreq_Value=64000000 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.RNGFreq_Value=16000000 +RCC.RSTFreq_Value=32000 +RCC.RSTRFFreq_Value=32000000 +RCC.SAESFreq_Value=64000000 +RCC.SPI1Freq_Value=64000000 +RCC.SPI3Freq_Value=64000000 +RCC.SYSCLKFreq_VALUE=64000000 +RCC.SYSCLKSourceVirtual=RCC_SYSCLKSOURCE_PLLCLK +RCC.USART1Freq_Value=64000000 +RCC.USART2Freq_Value=64000000 +RCC.VCOInputFreq_Value=16000000 +RCC.VCOOutputFreq_Value=128000000 +USART1.IPParameters=VirtualMode-Asynchronous +USART1.VirtualMode-Asynchronous=VM_ASYNC +VP_CORTEX_M33_NS_VS_Hclk.Mode=Hclk_Mode +VP_CORTEX_M33_NS_VS_Hclk.Signal=CORTEX_M33_NS_VS_Hclk +VP_ICACHE_VS_ICACHE.Mode=DirectMappedCache +VP_ICACHE_VS_ICACHE.Signal=ICACHE_VS_ICACHE +VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg +VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP +VP_PWR_VS_SECSignals.Mode=Security/Privilege +VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=custom diff --git a/WiseEye-LTE.ioc b/WiseEye-LTE.ioc new file mode 100644 index 0000000..c87fc78 --- /dev/null +++ b/WiseEye-LTE.ioc @@ -0,0 +1,249 @@ +#MicroXplorer Configuration settings - do not modify +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M33_NS.userName=CORTEX_M33 +File.Version=6 +GPIO.groupedBy=Expand Peripherals +KeepUserPlacement=false +LPUART1.BaudRate=115200 +LPUART1.IPParameters=BaudRate +MMTAppReg1.MEMORYMAP.AP=RW_priv_only +MMTAppReg1.MEMORYMAP.AppRegionName=RAM +MMTAppReg1.MEMORYMAP.ContextName=CortexM33 +MMTAppReg1.MEMORYMAP.CoreName=ARM Cortex-M33 +MMTAppReg1.MEMORYMAP.DefaultDataRegion=true +MMTAppReg1.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,ContextName,Name,AP +MMTAppReg1.MEMORYMAP.Name=RAM +MMTAppReg1.MEMORYMAP.Size=131072 +MMTAppReg1.MEMORYMAP.StartAddress=0x20000000 +MMTAppReg2.MEMORYMAP.AP=RO_priv_only +MMTAppReg2.MEMORYMAP.AppRegionName=FLASH +MMTAppReg2.MEMORYMAP.Cacheability=WTRA +MMTAppReg2.MEMORYMAP.ContextName=CortexM33 +MMTAppReg2.MEMORYMAP.CoreName=ARM Cortex-M33 +MMTAppReg2.MEMORYMAP.DefaultCodeRegion=true +MMTAppReg2.MEMORYMAP.DefaultDataRegion=false +MMTAppReg2.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,DefaultDataRegion,MemType,ContextName,Name,AP,Cacheability,DefaultCodeRegion +MMTAppReg2.MEMORYMAP.MemType=ROM +MMTAppReg2.MEMORYMAP.Name=FLASH +MMTAppReg2.MEMORYMAP.Size=1048576 +MMTAppReg2.MEMORYMAP.StartAddress=0x08000000 +MMTAppReg3.MEMORYMAP.AppRegionName=RX/TX_RAM_Radio +MMTAppReg3.MEMORYMAP.ContextName=CortexM33 +MMTAppReg3.MEMORYMAP.CoreName=ARM Cortex-M33 +MMTAppReg3.MEMORYMAP.DefaultDataRegion=false +MMTAppReg3.MEMORYMAP.IPParameters=StartAddress,Size,CoreName,SizeUnit,DefaultDataRegion,ContextName,Name,ReservedRegion,Security +MMTAppReg3.MEMORYMAP.Name=RX/TX_RAM_Radio +MMTAppReg3.MEMORYMAP.ReservedRegion=true +MMTAppReg3.MEMORYMAP.Security=NS +MMTAppReg3.MEMORYMAP.Size=16384 +MMTAppReg3.MEMORYMAP.SizeUnit=B +MMTAppReg3.MEMORYMAP.StartAddress=0x48028000 +MMTAppRegionsCount=3 +MMTConfigApplied=false +Mcu.CPN=STM32WBA52CGU6 +Mcu.ContextProject=TrustZoneDisabled +Mcu.Family=STM32WBA +Mcu.IP0=CORTEX_M33_NS +Mcu.IP1=DEBUG +Mcu.IP10=SYS +Mcu.IP11=USART1 +Mcu.IP2=HSEM +Mcu.IP3=ICACHE +Mcu.IP4=LPUART1 +Mcu.IP5=MEMORYMAP +Mcu.IP6=NVIC +Mcu.IP7=PWR +Mcu.IP8=RCC +Mcu.IP9=RTC +Mcu.IPNb=12 +Mcu.Name=STM32WBA52CGUx +Mcu.Package=UFQFPN48 +Mcu.Pin0=PB12 +Mcu.Pin1=PB11 +Mcu.Pin10=PB15 +Mcu.Pin11=OSC_OUT +Mcu.Pin12=OSC_IN +Mcu.Pin13=PA10 +Mcu.Pin14=VP_CORTEX_M33_NS_VS_Hclk +Mcu.Pin15=VP_HSEM_VS_HSEM +Mcu.Pin16=VP_ICACHE_VS_ICACHE +Mcu.Pin17=VP_PWR_VS_SECSignals +Mcu.Pin18=VP_RTC_VS_RTC_Activate +Mcu.Pin19=VP_RTC_VS_RTC_WakeUp_intern +Mcu.Pin2=PA8 +Mcu.Pin20=VP_SYS_VS_Systick +Mcu.Pin21=VP_MEMORYMAP_VS_MEMORYMAP +Mcu.Pin3=PC15-OSC32_OUT +Mcu.Pin4=PC14-OSC32_IN +Mcu.Pin5=PB7 +Mcu.Pin6=PB4 (NJTRST) +Mcu.Pin7=PA14 (JTCK/SWCLK) +Mcu.Pin8=PA13 (JTMS/SWDIO) +Mcu.Pin9=PB0 +Mcu.PinsNb=22 +Mcu.ThirdParty0=STMicroelectronics.X-CUBE-FREERTOS.1.3.1 +Mcu.ThirdPartyNb=1 +Mcu.UserConstants= +Mcu.UserName=STM32WBA52CGUx +MxCube.Version=6.15.0 +MxDb.Version=DB.6.0.150 +NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.ForceEnableDMAVector=true +NVIC.HSEM_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +OSC_IN.Mode=HSE-External-Oscillator +OSC_IN.Signal=RCC_OSC_IN +OSC_OUT.Mode=HSE-External-Oscillator +OSC_OUT.Signal=RCC_OSC_OUT +PA10.GPIOParameters=GPIO_Label +PA10.GPIO_Label=DEBUG_RX +PA10.Locked=true +PA10.Mode=Asynchronous +PA10.Signal=LPUART1_RX +PA13\ (JTMS/SWDIO).Mode=Serial_Wire +PA13\ (JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO +PA14\ (JTCK/SWCLK).Mode=Serial_Wire +PA14\ (JTCK/SWCLK).Signal=DEBUG_JTCK-SWCLK +PA8.GPIOParameters=GPIO_Label +PA8.GPIO_Label=LTE_RX +PA8.Mode=Asynchronous +PA8.Signal=USART1_RX +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=LTE_RST +PB0.Locked=true +PB0.Signal=GPIO_Output +PB11.GPIOParameters=GPIO_Label +PB11.GPIO_Label=DEBUG_TX +PB11.Mode=Asynchronous +PB11.Signal=LPUART1_TX +PB12.GPIOParameters=GPIO_Label +PB12.GPIO_Label=LTE_TX +PB12.Mode=Asynchronous +PB12.Signal=USART1_TX +PB15.GPIOParameters=GPIO_Label +PB15.GPIO_Label=LTE_PWRKEY +PB15.Locked=true +PB15.Signal=GPIO_Output +PB4\ (NJTRST).GPIOParameters=GPIO_Label +PB4\ (NJTRST).GPIO_Label=LTE_EN +PB4\ (NJTRST).Locked=true +PB4\ (NJTRST).Signal=GPIO_Output +PB7.GPIOParameters=GPIO_Label +PB7.GPIO_Label=STATUS_LED +PB7.Locked=true +PB7.Signal=GPIO_Output +PC14-OSC32_IN.Mode=LSE-External-Oscillator +PC14-OSC32_IN.Signal=RCC_OSC32_IN +PC15-OSC32_OUT.Mode=LSE-External-Oscillator +PC15-OSC32_OUT.Signal=RCC_OSC32_OUT +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=true +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=true +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=false +ProjectManager.DeviceId=STM32WBA52CGUx +ProjectManager.FirmwarePackage=STM32Cube FW_WBA V1.7.0 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=2 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain=STM32CubeIDE +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=WiseEye-LTE.ioc +ProjectManager.ProjectName=WiseEye-LTE +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x400 +ProjectManager.TargetToolchain=EWARM V9.20 +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_LPUART1_UART_Init-LPUART1-false-HAL-true,4-SystemPower_Config-PWR-false-HAL-true,5-MX_USART1_UART_Init-USART1-false-HAL-true,6-MX_RTC_Init-RTC-false-HAL-true,7-MX_ICACHE_Init-ICACHE-false-HAL-true,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true,0-MX_HSEM_Init-HSEM-false-HAL-true +RCC.ADCFreq_Value=64000000 +RCC.AHB4Freq_Value=64000000 +RCC.AHB5CLKDivider=DIV2 +RCC.AHB5Freq_Value=32000000 +RCC.AHBFreq_Value=64000000 +RCC.APB1Freq_Value=64000000 +RCC.APB1TimFreq_Value=64000000 +RCC.APB2Freq_Value=64000000 +RCC.APB2TimFreq_Value=64000000 +RCC.APB7Freq_Value=64000000 +RCC.ASFreq_Value=64000000 +RCC.CortexFreq_Value=8000000 +RCC.FCLKCortexFreq_Value=64000000 +RCC.HCLKFreq_Value=64000000 +RCC.HSESYSFreq_VALUE=32000000 +RCC.HSE_VALUE=32000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=64000000 +RCC.I2C3Freq_Value=64000000 +RCC.IPParameters=ADCFreq_Value,AHB4Freq_Value,AHB5CLKDivider,AHB5Freq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB7Freq_Value,ASFreq_Value,CortexFreq_Value,FCLKCortexFreq_Value,HCLKFreq_Value,HSESYSFreq_VALUE,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,PLLFRACN,PLLM,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSourceVirtual,RNGFreq_Value,RSTFreq_Value,RSTRFFreq_Value,RTCFreq_Value,SAESFreq_Value,SPI1Freq_Value,SPI3Freq_Value,SYSCLKFreq_VALUE,SYSCLKSourceVirtual,USART1Freq_Value,USART2Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value +RCC.LPTIM1Freq_Value=64000000 +RCC.LPTIM2Freq_Value=64000000 +RCC.LPUART1Freq_Value=64000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSI_VALUE=32000 +RCC.MCO1PinFreq_Value=64000000 +RCC.PLLFRACN=0 +RCC.PLLM=2 +RCC.PLLN=8 +RCC.PLLPoutputFreq_Value=64000000 +RCC.PLLQoutputFreq_Value=64000000 +RCC.PLLRCLKFreq_Value=64000000 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.RNGFreq_Value=16000000 +RCC.RSTFreq_Value=32000 +RCC.RSTRFFreq_Value=32000000 +RCC.RTCFreq_Value=32000 +RCC.SAESFreq_Value=64000000 +RCC.SPI1Freq_Value=64000000 +RCC.SPI3Freq_Value=64000000 +RCC.SYSCLKFreq_VALUE=64000000 +RCC.SYSCLKSourceVirtual=RCC_SYSCLKSOURCE_PLLCLK +RCC.USART1Freq_Value=64000000 +RCC.USART2Freq_Value=64000000 +RCC.VCOInputFreq_Value=16000000 +RCC.VCOOutputFreq_Value=128000000 +STMicroelectronics.X-CUBE-FREERTOS.1.3.1.CMSISJjRTOS2_Checked=false +STMicroelectronics.X-CUBE-FREERTOS.1.3.1_SwParameter=RTOS2CcCMSISJjRTOS2JjHeap\:HeapIi4;RTOS2CcCMSISJjRTOS2JjCore\:TZIiNonIiSupported; +USART1.IPParameters=VirtualMode-Asynchronous +USART1.VirtualMode-Asynchronous=VM_ASYNC +VP_CORTEX_M33_NS_VS_Hclk.Mode=Hclk_Mode +VP_CORTEX_M33_NS_VS_Hclk.Signal=CORTEX_M33_NS_VS_Hclk +VP_HSEM_VS_HSEM.Mode=HSEM_Activate +VP_HSEM_VS_HSEM.Signal=HSEM_VS_HSEM +VP_ICACHE_VS_ICACHE.Mode=DirectMappedCache +VP_ICACHE_VS_ICACHE.Signal=ICACHE_VS_ICACHE +VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg +VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP +VP_PWR_VS_SECSignals.Mode=Security/Privilege +VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals +VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled +VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate +VP_RTC_VS_RTC_WakeUp_intern.Mode=WakeUp +VP_RTC_VS_RTC_WakeUp_intern.Signal=RTC_VS_RTC_WakeUp_intern +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=custom