From 592d0e2790508e58b3031aee80c2f756ec811917 Mon Sep 17 00:00:00 2001 From: cpq Date: Fri, 15 May 2026 19:13:27 +0100 Subject: [PATCH] Add tutorials --- .../stm32/nucleo_f756zg/cubemx/README.md | 98 ++ .../nucleo_f756zg/cubemx/nucleo_f756zg.ioc | 210 +++++ .../stm32/nucleo_f756zg/minimal/Makefile | 38 + tutorials/stm32/nucleo_f756zg/minimal/hal.c | 125 +++ tutorials/stm32/nucleo_f756zg/minimal/hal.h | 196 ++++ tutorials/stm32/nucleo_f756zg/minimal/link.ld | 21 + tutorials/stm32/nucleo_f756zg/minimal/main.c | 70 ++ .../nucleo_f756zg/minimal/mongoose_config.h | 34 + .../stm32/nucleo_h563zi/cubemx/README.md | 98 ++ .../nucleo_h563zi/cubemx/nucleo_h563zi.ioc | 268 ++++++ .../stm32/nucleo_h563zi/minimal/Makefile | 47 + tutorials/stm32/nucleo_h563zi/minimal/hal.c | 125 +++ tutorials/stm32/nucleo_h563zi/minimal/hal.h | 212 +++++ tutorials/stm32/nucleo_h563zi/minimal/link.ld | 31 + tutorials/stm32/nucleo_h563zi/minimal/main.c | 71 ++ .../nucleo_h563zi/minimal/mongoose_config.h | 44 + .../stm32/nucleo_h723zg/cubemx/README.md | 105 +++ .../nucleo_h723zg/cubemx/nucleo_h723zg.ioc | 225 +++++ .../stm32/nucleo_h723zg/minimal/Makefile | 38 + tutorials/stm32/nucleo_h723zg/minimal/hal.c | 125 +++ tutorials/stm32/nucleo_h723zg/minimal/hal.h | 223 +++++ tutorials/stm32/nucleo_h723zg/minimal/link.ld | 28 + tutorials/stm32/nucleo_h723zg/minimal/main.c | 70 ++ .../nucleo_h723zg/minimal/mongoose_config.h | 35 + .../stm32/nucleo_n657x0_q/cubemx/README.md | 122 +++ .../cubemx/nucleo_n657x0_q.ioc | 880 ++++++++++++++++++ .../MX25UM51245G_STM32N6570-NUCLEO.stldr | Bin 0 -> 1899280 bytes .../stm32/nucleo_n657x0_q/minimal/Makefile | 61 ++ .../stm32/nucleo_n657x0_q/minimal/fsbl.c | 132 +++ .../stm32/nucleo_n657x0_q/minimal/fsbl.ld | 20 + tutorials/stm32/nucleo_n657x0_q/minimal/hal.c | 124 +++ tutorials/stm32/nucleo_n657x0_q/minimal/hal.h | 427 +++++++++ .../stm32/nucleo_n657x0_q/minimal/link.ld | 21 + .../stm32/nucleo_n657x0_q/minimal/main.c | 78 ++ .../nucleo_n657x0_q/minimal/mongoose_config.h | 34 + 35 files changed, 4436 insertions(+) create mode 100644 tutorials/stm32/nucleo_f756zg/cubemx/README.md create mode 100644 tutorials/stm32/nucleo_f756zg/cubemx/nucleo_f756zg.ioc create mode 100644 tutorials/stm32/nucleo_f756zg/minimal/Makefile create mode 100644 tutorials/stm32/nucleo_f756zg/minimal/hal.c create mode 100644 tutorials/stm32/nucleo_f756zg/minimal/hal.h create mode 100644 tutorials/stm32/nucleo_f756zg/minimal/link.ld create mode 100644 tutorials/stm32/nucleo_f756zg/minimal/main.c create mode 100644 tutorials/stm32/nucleo_f756zg/minimal/mongoose_config.h create mode 100644 tutorials/stm32/nucleo_h563zi/cubemx/README.md create mode 100644 tutorials/stm32/nucleo_h563zi/cubemx/nucleo_h563zi.ioc create mode 100644 tutorials/stm32/nucleo_h563zi/minimal/Makefile create mode 100644 tutorials/stm32/nucleo_h563zi/minimal/hal.c create mode 100644 tutorials/stm32/nucleo_h563zi/minimal/hal.h create mode 100644 tutorials/stm32/nucleo_h563zi/minimal/link.ld create mode 100644 tutorials/stm32/nucleo_h563zi/minimal/main.c create mode 100644 tutorials/stm32/nucleo_h563zi/minimal/mongoose_config.h create mode 100644 tutorials/stm32/nucleo_h723zg/cubemx/README.md create mode 100644 tutorials/stm32/nucleo_h723zg/cubemx/nucleo_h723zg.ioc create mode 100644 tutorials/stm32/nucleo_h723zg/minimal/Makefile create mode 100644 tutorials/stm32/nucleo_h723zg/minimal/hal.c create mode 100644 tutorials/stm32/nucleo_h723zg/minimal/hal.h create mode 100644 tutorials/stm32/nucleo_h723zg/minimal/link.ld create mode 100644 tutorials/stm32/nucleo_h723zg/minimal/main.c create mode 100644 tutorials/stm32/nucleo_h723zg/minimal/mongoose_config.h create mode 100644 tutorials/stm32/nucleo_n657x0_q/cubemx/README.md create mode 100644 tutorials/stm32/nucleo_n657x0_q/cubemx/nucleo_n657x0_q.ioc create mode 100755 tutorials/stm32/nucleo_n657x0_q/minimal/MX25UM51245G_STM32N6570-NUCLEO.stldr create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/Makefile create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.c create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.ld create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/hal.c create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/hal.h create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/link.ld create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/main.c create mode 100644 tutorials/stm32/nucleo_n657x0_q/minimal/mongoose_config.h diff --git a/tutorials/stm32/nucleo_f756zg/cubemx/README.md b/tutorials/stm32/nucleo_f756zg/cubemx/README.md new file mode 100644 index 00000000..2ef1fe35 --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/cubemx/README.md @@ -0,0 +1,98 @@ +# Mongoose CubeMX integration + +This is a step-by-step guide on how to bring up a production-grade Web UI +dashboard on STM32 Nucleo-F756ZG development board. + +A pre-configured project .zip is available for download at https://mongoose.ws. +However for those who want to configure the project from scratch, follow the steps +below. + +## Generate project code +- Open the .ioc file in your CubeMX +- Click on "Project Manager" + - If you're using CubeIDE, select "CubeIDE" in the toolchain/IDE dropdown + - If you're using VSCode, select "Cmake" in the toolchain/IDE dropdown + - If you're using Makefile, select "Makefile" in the toolchain/IDE dropdown +- Click "Generate Code" button on the top right + +This should generate project code in this directory the directory where .ioc file lives. +Open this directory in your IDE. + +## Configure .bin generation + +Normally, IDEs generate .elf firmware file, cause it is easier for a debugger +to load it to a device. However, for the firmware OTA update, the .bin file +is required. The .bin file is the firmware image that gets copied to the +beginning of the microcontroller's flash memory and gets executed after the +system boot. + +So, we need to tell the IDE to generate .bin firmware flash image file. + +- If you're using CubeIDE, select Project / Properties / C/C++ build / Settings + / MCU/MPU Post build outputs, enable "Convert to binary file (-O binary)" +- If you're using VSCode, add a section to the end of the top-level `CMakeLists.txt`: +```cmake +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary + ${PROJECT_NAME}.elf + ${PROJECT_NAME}.bin +) +``` + +## Call Mongoose from main.c + + +Edit `Core/Src/main.c` and update the following snippets - notice the `USER CODE BEGIN` / `USER CODE END` placeholders. At the top of the file: + +```c +/* USER CODE BEGIN Includes */ +#include "mongoose_glue.h" +/* USER CODE END Includes */ +``` + +Before the `main()` function: +```c +/* USER CODE BEGIN 0 */ +int _write(int fd, unsigned char *buf, int len) { + HAL_UART_Transmit(&huart3, buf, len, HAL_MAX_DELAY); + return len; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), HAL_GetTick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", HAL_GetTick()); + } + } +} + +// This blocks forever. Call it at the end of main(), or in a +// separate RTOS task. Give that task 8k stack space. +void run_mongoose(void) { + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + } +} +/* USER CODE END 0 */ +``` + +Inside the `main()` function: +```c +/* USER CODE BEGIN WHILE */ +run_mongoose(); // <----------------- Add this line +while (1) +{ + /* USER CODE END WHILE */ +``` + +## Build, flash, test + +Start serial console. +Use STM32CubeProgrammer to flash the firmware. diff --git a/tutorials/stm32/nucleo_f756zg/cubemx/nucleo_f756zg.ioc b/tutorials/stm32/nucleo_f756zg/cubemx/nucleo_f756zg.ioc new file mode 100644 index 00000000..1538131e --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/cubemx/nucleo_f756zg.ioc @@ -0,0 +1,210 @@ +#MicroXplorer Configuration settings - do not modify +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M7.IPParameters=default_mode_Activation +CORTEX_M7.default_mode_Activation=1 +Cesanta.I-CUBE-Mongoose.7.21.7.IPParameters=MongooseJjNetworkingOoCore,MongooseJjWebOoDeviceOoDashboard +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjNetworkingOoCore=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjNetworkingOoCore_Checked=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjWebOoDeviceOoDashboard=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjWebOoDeviceOoDashboard_Checked=true +Cesanta.I-CUBE-Mongoose.7.21.7_SwParameter=MongooseJjNetworkingOoCore\:true;MongooseJjWebOoDeviceOoDashboard\:true;MongooseJjMQTTOoClient\:true; +ETH.IPParameters=MediaInterface +ETH.MediaInterface=HAL_ETH_RMII_MODE +File.Version=6 +GPIO.groupedBy= +KeepUserPlacement=false +Mcu.CPN=STM32F756ZGT6 +Mcu.Family=STM32F7 +Mcu.IP0=CORTEX_M7 +Mcu.IP1=ETH +Mcu.IP2=NVIC +Mcu.IP3=RCC +Mcu.IP4=RNG +Mcu.IP5=SYS +Mcu.IP6=USART3 +Mcu.IPNb=7 +Mcu.Name=STM32F756ZGTx +Mcu.Package=LQFP144 +Mcu.Pin0=PC1 +Mcu.Pin1=PA1 +Mcu.Pin10=PD9 +Mcu.Pin11=PG11 +Mcu.Pin12=PG13 +Mcu.Pin13=PB7 +Mcu.Pin14=VP_RNG_VS_RNG +Mcu.Pin15=VP_SYS_VS_Systick +Mcu.Pin16=VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7 +Mcu.Pin17=VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7 +Mcu.Pin2=PA2 +Mcu.Pin3=PA7 +Mcu.Pin4=PC4 +Mcu.Pin5=PC5 +Mcu.Pin6=PB0 +Mcu.Pin7=PB13 +Mcu.Pin8=PB14 +Mcu.Pin9=PD8 +Mcu.PinsNb=18 +Mcu.ThirdParty0=Cesanta.I-CUBE-Mongoose.7.21.7 +Mcu.ThirdPartyNb=1 +Mcu.UserConstants= +Mcu.UserName=STM32F756ZGTx +MxCube.Version=6.17.0 +MxDb.Version=DB.6.0.170 +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.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA1.Mode=RMII +PA1.Signal=ETH_REF_CLK +PA2.Mode=RMII +PA2.Signal=ETH_MDIO +PA7.Mode=RMII +PA7.Signal=ETH_CRS_DV +PB0.Locked=true +PB0.Signal=GPIO_Output +PB13.Mode=RMII +PB13.Signal=ETH_TXD1 +PB14.Locked=true +PB14.Signal=GPIO_Output +PB7.Locked=true +PB7.Signal=GPIO_Output +PC1.Mode=RMII +PC1.Signal=ETH_MDC +PC4.Mode=RMII +PC4.Signal=ETH_RXD0 +PC5.Mode=RMII +PC5.Signal=ETH_RXD1 +PCC.Checker=false +PCC.Display=Plot\: All Steps +PCC.Line=STM32F7x6 +PCC.MCU=STM32F756ZGTx +PCC.PartNumber=STM32F756ZGTx +PCC.Series=STM32F7 +PCC.Temperature=25 +PCC.Vdd=3.3 +PD8.Locked=true +PD8.Mode=Asynchronous +PD8.Signal=USART3_TX +PD9.Locked=true +PD9.Mode=Asynchronous +PD9.Signal=USART3_RX +PG11.Locked=true +PG11.Mode=RMII +PG11.Signal=ETH_TX_EN +PG13.Locked=true +PG13.Mode=RMII +PG13.Signal=ETH_TXD0 +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32F756ZGTx +ProjectManager.FirmwarePackage=STM32Cube FW_F7 V1.17.4 +ProjectManager.FreePins=false +ProjectManager.FreePinsContext= +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x10000 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=nucleo_f756zg.ioc +ProjectManager.ProjectName=nucleo_f756zg +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x2000 +ProjectManager.TargetToolchain=CMake +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ETH_Init-ETH-false-HAL-true,4-MX_RNG_Init-RNG-false-HAL-true,5-MX_USART3_UART_Init-USART3-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +RCC.AHBFreq_Value=216000000 +RCC.APB1CLKDivider=RCC_HCLK_DIV4 +RCC.APB1Freq_Value=54000000 +RCC.APB1TimFreq_Value=108000000 +RCC.APB2CLKDivider=RCC_HCLK_DIV2 +RCC.APB2Freq_Value=108000000 +RCC.APB2TimFreq_Value=216000000 +RCC.CECFreq_Value=32786.88524590164 +RCC.CortexFreq_Value=216000000 +RCC.EthernetFreq_Value=216000000 +RCC.FCLKCortexFreq_Value=216000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=216000000 +RCC.HSE_VALUE=25000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=54000000 +RCC.I2C2Freq_Value=54000000 +RCC.I2C3Freq_Value=54000000 +RCC.I2C4Freq_Value=54000000 +RCC.I2SFreq_Value=192000000 +RCC.IPParameters=AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CECFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I2SFreq_Value,LCDTFToutputFreq_Value,LPTIM1Freq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLI2SPCLKFreq_Value,PLLI2SQCLKFreq_Value,PLLI2SRCLKFreq_Value,PLLI2SRoutputFreq_Value,PLLM,PLLN,PLLQ,PLLQCLKFreq_Value,PLLQoutputFreq_Value,PLLSAIPCLKFreq_Value,PLLSAIQCLKFreq_Value,PLLSAIRCLKFreq_Value,PLLSAIoutputFreq_Value,RNGFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,UART7Freq_Value,UART8Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBFreq_Value,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAIOutputFreq_Value +RCC.LCDTFToutputFreq_Value=96000000 +RCC.LPTIM1Freq_Value=54000000 +RCC.LSE_VALUE=32768 +RCC.LSI_VALUE=32000 +RCC.MCO2PinFreq_Value=216000000 +RCC.PLLCLKFreq_Value=216000000 +RCC.PLLI2SPCLKFreq_Value=192000000 +RCC.PLLI2SQCLKFreq_Value=192000000 +RCC.PLLI2SRCLKFreq_Value=192000000 +RCC.PLLI2SRoutputFreq_Value=192000000 +RCC.PLLM=8 +RCC.PLLN=216 +RCC.PLLQ=9 +RCC.PLLQCLKFreq_Value=48000000 +RCC.PLLQoutputFreq_Value=48000000 +RCC.PLLSAIPCLKFreq_Value=192000000 +RCC.PLLSAIQCLKFreq_Value=192000000 +RCC.PLLSAIRCLKFreq_Value=192000000 +RCC.PLLSAIoutputFreq_Value=192000000 +RCC.RNGFreq_Value=48000000 +RCC.SAI1Freq_Value=192000000 +RCC.SAI2Freq_Value=192000000 +RCC.SDMMCFreq_Value=216000000 +RCC.SPDIFRXFreq_Value=192000000 +RCC.SYSCLKFreq_VALUE=216000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.UART4Freq_Value=54000000 +RCC.UART5Freq_Value=54000000 +RCC.UART7Freq_Value=54000000 +RCC.UART8Freq_Value=54000000 +RCC.USART1Freq_Value=108000000 +RCC.USART2Freq_Value=54000000 +RCC.USART3Freq_Value=54000000 +RCC.USART6Freq_Value=108000000 +RCC.USBFreq_Value=48000000 +RCC.VCOI2SOutputFreq_Value=384000000 +RCC.VCOInputFreq_Value=2000000 +RCC.VCOOutputFreq_Value=432000000 +RCC.VCOSAIOutputFreq_Value=384000000 +USART3.IPParameters=VirtualMode-Asynchronous +USART3.VirtualMode-Asynchronous=VM_ASYNC +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7.Mode=MongooseJjNetworkingOoCore +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7.Signal=Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7 +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7.Mode=MongooseJjWebOoDeviceOoDashboard +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7.Signal=Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7 +VP_RNG_VS_RNG.Mode=RNG_Activate +VP_RNG_VS_RNG.Signal=RNG_VS_RNG +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=custom diff --git a/tutorials/stm32/nucleo_f756zg/minimal/Makefile b/tutorials/stm32/nucleo_f756zg/minimal/Makefile new file mode 100644 index 00000000..224649a1 --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/minimal/Makefile @@ -0,0 +1,38 @@ +# Copyright (c) 2026 Cesanta Software Limited +# Environment setup: https://mongoose.ws/docs/getting-started/build-environment/ + +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections +CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_f7/Include +CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 $(CFLAGS_EXTRA) +LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nosys.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map + +SOURCES = main.c hal.c +SOURCES += cmsis_f7/Source/Templates/gcc/startup_stm32f756xx.s + +TOP = ../../../.. +CFLAGS += -I$(TOP) +SOURCES += $(TOP)/mongoose.c + +all: firmware.bin + +firmware.elf: cmsis_core cmsis_f7 hal.h link.ld Makefile $(SOURCES) + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@ + +firmware.bin: firmware.elf + arm-none-eabi-objcopy -O binary $< $@ + @echo + @echo "To flash, run 'make flash', or use STM32CubeProgrammer" + +flash: firmware.bin + STM32_Programmer_CLI -c port=swd -e all -w firmware.elf -hardRst + +cmsis_core: + git clone -q -c advice.detachedHead=false --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ + +cmsis_f7: + git clone -q -c advice.detachedHead=false --depth 1 -b v1.2.10 https://github.com/STMicroelectronics/cmsis_device_f7 $@ + +clean: + rm -rf firmware.* diff --git a/tutorials/stm32/nucleo_f756zg/minimal/hal.c b/tutorials/stm32/nucleo_f756zg/minimal/hal.c new file mode 100644 index 00000000..e519bff3 --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/minimal/hal.c @@ -0,0 +1,125 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "hal.h" + +bool hal_timer_expired(volatile uint64_t *t, uint64_t period, uint64_t now) { + uint64_t diff = now - *t; // Wrap-safe elapsed time since last expiry + if (period == 0) return false; // Avoid division by zero + if (diff < period) return false; // Period has not elapsed yet + *t += (diff / period) * period; // Preserve cadence, skip missed periods + return true; +} + +static volatile uint64_t s_ticks; // Milliseconds since boot +void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms + s_ticks++; +} + +uint64_t hal_get_tick(void) { + return s_ticks; +}; + +uint32_t SystemCoreClock = 160000000; +void SystemInit(void) { // Called automatically by startup code + hal_system_init(); // Enable FPU + hal_clock_init(); + SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms +} + +void ExitRun0Mode(void) { +} + +struct stat; +__attribute__((weak)) int _fstat(int fd, struct stat *st) { + (void) fd, (void) st; + return -1; +} + +extern unsigned char _end[]; // End of data section, start of heap. See link.ld +static unsigned char *s_current_heap_end = _end; + +size_t hal_ram_used(void) { + return (size_t) (s_current_heap_end - _end); +} + +size_t hal_ram_free(void) { + unsigned char endofstack; + return (size_t) (&endofstack - s_current_heap_end); +} + +void *_sbrk(int incr) { + unsigned char *prev_heap; + unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256); + prev_heap = s_current_heap_end; + // Check how much space we got from the heap end to the stack end + if (s_current_heap_end + incr > heap_end) return (void *) -1; + s_current_heap_end += incr; + return prev_heap; +} + +__attribute__((weak)) int _open(const char *path) { + (void) path; + return -1; +} + +__attribute__((weak)) int _close(int fd) { + (void) fd; + return -1; +} + +__attribute__((weak)) int _isatty(int fd) { + (void) fd; + return 1; +} + +__attribute__((weak)) int _lseek(int fd, int ptr, int dir) { + (void) fd, (void) ptr, (void) dir; + return 0; +} + +__attribute__((weak)) void _exit(int status) { + (void) status; + for (;;) asm volatile("BKPT #0"); +} + +__attribute__((weak)) void _kill(int pid, int sig) { + (void) pid, (void) sig; +} + +__attribute__((weak)) int _getpid(void) { + return -1; +} + +__attribute__((weak)) int _write(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _read(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _link(const char *a, const char *b) { + (void) a, (void) b; + return -1; +} + +__attribute__((weak)) int _unlink(const char *a) { + (void) a; + return -1; +} + +__attribute__((weak)) int _stat(const char *path, struct stat *st) { + (void) path, (void) st; + return -1; +} + +__attribute__((weak)) int mkdir(const char *path, int mode) { + (void) path, (void) mode; + return -1; +} + +__attribute__((weak)) void _init(void) { +} diff --git a/tutorials/stm32/nucleo_f756zg/minimal/hal.h b/tutorials/stm32/nucleo_f756zg/minimal/hal.h new file mode 100644 index 00000000..9c9c65a7 --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/minimal/hal.h @@ -0,0 +1,196 @@ +// Copyright (c) 2022-2024 Cesanta Software Limited +// https://www.st.com/resource/en/reference_manual/dm00124865-stm32f75xxx-and-stm32f74xxx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf +// https://www.st.com/resource/en/datasheet/stm32f746zg.pdf + +#pragma once + +#include + +#include +#include +#include +#include + +#define BIT(x) (1UL << (x)) +#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set)) +#define PIN(bank, num) ((((bank) - 'A') << 8) | (num)) +#define PINNO(pin) (pin & 255) +#define PINBANK(pin) (pin >> 8) + +#define HAL_ETH_PINS \ + PIN('A', 1), /* ETH_REF_CLK */ \ + PIN('A', 2), /* ETH_MDIO */ \ + PIN('A', 7), /* ETH_CRS_DV */ \ + PIN('C', 1), /* ETH_MDC */ \ + PIN('C', 4), /* ETH_RXD0 */ \ + PIN('C', 5), /* ETH_RXD1 */ \ + PIN('B', 13), /* ETH_TXD1 */ \ + PIN('G', 11), /* ETH_TX_EN */ \ + PIN('G', 13) /* ETH_TXD0 */ + +extern bool hal_timer_expired(volatile uint64_t *t, uint64_t prd, uint64_t now); +extern uint64_t hal_get_tick(void); +extern size_t hal_ram_free(void); +extern size_t hal_ram_used(void); +extern uint32_t SystemCoreClock; + +/* System clock +5.3.3: APB1 clock <= 54MHz; APB2 clock <= 108MHz +3.3.2, Table 5: configure flash latency (WS) in accordance to clock freq +38.4: The AHB clock frequency must be at least 25 MHz when the Ethernet +controller is used */ +enum { + HAL_APB1_PRE = 5 /* AHB clock / 4 */, + HAL_APB2_PRE = 4 /* AHB clock / 2 */ +}; +enum { PLL_HSI = 16, PLL_M = 8, PLL_N = 216, PLL_P = 2 }; // Run at 216 Mhz +#define FLASH_LATENCY 7 +#define SYS_FREQUENCY ((PLL_HSI * PLL_N / PLL_M / PLL_P) * 1000000) +#define APB2_FREQUENCY (SYS_FREQUENCY / (BIT(HAL_APB2_PRE - 3))) +#define APB1_FREQUENCY (SYS_FREQUENCY / (BIT(HAL_APB1_PRE - 3))) + +enum { + HAL_GPIO_MODE_INPUT, + HAL_GPIO_MODE_OUTPUT, + HAL_GPIO_MODE_AF, + HAL_GPIO_MODE_ANALOG +}; +enum { HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_OTYPE_OPEN_DRAIN }; +enum { + HAL_GPIO_SPEED_LOW, + HAL_GPIO_SPEED_MEDIUM, + HAL_GPIO_SPEED_HIGH, + HAL_GPIO_SPEED_INSANE +}; +enum { HAL_GPIO_PULL_NONE, HAL_GPIO_PULL_UP, HAL_GPIO_PULL_DOWN }; +#define HAL_GPIO(N) ((GPIO_TypeDef *) (0x40020000 + 0x400 * (N))) + +static GPIO_TypeDef *hal_gpio_bank(uint16_t pin) { + return HAL_GPIO(PINBANK(pin)); +} +static inline void hal_gpio_toggle(uint16_t pin) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + uint32_t mask = BIT(PINNO(pin)); + gpio->BSRR = mask << (gpio->ODR & mask ? 16 : 0); +} +static inline int hal_gpio_read(uint16_t pin) { + return hal_gpio_bank(pin)->IDR & BIT(PINNO(pin)) ? 1 : 0; +} +static inline void hal_gpio_write(uint16_t pin, bool val) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + gpio->BSRR = BIT(PINNO(pin)) << (val ? 0 : 16); +} +static inline void hal_gpio_init(uint16_t pin, uint8_t mode, uint8_t type, + uint8_t speed, uint8_t pull, uint8_t af) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + uint8_t n = (uint8_t) (PINNO(pin)); + RCC->AHB1ENR |= BIT(PINBANK(pin)); // Enable GPIO clock + CLRSET(gpio->OTYPER, 1UL << n, ((uint32_t) type) << n); + CLRSET(gpio->OSPEEDR, 3UL << (n * 2), ((uint32_t) speed) << (n * 2)); + CLRSET(gpio->PUPDR, 3UL << (n * 2), ((uint32_t) pull) << (n * 2)); + CLRSET(gpio->AFR[n >> 3], 15UL << ((n & 7) * 4), + ((uint32_t) af) << ((n & 7) * 4)); + CLRSET(gpio->MODER, 3UL << (n * 2), ((uint32_t) mode) << (n * 2)); +} +static inline void hal_gpio_input(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, HAL_GPIO_PULL_NONE, 0); +} +static inline void hal_gpio_output(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, HAL_GPIO_PULL_NONE, 0); +} + +static inline void hal_irq_exti_attach(uint16_t pin) { + uint8_t bank = (uint8_t) (PINBANK(pin)), n = (uint8_t) (PINNO(pin)); + SYSCFG->EXTICR[n / 4] &= ~(15UL << ((n % 4) * 4)); + SYSCFG->EXTICR[n / 4] |= (uint32_t) (bank << ((n % 4) * 4)); + EXTI->IMR |= BIT(n); + EXTI->RTSR |= BIT(n); + EXTI->FTSR |= BIT(n); + int irqvec = n < 5 ? 6 + n : n < 10 ? 23 : 40; // IRQ vector index, 10.1.2 + NVIC_SetPriority(irqvec, 3); + NVIC_EnableIRQ(irqvec); +} + +static inline void hal_uart_init(USART_TypeDef *uart, unsigned long baud) { + uint8_t af = 7; // Alternate function + uint16_t rx = 0, tx = 0; // pins + uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1 + + if (uart == USART1) freq = APB2_FREQUENCY, RCC->APB2ENR |= BIT(4); + if (uart == USART2) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(17); + if (uart == USART3) freq = APB1_FREQUENCY, RCC->APB1ENR |= BIT(18); + + if (uart == USART1) tx = PIN('A', 9), rx = PIN('A', 10); + if (uart == USART2) tx = PIN('A', 2), rx = PIN('A', 3); + if (uart == USART3) tx = PIN('D', 8), rx = PIN('D', 9); + + hal_gpio_init(tx, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, 0, af); + hal_gpio_init(rx, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, 0, af); + uart->CR1 = 0; // Disable this UART + uart->BRR = freq / baud; // Set baud rate + uart->CR1 |= BIT(0) | BIT(2) | BIT(3); // Set UE, RE, TE +} +static inline void hal_uart_write_byte(USART_TypeDef *uart, uint8_t byte) { + uart->TDR = byte; + while ((uart->ISR & BIT(7)) == 0) (void) 0; +} +static inline void hal_uart_write_buf(USART_TypeDef *uart, char *buf, + size_t len) { + while (len-- > 0) hal_uart_write_byte(uart, *(uint8_t *) buf++); +} +static inline int hal_uart_read_ready(USART_TypeDef *uart) { + return uart->ISR & BIT(5); // If RXNE bit is set, data is ready +} +static inline uint8_t hal_uart_read_byte(USART_TypeDef *uart) { + return (uint8_t) (uart->RDR & 255); +} + +static inline void hal_rng_init(void) { + RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; + RNG->CR |= RNG_CR_RNGEN; +} +static inline uint32_t hal_rng_read(void) { + while ((RNG->SR & RNG_SR_DRDY) == 0) (void) 0; + return RNG->DR; +} + +// Hw pull-ups on PHY RXD0,1,DV to enable autonegotiation +static inline void hal_ethernet_init(void) { + // Initialise Ethernet. Enable MAC GPIO pins, see + // https://www.farnell.com/datasheets/2014265.pdf section 6.10 + uint16_t pins[] = {HAL_ETH_PINS}; + for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) { + hal_gpio_init(pins[i], HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_INSANE, HAL_GPIO_PULL_NONE, + 11); // 11 is the Ethernet function + } + NVIC_EnableIRQ(ETH_IRQn); // Setup Ethernet IRQ handler + SYSCFG->PMC |= SYSCFG_PMC_MII_RMII_SEL; // Use RMII. Goes first! + RCC->AHB1ENR |= + RCC_AHB1ENR_ETHMACEN | RCC_AHB1ENR_ETHMACTXEN | RCC_AHB1ENR_ETHMACRXEN; +} + +static inline void hal_clock_init(void) { + FLASH->ACR |= FLASH_LATENCY | BIT(8) | BIT(9); // Flash latency, prefetch + RCC->PLLCFGR &= ~((BIT(17) - 1)); // Clear PLL multipliers + RCC->PLLCFGR |= (((PLL_P - 2) / 2) & 3) << 16; // Set PLL_P + RCC->PLLCFGR |= PLL_M | (PLL_N << 6); // Set PLL_M and PLL_N + RCC->CR |= BIT(24); // Enable PLL + while ((RCC->CR & BIT(25)) == 0) (void) 0; // Wait until done + RCC->CFGR = (HAL_APB1_PRE << 10) | (HAL_APB2_PRE << 13); // Set prescalers + RCC->CFGR |= 2; // Set clock source to PLL + while ((RCC->CFGR & 12) == 0) (void) 0; // Wait until done + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; // Enable SYSCFG + SystemCoreClock = SYS_FREQUENCY; // Update SystemCoreClock global var + SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms +} + +static inline void hal_system_init(void) { + SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU + __DSB(); + __ISB(); +} diff --git a/tutorials/stm32/nucleo_f756zg/minimal/link.ld b/tutorials/stm32/nucleo_f756zg/minimal/link.ld new file mode 100644 index 00000000..4232d046 --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/minimal/link.ld @@ -0,0 +1,21 @@ +ENTRY(Reset_Handler); +MEMORY { + flash(rx) : ORIGIN = 0x08000000, LENGTH = 1024k + sram(rwx) : ORIGIN = 0x20000000, LENGTH = 320k +} +_estack = ORIGIN(sram) + LENGTH(sram); + +SECTIONS { + .vectors : { KEEP(*(.isr_vector)) } > flash + .text : { *(.text* .text.*) } > flash + .rodata : { *(.rodata*) } > flash + + /* Note the .iram section, for functions copied to RAM. Required for MG_IRAM OTA support */ + .data : { _sdata = .; *(.first_data) *(.iram .iram* .iram.*) *(.data SORT(.data.*)) _edata = .; } > sram AT > flash + _sidata = LOADADDR(.data); + + .bss : { _sbss = .; *(.bss SORT(.bss.*) COMMON) _ebss = .; } > sram + + . = ALIGN(8); + _end = .; +} diff --git a/tutorials/stm32/nucleo_f756zg/minimal/main.c b/tutorials/stm32/nucleo_f756zg/minimal/main.c new file mode 100644 index 00000000..2f3e99e5 --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/minimal/main.c @@ -0,0 +1,70 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "mongoose.h" +#include "hal.h" + +#define DEBUG_UART USART3 +#define LED1 PIN('B', 0) +#define LED2 PIN('B', 7) +#define LED3 PIN('B', 14) + +// Redirect stdout debug output to UART +int _write(int fd, char *ptr, int len) { + if (fd == 1 || fd == 2) hal_uart_write_buf(DEBUG_UART, ptr, (size_t) len); + return len; +} + +static void blink_task(void) { + static uint64_t blink_timer = 0; + if (hal_timer_expired(&blink_timer, 500, hal_get_tick())) { + hal_gpio_toggle(LED1); + } +} + +uint64_t mg_millis(void) { + return hal_get_tick(); +} + +bool mg_random(void *buf, size_t len) { + for (size_t n = 0; n < len; n += sizeof(uint32_t)) { + uint32_t r = hal_rng_read(); + memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r)); + } + return true; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), hal_get_tick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", + hal_get_tick()); + } + } +} + +int main(void) { + hal_clock_init(); + hal_rng_init(); + hal_gpio_output(LED1); + hal_gpio_output(LED2); + hal_gpio_output(LED3); + hal_uart_init(DEBUG_UART, 115200); + + hal_ethernet_init(); + + // Start a minimal web server + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + blink_task(); + } + + return 0; +} diff --git a/tutorials/stm32/nucleo_f756zg/minimal/mongoose_config.h b/tutorials/stm32/nucleo_f756zg/minimal/mongoose_config.h new file mode 100644 index 00000000..f7dd4eab --- /dev/null +++ b/tutorials/stm32/nucleo_f756zg/minimal/mongoose_config.h @@ -0,0 +1,34 @@ +#pragma once + +// See https://mongoose.ws/docs/getting-started/build-options/ +#define MG_ARCH MG_ARCH_ARMGCC +#define MG_TLS MG_TLS_BUILTIN +#define MG_OTA MG_OTA_STM32F + +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define MG_ENABLE_CUSTOM_RANDOM 1 +#define MG_ENABLE_DRIVER_STM32F 1 +#define MG_ENABLE_PACKED_FS 1 + +// #define MG_DRIVER_MDC_CR 4 // RMII MDC clock divider, from 0 to 4 +// #define MG_TCPIP_PHY_ADDR 0 // PHY address + +// For static IP configuration, define MG_TCPIP_{IP,MASK,GW} +// By default, those are set to zero, meaning that DHCP is used +// +// #define MG_TCPIP_IP MG_IPV4(192, 168, 0, 10) // IP +// #define MG_TCPIP_GW MG_IPV4(192, 168, 0, 1) // Gateway +// #define MG_TCPIP_MASK MG_IPV4(255, 255, 255, 0) // Netmask + +// Construct MAC address from the MCU unique ID +#define MGUID ((uint32_t *) 0x1ff0f420) // Unique 96-bit chip ID +#define MG_SET_MAC_ADDRESS(mac) \ + do { \ + mac[0] = 2; \ + mac[1] = MGUID[0] & 255; \ + mac[2] = (MGUID[0] >> 10) & 255; \ + mac[3] = (MGUID[0] >> 19) & 255; \ + mac[4] = MGUID[1] & 255; \ + mac[5] = MGUID[2] & 255; \ + } while (0) diff --git a/tutorials/stm32/nucleo_h563zi/cubemx/README.md b/tutorials/stm32/nucleo_h563zi/cubemx/README.md new file mode 100644 index 00000000..d3e60b1e --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/cubemx/README.md @@ -0,0 +1,98 @@ +# Mongoose CubeMX integration + +This is a step-by-step guide on how to bring up a production-grade Web UI +dashboard on STM32 Nucleo-H563ZI development board. + +A pre-configured project .zip is available for download at https://mongoose.ws. +However for those who want to configure the project from scratch, follow the steps +below. + + +## Generate project code +- Open the .ioc file in your CubeMX +- Click on "Project Manager" + - If you're using CubeIDE, select "CubeIDE" in the toolchain/IDE dropdown + - If you're using VSCode, select "Cmake" in the toolchain/IDE dropdown + - If you're using Makefile, select "Makefile" in the toolchain/IDE dropdown +- Click "Generate Code" button on the top right + +This should generate project code in this directory the directory where .ioc file lives. +Open this directory in your IDE. + +## Configure .bin generation + +Normally, IDEs generate .elf firmware file, cause it is easier for a debugger +to load it to a device. However, for the firmware OTA update, the .bin file +is required. The .bin file is the firmware image that gets copied to the +beginning of the microcontroller's flash memory and gets executed after the +system boot. + +So, we need to tell the IDE to generate .bin firmware flash image file. + +- If you're using CubeIDE, select Project / Properties / C/C++ build / Settings + / MCU/MPU Post build outputs, enable "Convert to binary file (-O binary)" +- If you're using VSCode, add a section to the end of the top-level `CMakeLists.txt`: +```cmake +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary + ${PROJECT_NAME}.elf + ${PROJECT_NAME}.bin +) +``` + +## Call Mongoose from main.c + +Edit `Core/Src/main.c` and update the following snippets - notice the `USER CODE BEGIN` / `USER CODE END` placeholders. At the top of the file: + +```c +/* USER CODE BEGIN Includes */ +#include "mongoose_glue.h" +/* USER CODE END Includes */ +``` + +Before the `main()` function: +```c +/* USER CODE BEGIN 0 */ +int _write(int fd, unsigned char *buf, int len) { + HAL_UART_Transmit(&huart3, buf, len, HAL_MAX_DELAY); + return len; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), HAL_GetTick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", HAL_GetTick()); + } + } +} + +// This blocks forever. Call it at the end of main(), or in a +// separate RTOS task. Give that task 8k stack space. +void run_mongoose(void) { + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + } +} +/* USER CODE END 0 */ +``` + +Inside the `main()` function: +```c +/* USER CODE BEGIN WHILE */ +run_mongoose(); // <----------------- Add this line +while (1) +{ + /* USER CODE END WHILE */ +``` + +## Build, flash, test + +Start serial console. +Use STM32CubeProgrammer to flash the firmware. diff --git a/tutorials/stm32/nucleo_h563zi/cubemx/nucleo_h563zi.ioc b/tutorials/stm32/nucleo_h563zi/cubemx/nucleo_h563zi.ioc new file mode 100644 index 00000000..89418b61 --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/cubemx/nucleo_h563zi.ioc @@ -0,0 +1,268 @@ +#MicroXplorer Configuration settings - do not modify +BOOTPATH.BootPathName=LEGACY +BOOTPATH.IPParameters=BootPathName +BOOTPATH.UserSelectedBootPath=LEGACY +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M33_NS.IPParameters=default_mode_Activation,Number-Cortex_Memory_Protection_Unit_Region0_OTP_RO_AREAS_Settings +CORTEX_M33_NS.Number-Cortex_Memory_Protection_Unit_Region0_OTP_RO_AREAS_Settings=MPU_REGION_NUMBER0 +CORTEX_M33_NS.default_mode_Activation=1 +CORTEX_M33_NS.userName=CORTEX_M33 +Cesanta.I-CUBE-Mongoose.7.21.7.IPParameters=MongooseJjNetworkingOoCore,MongooseJjWebOoDeviceOoDashboard +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjNetworkingOoCore=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjNetworkingOoCore_Checked=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjWebOoDeviceOoDashboard=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjWebOoDeviceOoDashboard_Checked=true +Cesanta.I-CUBE-Mongoose.7.21.7_SwParameter=MongooseJjNetworkingOoCore\:true;MongooseJjWebOoDeviceOoDashboard\:true; +ETH.IPParameters=MediaInterface +ETH.MediaInterface=HAL_ETH_RMII_MODE +File.Version=6 +GPIO.groupedBy= +KeepUserPlacement=false +MMTAppRegionsCount=0 +MMTConfigApplied=false +MMTSectionSuffix= +Mcu.CPN=STM32H563ZIT6 +Mcu.ContextProject=TrustZoneDisabled +Mcu.Family=STM32H5 +Mcu.IP0=BOOTPATH +Mcu.IP1=CORTEX_M33_NS +Mcu.IP10=USART3 +Mcu.IP2=ETH +Mcu.IP3=ICACHE +Mcu.IP4=MEMORYMAP +Mcu.IP5=NVIC +Mcu.IP6=PWR +Mcu.IP7=RCC +Mcu.IP8=RNG +Mcu.IP9=SYS +Mcu.IPNb=11 +Mcu.Name=STM32H563ZITx +Mcu.Package=LQFP144 +Mcu.Pin0=PF4 +Mcu.Pin1=PC1 +Mcu.Pin10=PD9 +Mcu.Pin11=PG4 +Mcu.Pin12=PG11 +Mcu.Pin13=PG13 +Mcu.Pin14=VP_CORTEX_M33_NS_VS_Hclk +Mcu.Pin15=VP_ICACHE_VS_ICACHE +Mcu.Pin16=VP_PWR_VS_SECSignals +Mcu.Pin17=VP_PWR_VS_LPOM +Mcu.Pin18=VP_RNG_VS_RNG +Mcu.Pin19=VP_SYS_VS_Systick +Mcu.Pin2=PA1 +Mcu.Pin20=VP_BOOTPATH_VS_BOOTPATH +Mcu.Pin21=VP_MEMORYMAP_VS_MEMORYMAP +Mcu.Pin22=VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7 +Mcu.Pin23=VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7 +Mcu.Pin3=PA2 +Mcu.Pin4=PA7 +Mcu.Pin5=PC4 +Mcu.Pin6=PC5 +Mcu.Pin7=PB0 +Mcu.Pin8=PB15 +Mcu.Pin9=PD8 +Mcu.PinsNb=24 +Mcu.ThirdParty0=Cesanta.I-CUBE-Mongoose.7.21.7 +Mcu.ThirdPartyNb=1 +Mcu.UserConstants= +Mcu.UserName=STM32H563ZITx +MxCube.Version=6.17.0 +MxDb.Version=DB.6.0.170 +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.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA1.Mode=RMII +PA1.Signal=ETH_REF_CLK +PA2.Mode=RMII +PA2.Signal=ETH_MDIO +PA7.Mode=RMII +PA7.Signal=ETH_CRS_DV +PB0.Locked=true +PB0.Signal=GPIO_Output +PB15.Mode=RMII +PB15.Signal=ETH_TXD1 +PC1.Mode=RMII +PC1.Signal=ETH_MDC +PC4.Mode=RMII +PC4.Signal=ETH_RXD0 +PC5.Mode=RMII +PC5.Signal=ETH_RXD1 +PCC.Checker=false +PCC.Display=Plot\: All Steps +PCC.Line=STM32H563/H573 +PCC.MCU=STM32H563ZITx +PCC.PartNumber=STM32H563ZITx +PCC.Series=STM32H5 +PCC.Temperature=25 +PCC.Vdd=3.0 +PD8.Locked=true +PD8.Mode=Asynchronous +PD8.Signal=USART3_TX +PD9.Locked=true +PD9.Mode=Asynchronous +PD9.Signal=USART3_RX +PF4.Locked=true +PF4.Signal=GPIO_Output +PG11.Locked=true +PG11.Mode=RMII +PG11.Signal=ETH_TX_EN +PG13.Locked=true +PG13.Mode=RMII +PG13.Signal=ETH_TXD0 +PG4.Locked=true +PG4.Signal=GPIO_Output +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32H563ZITx +ProjectManager.FirmwarePackage=STM32Cube FW_H5 V1.6.0 +ProjectManager.FreePins=false +ProjectManager.FreePinsContext= +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x10000 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=nucleo_h563zi.ioc +ProjectManager.ProjectName=nucleo_h563zi +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x2000 +ProjectManager.TargetToolchain=CMake +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ETH_Init-ETH-false-HAL-true,4-MX_ICACHE_Init-ICACHE-false-HAL-true,5-MX_RNG_Init-RNG-false-HAL-true,6-MX_USART3_UART_Init-USART3-false-HAL-true,0-MX_CORTEX_M33_NS_Init-CORTEX_M33_NS-false-HAL-true,0-MX_PWR_Init-PWR-false-HAL-true +RCC.ADCFreq_Value=250000000 +RCC.AHBFreq_Value=250000000 +RCC.APB1Freq_Value=250000000 +RCC.APB1TimFreq_Value=250000000 +RCC.APB2Freq_Value=250000000 +RCC.APB2TimFreq_Value=250000000 +RCC.APB3Freq_Value=250000000 +RCC.CECFreq_Value=32000 +RCC.CKPERFreq_Value=32000000 +RCC.CRSFreq_Value=48000000 +RCC.CSI_VALUE=4000000 +RCC.CortexFreq_Value=250000000 +RCC.DACFreq_Value=32768 +RCC.EPOD_VALUE=4000000 +RCC.ETHFreq_Value=250000000 +RCC.FCLKCortexFreq_Value=250000000 +RCC.FDCANFreq_Value=25000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=250000000 +RCC.HSE_VALUE=25000000 +RCC.HSI48_VALUE=48000000 +RCC.HSI_VALUE=64000000 +RCC.I2C1Freq_Value=250000000 +RCC.I2C2Freq_Value=250000000 +RCC.I2C3Freq_Value=250000000 +RCC.I2C4Freq_Value=250000000 +RCC.I3C1Freq_Value=250000000 +RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,CECFreq_Value,CKPERFreq_Value,CRSFreq_Value,CSI_VALUE,CortexFreq_Value,DACFreq_Value,EPOD_VALUE,ETHFreq_Value,FCLKCortexFreq_Value,FDCANFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I3C1Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM3Freq_Value,LPTIM4Freq_Value,LPTIM5Freq_Value,LPTIM6Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_VALUE,LSIRC_VALUE,MCO1PinFreq_Value,MCO2PinFreq_Value,OCTOSPIMFreq_Value,PLL2FRACN,PLL2PoutputFreq_Value,PLL2QoutputFreq_Value,PLL2RoutputFreq_Value,PLL3FRACN,PLL3PoutputFreq_Value,PLL3QoutputFreq_Value,PLL3RoutputFreq_Value,PLLFRACN,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PWRFreq_Value,RNGFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMC1Freq_Value,SDMMC2Freq_Value,SPI1Freq_Value,SPI2Freq_Value,SPI3Freq_Value,SPI4Freq_Value,SPI5Freq_Value,SPI6Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART12Freq_Value,UART4Freq_Value,UART5Freq_Value,UART7Freq_Value,UART8Freq_Value,UART9Freq_Value,UCPD1outputFreq_Value,USART10Freq_Value,USART11Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,USBFreq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOPLL2OutputFreq_Value,VCOPLL3OutputFreq_Value +RCC.LPTIM1Freq_Value=250000000 +RCC.LPTIM2Freq_Value=250000000 +RCC.LPTIM3Freq_Value=250000000 +RCC.LPTIM4Freq_Value=250000000 +RCC.LPTIM5Freq_Value=250000000 +RCC.LPTIM6Freq_Value=250000000 +RCC.LPUART1Freq_Value=250000000 +RCC.LSCOPinFreq_Value=32000 +RCC.LSE_VALUE=32768 +RCC.LSIRC_VALUE=32000 +RCC.MCO1PinFreq_Value=32000000 +RCC.MCO2PinFreq_Value=250000000 +RCC.OCTOSPIMFreq_Value=250000000 +RCC.PLL2FRACN=0 +RCC.PLL2PoutputFreq_Value=258000000 +RCC.PLL2QoutputFreq_Value=258000000 +RCC.PLL2RoutputFreq_Value=258000000 +RCC.PLL3FRACN=0 +RCC.PLL3PoutputFreq_Value=258000000 +RCC.PLL3QoutputFreq_Value=258000000 +RCC.PLL3RoutputFreq_Value=258000000 +RCC.PLLFRACN=0 +RCC.PLLN=125 +RCC.PLLPoutputFreq_Value=250000000 +RCC.PLLQoutputFreq_Value=250000000 +RCC.PWRFreq_Value=250000000 +RCC.RNGFreq_Value=48000000 +RCC.SAI1Freq_Value=258000000 +RCC.SAI2Freq_Value=258000000 +RCC.SDMMC1Freq_Value=250000000 +RCC.SDMMC2Freq_Value=250000000 +RCC.SPI1Freq_Value=250000000 +RCC.SPI2Freq_Value=250000000 +RCC.SPI3Freq_Value=250000000 +RCC.SPI4Freq_Value=250000000 +RCC.SPI5Freq_Value=250000000 +RCC.SPI6Freq_Value=250000000 +RCC.SYSCLKFreq_VALUE=250000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.UART12Freq_Value=250000000 +RCC.UART4Freq_Value=250000000 +RCC.UART5Freq_Value=250000000 +RCC.UART7Freq_Value=250000000 +RCC.UART8Freq_Value=250000000 +RCC.UART9Freq_Value=250000000 +RCC.UCPD1outputFreq_Value=8000000 +RCC.USART10Freq_Value=250000000 +RCC.USART11Freq_Value=250000000 +RCC.USART1Freq_Value=250000000 +RCC.USART2Freq_Value=250000000 +RCC.USART3Freq_Value=250000000 +RCC.USART6Freq_Value=250000000 +RCC.USBFreq_Value=48000000 +RCC.VCOInput2Freq_Value=4000000 +RCC.VCOInput3Freq_Value=4000000 +RCC.VCOInputFreq_Value=4000000 +RCC.VCOOutputFreq_Value=500000000 +RCC.VCOPLL2OutputFreq_Value=516000000 +RCC.VCOPLL3OutputFreq_Value=516000000 +USART3.IPParameters=VirtualMode-Asynchronous +USART3.VirtualMode-Asynchronous=VM_ASYNC +VP_BOOTPATH_VS_BOOTPATH.Mode=BP_Activate +VP_BOOTPATH_VS_BOOTPATH.Signal=BOOTPATH_VS_BOOTPATH +VP_CORTEX_M33_NS_VS_Hclk.Mode=Hclk_Mode +VP_CORTEX_M33_NS_VS_Hclk.Signal=CORTEX_M33_NS_VS_Hclk +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7.Mode=MongooseJjNetworkingOoCore +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7.Signal=Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7 +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7.Mode=MongooseJjWebOoDeviceOoDashboard +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7.Signal=Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7 +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_LPOM.Mode=PowerOptimisation +VP_PWR_VS_LPOM.Signal=PWR_VS_LPOM +VP_PWR_VS_SECSignals.Mode=Security/Privilege +VP_PWR_VS_SECSignals.Signal=PWR_VS_SECSignals +VP_RNG_VS_RNG.Mode=RNG_Activate +VP_RNG_VS_RNG.Signal=RNG_VS_RNG +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=custom diff --git a/tutorials/stm32/nucleo_h563zi/minimal/Makefile b/tutorials/stm32/nucleo_h563zi/minimal/Makefile new file mode 100644 index 00000000..7b0c37f9 --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/minimal/Makefile @@ -0,0 +1,47 @@ +# Copyright (c) 2026 Cesanta Software Limited +# Environment setup: https://mongoose.ws/docs/getting-started/build-environment/ + +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections +CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_h5/Include +CFLAGS += -mcpu=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard $(CFLAGS_EXTRA) +LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nosys.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map + +SOURCES = main.c hal.c +SOURCES += cmsis_h5/Source/Templates/gcc/startup_stm32h563xx.s + +TOP = ../../../.. +CFLAGS += -I$(TOP) +SOURCES += $(TOP)/mongoose.c + +all: firmware.bin + +firmware.elf: cmsis_core cmsis_h5 hal.h link.ld Makefile $(SOURCES) + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@ + +firmware.bin: firmware.elf + arm-none-eabi-objcopy -O binary $< $@ + @echo + @echo "To flash, run 'make flash', or use STM32CubeProgrammer" + +flash: firmware.bin + STM32_Programmer_CLI -c port=swd mode=UR -w firmware.elf -hardRst + +gdb: firmware.elf + arm-none-eabi-gdb -q $^ -ex='set confirm off' -ex 'target remote :61234' + +# Directory where STM32_Programmer_CLI binary lives +CUBEPROG_DIR ?= $(dir $(shell which STM32_Programmer_CLI)) +gdb_server: + ST-LINK_gdbserver --port-number 61234 --log-level 1 --swd --verify --stm32cubeprogrammer-path $(CUBEPROG_DIR) --apid 1 --initialize-reset + + +cmsis_core: + git clone -q -c advice.detachedHead=false --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ + +cmsis_h5: + git clone -q -c advice.detachedHead=false --depth 1 -b v1.6.0 https://github.com/STMicroelectronics/cmsis-device-h5 $@ + +clean: + rm -rf firmware.* diff --git a/tutorials/stm32/nucleo_h563zi/minimal/hal.c b/tutorials/stm32/nucleo_h563zi/minimal/hal.c new file mode 100644 index 00000000..e519bff3 --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/minimal/hal.c @@ -0,0 +1,125 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "hal.h" + +bool hal_timer_expired(volatile uint64_t *t, uint64_t period, uint64_t now) { + uint64_t diff = now - *t; // Wrap-safe elapsed time since last expiry + if (period == 0) return false; // Avoid division by zero + if (diff < period) return false; // Period has not elapsed yet + *t += (diff / period) * period; // Preserve cadence, skip missed periods + return true; +} + +static volatile uint64_t s_ticks; // Milliseconds since boot +void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms + s_ticks++; +} + +uint64_t hal_get_tick(void) { + return s_ticks; +}; + +uint32_t SystemCoreClock = 160000000; +void SystemInit(void) { // Called automatically by startup code + hal_system_init(); // Enable FPU + hal_clock_init(); + SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms +} + +void ExitRun0Mode(void) { +} + +struct stat; +__attribute__((weak)) int _fstat(int fd, struct stat *st) { + (void) fd, (void) st; + return -1; +} + +extern unsigned char _end[]; // End of data section, start of heap. See link.ld +static unsigned char *s_current_heap_end = _end; + +size_t hal_ram_used(void) { + return (size_t) (s_current_heap_end - _end); +} + +size_t hal_ram_free(void) { + unsigned char endofstack; + return (size_t) (&endofstack - s_current_heap_end); +} + +void *_sbrk(int incr) { + unsigned char *prev_heap; + unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256); + prev_heap = s_current_heap_end; + // Check how much space we got from the heap end to the stack end + if (s_current_heap_end + incr > heap_end) return (void *) -1; + s_current_heap_end += incr; + return prev_heap; +} + +__attribute__((weak)) int _open(const char *path) { + (void) path; + return -1; +} + +__attribute__((weak)) int _close(int fd) { + (void) fd; + return -1; +} + +__attribute__((weak)) int _isatty(int fd) { + (void) fd; + return 1; +} + +__attribute__((weak)) int _lseek(int fd, int ptr, int dir) { + (void) fd, (void) ptr, (void) dir; + return 0; +} + +__attribute__((weak)) void _exit(int status) { + (void) status; + for (;;) asm volatile("BKPT #0"); +} + +__attribute__((weak)) void _kill(int pid, int sig) { + (void) pid, (void) sig; +} + +__attribute__((weak)) int _getpid(void) { + return -1; +} + +__attribute__((weak)) int _write(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _read(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _link(const char *a, const char *b) { + (void) a, (void) b; + return -1; +} + +__attribute__((weak)) int _unlink(const char *a) { + (void) a; + return -1; +} + +__attribute__((weak)) int _stat(const char *path, struct stat *st) { + (void) path, (void) st; + return -1; +} + +__attribute__((weak)) int mkdir(const char *path, int mode) { + (void) path, (void) mode; + return -1; +} + +__attribute__((weak)) void _init(void) { +} diff --git a/tutorials/stm32/nucleo_h563zi/minimal/hal.h b/tutorials/stm32/nucleo_h563zi/minimal/hal.h new file mode 100644 index 00000000..d66a7620 --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/minimal/hal.h @@ -0,0 +1,212 @@ +// Copyright (c) 2022-2026 Cesanta Software Limited +// All rights reserved +// +// Datasheet: RM0481, devboard manual: UM3115 +// https://www.st.com/resource/en/reference_manual/rm0481-stm32h563h573-and-stm32h562-armbased-32bit-mcus-stmicroelectronics.pdf +// Alternate functions: https://www.st.com/resource/en/datasheet/stm32h563vi.pdf + +#pragma once + +#include + +#include +#include +#include +#include +#include + +void hal_init(void); +size_t hal_ram_free(void); +size_t hal_ram_used(void); +bool hal_timer_expired(volatile uint64_t *t, uint64_t prd, uint64_t now); +uint64_t hal_get_tick(void); + +#define BIT(x) (1UL << (x)) +#define CLRSET(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK) +#define PIN(bank, num) ((((bank) - 'A') << 8) | (num)) +#define PINNO(pin) (pin & 255) +#define PINBANK(pin) (pin >> 8) + +#define HAL_ETH_PINS \ + PIN('A', 1), /* ETH_REF_CLK */ \ + PIN('A', 2), /* ETH_MDIO */ \ + PIN('A', 7), /* ETH_CRS_DV */ \ + PIN('B', 15), /* ETH_TXD1 */ \ + PIN('C', 1), /* ETH_MDC */ \ + PIN('C', 4), /* ETH_RXD0 */ \ + PIN('C', 5), /* ETH_RXD1 */ \ + PIN('G', 11), /* ETH_TX_EN */ \ + PIN('G', 13) /* ETH_TXD0 */ + +// System clock (11.4, Figure 48; 11.4.5, Figure 51; 11.4.8 +// SYS_FREQUENCY <= 250 MHz; (CLOCK_FREQUENCY / HPRE) ; hclk = SYS_FREQUENCY +// APB clocks <= 250 MHz. Configure flash latency (WS) in accordance to hclk +// freq (7.3.4, Table 37) +enum { + HAL_HPRE = 7, // register value, divisor value = BIT(value - 7) = / 1 + HAL_PPRE1 = 4, // register values, divisor value = BIT(value - 3) = / 2 + HAL_PPRE2 = 4, + HAL_PPRE3 = 4, +}; +// Make sure your chip package uses the internal LDO, otherwise set PLL1_N = 200 +enum { PLL1_HSI = 64, PLL1_M = 32, PLL1_N = 250, PLL1_P = 2 }; +#define SYS_FREQUENCY \ + ((PLL1_HSI * PLL1_N / PLL1_M / PLL1_P / (BIT(HAL_HPRE - 7))) * 1000000) +#define AHB_FREQUENCY SYS_FREQUENCY +#define APB2_FREQUENCY (AHB_FREQUENCY / (BIT(HAL_PPRE2 - 3))) +#define APB1_FREQUENCY (AHB_FREQUENCY / (BIT(HAL_PPRE1 - 3))) + +static inline void spin(volatile uint32_t n) { + while (n--) (void) 0; +} + +enum { HAL_GPIO_MODE_INPUT, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_MODE_AF, HAL_GPIO_MODE_ANALOG }; +enum { HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_OTYPE_OPEN_DRAIN }; +enum { HAL_GPIO_SPEED_LOW, HAL_GPIO_SPEED_MEDIUM, HAL_GPIO_SPEED_HIGH, HAL_GPIO_SPEED_INSANE }; +enum { HAL_GPIO_PULL_NONE, HAL_GPIO_PULL_UP, HAL_GPIO_PULL_DOWN }; + +#define HAL_GPIO(N) ((GPIO_TypeDef *) ((GPIOA_BASE_NS) + 0x400 * (N))) + +static GPIO_TypeDef *hal_gpio_bank(uint16_t pin) { + return HAL_GPIO(PINBANK(pin)); +} +static inline void hal_gpio_toggle(uint16_t pin) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + uint32_t mask = BIT(PINNO(pin)); + gpio->BSRR = mask << (gpio->ODR & mask ? 16 : 0); +} +static inline int hal_gpio_read(uint16_t pin) { + return hal_gpio_bank(pin)->IDR & BIT(PINNO(pin)) ? 1 : 0; +} +static inline void hal_gpio_write(uint16_t pin, bool val) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + gpio->BSRR = BIT(PINNO(pin)) << (val ? 0 : 16); +} +static inline void hal_gpio_init(uint16_t pin, uint8_t mode, uint8_t type, + uint8_t speed, uint8_t pull, uint8_t af) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + uint8_t n = (uint8_t) (PINNO(pin)); + RCC->AHB2ENR |= BIT(PINBANK(pin)); // Enable GPIO clock + CLRSET(gpio->OTYPER, 1UL << n, ((uint32_t) type) << n); + CLRSET(gpio->OSPEEDR, 3UL << (n * 2), ((uint32_t) speed) << (n * 2)); + CLRSET(gpio->PUPDR, 3UL << (n * 2), ((uint32_t) pull) << (n * 2)); + CLRSET(gpio->AFR[n >> 3], 15UL << ((n & 7) * 4), + ((uint32_t) af) << ((n & 7) * 4)); + CLRSET(gpio->MODER, 3UL << (n * 2), ((uint32_t) mode) << (n * 2)); +} +static inline void hal_gpio_input(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, + HAL_GPIO_PULL_NONE, 0); +} +static inline void hal_gpio_output(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, + HAL_GPIO_PULL_NONE, 0); +} + +static inline bool hal_uart_init(USART_TypeDef *uart, uint16_t tx_pin, + uint16_t rx_pin, unsigned long baud) { + uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1 + + if (uart == USART1) { + freq = APB2_FREQUENCY, RCC->APB2ENR |= RCC_APB2ENR_USART1EN; + } else if (uart == USART2) { + freq = APB1_FREQUENCY, RCC->APB1LENR |= RCC_APB1LENR_USART2EN; + } else if (uart == USART3) { + freq = APB1_FREQUENCY, RCC->APB1LENR |= RCC_APB1LENR_USART3EN; + } else { + return false; + } + hal_gpio_init(tx_pin, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, 0, 7U); + hal_gpio_init(rx_pin, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, 0, 7U); + uart->CR1 = 0; // Disable UART + uart->BRR = freq / baud; // Set baud rate + uart->CR1 = USART_CR1_RE | USART_CR1_TE; // Set mode to TX & RX + uart->CR1 |= USART_CR1_UE; // Enable UART + return true; +} +static inline void hal_uart_write_byte(USART_TypeDef *uart, uint8_t byte) { + uart->TDR = byte; + while ((uart->ISR & BIT(7)) == 0) spin(1); +} +static inline void hal_uart_write_buf(USART_TypeDef *uart, char *buf, size_t len) { + while (len-- > 0) hal_uart_write_byte(uart, *(uint8_t *) buf++); +} +static inline int hal_uart_read_ready(USART_TypeDef *uart) { + return uart->ISR & BIT(5); // If RXNE bit is set, data is ready +} +static inline uint8_t hal_uart_read_byte(USART_TypeDef *uart) { + return (uint8_t) (uart->RDR & 255); +} + +static inline void hal_rng_init(void) { + RCC->CCIPR5 |= RCC_CCIPR5_RNGSEL_0; // RNG clock source pll1_q_ck + RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; // Enable RNG clock + RNG->CR |= RNG_CR_RNGEN; // Enable RNG +} +static inline uint32_t hal_rng_read(void) { + while ((RNG->SR & RNG_SR_DRDY) == 0) spin(1); + return RNG->DR; +} + +static inline bool hal_ldo_is_on(void) { + return (PWR->SCCR & PWR_SCCR_LDOEN) == PWR_SCCR_LDOEN; +} + +// Hw pull-ups on PHY RXD0,1,DV to enable autonegotiation +static inline void hal_ethernet_init(void) { + // Initialise Ethernet. Enable MAC GPIO pins, see UM3115 section 10.7 + uint16_t pins[] = {HAL_ETH_PINS}; + for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) { + hal_gpio_init(pins[i], HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_INSANE, + HAL_GPIO_PULL_NONE, 11); // 11 is the Ethernet function + } + NVIC_EnableIRQ(ETH_IRQn); // Setup Ethernet IRQ handler + RCC->APB3ENR |= RCC_APB3ENR_SBSEN; // Enable SBS clock + CLRSET(SBS->PMCR, SBS_PMCR_ETH_SEL_PHY, SBS_PMCR_ETH_SEL_PHY_2); // RMII + RCC->AHB1ENR |= RCC_AHB1ENR_ETHEN | RCC_AHB1ENR_ETHRXEN | RCC_AHB1ENR_ETHTXEN; +} + +#define UUID ((uint32_t *) UID_BASE) // Unique 96-bit chip ID. TRM 59.1 + +// Helper macro for MAC generation, byte reads not allowed +#define GENERATE_LOCALLY_ADMINISTERED_MAC() \ + { \ + 2, UUID[0] & 255, (UUID[0] >> 10) & 255, (UUID[0] >> 19) & 255, \ + UUID[1] & 255, UUID[2] & 255 \ + } + +static inline void hal_system_init(void) { + SCB->CPACR |= ((3UL << 20U) | (3UL << 22U)); // Enable FPU + __DSB(); + __ISB(); +} + +static inline void hal_clock_init(void) { + // Set flash latency. RM0481, section 7.11.1, section 7.3.4 table 37 + CLRSET(FLASH->ACR, (FLASH_ACR_WRHIGHFREQ_Msk | FLASH_ACR_LATENCY_Msk), + FLASH_ACR_LATENCY_5WS | FLASH_ACR_WRHIGHFREQ_1); + + if (hal_ldo_is_on()) { + PWR->VOSCR = PWR_VOSCR_VOS_0 | PWR_VOSCR_VOS_1; // Select VOS0 + } else { + PWR->VOSCR = PWR_VOSCR_VOS_1; // Select VOS1 + } + uint32_t f = PWR->VOSCR; // fake read to wait for bus clocking + while ((PWR->VOSSR & PWR_VOSSR_ACTVOSRDY) == 0) spin(1); + (void) f; + RCC->CR = RCC_CR_HSION; // Clear HSI clock divisor + while ((RCC->CR & RCC_CR_HSIRDY) == 0) spin(1); // Wait until done + RCC->CFGR2 = (HAL_PPRE3 << 12) | (HAL_PPRE2 << 8) | (HAL_PPRE1 << 4) | (HAL_HPRE << 0); + RCC->PLL1DIVR = + ((PLL1_P - 1) << 9) | ((PLL1_N - 1) << 0); // Set PLL1_P PLL1_N + // Enable P and Q divider outputs; set PLL1_M, select HSI as source, + // !PLL1VCOSEL, PLL1RGE=0 + RCC->PLL1CFGR = + RCC_PLL1CFGR_PLL1QEN | RCC_PLL1CFGR_PLL1PEN | (PLL1_M << 8) | (1 << 0); + RCC->CR |= RCC_CR_PLL1ON; // Enable PLL1 + while ((RCC->CR & RCC_CR_PLL1RDY) == 0) spin(1); // Wait until done + RCC->CFGR1 |= (3 << 0); // Set clock source to PLL1 + while ((RCC->CFGR1 & (7 << 3)) != (3 << 3)) spin(1); // Wait until done + + SystemCoreClock = SYS_FREQUENCY; +} diff --git a/tutorials/stm32/nucleo_h563zi/minimal/link.ld b/tutorials/stm32/nucleo_h563zi/minimal/link.ld new file mode 100644 index 00000000..fac73050 --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/minimal/link.ld @@ -0,0 +1,31 @@ +ENTRY(Reset_Handler); +MEMORY { + flash(rx) : ORIGIN = 0x08000000, LENGTH = 2048k + sram(rwx) : ORIGIN = 0x20000000, LENGTH = 640k +} +_estack = ORIGIN(sram) + LENGTH(sram); /* End of RAM. stack points here */ +_sstack = _estack - 4098; + +SECTIONS { + .vectors : { KEEP(*(.isr_vector)) } > flash + .text : { *(.text* .text.*) } > flash + .rodata : { *(.rodata*) } > flash + + .data : { + _sdata = .; + *(.first_data) + *(.ram) + *(.data SORT(.data.*)) + _edata = .; + } > sram AT > flash + _sidata = LOADADDR(.data); + + .bss : { + _sbss = .; + *(.bss SORT(.bss.*) COMMON) + _ebss = .; + } > sram + + . = ALIGN(8); + _end = .; +} diff --git a/tutorials/stm32/nucleo_h563zi/minimal/main.c b/tutorials/stm32/nucleo_h563zi/minimal/main.c new file mode 100644 index 00000000..a64d0205 --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/minimal/main.c @@ -0,0 +1,71 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "hal.h" +#include "mongoose.h" + +#define DEBUG_UART USART3 +#define DEBUG_UART_TX_PIN PIN('D', 8) +#define DEBUG_UART_RX_PIN PIN('D', 9) + +#define LED_1 PIN('B', 0) // On-board LED pin (green) +#define LED_2 PIN('F', 4) // On-board LED pin (yellow) +#define LED_3 PIN('G', 4) // On-board LED pin (red) + +// Redirect stdout debug output to UART +int _write(int fd, char *ptr, int len) { + if (fd == 1 || fd == 2) hal_uart_write_buf(DEBUG_UART, ptr, (size_t) len); + return len; +} + +static void blink_task(void) { + static uint64_t blink_timer = 0; + if (hal_timer_expired(&blink_timer, 500, hal_get_tick())) { + hal_gpio_toggle(LED_1); + } +} + +uint64_t mg_millis(void) { + return hal_get_tick(); +} + +bool mg_random(void *buf, size_t len) { + for (size_t n = 0; n < len; n += sizeof(uint32_t)) { + uint32_t r = hal_rng_read(); + memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r)); + } + return true; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), hal_get_tick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", hal_get_tick()); + } + } +} + +int main(void) { + hal_uart_init(DEBUG_UART, DEBUG_UART_TX_PIN, DEBUG_UART_RX_PIN, 115200); + hal_rng_init(); + hal_gpio_output(LED_1); + hal_gpio_output(LED_2); + hal_gpio_output(LED_3); + + hal_ethernet_init(); + + // Start a minimal web server + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + blink_task(); + } + + return 0; +} diff --git a/tutorials/stm32/nucleo_h563zi/minimal/mongoose_config.h b/tutorials/stm32/nucleo_h563zi/minimal/mongoose_config.h new file mode 100644 index 00000000..dc0ca30b --- /dev/null +++ b/tutorials/stm32/nucleo_h563zi/minimal/mongoose_config.h @@ -0,0 +1,44 @@ +#pragma once + +// See https://mongoose.ws/documentation/#build-options +#define MG_ARCH MG_ARCH_ARMGCC +#define MG_OTA MG_OTA_STM32H5 +#define MG_TLS MG_TLS_BUILTIN +#define MG_IO_SIZE 2048 + +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define MG_ENABLE_CUSTOM_RANDOM 1 +#define MG_ENABLE_PACKED_FS 1 +#define MG_ENABLE_DRIVER_STM32H 1 + +// #define MG_DRIVER_MDC_CR 4 // RMII MDC clock divider, from 0 to 4 +// #define MG_TCPIP_PHY_ADDR 0 // PHY address + +// For static IP configuration, define MG_TCPIP_{IP,MASK,GW} +// By default, those are set to zero, meaning that DHCP is used +// +// #define MG_TCPIP_IP MG_IPV4(192, 168, 0, 10) +// #define MG_TCPIP_GW MG_IPV4(192, 168, 0, 1) +// #define MG_TCPIP_MASK MG_IPV4(255, 255, 255, 0) + +// Set custom MAC address. By default, it is randomly generated +// Using a build-time constant: +// #define MG_SET_MAC_ADDRESS(mac) do { mac[0] = 2; mac[1] = 3; mac[2] = 4; mac[3] = 5; mac[4] = 6; mac[5] = 7; } while (0) +// +// Using custom function: +// extern void my_function(unsigned char *mac); +// #define MG_SET_MAC_ADDRESS(mac) my_function(mac) + +// Construct MAC address from the MCU unique ID. It is defined in the +// ST CMSIS header as UID_BASE +#define MGUID ((uint32_t *) 0x08fff800) // Unique 96-bit chip ID +#define MG_SET_MAC_ADDRESS(mac) \ + do { \ + mac[0] = 2; \ + mac[1] = MGUID[0] & 255; \ + mac[2] = (MGUID[0] >> 10) & 255; \ + mac[3] = (MGUID[0] >> 19) & 255; \ + mac[4] = MGUID[1] & 255; \ + mac[5] = MGUID[2] & 255; \ + } while (0) diff --git a/tutorials/stm32/nucleo_h723zg/cubemx/README.md b/tutorials/stm32/nucleo_h723zg/cubemx/README.md new file mode 100644 index 00000000..adce66c2 --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/cubemx/README.md @@ -0,0 +1,105 @@ +# Mongoose CubeMX integration + +This is a step-by-step guide on how to bring up a production-grade Web UI +dashboard on STM32 Nucleo-H723ZG development board. + +A pre-configured project .zip is available for download at https://mongoose.ws. +However for those who want to configure the project from scratch, follow the steps +below. + + +## Generate project code +- Open the .ioc file in your CubeMX +- Click on "Project Manager" + - If you're using CubeIDE, select "CubeIDE" in the toolchain/IDE dropdown + - If you're using VSCode, select "Cmake" in the toolchain/IDE dropdown + - If you're using Makefile, select "Makefile" in the toolchain/IDE dropdown +- Click "Generate Code" button on the top right + +This should generate project code in this directory the directory where .ioc file lives. +Open this directory in your IDE. + +## Configure .bin generation + +Normally, IDEs generate .elf firmware file, cause it is easier for a debugger +to load it to a device. However, for the firmware OTA update, the .bin file +is required. The .bin file is the firmware image that gets copied to the +beginning of the microcontroller's flash memory and gets executed after the +system boot. + +So, we need to tell the IDE to generate .bin firmware flash image file. + +- If you're using CubeIDE, select Project / Properties / C/C++ build / Settings + / MCU/MPU Post build outputs, enable "Convert to binary file (-O binary)" +- If you're using VSCode, add a section to the end of the top-level `CMakeLists.txt`: +```cmake +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary + ${PROJECT_NAME}.elf + ${PROJECT_NAME}.bin +) +``` + +## Call Mongoose from main.c + +Edit `Core/Src/main.c` and update the following snippets - notice the `USER CODE BEGIN` / `USER CODE END` placeholders. At the top of the file: + +```c +/* USER CODE BEGIN Includes */ +#include "mongoose_glue.h" +/* USER CODE END Includes */ +``` +Before the `main()` function: +```c +/* USER CODE BEGIN 0 */ +int _write(int fd, unsigned char *buf, int len) { + HAL_UART_Transmit(&huart3, buf, len, HAL_MAX_DELAY); + return len; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), HAL_GetTick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", HAL_GetTick()); + } + } +} + +// This blocks forever. Call it at the end of main(), or in a +// separate RTOS task. Give that task 8k stack space. +void run_mongoose(void) { + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + } +} +/* USER CODE END 0 */ +``` + +Inside the `main()` function: +```c +/* USER CODE BEGIN WHILE */ +run_mongoose(); // <----------------- Add this line +while (1) +{ + /* USER CODE END WHILE */ +``` + + +## Edit linker script + +Edit `STM32H723XG_FLASH.ld`, add the following line before the `.bss (NOLOAD)` line: +```text +.eth_ram : { *(.eth_ram .eth_ram*) } > RAM_D2 AT > FLASH +``` + +## Build, flash, test + +Start serial console. +Use STM32CubeProgrammer to flash the firmware. diff --git a/tutorials/stm32/nucleo_h723zg/cubemx/nucleo_h723zg.ioc b/tutorials/stm32/nucleo_h723zg/cubemx/nucleo_h723zg.ioc new file mode 100644 index 00000000..cbeee74c --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/cubemx/nucleo_h723zg.ioc @@ -0,0 +1,225 @@ +#MicroXplorer Configuration settings - do not modify +CAD.formats= +CAD.pinconfig= +CAD.provider= +CORTEX_M7.IPParameters=default_mode_Activation +CORTEX_M7.default_mode_Activation=1 +Cesanta.I-CUBE-Mongoose.7.21.7.IPParameters=MongooseJjNetworkingOoCore,MongooseJjWebOoDeviceOoDashboard +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjNetworkingOoCore=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjNetworkingOoCore_Checked=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjWebOoDeviceOoDashboard=true +Cesanta.I-CUBE-Mongoose.7.21.7.MongooseJjWebOoDeviceOoDashboard_Checked=true +Cesanta.I-CUBE-Mongoose.7.21.7_SwParameter=MongooseJjNetworkingOoCore\:true;MongooseJjWebOoDeviceOoDashboard\:true;MongooseJjMQTTOoClient\:true; +ETH.IPParameters=MediaInterface +ETH.MediaInterface=HAL_ETH_RMII_MODE +File.Version=6 +GPIO.groupedBy= +KeepUserPlacement=false +MMTAppRegionsCount=0 +MMTConfigApplied=false +MMTSectionSuffix= +Mcu.CPN=STM32H723ZGT6 +Mcu.Family=STM32H7 +Mcu.IP0=CORTEX_M7 +Mcu.IP1=ETH +Mcu.IP2=MEMORYMAP +Mcu.IP3=NVIC +Mcu.IP4=RCC +Mcu.IP5=RNG +Mcu.IP6=SYS +Mcu.IP7=USART3 +Mcu.IPNb=8 +Mcu.Name=STM32H723ZGTx +Mcu.Package=LQFP144 +Mcu.Pin0=PC1 +Mcu.Pin1=PA1 +Mcu.Pin10=PD9 +Mcu.Pin11=PG11 +Mcu.Pin12=PG13 +Mcu.Pin13=PE1 +Mcu.Pin14=VP_RNG_VS_RNG +Mcu.Pin15=VP_SYS_VS_Systick +Mcu.Pin16=VP_MEMORYMAP_VS_MEMORYMAP +Mcu.Pin17=VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7 +Mcu.Pin18=VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7 +Mcu.Pin2=PA2 +Mcu.Pin3=PA7 +Mcu.Pin4=PC4 +Mcu.Pin5=PC5 +Mcu.Pin6=PB0 +Mcu.Pin7=PB13 +Mcu.Pin8=PB14 +Mcu.Pin9=PD8 +Mcu.PinsNb=19 +Mcu.ThirdParty0=Cesanta.I-CUBE-Mongoose.7.21.7 +Mcu.ThirdPartyNb=1 +Mcu.UserConstants= +Mcu.UserName=STM32H723ZGTx +MxCube.Version=6.17.0 +MxDb.Version=DB.6.0.170 +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.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA1.Mode=RMII +PA1.Signal=ETH_REF_CLK +PA2.Mode=RMII +PA2.Signal=ETH_MDIO +PA7.Mode=RMII +PA7.Signal=ETH_CRS_DV +PB0.Locked=true +PB0.Signal=GPIO_Output +PB13.Mode=RMII +PB13.Signal=ETH_TXD1 +PB14.Locked=true +PB14.Signal=GPIO_Output +PC1.Mode=RMII +PC1.Signal=ETH_MDC +PC4.Mode=RMII +PC4.Signal=ETH_RXD0 +PC5.Mode=RMII +PC5.Signal=ETH_RXD1 +PD8.Locked=true +PD8.Mode=Asynchronous +PD8.Signal=USART3_TX +PD9.Locked=true +PD9.Mode=Asynchronous +PD9.Signal=USART3_RX +PE1.Locked=true +PE1.Signal=GPIO_Output +PG11.Locked=true +PG11.Mode=RMII +PG11.Signal=ETH_TX_EN +PG13.Locked=true +PG13.Mode=RMII +PG13.Signal=ETH_TXD0 +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32H723ZGTx +ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.13.0 +ProjectManager.FreePins=false +ProjectManager.FreePinsContext= +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=0x10000 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=h723.ioc +ProjectManager.ProjectName=h723 +ProjectManager.ProjectStructure= +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0x2000 +ProjectManager.TargetToolchain=CMake +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_ETH_Init-ETH-false-HAL-true,4-MX_RNG_Init-RNG-false-HAL-true,5-MX_USART3_UART_Init-USART3-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +RCC.ADCFreq_Value=129000000 +RCC.AHB12Freq_Value=275000000 +RCC.AHB4Freq_Value=275000000 +RCC.APB1Freq_Value=137500000 +RCC.APB2Freq_Value=137500000 +RCC.APB3Freq_Value=137500000 +RCC.APB4Freq_Value=137500000 +RCC.AXIClockFreq_Value=275000000 +RCC.CECFreq_Value=32000 +RCC.CKPERFreq_Value=64000000 +RCC.CortexFreq_Value=550000000 +RCC.CpuClockFreq_Value=550000000 +RCC.D1CPREFreq_Value=550000000 +RCC.D1PPRE=RCC_APB3_DIV2 +RCC.D2PPRE1=RCC_APB1_DIV2 +RCC.D2PPRE2=RCC_APB2_DIV2 +RCC.D3PPRE=RCC_APB4_DIV2 +RCC.DFSDMACLkFreq_Value=275000000 +RCC.DFSDMFreq_Value=137500000 +RCC.DIVM1=4 +RCC.DIVN1=34 +RCC.DIVP1=1 +RCC.DIVP1Freq_Value=550000000 +RCC.DIVP2Freq_Value=129000000 +RCC.DIVP3Freq_Value=129000000 +RCC.DIVQ1Freq_Value=275000000 +RCC.DIVQ2Freq_Value=129000000 +RCC.DIVQ3Freq_Value=129000000 +RCC.DIVR1Freq_Value=275000000 +RCC.DIVR2Freq_Value=129000000 +RCC.DIVR3Freq_Value=129000000 +RCC.FDCANFreq_Value=275000000 +RCC.FMCFreq_Value=275000000 +RCC.FamilyName=M +RCC.HCLK3ClockFreq_Value=275000000 +RCC.HCLKFreq_Value=275000000 +RCC.HPRE=RCC_HCLK_DIV2 +RCC.I2C123Freq_Value=137500000 +RCC.I2C4Freq_Value=137500000 +RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value +RCC.LPTIM1Freq_Value=137500000 +RCC.LPTIM2Freq_Value=137500000 +RCC.LPTIM345Freq_Value=137500000 +RCC.LPUART1Freq_Value=137500000 +RCC.LTDCFreq_Value=129000000 +RCC.MCO1PinFreq_Value=64000000 +RCC.MCO2PinFreq_Value=550000000 +RCC.PLL2FRACN=0 +RCC.PLL3FRACN=0 +RCC.PLLFRACN=3072 +RCC.QSPIFreq_Value=275000000 +RCC.RNGFreq_Value=48000000 +RCC.RTCFreq_Value=32000 +RCC.SAI1Freq_Value=275000000 +RCC.SAI4AFreq_Value=275000000 +RCC.SAI4BFreq_Value=275000000 +RCC.SDMMCFreq_Value=275000000 +RCC.SPDIFRXFreq_Value=275000000 +RCC.SPI123Freq_Value=275000000 +RCC.SPI45Freq_Value=137500000 +RCC.SPI6Freq_Value=137500000 +RCC.SWPMI1Freq_Value=137500000 +RCC.SYSCLKFreq_VALUE=550000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.Tim1OutputFreq_Value=275000000 +RCC.Tim2OutputFreq_Value=275000000 +RCC.TraceFreq_Value=64000000 +RCC.USART16Freq_Value=137500000 +RCC.USART234578Freq_Value=137500000 +RCC.USBFreq_Value=275000000 +RCC.VCO1OutputFreq_Value=550000000 +RCC.VCO2OutputFreq_Value=258000000 +RCC.VCO3OutputFreq_Value=258000000 +RCC.VCOInput1Freq_Value=16000000 +RCC.VCOInput2Freq_Value=2000000 +RCC.VCOInput3Freq_Value=2000000 +USART3.IPParameters=VirtualMode-Asynchronous +USART3.VirtualMode-Asynchronous=VM_ASYNC +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7.Mode=MongooseJjNetworkingOoCore +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7.Signal=Cesanta.I-CUBE-Mongoose_VS_MongooseJjNetworkingOoCore_7.21.7_7.21.7 +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7.Mode=MongooseJjWebOoDeviceOoDashboard +VP_Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7.Signal=Cesanta.I-CUBE-Mongoose_VS_MongooseJjWebOoDeviceOoDashboard_7.21.7_7.21.7 +VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg +VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP +VP_RNG_VS_RNG.Mode=RNG_Activate +VP_RNG_VS_RNG.Signal=RNG_VS_RNG +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=custom diff --git a/tutorials/stm32/nucleo_h723zg/minimal/Makefile b/tutorials/stm32/nucleo_h723zg/minimal/Makefile new file mode 100644 index 00000000..9ed5f162 --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/minimal/Makefile @@ -0,0 +1,38 @@ +# Copyright (c) 2026 Cesanta Software Limited +# Environment setup: https://mongoose.ws/docs/getting-started/build-environment/ + +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections +CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_h7/Include +CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 $(CFLAGS_EXTRA) +LDFLAGS ?= -Tlink.ld -nostdlib -nostartfiles --specs nosys.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map + +SOURCES = main.c hal.c +SOURCES += cmsis_h7/Source/Templates/gcc/startup_stm32h723xx.s + +TOP = ../../../.. +CFLAGS += -I$(TOP) +SOURCES += $(TOP)/mongoose.c + +all: firmware.bin + +firmware.elf: cmsis_core cmsis_h7 hal.h link.ld Makefile $(SOURCES) + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@ + +firmware.bin: firmware.elf + arm-none-eabi-objcopy -O binary $< $@ + @echo + @echo "To flash, run 'make flash', or use STM32CubeProgrammer" + +flash: firmware.bin + STM32_Programmer_CLI -c port=swd -e all -w firmware.elf -hardRst + +cmsis_core: + git clone -q -c advice.detachedHead=false --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ + +cmsis_h7: + git clone -q -c advice.detachedHead=false --depth 1 -b v1.10.6 https://github.com/STMicroelectronics/cmsis_device_h7 $@ + +clean: + rm -rf firmware.* diff --git a/tutorials/stm32/nucleo_h723zg/minimal/hal.c b/tutorials/stm32/nucleo_h723zg/minimal/hal.c new file mode 100644 index 00000000..e519bff3 --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/minimal/hal.c @@ -0,0 +1,125 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "hal.h" + +bool hal_timer_expired(volatile uint64_t *t, uint64_t period, uint64_t now) { + uint64_t diff = now - *t; // Wrap-safe elapsed time since last expiry + if (period == 0) return false; // Avoid division by zero + if (diff < period) return false; // Period has not elapsed yet + *t += (diff / period) * period; // Preserve cadence, skip missed periods + return true; +} + +static volatile uint64_t s_ticks; // Milliseconds since boot +void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms + s_ticks++; +} + +uint64_t hal_get_tick(void) { + return s_ticks; +}; + +uint32_t SystemCoreClock = 160000000; +void SystemInit(void) { // Called automatically by startup code + hal_system_init(); // Enable FPU + hal_clock_init(); + SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms +} + +void ExitRun0Mode(void) { +} + +struct stat; +__attribute__((weak)) int _fstat(int fd, struct stat *st) { + (void) fd, (void) st; + return -1; +} + +extern unsigned char _end[]; // End of data section, start of heap. See link.ld +static unsigned char *s_current_heap_end = _end; + +size_t hal_ram_used(void) { + return (size_t) (s_current_heap_end - _end); +} + +size_t hal_ram_free(void) { + unsigned char endofstack; + return (size_t) (&endofstack - s_current_heap_end); +} + +void *_sbrk(int incr) { + unsigned char *prev_heap; + unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256); + prev_heap = s_current_heap_end; + // Check how much space we got from the heap end to the stack end + if (s_current_heap_end + incr > heap_end) return (void *) -1; + s_current_heap_end += incr; + return prev_heap; +} + +__attribute__((weak)) int _open(const char *path) { + (void) path; + return -1; +} + +__attribute__((weak)) int _close(int fd) { + (void) fd; + return -1; +} + +__attribute__((weak)) int _isatty(int fd) { + (void) fd; + return 1; +} + +__attribute__((weak)) int _lseek(int fd, int ptr, int dir) { + (void) fd, (void) ptr, (void) dir; + return 0; +} + +__attribute__((weak)) void _exit(int status) { + (void) status; + for (;;) asm volatile("BKPT #0"); +} + +__attribute__((weak)) void _kill(int pid, int sig) { + (void) pid, (void) sig; +} + +__attribute__((weak)) int _getpid(void) { + return -1; +} + +__attribute__((weak)) int _write(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _read(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _link(const char *a, const char *b) { + (void) a, (void) b; + return -1; +} + +__attribute__((weak)) int _unlink(const char *a) { + (void) a; + return -1; +} + +__attribute__((weak)) int _stat(const char *path, struct stat *st) { + (void) path, (void) st; + return -1; +} + +__attribute__((weak)) int mkdir(const char *path, int mode) { + (void) path, (void) mode; + return -1; +} + +__attribute__((weak)) void _init(void) { +} diff --git a/tutorials/stm32/nucleo_h723zg/minimal/hal.h b/tutorials/stm32/nucleo_h723zg/minimal/hal.h new file mode 100644 index 00000000..19667f52 --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/minimal/hal.h @@ -0,0 +1,223 @@ +// Copyright (c) 2022-2026 Cesanta Software Limited +// Datasheet: RM0468, devboard manual: UM2407 +// https://www.st.com/resource/en/reference_manual/rm0468-stm32h723733-stm32h725735-and-stm32h730-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf +// https://www.st.com/resource/en/user_manual/um2407-stm32h7-nucleo144-boards-mb1364-stmicroelectronics.pdf +// Alternate functions: https://www.st.com/resource/en/datasheet/stm32h723.pdf + +#pragma once + +#include + +#include +#include +#include +#include + +extern bool hal_timer_expired(volatile uint64_t *t, uint64_t prd, uint64_t now); +extern uint64_t hal_get_tick(void); +extern size_t hal_ram_free(void); +extern size_t hal_ram_used(void); +extern uint32_t SystemCoreClock; + +#define BIT(x) (1UL << (x)) +#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set)) +#define PIN(bank, num) ((((bank) - 'A') << 8) | (num)) +#define PINNO(pin) (pin & 255) +#define PINBANK(pin) (pin >> 8) + +#define HAL_ETH_PINS PIN('A', 1), PIN('A', 2), PIN('A', 7), \ + PIN('B', 13), PIN('C', 1), PIN('C', 4), \ + PIN('C', 5), PIN('G', 11), PIN('G', 13) + +// System clock (2.1, Figure 1; 8.5, Figure 45; 8.5.5, Figure 47; 8.5.6, Figure +// 49; 8.5.8 Table 56; datasheet) CPU_FREQUENCY <= 550 MHz; hclk = CPU_FREQUENCY +// / HAL_HPRE ; hclk <= 275 MHz; APB clocks <= 137.5 MHz. D1 domain bus matrix (and +// so flash) runs at hclk frequency. Configure flash latency (WS) in accordance +// to hclk freq (4.3.8, Table 16) The Ethernet controller is in D2 domain and +// runs at hclk frequency +enum { + HAL_D1CPRE = 1, // actual divisor value + HAL_HPRE = 2, // actual divisor value + HAL_D1PPRE = 4, // register values, divisor value = BIT(value - 3) = / 2 + HAL_D2PPRE1 = 4, + HAL_D2PPRE2 = 4, + HAL_D3PPRE = 4 +}; +// PLL1_P: odd division factors are not allowed (8.7.12) (except for '1') +enum { PLL1_HSI = 64, PLL1_M = 32, PLL1_N = 225, PLL1_P = 1 }; +#define HAL_FLASH_LATENCY 0x33 // WRHIGHFREQ LATENCY +#define SYS_FREQUENCY ((PLL1_HSI * PLL1_N / PLL1_M / PLL1_P / HAL_D1CPRE) * 1000000) +#define AHB_FREQUENCY (SYS_FREQUENCY / HAL_HPRE) +#define APB2_FREQUENCY (AHB_FREQUENCY / (BIT(HAL_D2PPRE2 - 3))) +#define APB1_FREQUENCY (AHB_FREQUENCY / (BIT(HAL_D2PPRE1 - 3))) + +static inline void hal_spin(volatile uint32_t n) { + while (n--) (void) 0; +} + +enum { HAL_GPIO_MODE_INPUT, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_MODE_AF, HAL_GPIO_MODE_ANALOG }; +enum { HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_OTYPE_OPEN_DRAIN }; +enum { HAL_GPIO_SPEED_LOW, HAL_GPIO_SPEED_MEDIUM, HAL_GPIO_SPEED_HIGH, HAL_GPIO_SPEED_INSANE }; +enum { HAL_GPIO_PULL_NONE, HAL_GPIO_PULL_UP, HAL_GPIO_PULL_DOWN }; + +#define HAL_GPIO(N) ((GPIO_TypeDef *) (0x40000000 + 0x18020000UL + 0x400 * (N))) + +static GPIO_TypeDef *hal_gpio_bank(uint16_t pin) { + return HAL_GPIO(PINBANK(pin)); +} +static inline void hal_gpio_toggle(uint16_t pin) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + uint32_t mask = BIT(PINNO(pin)); + gpio->BSRR = mask << (gpio->ODR & mask ? 16 : 0); +} +static inline int hal_gpio_read(uint16_t pin) { + return hal_gpio_bank(pin)->IDR & BIT(PINNO(pin)) ? 1 : 0; +} +static inline void hal_gpio_write(uint16_t pin, bool val) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + gpio->BSRR = BIT(PINNO(pin)) << (val ? 0 : 16); +} +static inline void hal_gpio_init(uint16_t pin, uint8_t mode, uint8_t type, + uint8_t speed, uint8_t pull, uint8_t af) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + uint8_t n = (uint8_t) (PINNO(pin)); + RCC->AHB4ENR |= BIT(PINBANK(pin)); // Enable GPIO clock + CLRSET(gpio->OTYPER, 1UL << n, ((uint32_t) type) << n); + CLRSET(gpio->OSPEEDR, 3UL << (n * 2), ((uint32_t) speed) << (n * 2)); + CLRSET(gpio->PUPDR, 3UL << (n * 2), ((uint32_t) pull) << (n * 2)); + CLRSET(gpio->AFR[n >> 3], 15UL << ((n & 7) * 4), + ((uint32_t) af) << ((n & 7) * 4)); + CLRSET(gpio->MODER, 3UL << (n * 2), ((uint32_t) mode) << (n * 2)); +} +static inline void hal_gpio_input(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, + HAL_GPIO_PULL_NONE, 0); +} +static inline void hal_gpio_output(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, + HAL_GPIO_PULL_NONE, 0); +} + +// D2 Kernel clock (8.7.21) USART1 defaults to pclk2 (APB2), while USART2,3 +// default to pclk1 (APB1). Even if using other kernel clocks, the APBx clocks +// must be enabled for CPU access, as the kernel clock drives the BRR, not the +// APB bus interface +static inline void hal_uart_init(USART_TypeDef *uart, unsigned long baud) { + uint8_t af = 7; // Alternate function + uint16_t rx = 0, tx = 0; // pins + uint32_t freq = 0; // Bus frequency. UART1 is on APB2, rest on APB1 + + if (uart == USART1) freq = APB2_FREQUENCY, RCC->APB2ENR |= BIT(4); + if (uart == USART2) freq = APB1_FREQUENCY, RCC->APB1LENR |= BIT(17); + if (uart == USART3) freq = APB1_FREQUENCY, RCC->APB1LENR |= BIT(18); + + if (uart == USART1) tx = PIN('A', 9), rx = PIN('A', 10); + if (uart == USART2) tx = PIN('A', 2), rx = PIN('A', 3); + if (uart == USART3) tx = PIN('D', 8), rx = PIN('D', 9); + +#if 0 // CONSTANT BAUD RATE FOR REMOTE DEBUGGING WHILE SETTING THE PLL + CLRSET(RCC->D2CCIP2R, 7 << 3, 3 << 3); // use HSI for UART1 + freq = 64000000; +#endif + + hal_gpio_init(tx, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, 0, af); + hal_gpio_init(rx, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_HIGH, 0, af); + uart->CR1 = 0; // Disable this UART + uart->BRR = freq / baud; // Set baud rate + uart->CR1 = BIT(0) | BIT(2) | BIT(3); // Set UE, RE, TE +} +static inline void hal_uart_write_byte(USART_TypeDef *uart, uint8_t byte) { + uart->TDR = byte; + while ((uart->ISR & BIT(7)) == 0) hal_spin(1); +} +static inline void hal_uart_write_buf(USART_TypeDef *uart, char *buf, size_t len) { + while (len-- > 0) hal_uart_write_byte(uart, *(uint8_t *) buf++); +} +static inline int hal_uart_read_ready(USART_TypeDef *uart) { + return uart->ISR & BIT(5); // If RXNE bit is set, data is ready +} +static inline uint8_t hal_uart_read_byte(USART_TypeDef *uart) { + return (uint8_t) (uart->RDR & 255); +} + +// RNG clock (rng_clk) defaults to HSI48 and is characterized at this frequency. +// Enable at SystemInit. (STM32CubeMX) It won't work with a 275MHz (AHB) +static inline void hal_rng_init(void) { + RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; // Enable RNG AHB clock (hal_rng_hclk) + // 39.6.2 Table 320 init + RNG->CR = RNG_CR_CONDRST | (0x0F << RNG_CR_RNG_CONFIG1_Pos) | + (0 << RNG_CR_RNG_CONFIG2_Pos) | (0xD << RNG_CR_RNG_CONFIG3_Pos); + RNG->HTCR = 0x17590abc; + RNG->HTCR = 0xaa74; + RNG->CR &= ~RNG_CR_CONDRST ; + while(RNG->CR & RNG_CR_CONDRST) hal_spin(1); // 39.7.1 + RNG->CR |= RNG_CR_RNGEN; // Enable RNG +} + +static inline uint32_t hal_rng_read(void) { + while ((RNG->SR & RNG_SR_DRDY) == 0) (void) 0; + return RNG->DR; +} + +// Hw pull-ups on PHY RXD0,1,DV to enable autonegotiation +static inline void hal_ethernet_init(void) { + // Initialise Ethernet. Enable MAC GPIO pins, see + // https://www.st.com/resource/en/user_manual/um2407-stm32h7-nucleo144-boards-mb1364-stmicroelectronics.pdf + uint16_t pins[] = {HAL_ETH_PINS}; + for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) { + hal_gpio_init(pins[i], HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, HAL_GPIO_SPEED_INSANE, + HAL_GPIO_PULL_NONE, 11); // 11 is the Ethernet function + } + NVIC_EnableIRQ(ETH_IRQn); // Setup Ethernet IRQ handler + CLRSET(SYSCFG->PMCR, 7 << 21, 4 << 21); // Use RMII (12.3.1) + RCC->AHB1ENR |= BIT(15) | BIT(16) | BIT(17); // Enable Ethernet clocks +} + +static inline unsigned int hal_div2prescval(unsigned int div) { + // 0 --> /1; 8 --> /2 ... 11 --> /16; 12 --> /64 ... 15 --> /512 + if (div == 1) return 0; + if (div > 16) div /= 2; + unsigned int val = 7; + while (div >>= 1) ++val; + return val; +} + +static inline unsigned int hal_pllrge(unsigned int f) { + unsigned int val = 0; + while (f >>= 1) ++val; + return val - 1; +} + +static inline void hal_clock_init(void) { + PWR->CR3 |= BIT(1); // select LDO (reset value) + while ((PWR->CSR1 & BIT(13)) == 0) hal_spin(1); // ACTVOSRDY + PWR->D3CR &= ~(BIT(15) | BIT(14)); // Select VOS0 + while ((PWR->D3CR & BIT(13)) == 0) hal_spin(1); // VOSRDY + CLRSET( + RCC->D1CFGR, (0x0F << 8) | (7 << 4) | (0x0F << 0), + (hal_div2prescval(HAL_D1CPRE) << 8) | (HAL_D1PPRE << 4) | (hal_div2prescval(HAL_HPRE) << 0)); + RCC->D2CFGR = (HAL_D2PPRE2 << 8) | (HAL_D2PPRE1 << 4); + RCC->D3CFGR = (HAL_D3PPRE << 4); + CLRSET(RCC->PLLCFGR, 3 << 2, + hal_pllrge(PLL1_HSI / PLL1_M) + << 2); // keep reset config (DIVP1EN, !PLL1VCOSEL), PLL1RGE + CLRSET(RCC->PLL1DIVR, (0x7F << 9) | (0x1FF << 0), + ((PLL1_P - 1) << 9) | ((PLL1_N - 1) << 0)); // Set PLL1_P PLL1_N + CLRSET(RCC->PLLCKSELR, 0x3F << 4, + PLL1_M << 4); // Set PLL1_M (source defaults to HSI) + RCC->CR |= BIT(24) | BIT(12); // Enable PLL1 and HSI48 (for RNG) + while ((RCC->CR & BIT(25)) == 0) hal_spin(1); // Wait until done + RCC->CFGR |= (3 << 0); // Set clock source to PLL1 + while ((RCC->CFGR & (7 << 3)) != (3 << 3)) hal_spin(1); // Wait until done + FLASH->ACR = HAL_FLASH_LATENCY; // default is larger + RCC->APB4ENR |= RCC_APB4ENR_SYSCFGEN; // Enable SYSCFG + while ((RCC->CR & BIT(13)) == 0) hal_spin(1); // Make sure HSI48 is ready + SystemCoreClock = SYS_FREQUENCY; // Update SystemCoreClock global var + SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms +} + +static inline void hal_system_init(void) { + SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU + __DSB(); + __ISB(); +} diff --git a/tutorials/stm32/nucleo_h723zg/minimal/link.ld b/tutorials/stm32/nucleo_h723zg/minimal/link.ld new file mode 100644 index 00000000..a62749dc --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/minimal/link.ld @@ -0,0 +1,28 @@ +ENTRY(Reset_Handler); +MEMORY { + flash(rx) : ORIGIN = 0x08000000, LENGTH = 1024k + + dtcmram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K + ram_d1 (rwx) : ORIGIN = 0x24000000, LENGTH = 320K + ram_d2 (rwx) : ORIGIN = 0x30000000, LENGTH = 32K + ram_d3 (rwx) : ORIGIN = 0x38000000, LENGTH = 16K + itcmram (rwx) : ORIGIN = 0x00000000, LENGTH = 64K +} +_estack = ORIGIN(ram_d1) + LENGTH(ram_d1); + +SECTIONS { + .vectors : { KEEP(*(.isr_vector)) } > flash + .text : { *(.text* .text.*) } > flash + .rodata : { *(.rodata*) } > flash + + /* Note the .iram section, for functions copied to RAM. Required for MG_IRAM OTA support */ + .data : { _sdata = .; *(.first_data) *(.iram .iram* .iram.*) *(.data SORT(.data.*)) _edata = .; } > ram_d1 AT > flash + _sidata = LOADADDR(.data); + + .bss : { _sbss = .; *(.bss SORT(.bss.*) COMMON) _ebss = .; } > ram_d1 + + .eth_ram : { *(.eth_ram .eth_ram*) } > ram_d1 AT > flash + + . = ALIGN(8); + _end = .; +} diff --git a/tutorials/stm32/nucleo_h723zg/minimal/main.c b/tutorials/stm32/nucleo_h723zg/minimal/main.c new file mode 100644 index 00000000..38f16d68 --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/minimal/main.c @@ -0,0 +1,70 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "hal.h" +#include "mongoose.h" + +#define DEBUG_UART USART3 +#define LED1 PIN('B', 0) +#define LED2 PIN('E', 1) +#define LED3 PIN('B', 14) + +// Redirect stdout debug output to UART +int _write(int fd, char *ptr, int len) { + if (fd == 1) hal_uart_write_buf(DEBUG_UART, ptr, (size_t) len); + return len; +} + +static void blink_task(void) { + static uint64_t blink_timer = 0; + if (hal_timer_expired(&blink_timer, 500, hal_get_tick())) { + hal_gpio_toggle(LED1); + } +} + +uint64_t mg_millis(void) { + return hal_get_tick(); +} + +bool mg_random(void *buf, size_t len) { + for (size_t n = 0; n < len; n += sizeof(uint32_t)) { + uint32_t r = hal_rng_read(); + memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r)); + } + return true; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), hal_get_tick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", hal_get_tick()); + } + } +} + +int main(void) { + hal_clock_init(); + hal_uart_init(DEBUG_UART, 115200); + hal_rng_init(); + hal_ethernet_init(); + hal_gpio_output(LED1); + hal_gpio_output(LED2); + hal_gpio_output(LED3); + + printf("Initialised. CPU clock: %lu MHz\r\n", SystemCoreClock / 1000000); + + // Start a minimal web server + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + blink_task(); + } + + return 0; +} diff --git a/tutorials/stm32/nucleo_h723zg/minimal/mongoose_config.h b/tutorials/stm32/nucleo_h723zg/minimal/mongoose_config.h new file mode 100644 index 00000000..a9513324 --- /dev/null +++ b/tutorials/stm32/nucleo_h723zg/minimal/mongoose_config.h @@ -0,0 +1,35 @@ +#pragma once + +// See https://mongoose.ws/docs/getting-started/build-options/ +#define MG_ARCH MG_ARCH_ARMGCC +#define MG_TLS MG_TLS_BUILTIN +#define MG_OTA MG_OTA_STM32H7 + +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define MG_ENABLE_CUSTOM_RANDOM 1 +#define MG_ENABLE_DRIVER_STM32H 1 +#define MG_ENABLE_PACKED_FS 1 +#define MG_ETH_RAM __attribute__((section(".eth_ram"))) + +// #define MG_DRIVER_MDC_CR 4 // RMII MDC clock divider, from 0 to 5 +// #define MG_TCPIP_PHY_ADDR 0 // PHY address + +// For static IP configuration, define MG_TCPIP_{IP,MASK,GW} +// By default, those are set to zero, meaning that DHCP is used +// +// #define MG_TCPIP_IP MG_IPV4(192, 168, 0, 10) // IP +// #define MG_TCPIP_GW MG_IPV4(192, 168, 0, 1) // Gateway +// #define MG_TCPIP_MASK MG_IPV4(255, 255, 255, 0) // Netmask + +// Construct MAC address from the MCU unique ID +#define MGUID ((uint32_t *) 0x1ff1e800) // Unique 96-bit chip ID +#define MG_SET_MAC_ADDRESS(mac) \ + do { \ + mac[0] = 2; \ + mac[1] = MGUID[0] & 255; \ + mac[2] = (MGUID[0] >> 10) & 255; \ + mac[3] = (MGUID[0] >> 19) & 255; \ + mac[4] = MGUID[1] & 255; \ + mac[5] = MGUID[2] & 255; \ + } while (0) diff --git a/tutorials/stm32/nucleo_n657x0_q/cubemx/README.md b/tutorials/stm32/nucleo_n657x0_q/cubemx/README.md new file mode 100644 index 00000000..14cf1253 --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/cubemx/README.md @@ -0,0 +1,122 @@ +# Mongoose CubeMX integration + +This is a step-by-step guide on how to bring up a production-grade Web UI +dashboard on STM32 Nucleo-N657X0-Q development board. + +A pre-configured project .zip is available for download at https://mongoose.ws. +However for those who want to configure the project from scratch, follow the steps +below. + +## Generate .ioc file + +This directory already has a pre-configured `.ioc` file so you can just open it +in your CubeMX and skip this step. However for those who want to create the +project from scratch, here are the steps: + +- Open CubeMX, File / New project, type "STM32N657X0H3Q" in the part number, select + it from the list, click "Start project" on the top right, choose "Secure domain only" +- Project Manager: Project name: "n657". Project location: path to this directory. + Project strucure: "FSBL" only. Toolchain/IDE: pick ether Cmake or CubeIDE. +- Clock configuration: Find SYSB, enter 400 MHz, Resolve clock issues +- MCU pinout view: set PG0, PG8, PG10 to GPIO_Output mode +- Pinout & Configuration / System Core: click on "GPIO", then click on each + of the PG0, PG8, PG10 pins and select Pin Context Assignment / First Stage Boot Loader +- Pinout & Configuration / Security: Enable RIF and RNG for FSBL, click on RNG, check Activate +- Pinout & Configuration / Connectivity: enable USART1 for FSBL, mode asynchronous, + configure pins PE5 and PE6 for USART1 function +- Pinout & Configuration / Connectivity: enable ETH1 for FSBL, mode RMII, + pins PF4, PF5, PF7, PF10, PF11, PF12, PF13, PF14, PF15, PG11 for Ethernet function +- RIF: + - Peripherals (RISUP), enable "Privilege" on ETH1 + - Domains (RIMU): for ETH1, enable SECURE and PRIVILEGE +- Clock configuration: resolve clocks if required. Find "To ETH1" and make sure it has 100 MHz + +## Generate project code +- Clone this repo to your workstation. Open the .ioc file in your CubeMX +- Click on "Project Manager" + - If you're using CubeIDE, select "CubeIDE" in the toolchain/IDE dropdown + - If you're using VSCode, select "Cmake" in the toolchain/IDE dropdown + - If you're using Makefile, select "Makefile" in the toolchain/IDE dropdown +- Click "Generate Code" button on the top right + +## Configure .bin generation + +Normally, IDEs generate .elf firmware file, cause it is easier for a debugger +to load it to a device. However, for the firmware OTA update, the .bin file +is required. The .bin file is the firmware image that gets copied to the +beginning of the microcontroller's flash memory and gets executed after the +system boot. + +So, we need to tell the IDE to generate .bin firmware flash image file. + +- If you're using CubeIDE, select Project / Properties / C/C++ build / Settings + / MCU/MPU Post build outputs, enable "Convert to binary file (-O binary)" +- If you're using VSCode, add a section to the end of the top-level `CMakeLists.txt`: +```cmake +add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -O binary + ${PROJECT_NAME}.elf + ${PROJECT_NAME}.bin +) +``` + +## Call Mongoose from main.c + +Edit `Core/Src/main.c` and update the following snippets - notice the `USER CODE BEGIN` / `USER CODE END` placeholders. At the top of the file: + +```c +/* USER CODE BEGIN Includes */ +#include "mongoose_glue.h" +/* USER CODE END Includes */ +``` + +Before the `main()` function: +```c +/* USER CODE BEGIN 0 */ +int _write(int fd, unsigned char *buf, int len) { + HAL_UART_Transmit(&huart1, buf, len, HAL_MAX_DELAY); + return len; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), HAL_GetTick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", HAL_GetTick()); + } + } +} + +// This blocks forever. Call it at the end of main(), or in a +// separate RTOS task. Give that task 8k stack space. +void run_mongoose(void) { + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + } +} +/* USER CODE END 0 */ +``` + +Inside the `main()` function: +```c +/* USER CODE BEGIN WHILE */ +HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, 1); +HAL_GPIO_WritePin(GPIOG, GPIO_PIN_8, 1); +HAL_GPIO_WritePin(GPIOG, GPIO_PIN_10, 1); +run_mongoose(); +while (1) +{ + /* USER CODE END WHILE */ +``` + +## Build, flash, test + +Start serial console. +Use STM32CubeProgrammer to flash the firmware. Don't forget to specify +the `MX25UM51245G_STM32N6570-NUCLEO.stldr` external loader for this board. diff --git a/tutorials/stm32/nucleo_n657x0_q/cubemx/nucleo_n657x0_q.ioc b/tutorials/stm32/nucleo_n657x0_q/cubemx/nucleo_n657x0_q.ioc new file mode 100644 index 00000000..dfc17da2 --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/cubemx/nucleo_n657x0_q.ioc @@ -0,0 +1,880 @@ +#MicroXplorer Configuration settings - do not modify +Appli.IPs=CORTEX_M55_S,GPDMA1,HPDMA1,LINKEDLIST,RCC,SAU,GPIO,NVIC1\:I +CAD.formats= +CAD.pinconfig= +CAD.provider= +ETH1.IPParameters=MediaInterface +ETH1.MediaInterface=HAL_ETH_RMII_MODE +ExtMemLoader.IPs=EXTMEM_LOADER,EXTMEM_MANAGER,RCC\:I,GPIO +FSBL.IPs=CORTEX_M55_FSBL,GPDMA1\:I,HDP,HPDMA1\:I,LINKEDLIST,RCC,GPIO\:I,NVIC\:I,RIF,RNG,USART1,ETH1 +FSBL.Pins=PG0,PG10,PG8 +File.Version=6 +GPIO.groupedBy= +KeepUserPlacement=false +Mcu.CPN=STM32N657X0H3Q +Mcu.Context0=FSBL +Mcu.Context1=Appli +Mcu.Context2=ExtMemLoader +Mcu.ContextNb=3 +Mcu.ContextProject=FullSecure +Mcu.Family=STM32N6 +Mcu.IP0=CORTEX_M55_FSBL +Mcu.IP1=CORTEX_M55_S +Mcu.IP2=ETH1 +Mcu.IP3=NVIC1 +Mcu.IP4=NVIC +Mcu.IP5=RCC +Mcu.IP6=RIF +Mcu.IP7=RNG +Mcu.IP8=USART1 +Mcu.IPNb=9 +Mcu.Name=STM32N657X0HxQ +Mcu.Package=VFBGA264 +Mcu.Pin0=PE5 +Mcu.Pin1=PE6 +Mcu.Pin10=PG0 +Mcu.Pin11=PF12 +Mcu.Pin12=PG10 +Mcu.Pin13=PG8 +Mcu.Pin14=PG11 +Mcu.Pin15=VP_RIF_VS_RIF1 +Mcu.Pin16=VP_RNG_VS_RNG +Mcu.Pin2=PF4 +Mcu.Pin3=PF10 +Mcu.Pin4=PF7 +Mcu.Pin5=PF5 +Mcu.Pin6=PF15 +Mcu.Pin7=PF14 +Mcu.Pin8=PF11 +Mcu.Pin9=PF13 +Mcu.PinsNb=17 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32N657X0HxQ +MxCube.Version=6.17.0 +MxDb.Version=DB.6.0.170 +NVIC.BFHFNMINS=0 +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.PRIS=0 +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.SecureFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.BFHFNMINS=0 +NVIC1.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.ForceEnableDMAVector=true +NVIC1.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.PRIS=0 +NVIC1.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.PriorityGroup=NVIC_PRIORITYGROUP_4 +NVIC1.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.SecureFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC1.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false +NVIC1.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PCC.Checker=false +PCC.Display=Plot\: All Steps +PCC.Line=STM32N6x7 +PCC.MCU=STM32N657X0HxQ +PCC.PartNumber=STM32N657X0HxQ +PCC.Series=STM32N6 +PCC.Temperature=25 +PCC.Vdd=1.8 +PE5.GPIOParameters=PinAttribute +PE5.Locked=true +PE5.Mode=Asynchronous +PE5.PinAttribute=FSBL +PE5.Signal=USART1_TX +PE6.GPIOParameters=PinAttribute +PE6.Mode=Asynchronous +PE6.PinAttribute=FSBL +PE6.Signal=USART1_RX +PF10.GPIOParameters=PinAttribute +PF10.Mode=RMII +PF10.PinAttribute=FSBL +PF10.Signal=ETH1_RMII_CRS_DV +PF11.GPIOParameters=PinAttribute +PF11.Mode=RMII +PF11.PinAttribute=FSBL +PF11.Signal=ETH1_RMII_TX_EN +PF12.GPIOParameters=PinAttribute +PF12.Mode=RMII +PF12.PinAttribute=FSBL +PF12.Signal=ETH1_RMII_TXD0 +PF13.GPIOParameters=PinAttribute +PF13.Mode=RMII +PF13.PinAttribute=FSBL +PF13.Signal=ETH1_RMII_TXD1 +PF14.GPIOParameters=PinAttribute +PF14.Mode=RMII +PF14.PinAttribute=FSBL +PF14.Signal=ETH1_RMII_RXD0 +PF15.GPIOParameters=PinAttribute +PF15.Mode=RMII +PF15.PinAttribute=FSBL +PF15.Signal=ETH1_RMII_RXD1 +PF4.GPIOParameters=PinAttribute +PF4.Locked=true +PF4.Mode=RMII +PF4.PinAttribute=FSBL +PF4.Signal=ETH1_MDIO +PF5.GPIOParameters=PinAttribute +PF5.Mode=RMII +PF5.PinAttribute=FSBL +PF5.Signal=ETH1_CLK +PF7.GPIOParameters=PinAttribute +PF7.Mode=RMII +PF7.PinAttribute=FSBL +PF7.Signal=ETH1_RMII_REF_CLK +PG0.ContextOwner=FSBL +PG0.GPIOParameters=PinAttribute +PG0.Locked=true +PG0.PinAttribute=FSBL +PG0.Signal=GPIO_Output +PG10.ContextOwner=FSBL +PG10.GPIOParameters=PinAttribute +PG10.Locked=true +PG10.PinAttribute=FSBL +PG10.Signal=GPIO_Output +PG11.GPIOParameters=PinAttribute +PG11.Locked=true +PG11.Mode=RMII +PG11.PinAttribute=FSBL +PG11.Signal=ETH1_MDC +PG8.ContextOwner=FSBL +PG8.GPIOParameters=PinAttribute +PG8.Locked=true +PG8.PinAttribute=FSBL +PG8.Signal=GPIO_Output +PinOutPanel.CurrentBGAView=Top +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerLinker=GCC +ProjectManager.CompilerOptimize=6 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=false +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=true +ProjectManager.DeviceId=STM32N657X0HxQ +ProjectManager.FirmwarePackage=STM32Cube FW_N6 V1.3.0 +ProjectManager.FreePins=false +ProjectManager.FreePinsContext=FSBL +ProjectManager.HalAssertFull=false +ProjectManager.HeapSize=FSBL-0x200,Appli-0x200,ExtMemLoader-0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Core/Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain=STM32CubeIDE +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=n567.ioc +ProjectManager.ProjectName=n567 +ProjectManager.ProjectStructure=FSBL\:FSBL\:true;Appli\:Appli\:false;ExtMemLoader\:ExtMemLoader\:false; +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=FSBL-0x800,Appli-0x800,ExtMemLoader-0x800 +ProjectManager.TargetToolchain=STM32CubeIDE +ProjectManager.ToolChainLocation= +ProjectManager.UAScriptAfterPath= +ProjectManager.UAScriptBeforePath= +ProjectManager.UnderRoot=true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false-FSBL,2-MX_GPIO_Init-GPIO-false-HAL-true-FSBL,3-MX_ETH1_Init-ETH1-false-HAL-true-FSBL,4-MX_RNG_Init-RNG-false-HAL-true-FSBL,5-MX_USART1_UART_Init-USART1-false-HAL-true-FSBL,6-SystemIsolation_Config-RIF-false-HAL-true-FSBL,0-MX_CORTEX_M55_FSBL_Init-CORTEX_M55_FSBL-false-HAL-true-FSBL,0-MX_CORTEX_M55_S_Init-CORTEX_M55_S-false-HAL-true-Appli +RCC.ADC12Freq_Value=100000000 +RCC.ADFFreq_Value=100000000 +RCC.AHB1234Freq_Value=100000000 +RCC.AHBFreq_Value=8000000 +RCC.APB1Freq_Value=100000000 +RCC.APB2Freq_Value=100000000 +RCC.APB4Freq_Value=100000000 +RCC.APB5Freq_Value=100000000 +RCC.AXIClockFreq_Value=400000000 +RCC.CKPERFreq_Value=64000000 +RCC.CortexFreq_Value=8000000 +RCC.CpuClockFreq_Value=64000000 +RCC.DCMIPPFreq_Value=100000000 +RCC.ETH1Freq_Value=100000000 +RCC.FDCANFreq_Value=100000000 +RCC.FMCFreq_Value=100000000 +RCC.FOUTPOSTDIV1Freq_Value=1600000000 +RCC.FOUTPOSTDIV2Freq_Value=1600000000 +RCC.FOUTPOSTDIV3Freq_Value=1600000000 +RCC.FOUTPOSTDIV4Freq_Value=1600000000 +RCC.FamilyName=M +RCC.HPRE_Div=RCC_HCLK_DIV4 +RCC.HSE_VALUE=48000000 +RCC.HSI_VALUE=64000000 +RCC.I2C1Freq_Value=100000000 +RCC.I2C2Freq_Value=100000000 +RCC.I2C3Freq_Value=100000000 +RCC.I2C4Freq_Value=100000000 +RCC.I3C1Freq_Value=100000000 +RCC.I3C2Freq_Value=100000000 +RCC.IC10Freq_VALUE=1600000000 +RCC.IC11Freq_VALUE=400000000 +RCC.IC12Freq_VALUE=1600000000 +RCC.IC13Freq_VALUE=1600000000 +RCC.IC14Freq_VALUE=1600000000 +RCC.IC15Freq_VALUE=1600000000 +RCC.IC16Freq_VALUE=1600000000 +RCC.IC17Freq_VALUE=1600000000 +RCC.IC18Freq_VALUE=1600000000 +RCC.IC19Freq_VALUE=1600000000 +RCC.IC1Freq_VALUE=533333333.3333333 +RCC.IC20Freq_VALUE=1600000000 +RCC.IC2Freq_VALUE=400000000 +RCC.IC3Freq_VALUE=1600000000 +RCC.IC4Freq_VALUE=1600000000 +RCC.IC5Freq_VALUE=1600000000 +RCC.IC6Freq_VALUE=400000000 +RCC.IC7Freq_VALUE=1600000000 +RCC.IC8Freq_VALUE=1600000000 +RCC.IC9Freq_VALUE=1600000000 +RCC.IPParameters=ADC12Freq_Value,ADFFreq_Value,AHB1234Freq_Value,AHBFreq_Value,APB1Freq_Value,APB2Freq_Value,APB4Freq_Value,APB5Freq_Value,AXIClockFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,DCMIPPFreq_Value,ETH1Freq_Value,FDCANFreq_Value,FMCFreq_Value,FOUTPOSTDIV1Freq_Value,FOUTPOSTDIV2Freq_Value,FOUTPOSTDIV3Freq_Value,FOUTPOSTDIV4Freq_Value,FamilyName,HPRE_Div,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,I2C4Freq_Value,I3C1Freq_Value,I3C2Freq_Value,IC10Freq_VALUE,IC11Freq_VALUE,IC12Freq_VALUE,IC13Freq_VALUE,IC14Freq_VALUE,IC15Freq_VALUE,IC16Freq_VALUE,IC17Freq_VALUE,IC18Freq_VALUE,IC19Freq_VALUE,IC1Freq_VALUE,IC20Freq_VALUE,IC2Freq_VALUE,IC3Freq_VALUE,IC4Freq_VALUE,IC5Freq_VALUE,IC6Freq_VALUE,IC7Freq_VALUE,IC8Freq_VALUE,IC9Freq_VALUE,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM3Freq_Value,LPTIM4Freq_Value,LPTIM5Freq_Value,LPUART1Freq_Value,LSE_VALUE,LSI_VALUE,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,MDFFreq_Value,MSI_VALUE,OTGHS1Freq_Value,OTGHS2Freq_Value,OTGPHY1Freq_Value,OTGPHY2Freq_Value,PLL1FRACV,PLL2FRACV,PLL3FRACV,PLL4FRACV,PSSIFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMC1Freq_Value,SDMMC2Freq_Value,SPDIFRX1Freq_Value,SPI1Freq_Value,SPI2Freq_Value,SPI3Freq_Value,SPI4Freq_Value,SPI5Freq_Value,SPI6Freq_Value,SYSBCLKFreq_VALUE,SYSBCLKSource,SYSCCLKFreq_VALUE,SYSDCLKFreq_VALUE,TIMGFreq_Value,UART4Freq_Value,UART5Freq_Value,UART7Freq_Value,UART8Freq_Value,UART9Freq_Value,USART10Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USART6Freq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCO4OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value,VCOInput4Freq_Value,XSPI1Freq_Value,XSPI2Freq_Value,XSPI3Freq_Value +RCC.LPTIM1Freq_Value=100000000 +RCC.LPTIM2Freq_Value=100000000 +RCC.LPTIM3Freq_Value=100000000 +RCC.LPTIM4Freq_Value=100000000 +RCC.LPTIM5Freq_Value=100000000 +RCC.LPUART1Freq_Value=100000000 +RCC.LSE_VALUE=32768 +RCC.LSI_VALUE=32000 +RCC.LTDCFreq_Value=100000000 +RCC.MCO1PinFreq_Value=64000000 +RCC.MCO2PinFreq_Value=64000000 +RCC.MDFFreq_Value=100000000 +RCC.MSI_VALUE=16000000 +RCC.OTGHS1Freq_Value=24000000 +RCC.OTGHS2Freq_Value=24000000 +RCC.OTGPHY1Freq_Value=24000000 +RCC.OTGPHY2Freq_Value=24000000 +RCC.PLL1FRACV=0 +RCC.PLL2FRACV=0 +RCC.PLL3FRACV=0 +RCC.PLL4FRACV=0 +RCC.PSSIFreq_Value=100000000 +RCC.RTCFreq_Value=32000 +RCC.SAI1Freq_Value=100000000 +RCC.SAI2Freq_Value=100000000 +RCC.SDMMC1Freq_Value=100000000 +RCC.SDMMC2Freq_Value=100000000 +RCC.SPDIFRX1Freq_Value=100000000 +RCC.SPI1Freq_Value=100000000 +RCC.SPI2Freq_Value=100000000 +RCC.SPI3Freq_Value=100000000 +RCC.SPI4Freq_Value=100000000 +RCC.SPI5Freq_Value=100000000 +RCC.SPI6Freq_Value=100000000 +RCC.SYSBCLKFreq_VALUE=400000000 +RCC.SYSBCLKSource=RCC_SYSCLKSOURCE_IC2_IC6_IC11 +RCC.SYSCCLKFreq_VALUE=400000000 +RCC.SYSDCLKFreq_VALUE=400000000 +RCC.TIMGFreq_Value=400000000 +RCC.UART4Freq_Value=100000000 +RCC.UART5Freq_Value=100000000 +RCC.UART7Freq_Value=100000000 +RCC.UART8Freq_Value=100000000 +RCC.UART9Freq_Value=100000000 +RCC.USART10Freq_Value=100000000 +RCC.USART1Freq_Value=100000000 +RCC.USART2Freq_Value=100000000 +RCC.USART3Freq_Value=100000000 +RCC.USART6Freq_Value=100000000 +RCC.VCO1OutputFreq_Value=1600000000 +RCC.VCO2OutputFreq_Value=1600000000 +RCC.VCO3OutputFreq_Value=1600000000 +RCC.VCO4OutputFreq_Value=1600000000 +RCC.VCOInput1Freq_Value=64000000 +RCC.VCOInput2Freq_Value=64000000 +RCC.VCOInput3Freq_Value=64000000 +RCC.VCOInput4Freq_Value=64000000 +RCC.XSPI1Freq_Value=100000000 +RCC.XSPI2Freq_Value=100000000 +RCC.XSPI3Freq_Value=100000000 +RIF.DCMIPP_CID_RIMU=0 +RIF.DMA2D_CID_RIMU=0 +RIF.ETH1_CID_RIMU=1 +RIF.ETR_CID_RIMU=0 +RIF.GPU_CID_RIMU=0 +RIF.IPParameters=ETR_CID_RIMU,SDMMC1_CID_RIMU,SDMMC2_CID_RIMU,OTG1_CID_RIMU,OTG2_CID_RIMU,ETH1_CID_RIMU,GPU_CID_RIMU,DMA2D_CID_RIMU,DCMIPP_CID_RIMU,LTDC_L1_CID_RIMU,LTDC_L2_CID_RIMU,VENC_CID_RIMU +RIF.LTDC_L1_CID_RIMU=0 +RIF.LTDC_L2_CID_RIMU=0 +RIF.OTG1_CID_RIMU=0 +RIF.OTG2_CID_RIMU=0 +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 0\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 0\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 0\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 1\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 1\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 1\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 10\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 10\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 10\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 11\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 11\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 11\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 12\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 12\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 12\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 13\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 13\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 13\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 14\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 14\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 14\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 15\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 15\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 15\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 2\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 2\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 2\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 3\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 3\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 3\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 4\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 4\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 4\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 5\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 5\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 5\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 6\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 6\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 6\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 7\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 7\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 7\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 8\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 8\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 8\ Secure=false +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 9\ Cid=- +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 9\ Privilege=true +RIF.RIFAWARE.GPDMA1\ Feature\ GPDMA1\ channel\ 9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA10\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA10\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA11\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA11\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PA9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PA9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB10\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB10\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB11\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB11\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB13\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB13\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB14\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB14\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB15\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB15\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PB9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PB9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC10\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC10\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC11\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC11\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC13\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC13\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PC9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PC9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD10\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD10\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD11\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD11\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD13\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD13\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD14\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD14\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD15\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD15\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PD9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PD9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE10\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE10\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE11\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE11\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE13\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE13\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE14\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE14\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE15\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE15\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE5\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PE5\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PE5\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PE6\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PE6\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PE6\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PE7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PE9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PE9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PF0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PF0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PF1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PF1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PF10\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF10\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF10\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF11\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF11\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF11\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF12\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF12\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF12\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF13\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF13\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF13\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF14\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF14\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF14\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF15\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF15\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF15\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PF2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PF3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PF3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PF4\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF4\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF4\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF5\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF5\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF5\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PF6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PF7\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PF7\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PF7\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PF8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PF8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PF9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PF9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG0\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PG0\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PG0\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PG1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG10\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PG10\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PG10\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PG11\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PG11\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PG11\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PG12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG13\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG13\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG14\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG14\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG15\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG15\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PG8\ Cid=1 +RIF.RIFAWARE.GPIO\ Feature\ PG8\ FSBL=true +RIF.RIFAWARE.GPIO\ Feature\ PG8\ Secure=true +RIF.RIFAWARE.GPIO\ Feature\ PG9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PG9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PH9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PH9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN10\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN10\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN11\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN11\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PN9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PN9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PO0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PO0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PO1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PO1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PO2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PO2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PO3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PO3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PO4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PO4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PO5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PO5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP10\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP10\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP11\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP11\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP12\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP12\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP13\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP13\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP14\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP14\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP15\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP15\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP7\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP8\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP8\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PP9\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PP9\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ0\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ0\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ1\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ1\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ2\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ2\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ3\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ3\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ4\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ4\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ5\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ5\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ6\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ6\ Secure=false +RIF.RIFAWARE.GPIO\ Feature\ PQ7\ Cid=- +RIF.RIFAWARE.GPIO\ Feature\ PQ7\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 0\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 0\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 0\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 1\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 1\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 1\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 10\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 10\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 10\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 11\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 11\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 11\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 12\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 12\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 12\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 13\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 13\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 13\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 14\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 14\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 14\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 15\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 15\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 15\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 2\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 2\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 2\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 3\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 3\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 3\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 4\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 4\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 4\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 5\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 5\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 5\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 6\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 6\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 6\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 7\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 7\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 7\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 8\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 8\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 8\ Secure=false +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 9\ Cid=- +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 9\ Privilege=true +RIF.RIFAWARE.HPDMA1\ Feature\ HPDMA1\ channel\ 9\ Secure=false +RIF.RIFAWARE.LTDC\ Feature\ LTDC_L1\ Cid=- +RIF.RIFAWARE.LTDC\ Feature\ LTDC_L1\ Secure=false +RIF.RIFAWARE.LTDC\ Feature\ LTDC_L2\ Cid=- +RIF.RIFAWARE.LTDC\ Feature\ LTDC_L2\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ Backup\ domain\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ Backup\ domain\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ CPU\ power\ control\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ CPU\ power\ control\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ I-TCM,\ D-TCM,\ and\ I-TCM\ FLEXMEM\ low\ power\ control\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ I-TCM,\ D-TCM,\ and\ I-TCM\ FLEXMEM\ low\ power\ control\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ Peripheral\ voltage\ monitor\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ Peripheral\ voltage\ monitor\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ Programmable\ voltage\ detector\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ Programmable\ voltage\ detector\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ System\ supply\ configuration\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ System\ supply\ configuration\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ VDDCORE\ monitor\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ VDDCORE\ monitor\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ Voltage\ scaling\ selection\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ Voltage\ scaling\ selection\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ WKUP1\ pin\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ WKUP1\ pin\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ WKUP2\ pin\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ WKUP2\ pin\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ WKUP3\ pin\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ WKUP3\ pin\ protection\ Secure=false +RIF.RIFAWARE.PWR\ Feature\ WKUP4\ pin\ protection\ Cid=- +RIF.RIFAWARE.PWR\ Feature\ WKUP4\ pin\ protection\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ BUS\ system\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ BUS\ system\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ DFT\ system\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ DFT\ system\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC1\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC1\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC10\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC10\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC11\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC11\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC12\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC12\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC13\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC13\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC14\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC14\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC15\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC15\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC16\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC16\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC17\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC17\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC18\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC18\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC19\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC19\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC2\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC2\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC20\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC20\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC3\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC3\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC4\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC4\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC5\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC5\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC6\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC6\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC7\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC7\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC8\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC8\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC9\ divider\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ IC9\ divider\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ INT\ system\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ INT\ system\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ MOD\ system\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ MOD\ system\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PER\ system\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PER\ system\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL1\ configuration\ bits\u200B\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL1\ configuration\ bits\u200B\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL2\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL2\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL3\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL3\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL4\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ PLL4\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ RST\ system\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ RST\ system\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ SYS\ system\ configuration\ bit\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ Protection\ of\ SYS\ system\ configuration\ bit\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ ACLKN\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ ACLKN\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ ACLKNC\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ ACLKNC\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB1\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB1\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB2\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB2\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB3\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB3\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB4\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB4\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB5\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHB5\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHBM\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ AHBM\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB1\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB1\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB2\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB2\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB3\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB3\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB4\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB4\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB5\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ APB5\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ NOC\ bus\ configuration\ bits\ Cid=- +RIF.RIFAWARE.RCC\ Feature\ protection\ of\ NOC\ bus\ configuration\ bits\ Secure=false +RIF.RIFAWARE.RTC\ Feature\ Alarm\ A\ and\ SSR\ underflow\ protection\u200B\ Cid=- +RIF.RIFAWARE.RTC\ Feature\ Alarm\ A\ and\ SSR\ underflow\ protection\u200B\ Secure=false +RIF.RIFAWARE.RTC\ Feature\ Alarm\ B\ protection\ Cid=- +RIF.RIFAWARE.RTC\ Feature\ Alarm\ B\ protection\ Secure=false +RIF.RIFAWARE.RTC\ Feature\ Initialization\ protection\ Cid=- +RIF.RIFAWARE.RTC\ Feature\ Initialization\ protection\ Secure=false +RIF.RIFAWARE.RTC\ Feature\ RTC\ global\ protection\ Cid=- +RIF.RIFAWARE.RTC\ Feature\ RTC\ global\ protection\ Secure=false +RIF.RIFAWARE.RTC\ Feature\ Shift\ register,\ daylight\ saving,\ calibration\ and\ reference\ clock\ protection\ Cid=- +RIF.RIFAWARE.RTC\ Feature\ Shift\ register,\ daylight\ saving,\ calibration\ and\ reference\ clock\ protection\ Secure=false +RIF.RIFAWARE.RTC\ Feature\ Timestamp\ protection\ Cid=- +RIF.RIFAWARE.RTC\ Feature\ Timestamp\ protection\ Secure=false +RIF.RIFAWARE.RTC\ Feature\ Wake-up\ timer\ protection\ Cid=- +RIF.RIFAWARE.RTC\ Feature\ Wake-up\ timer\ protection\ Secure=false +RIF.RISUP.ETH1.Privilege=true +RIF.SDMMC1_CID_RIMU=0 +RIF.SDMMC2_CID_RIMU=0 +RIF.VENC_CID_RIMU=0 +RIF.default_config=false +USART1.IPParameters=VirtualMode-Asynchronous +USART1.VirtualMode-Asynchronous=VM_ASYNC +VP_RIF_VS_RIF1.Mode=RISUP +VP_RIF_VS_RIF1.Signal=RIF_VS_RIF1 +VP_RNG_VS_RNG.Mode=RNG_Activate +VP_RNG_VS_RNG.Signal=RNG_VS_RNG +board=custom diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/MX25UM51245G_STM32N6570-NUCLEO.stldr b/tutorials/stm32/nucleo_n657x0_q/minimal/MX25UM51245G_STM32N6570-NUCLEO.stldr new file mode 100755 index 0000000000000000000000000000000000000000..b6a533da7d1f2d841dcba01fb72dedf1a6bb75af GIT binary patch literal 1899280 zcmbq+dwf*Ywf{b6-jgAjJb(~}aArtg5~2=>8kFiu1|}1X5Gfc31BuoX5}Y%W$NawQ%mmZhd;j|7 zlYRDHd#|&)kfluQuf_3Pc^O4Gw>XMND9nHVvuQtyy^4 zjn`eaVBw<6D%P&P;kru~UVr&zS9mVE{zh-rvK14Y{{MVkk~|1c&+LpP2-ef%+p-e$ z|MORRFsXdnhSoeo_=Pp8i zrOc&MP9I|Ic7L;cyPrwSa-V!F{2ucr`4)nQdxF7=?;;d3*U2}+7tI^w)$rHJOiA#o zD(wd!&E>6W60gkW_369Co*|R?b1#eY=kmPPfW2#=ufOkX-gS}x zLtG$OafMc{S@Pw6qkNg)B3}x)$2?W@nIcvPD?A#mNfaHyiuuIJVw6k#U-!-TpX-}P z)E1_2;O+MR4e*&h7jdu*_Z9m8(pTV@`|^p#`X%Cf`<(uheR+UI>lb~q{U0GM+&7Kj zv{QW!|9gEi{YU$<0Ef~}^v&>h_2v3|`qBxueF(gReN+91`mBI^Z147E`+o)8_P!fJ z{7rf|Kitx7{7tvP)xs437Ps>^eF#4ccLMGdoDBB`+!;6(ZWPW2d^_AlXVn#Yv@&Zs zah7qPskYbPZsR#`?~8(}BO8}X{IIyGrQ90+OciXLRHk6m1ekQ#w5FRA zvU`DZf3wtnKD0F>qEqy$(dU*zCd&z48Bc^}mYsWa!OrsY$92eOn%s;YB5v$BFK#tQ zkc(YFF3#aC3(VdRkY}?*am*SRvN!?Tsa*QO9hT2j^;Y!D2R~DX8{i)FnwIu{tS%Dt z#iq!s(o6MnJyV`Z*j=v%E|v|&=Ey*u>(0QPO!;wQpyu}~YcG(Eh@Ic?Qj^@olu%;D zaHxF#`dnF8Y>mus{8-HqK2~!XQ|_h|*ZkTv*@Tn^q&ScwAmt9EFjqtE!T?I>p}ape zm-oM;Ln%F(!yzs&{ITk0DCf+b<$Q!G^AZO6GxbYAIzV5HdjbTDj-BQDZc%6t5OyNk zI!-mr9A-MAF9Cf4Fo@oy(dPmp`gc?Gwn_9Qpx>0FS3-9ay$AIE6n)<~<+mh7|BDp8 zXA->!^s6*_-Y^H!ED!`pbH4Oa-RU}}92?iW<_FBO2XbqWT=g}O@X>Lzt0Ay3pp)&z zsDpiJSBb<^(tyY?&DQPTDmF8{0Nof#vB5Kx3 z!`wtovS>?DFVm=Zr>OH%)H^3plPu1Tku2Xa%|cyDQ5TY8Xk3RHkOYI{lgs^T)5q!( zJES!~Tdd6Y_H%QHCfob!_qUs-gI*MPjXnT+okm}+(Q~PK6TO(~0k3|aH(7fJ8a`HS z=qu>G%A#@fm4yTA7Y5!jI>2qIaNs@4BnzE~XfW`?`j8Day4;$^lUNiE?$eci{WwMq@9o5knH^2DD!2Zi?A%Ala=!-7S$<>tDL-G;;gTF_d%FtH@0!Pt=|` z-v+87-73hA&n6lzR|C~H0Q$6VM-}S&8u7rWn#?2Fa{|Ki7)1|b6fsYaeg>#((e8(4 zB*(xFV>a~R*HX}iG3wF30F>-Agqw(-8KqX=uF*=M-I>C^T%+BRf+{rHdnVCJp#4Cj zE!SupLAxe}ovYDSrJy2>cIhPAM$o>d(efH?5VY_|ar8g0%b+8}73)M$_B zsJ{1rR?SV;_moEaWeWOgl4qH~jV;t5+1?5Y&@ zV;Z(N30n{BjASh|Y%{P6QrLHE*p5lqW?-u$)W+o+whh=Ug?*cbJv@CvLMK%luup5) z=y4D7yc?yl)A+$^^J?8oji(!#vSIX9ZB59;xD&TpA_MiVrW&jYH;-amts0mZS6h?g z>JzoZLp(5!*3%4E;yJ?QgKLg(V32K1i!?NxP(v8g*rzF_#G$+)Ii?3g7dYs_AqV3{ z#3=hf)qA#c4sgh&a$Q5S)J3B-2Z-0uJmnZojq7VB@;8GzH#LqwP|coljoN`34!KXP zP{=(tg50$gYV!PS2esqE{A~C1XmhgwDVkGK{Qd~_Gm$EnkUEv!uTg&ph^Q}5QTI%0lLAoZ5%rvG>>G;0CsjY=-PTA^U0cIqk@Lz8Vt!da zD-(sHnlxGGPK(sl35}EzXiTPrgt{6J%|GtsNcaS6HMrP&%w_#O>;pjA3eU{|XKe*c zl`MaRMxvO4R%_*4G^t#){)OYzvoaOEj;I%*Ub!j!M4YH?DQJ;Kt)E1_2-F=ZYO_XN z3hFPWC8Z*3)TdI=RE;_eC|UlKYAL8&Q`B~idI_lCNa2rZ)caG=uj14`ZIh^%fcowf zwV+Xppbn+*|68MOPC-v<)Qyv+FQJ(-b zA-QT$e-qPMZ8)@^^1cDoZ=~=88ue=_NYtp?CQ;u2>OZHbnMS<^)H_o6Wg2yJ3UX@H z!AaC>Kz(Q;@70v|ZJ@4B;kz_ye+uF?>Lrt?Zv*w-iM%!H0H}o&zD}dgNkM;&QJdQ) zQ3pW%z(n3&%9~coFLRPo`yxiY^@|kru10+l(1g@zrMz__Z*M-RX{~%ah5ueG6V&a1 zOc=wzj9F#YU4`=joijdDUzo&)R?RCWN^$8-@S$}xL>Qpl7fZ)kiD-f;&ReyTNRv3w z+Bt2aB$v(x2U zOi-AZh<>h8m?=M3bGk)EM6Afn8&a6rgt;Y!`4KR;0Q1Rz!NmGeiGBH;5@6Fh`$qQ8 za(kq>p{?n3)0HCct;{d)=gN!M<8;wN^2%YnE{ExKpQ(=nb3*RTseJYzpJwE9%fIA< zvr{wj$@U;0T4iqlbxtau>7ohwRP=KdmuUHV>)<%#S1>6*mdY=H{BT-V zT>p|^rV`RwaE=@1x%!i;S#T=i#untb>InZ_H+*6F@n30DWd6+4Wce8pj z%y$MW7;~VW4%E}ZIGqFKaG)Fxl;bIuNZ1%}vN0VTXR_%L)+4M(*o?3lVKc%ugl!1h z5Vj+1N7#;V4#GJI=WwPH;Fkcm1h^%@D*;{!a7utvLg~5ib2(Ez)`^!`n=jQ^t_p|^>}>xus>b#2(Ce9P&T6sKaT4d=3N4@dhgz>Rgbcm9PY-x{z|#Ys9`N*lrw2Se#M6PW z17QbeS_J-!z<&|=F9QEX;J*m`b8P6tHjI}X_&J=8<}==R(OIP;4O$OwE=JpOxDVhS zfO`xs53V1*0P)q&!QH~Bh;yd1cW}&LbUf} z%BfU1gnefAcH)G1gy*Nip|wo8eIg#=TPEUHFy*@w@d)2A5r56MVTSO^iTF#t4KswV zpNOB$lxrvWAnc!r&tS^3iTH2B*t;_2N6C2Xa+&h8RG7;D*+e|Txese~8Km-GmI^b3 z7f!^l_%_TCzT{yJb!U){=VAUrNS_K_{IEF{DtXwR3Kc&rq(bh8#Z+kS!>>cvl;lHU z?Cv$5E{bnThVv;t70#phwaNHt6rT!bQT&Qzd^*La!d8mECK+#}_*B?H@s}jy^%S29 zGm4*`j33>O_*8fV;ZR00K2Gte@Hg9EhlH_vh8)gqKmYklO<78izaeZdzCJ7zFARH% zXNARLTe!M7BOE9;hJ(e+BfRpfI8*qMWwPk=%0*J8N$f54U5${%bXBj^*aN+!j$I6# zMY2V*7#H+1#XMpOcc5+Z@nmar@f6o)g$rb0j!Xkqr7<5^e~*8oVWnwUh9nkN--kx@ z!1Rr9covMbkDOObvPqy5icaR0JCM^m@qJB)hfL02$}ctXiitNB=brrROqOEdFJ-yR z%wFL>;r4Ss=cqhs$f+luuH}@WZB$~Wd;*_((sB6W+Akx2 zJZ+I4)t%`*-N2LwCXvw6;pmgxZwY5_-w6?u-A4*s!4VRv6r-6{&-FO4&d{Oj@K1?P%~bc z?>6y8()-4uUcYZ1aNpM#^zN&N43_N!#r$}tR=>%T%z-3N#!ZmnzBtKqYn9r?^XO1b^J}qxy zCu^b@TPo&?w?9+$CM#l?MsbQq;}eB zr5MaU(a?eOZA}3{J$SA}nIF}U^q$t*<22f1ee6!HZuDep=_#(w4u1!D?;A#X_tk0b z23_Zh*v%RqJ=t1%ifacVt!S4al_}qgWu@goqIyVF+++_Qz}TIIC)~9$Hf0c{0_9*rJH|3^{mKm|-TB(<6rM_A#b!qrNk)9k)arH_q zeUX-av6lXIWFBf_*ZRgH%r_TfzDYyBFh`2eFAV=QkGxDdp?}q&e;rY48Z#Af<-hiC z8~V2tqyD`hM*TY@M*aJ^O8t8$<_l^~{&QZr9(8$D-AcLJIn4qP+Bz-Vfi|6jr?_xS1^{5*3s2nY3 zqSt->_Qd?)>!N-(MeA+U=SGdxQ%8-|=Tsy0In|i#bBDTS__O61{!F+GI5V6P&H~57 zF}Nh=@b9LlLW%BaNSg)=lvj)4l+wID5G9>%c$fiuI|;OuZY zaJg^}hJ6ei(sS&L%fW{FP6x?8SV8^uPS~Z2>MiMU9O;LSuz2!n`jh0$-A$7~aTd#9Vtf0q`-}{*ws0&IWn~j;+tul9h_gTzGhLx;n zT6mLmk94W@Rnw6nejV5P?$D8StaXmE)%)I1nhSHas+Z3+F^&ginyU8+zWcgza#401 zh;kU5p6QUT$l_l48voS?VIeEPx$@?aA-#9MRK_wvSFYt)g!zVYG>4f|46Z1f#`RK- z>(yPJ3)HnYi<7A5{0lY8ae+D~MV(`2x>uyvqz36C>3^%qy+nah`p}*erDQj=3;86X zUnfW|-0lVy}YvUO`JvL~a zM)WN`miNRZC^zO)cPUP-JHC4vpmzW*0HoY}F`$wda~Ff+V&pv@Es9+tC!!yY&qhjF zOo3dMYVp^^<{wG>X56&-PK?%>6gu&DZee#`^mb(d)-Q>9b)x+c2JO81FWW zcN@mL4dcB8a0%ejgX7VksWc{DgPzQR79-u?8r1L?DVVf>)qr0}!F%AZ0K7W|x4^Fe z{CEo93EvBNM+zq0;8lRPq+rqxih%D)!LLF4OY+?hpYs0&{2KwcrQjFfUk8{h29&-V z{&xVkq+qfgTox{qIpvnIMD(d~vTV{iU>niz) zs^|6b=yt3QTVj4qu7jFfjhbAI;pxD9ZA_0R2abv8LbS{IVVgV_eK+Cn7>mA_V9F3y z9tu(4u3aXe%@`|zj7vzym{Us+jzyIO$@dI2xK#cx;JZ0irU?l~A3I7hjXHqcrjSYaQ zZ_I`asBa{nw;+~!2uX%|$W4H$hY;3I4QmIU*CI9qpRl&TuLax;pRn$MpM2hoSh743 zRwMlH0w&uNVby9_0X(Y^dmDVhS_6MM;2Yo*RyBO=7ho;ECR~9YYC#KKjb2(dW(LFq zx&n|N(q+mU7`d0BRTiPW7NET@hjcxucCl#vlAhvPOW1|B2#lKWd=}Olw96>9&R<8V zb#lOA`}ocd=n)|g1%u?_uYD(!Ue8L}wPqJ51@R#s?fX}4hFW^%v$SL@g zmR^Zc-akSX&P4P#qh*jvQS5517R-GWWU^zN%DZ(u4fV|(or#o(#+mzKq-@nv9vDyd z2DLmE!Z z47I%sr9%57ry`VLXpFfFQ6qJX>Z*)cQSO&U@{n?V>?lf`j2{|H)>QeYn$p-_t<`it z&d!PG$8>hq+Ia`|1*KTa$D+R)GrE^2SH83iNBNZ%j8nSeiRd|$3>P@OS)mw2}9>+5)#qqThxjrW2_Js0JKsDT4!mhwM6*PJB2<|OH(n6w3rtWvJp3}1y$*klb& zJ|9G^0*HFhm+*1N1YBu7p}BJMdP3!yyq-{bCa)(OJU$&MyGJGT#h+;L zt)t0N@mFnBq;^!{S-?Gtvtc5-61tD!^HV|f*O3(Y*7U!Q__2n6ag#Rs zZ_**=qY+pouA_YzHjvmq(>_|WA22=o5}X;%2FDD5;mmM0xYQmiX~P=7En{4Nq!WH+-ThfKP2Gz$YvR{N(d{h|Nu5<-lJL*q*|&X;@}F*C198 zpLj9&TL6#3a!9;X_{rx+#0~=@ECoLC`Z9$@wpU0UPvRxRCoHnT`T?JWPrS$qn|yvJ zyaK&vgPMpwhaU7|jQY~|06nci)W-I4z3)3{z2=c*k9lB(W~qBesK<<}G><+wLOtdO zTKs0TI_<&#c^;)6^B*|HC8Bz*-&_`>c{B^Oe~34u-yB8H{RVxILZ#?6uPvor;P2yR zZQZ3=ENMF;yAj!p;K;5-HYKtrp)Y85B+Nx6usf8%-cW*mQ3Cry3HnqC`cw(}ND2B# zNiH1vRSEi43HnP3`pd-riu%Wgaq1s$=ZJZ0ac(`St`D=>w;=Q<^?P_8Rd2xauu5qk zsJErk4y)e<{HB)nx_TqRZ>y`2R*lf>>UDU&rY^_xmm0>e)s;wFp}|#n{#32R^C#*? zJloW}kk+Wdb$GU@ci{P`mUpXqE7ES(;G6K=uCB)OLDi4v4s{vQyc#Uxd5`*?@by>& zHzyL&U!ye-sb)Z%0R20lS5#`(f-${s38egZoX%roQQR&-yFMDHcFoe-^{IFO?b@ov zKN0`m+SP$w|2sG}WA~u(tR!90a3;8ZigW8&^b~rLb<_g*RLs+Hu!>ssQ=D6AH#M=h zB|8-y+EBAsq1`l_71}BnZIw&ylS^%6gb$Zvf^Rad7;Y>R^MVyChQ*qszjb5M4{0#9 zWnYXHbXETDIvN9Am9#^kr=$CAJZ)imI=bJ&b4Hk+j_x<{w1gL+HrNOHE<#!F!6~pP zY(l6h=7uclW9H5SRf1gN%SW6keiC)GqVMWcz5bu~l{QFcQNo00J!CW<{ZWF$^S6nK zJ;cO*K52i24HouTJIeiIlzT7Ak`<WBVB^oN?x!roN^d1>}s*mg+{wcz(CsAqT6lU#0irv}rL+|=+R8ca`enc*L4Fg?l9 z-ij%!#>btH>S`_i^3-YYpXUS% zaDO>Ya*5-7g_HILxzPTEY|;PMIVWkugk4gzS(2@iY?N?h<0RWA*)++Pi9V&-F3Ijm z_D-^Ml6@0>OtWWV%@Hs^2$&xP%nt(koPa(jVC@kwM+lfB1k4cv`k(-r3VI{r;cRer zIP^&YeUkQ2r02V!|GS|3gKbl@fs(zG?3_vare+@{yC~T}Vf!R|r)DoDJ1N;jVGCV^ zHPM4|c~CA7%H(nA5obUg9LnTDc{~mS;*5xcLwP(Xi^lQN!VLK%o zD%nqMxC@Y@({xyxUXt{Cc8<%*g-hx9NWYeYdjWJWf$j}xcOvMn0^KD*ztZk3;7&p5 zL94Gx(d(N#Z@Bg| z2kCmG&sNQyyzA4x_U6g4If&(4;XaQRo7+JeQReJA-eX+Z{?ToEDesXPp*%o)Vt;gRj zs`~lwo7~-k%Fp+AGnJdqu>Z1GTADe56|o4FdByMpo2FcQU}SL6A=&%}*Bc{)!^~Nm zzcjEdzz3LM?=n_eC8Phij_>89N(a3$5UhCop4>%y;OsJ!Ti|2=W1+V!@?^9bLi9EU zb~y-z%yxv#lxj^wh~C7&UItoC(W*n}3_?BW$+t1EYXKCpM*FaDF`vUTOsUqdwNQT_ zz3H%{UC#p8&$O?BYyPw92*I_hP3B=SH%$?5CC#s{#Vuhsy@$eliyO8fS>#&WuqDYN zYq?qynh%?V-b1i2=61gYP3-irZVzc>xrk!OJi+fJ`w925QsJP%aDr*!`y&es z_x1)P=AIRHHt#eQ^&T2z85*CAEbuXR4jR%=@bEhf))O53jRxZh+{$r_$_t?d261q2 zNCq`igzcLfg*xYO&qmI>xps470O4_t?oe*76`G+p*?$-o%0sY)68F&B8CoerS}C)& zQc}3xFhwgRg@Xo@R?5&?QF&U+t0g4YG567MX=6>jFs$0eeoia}cg`dZ9tyP~4SSOi z=VZ#)F{7_k>M^mw*FuS?0dIWp?r-q6NB8M~WOtjp-^VxW;A6FiRgXfB&!g(Z9RW8Fz(VY&L97N zAD6<|pkegD7MF;w)l#F!*YpX^Wu{wu+ax|E&&$KroxDa7Yj6&S7R1)84FaTEB>T_t zkaAi?ZQxxbXH`oHdDQhJRT^b<0@l)<6X_z_K})w=ZRB9gKiFQ8YzDqp?$Fb#%klx;7hbL3o1l81|eCB4&ACJzs=76>hq3 z{3y;B^CE#p=Jo(@DTmofd2WP52}LW-3|vtjupU$O-3)Jc(HX;%%7tzjIJ#lWU5mRI zYwx>2{WIj!6tT!Pjmcc}5#o6x@~MpocQJPfFasQqxI0jjdX@O!a)CcvyYd2mrtxRs z&(``bP&I-7HQ?{OYl1)VDg^&U5xGf#oVIW}#9X1(q9;`g2XdKrAr}!hI+C&?OEuL( zL@s38o}gY5mpYkXXveDc)aj;VPTxd`uY&vs!O|$?9+aj-st8|LEnpz`RLGoj% zoP!nUH}*ty2DERE9CIKM&Cx7JdUi{g<{D`=hxQigit5RVwGAianK8_gc-thP#RauE zE8?~xu8rb`+lap~yiaSGb;3rEOo<{p;iaYmcDdx5N;O;nV`VMB%cJ1!G zTk0`RmD^!QpAzv%&U&W&Rps0dMKEU}{2SF1;Dl1V#e{d$u5n9zL^Say?vk0QvG;6U zKynU?3pnrD8k}xMxB1T0)zG_X_Vxj8wke#5wvDz8SeUr%9OkkoW!&siq0P=R2T&8! z^%#qo_qXOos07Qvtxckvlu2$6j~c;kpQQCUaJvHBHjjp8ipz$MpX`JFcxyo1_80xtHGMn4Q&YF%(PBC=MqZ; zhx?eDYQ{`&pWtNC)Omsvu8{v(ilnz#1Sw8#DT?zUZgNXe++~QH+)@-*KrJw-r6?|2 zUFT;KS@#mrp|{{aT$xYvX0SqktO#?W%$dFJbr&G#KS5=aASE~n^L?|}f0z*+$xbxy-Sk)^&ta0u|~c{rkerPIk@YlCT~8`6YoxG zcONXk#d%7lv(?+sD~v}^;`})twZxXnl#e5s4@LrbV@^Om8ZC`3%4bn3p8|QV>_$FH zHdChmpZToP^4Y27^9wDXUezvJB?~Oirlqwhi#~QDIy*+zYZso-jVbo7N9)c0_bp`O zKPuY0NEb_X;}G10PL}OV+LUQ8wHt1$lMBH1k!_W-EO=YS| z>U1?6?wJAh!Z{Dul-E351HBVyfV~>!DqrQ$tt(%L_dPGb53f72Zh76eux@?%`bRO= z#Z|bCP*&;KzW(rf(#NwFyi*$D811xdKIoQKL8G(~yEGT>wr(^Gu&KHMmd6jU>0F$B zBS6qu*V7sGR)SmK6lxT09&7|`D zrcdXd9|=fDHH}rKrsL$1{(QWxgDKxpO{l|VY9?Yr@g7h_KYkHw2Pq25Ri@QxD&BC(j+9CQ%267iH?#HNmaZDW?Pe|i=*Rc zl5N8A`qE&C-K#i$YdWp31+K8&}nJxZUilE0bS5?1mwg39LOTGQ+bADDnC*r-d+@kiyjH!JAFZb`>g zb?XF9ut=Ce!ko+QQ*gSo!5)^>6WKIrX5dL{SuUiNh_!cOFQMs|xOfO*9d6Mjphc-h z*b*=8GypQka{*c7tdkX1b-aPGYYV@Dv73SC1gB3lPN$%4NIb z-AB;4b;} zRkV)rsfH;-JNE+_81!pd>Gl+6fNvgzSlJJ&DE30wG%__m?F z;@bl{TMsAV9SW=}Jjy<52cOpmY_|6~^w6^3^x0XkLS$CZn!|S7gWKJmi6<|YD+$c} zVcaHf>E|-U!N$-w;Cu5h%FD0rUM=?Iy`OvBvKBSY9uPAYb-zAPmLbYp1|q9%$1!r9 zu9J}gQLr2rt?ur%{neZ}@FCvC7xSiuMJmU+RgM->w65r1GUxRHe*KPaHgGpH$=JWL zylJ1Bjtp|RWtWTGbLWqqS`gQre`mi=7ZI!anX74N8e5f{aeQ_E zk=0fGtN6Pi(dvOLp`2wwdZpdL3c?6htnTO6yZUVx(t{P1d{*~!ea?JNhH5)-PMP%qu^ihq`S-3)@JZj(#3K6Ure2ZlIiBJ@^CNivCRJ z0o*L*M(nP@(0?si(a*cSh5yqr0UQ64m|yhCZT;0u9C!z<@XjEwBbpiW#r`VJh8mYC zp^eT{&bUr_XHd}X6*IjX(X*=uY^cNfWqI8;lxp3wESXBfa*4tiuFTDgP^e1lDeq%W zXhInSKB6#24h-1%^I;Bs#xDjdmZR2YpI>C?iGVt_{&{Yf=EPi-VQEWXfGJ?$vqAY5$dkUmWFMc4Iz1KdN?;-!f(uIOTji z8QVYF*7>5E&a7^Cw?!}vzQCD-FRB?#@A3zkQlh?ydySb1>hYOqU;i+!mML*w|8lZ)EeE9B)bX1=-f(9*JVI~P>FeuZ>< zM=9Z)`}YB>iH-30|9kn)?s>rH^J_i}7^S~GuVWwY6H>;U$iBW7^4 zL2o$?`ItSxQMO%(!~QcRiQ7%FEev@jb6Ol<{7{o(Fz)L(^pH2d`62$9E1RD$;|hN$ zeszFrWzT$?5r61m@zVoI>^Eqgo9pq7cQF^Iyx)mg30#?A?c{`DSI5Y?^MxH9Bj>+4 zQ10%&Gr!(}n86u=InoU211Zb8te-FZC=k@7;0y?}43$;j(jL)e z-+Q^}?C^@m+L`MKl@q*@zR2?Q4#~Xx9m(|cdv$!Bw{AzB@tNP(8|uSqK}%S5w;7)G zHH1}y6xu`TDm!|;J*|kH z+a98HBmOcoXO&!8x#oLp4(DP8D~3b&!uE6XbG{WysJTF9b97p)crRiQzd{k4*<729 z*g0lkiyAgk>L~>?^c}`|X`o8++5n6sFNw`H&wJkIr*Sn$%STH~Qif=UdWU(Q1F3e6 zZ|GlAbLLHv=~VVpDw(85*sq1#G+OICaJY4bO!-ZdIqdwoU5`qCQQbW+sI131tY((= z+sgiez1D~LB7{M3=Pq#DW%b0%e zZnc`-f?1_HZgytwLT)X_pJY7Sf&2FQZpfk9++ru)Ws|KNb*aWFtOf7<#EgvI{9c3a zym*+STfp8r9{2dN+m)_naHg?74Wp(f#s6pEFU0v4-JXnRIky2Ts;MQj1rpn2#M|D+ z3$VB;y)|FfyK@m^Y;iXqahoH_+%qG3fjKi@pnN+%0QM#P=V3#1(x{5HD{iGAt0xy;HQQUt;&o}Pz<^7B)-$#i(&C5~tqcKS0 znT(&bQ~%k>xii9eV?Ate+b{#N8pN%$?6S8GHfJJl!~{((>B#%X$Xg#N!)$|@2AaSL z=`?84p*b5XQ5ogC(>EP!QQlASURg>?<)C?ja)ta+D{xz{aVyfeJvNEkQmr=Nwk;{` zbku>~6JW}?szVEMMbvg7l*#xEaiWraM>V8csxa=>WRdIx{kV5{HQc4DxjVg;?p&Lg zF>+JKgrwfXd8RZ)X^u~mlT?2K1#VnpO-NE@fJzs+x&yae6W`)1u~My1WbGnub&z}2 zA?7sgVlKWVvvmQ>cs8pQ`T?yEUg=9e4cSyY-EQ>Jie((EHtqE}UYPZwu{(3u5%i&CkC=jCArX7C+mF~=o9%q$>-G44*yO$_!HD41NO0epMF11 zI0?Ixxg?bN<#A5Xx0tm$TnYGEw5t=+nHIsBEfw#0VIfkkR=oy>o#^~b+ zZ0p8qChWy|Sgx^pp9??>DQJ3yZid=^aL8U{h-C8g1&CwbV+X8WJ9dr?{Bipg805d! z4K2i^KM|kgU@W=!U~}2LO9JLO#XhF3?uqC_V}Z^hiAL&C+&471O_BQ?dSUPYU(|p6 zT$fHb*QJLetKv5FNImE+gKP8|-@H+pt4?Q@!CIar$1Q0SAeN3$xD#w3IlgjvjkyA801HN1y+ zgqxinpSfTpS`qsIX|}X1dFF^U>cq|bb2D&9V`ObVvs{aJW|W)Fi#V@!kYh!Gwee8g z{ebA$zU<6#CVZr_5UgQ%ll9aqA)ggm6f<<@LL=U;5u|__6u?(!j+m7za!V!m>&$i4 z17>$xSajRMAvfMMIM48=6*Q-K(_j_o=LB4{OtN*bl&3dm9xvt)7I;>CEX?+7mY!#3 zPa=8@H^e>&e+&tbZi2>7$Y+M^pp{$B$>z(qI`*h9*wq7-_zu;AV=nB`M6^KGh=CPH z1eEWq$eagipo=M}f1WLzW!9v-e^l;V(1`a!gp(bIhnR4v(_-BT`@?cm)(Nx8e&Pe8 zwU_o%cfkJgTAV_A5&C!N33eK}6ShJoXW%SPBjuvALy+_j+s%W`rqZpf@MRx|FPNDM z#lZ&Xq1r3kU|rLn5FI#iDm{a%saE-BjqnQ5$cJKOE$ilNdF4uF;o*|umo7fTH zog42L>XrMQ^%m>mpis|j&Gbw^6b#fuSxd1S1N9l-Jf4XZgpjhawAtU$R^KzEhyKtX z?-?o+$bU0%C>8(i9HuNmJcs@2l6X8&x;crz!;8Dfh(BCS{*^U{Hj5gcrR$-gjfXN| zMTkF8BiHX%-F9$ax5~jO8Qe;5#y7cH$R)T6-!UumcGei28}D0iZ$Ro9!T@pGx~m1F z;JHs|v@5!dqDYykptl-utPa+<{X1cG+#RAXo+Vr-GxEbTt(V@*l)e~Z80E;ZcEFzz z?0IL11!3Fl{xn^uaJr#;&)sX3?MiM27d8t2)n_d{bovuD$8$1cI=I|@AKsn@RZfbF z0{Ax?SCk4|z8j{rq;=PGzfNes-(o83UAUPqzWS8znal3>Y*st8H=P832Z!$g9v&*U zZ_m}WTC5%SbAsn?XPr6SjB~lZ94RXwLrVMoJmQ6i4x4zq`Nx#|VxG;sJLA(p9m&Dp zLEk)UjOl?xJ@N&uN9y(jadz8{`zo~Gc^Lkdh+218zr5G8S?8{ZcpkK1w?ewSh4RAt zU+v?B_WRD?_fo@=p%Alo+xcGq{;( zkD?9Cf(51R(HrPJcvh}hE-N4R_iLcuV|16u+x0~{N7yN)m8BW5u*)W71 z(E}TmA9(ZIf57kBw3#U{#TRbf_yanxB**VwIhmA`6pxK?1!e#+;2M_EN zMzy(v_$HwcpfL?v!b*dm;+t<4YbW`P*-AHRK8?t&oUyJqSqd}ke4na6cAS@aUjy!w&}vYMyJ}Mk%Vgso&I$Wi zAs1wOK2<&TmU8p)Pt_9P$k4m?(hgnAk)a*j49ukd!j^Kw@uTUcunsxySeb#iQp6dL zA0ApN<^mJ_c!6F%3_1;i3vND&9%*;#c3EY$Zo9#X?==dnC&L(~_OFEwlQa%YPRG2b z=?b1ojf84#jHGwmAFOx|D-(Ssv;95_XKUf$y}^oG9k_?j2P;RH*<4; zDt<$!+Gm@#yt2jYF+o%I>48MFas=yTfq+x3)onVKaqgb-g~%UwXLI~i2J8i{K9~cY z#7Ae@jpjM^K3Z+?wzK>Gh!A*D)!Ch!UQ`V@OB$Jlr<)MiD>2SngESN4ps@_O&BsW; za@ceOw9%X(1l)L2FXaC2aXNo~V7jea?{o$d=+6WT(qM-dZaP_Y#T>UDA#r+f(e@Rcz zOMSY+eSKSS;y--72XE5p((}Sks669rbe`s|L5WW5x8`%{Pe3Z1^$AFYw^5y*z#Gg@ zKt4>V!brR*(k`)d8~U>YQglRKmvV^%Ugk}{{W&Y*sblF@q}y;m>e9MoY7n#J47Itl z9ck%E8&@$N3#Z7hr_vRqTM(C4sFO)sk%-P7apP^!87K#5|F%rLCt0qU>61%#YyR^G zra+gQr2I8bX{vXM?+M)8+2&h})4FcIF?5u1Csg5&}`A`UgcVNjO22kB|W)U`w+FgHga0iz9eHFKuozdi?u=f5_pK;!Zo%I=wY`-}MEBaNYl#pk>~6sLNhP;J$SW4w#C zKA}!wx>w76?;l9g^RPM8I%#Kk_xPI5#S)c@%J*%_4yvrf2EC3!)9yk4dGJ9{B(3cXd1?^A~L#WTaxx^}BUJ5$!8O&3Kt>>WxGx`cW$<1kJ{ zeEW#nm2={)6ui~s!c06z&6l+koO>qlI7TB}RCwS)ouzTRQVn+UpeCx)goydXqPja1 z=s&<#j8sx#T30Q;ADs4g!ZW0H)n6YX>(dPX;f9PttTuLchkzRI!KJvEeI|Sf0UNK%8%N_0rY8rPa)==k;d2(PFmbSgaO1&IMds z28+}A0Fwhln6WqkPPUMhL(x&oe#rif9Yv&-yN+uCj?R=Zo9agIIv9L8gIosWkNbMH zxwv~fD$Z;xj~`#q#k%Q!o0wbaaCCPJavW~XT@=G@ImVWEFqWxuSFOrN+*OWl3afp= z3L43{BRtCH8ho}+Zf+ZDdU`|Kop|FkB49TEa0L2Ik8pLT0$7lEiR?FgpskK~>v2BV25T+PZ3_sEIGfB)#SF8|Z2{7jn7TRVz74$4 zw!woLhuVr2LZXG~GS#xuT***3@Ng!1K(>#JFi=qMQxDQ@2$QevPM$PW$`aL%XSsT= zD+gyL+^;~aNiJ{?Bh0z^aFL`d`Uf!nGbX$xZ%FEBqA`yBJ@Rrx5k||Am`mcFE7zUt zDv~lg^~eR<>mpNR-<<{6%jsP&0nTv__3=d?Augxre7L~*Wgm|dr;K|gp(f}>G%ea# z^!B&xPEI(zfvgy#WlVWi4dLs`4Em8A=zGo1i{zK@)EBuUtWk8FsXf!UzqYZqSh7n3 z?oVX;%mMbS*T=c&Uz?(~S%$Tcqx);Cr=q}sEMmHB5u!`uTA!eh!h;86Y7sL(_T zcIVj*(BE$(>D;0gNsl$cBD{dRkaxMl)2Lsj=KqkJ5s$N*kBuH1dMV%=7_mU&m9ZBR&O50mKom(t&z|t<{VKynMKmI z>xv|+R6ZQavIgd3Gz!_XB$qS=>(??xym40GzAoxOwY0FLNy)=TbLso{d7uE~%h5*9;GGAg5%mcS+lf zcFEC8>kjo(;jT*|Az08Mqj}I)&VV#|;ZmP}T_So9-ol-QxD3nzOvzJej6=?;9?oMl z@whF@70MXP_jTc(gQDj+Xpq>mS7GiEuuAD=iWOH6LS<&Ttse8s3S%k`mfW%) zqzy=C>)8DDVY;K#tLB9EH?X2B00}L5F7M~K z`Hhu$a^4x<>GIXm6@H`mKQSnMao}`4-MG|uOLe4$qI);2W^rJ@^da^pFW1eH_SX93 zK*thkUZqW(b0H6%*WIY|UKPla7fX*?uJ7Mw*J){21!Stn|H02GpY7P+aB)4#-V>m* z%h}iJ`qNQj*ygzfUJhJ2uTj2Anlrp*^+YU6gE79dmY2-}=aM(rNoRyFAu@)S^#9b; zlThFi_*d{y(7U9o@Rkb;2P=XHzl4>HwU$=#f?QL2-I+Shg-yfW&uh-qVGo7SBEPX^ zi_-}G@o%v^rY{z-J)TOVUZ;%|y^F_wtW>qTGFr|1<56hifpa>By}#2Lz={J73^o+b ziCv?j#DE(|+RB=Mq@~eGLBNfu94FVx?ZFxj4R6;7=EGe&m-x-rpuUwkxfb0ni_6f; zy`1eQUX8GaFx<^zx{uD9=cKnT+C?=op+;uxg+r^X*X9L4yU_&ff4oUM82n)lxDEGV zZqvSJ!fvAPP_jk*O@UT=ubK8SMtt943GT2~G427rhz|>{BY|16Q(9hEuITyY&^>XR zXkYS}e%gsqd`(51X~ZpT!apqOTxE)#I~?FQaht71zIQwHY?*hX74pjL#wgX)M{?Ew%S_LTQjtL|4qvm?@EqLtD5c? z0xMvbkpr-BI0H2`1XVNFY^S{LrGT^MrJB!cT?#zlXYC-cGjioUfQ%{WaDFoJVMkkmS0Dnw|<)jQ5q|X6YUXi`FEwR|t$o@4;6R zg!*kdGe*E&<6^2moIg&zJlSWVHS*})h1&N4bXNQHe6|PsxlmB-=hl&Bgdhf}ETEUQ z6x?*&7TAN7+zWVlfYw}qZUIE!-@)5iXir!)HJIUBy^G+Mz=aN?r4%FXv^(P&!YID2 zVD8`qzAF)Z4E5x@_+(GeC~pff{C0@4g5G*{KMeOY+|O4i88+UR=34;$l_UGH@|g8HTuH=d92k|Csh%5Z1=oZh1YnX2ClVVf9G5vdzQPG*W zOB~(sjr_$Kk!PjPr1XBH@hS0Y@3VoMq`CbD!}p}$53yhB zFEWJxOL{^i{L8$(fmxdkcz27xC^PamGe7V{16IZMe`7|)VZ_cSI=|nPHoMLgH-6*8 z>Uit&>BU>w8{foj zDCVRucYK-o7{Z*BzHan|7UrGv=}e`CbsYGH$O2Ey-ZVWTrU+*CTBzpPv39pvR@Jyd~n}0o+KH zFGhP@ANWuz6h8`_QbjG_58R5<7X}&P&7->)UP51>fa+m)?^0ryy zw)3tP25{~qdCz+$JR7xxwCA;i^R*B^@5f<>7Shf8QFx{n($9;9XJ{eAyy0-J7BbHJ zIy_AandYU3r)nYdJWDuR3t8sr!&wMz9S;15b>2En#+VtZF~;Bma7=__aC$g1oDI$n zmjjmz=YYey%1Ysu@HYhyK2h}qX00duoRbSYQORMB=L)CP{&+dQsUKj4HwM_;X9FB` zKi8-{o=a36o{LpIo|mfzJTFy^czRS5o)@V&AKmfL^3_s-^w71Az(ZAq(z4;ujfH`^ zl25T4=LQO-sfc0ArUq`1mMV7r4e)Q23KhHI#sJx3UYkJ>!vH@xAKX?|a#Y-xIRqU1!|jrze|@+rGHLpBDbH zO!obqaNyx7HS4XF)lyRE?=}F1T*tbxdA( z-J-YLSl6t$E53&IKXGm^zK0WcBAkx6YWSo0B`pDd0lxer!XL)_&3^bwtO(DMRO-|b zeEkPsLuiI&(1c%~!Y#M+v;2lY*O};3?ez|PA%ko@?}@<**l%y?8A_Xv8C{Xf*e<)m zYJ(M_gNf+UL?*s7$cs$+*_rf~dn(LWmtKHADi?dUTJiW<~D-y9yPsFK;PMzg7-HALspk~E?ylNnq6*1%XSZ~eah@l^x-_E?F;y(RpwPJ zxwA;Fc`&UYp8_}ri@g2d)+%V*gKapKx|&zz>x!o)Z~qzXR;J{r^rqiBw3buF9vCao zWh!CgMh~=uxdJp{v17 zKvh6lm{X_S%;JR7AbbAzLpsr@WEf}W(a!y|1DEGw9m49OPzH**oVB=b>|=Lv-|!Zdv5|?XHo8t&wG~SWNC7ebCR5FC0&40piR<44N#z2 zX=t|Qqzh0yq{%4_q)E&IEtb^+1uGUWB61NyxQK|zPf^h8W%q&$++IOcM8yR~1!QqS z1pI%WnR(tlk=A?h8vfza!#mISneCbVnP+BnV!<5kPIRlJrn zc2Cpq_ZqN7JfS7pvin!`b?L9Rp)S2(2>NSy9y-}5>?V;mjCaO7fqBL?n3)+;qnp=O z^U_!&@EWo34cz&`bfyfOl-Isg+BWZ{u~zW6OqGj+>)Ylbt~dVl=4*+sB+GBZc|`Gy zad1Q1E0~*wR~c==JGZo*|7y;z&%Y|pr+=h#{h zNnYVmg+~`2S@@eSDC-NtA{a5sG;)#n8x4GAGil!HEt@ma$3tU@s1 zK}Gzp1PLfIf{_CwvAk$mb6KkVg|0jd%}gsYinF3+zw9deRaaDFMKPo&4~dA!;Bf`+ zz$z<6YT8T8^x#5$NvW|>O3SpbylQ;ZMG-J^9-SwaBBbC#1dvyFEMm@CgwHC_a+iS5 zmdWGtSC%PHb390Uv<6-7uL9%e7ERF(CrYXx_QLvCA9{%!4x!&!Uq!Y4{FYL?e=`GLf9 zT`1bTq^wr?^uGW$%!5kCBF9IJS*}V+{4)q}raG4IsZq8nk|$*{2UUcH6P_Wn5l?2b zT@*^E2y+FA*jrGJy)yXKf^077Tu+Lj-lw{4E7Ks#l-k{N!WMB(M7EE33w^{}oQFoT z7U@seQ(d7P)b7jd83?P|9Gt%0=gv^6QI}P_FXu{K<;iokr`=a_yD#yGBVUPQj;iTq zsYbX|y;a_-!bQF%PLhbZN*A4si$disn}A=152*^C<=2VerWe&Em--Y>k*jzRuZu$Q zq7Y>_P5-mCkDTd?Br-#hRCo%Yz}~Brdqke4WL?H0p1zYU@ewffIC(yF?pNlx1dU2xsQ2Y8?66P0Pq>8bot#kcF;(xQRw>8=q4ZVTOW^=^oKZLjoo9`5Do2&Qgs5oH zm*!93aI$A;IF(#NbGd}(dz#V$PYKQAzO2~Z$|^jqEKikNmS>zQ^C=|%VchEJ;y!*> zmXY8}T*Zjq#YG{>m%3>)HMfYW1)&*xKfeiSnWq-aaZxBOaW@TVK`%)?Vu@8VsGQ9? zY^A->|GtT91s8fX7y4XJp&#HW^g?@C>mJqCMs-=MsR-sI=KQtTQ*PW%mU<91fAt^J zRG*da<44s3?|A2K@Fe+}=EfD=y#4x8Z}aw>hv?>Q>tyHJ3z3?**|+BY&6XRUq2*R_ zA*zzHcd3q6Svg&+%uz$2>Qqr+g-X^F-zdy~{Z(LQOxf`ng#AVvaqn?@j zPF$i~!UaAZc#gYKqPln*FB&Q>jLc?9>rAsm^=O$reP2A&Xj#l9THGGRHb^o1g*C+kJ7{^0o(6 zMCCpm9)%S1p>tS8o?>;kDe4Nb9H0RQQ&UwIdS)5)8}rPf_nYyTxEc-?q%I0YSL~*t zI8j9?3FTo~oSq4gyJ69=w;zfc%xy@6LaG|G1|&*A!@SDV)bj1aoGxwKFc(qnPHQF1 z^@F!(^e-bWp{S?yRB8LqUe(Z- zb(xDJ+Xtbc%3H_%1n#NhruKM_kL3O2>`)wgw8i_;`&epXPqp=GeZ#7IDPZY&hi;aW z-$+7o^2*OzLb-bdt^P5!o$X2$qq_&Q&rkS>uGCdUQ8Qf>+2yGI-8LPT3tvj-^z&ls z9?&)KXJ>Er@ZNdxoSD0JEqm(WQOxFa*gG&&1)jcO{MI{^Vef=Mt#-UahgD$HclquW zuK&ypYa(ZtKbI%Kc&XX5nd0q;{1iy;Ef-Q-VQi<)sgimmOpvWUs+2x?lOw?$7ES2P z8T5Sn3_7C9o+i@!(bQ^q2CY;U_BBzFz3dP0Os8o)r#h#~zM7k#ck)GL?;SC?QFtQP>wjOfT_I2<=mbs;4WPMQQvPWr}y2U|DckaUUi|@ zNc-8kp|RkpoTw`=4~-$H{`p*|yz?BZCb;J>{$k+r7I^Og z76zxIn+@R$zoA63L4K(pg&#AY@rO=JBroGlb+9P>`2~!hK9oq>Efy4h&S8vSH4b|r zPxwDOoblU%7klu)QpWECzSx7`T+8?l;1wRcV-@4)Clkpf9(;E@1je5L z{sj;Irw+#V9Fa)Yd+>w07=Hlxu^xQgTE@4)Ho+^u4D9(-`3wU`X3Re&-_iAq-wAx7 ziE{Zox`FZU1BbB8Kjps^rXni*$ou^KAAK_8hXMEczicDp8-YhX^<&2f-Q-aGkzOzZ~fhI z3FCJHkDH;he15-+@kfB$ZI4v^4VN*#*B5^gmQ$+!J`dd6zE1r$i;Q!VElm-6UjR~>A(GtjNfunBKd{~U;i58cb<&ee`b8+M!)ng{tM&R17GOz z|ItE2m(NRWiR6RMX5ilXd38DCX9M?X|3@(%KRuDGF+=D2eeuzZCxLt0$F(?St}0E#DT(AFkN=@& z#-HEpm%qDO7+;L>*(;wVU5qap^UL1_-HfjQ?rnd6IGOQ2#DA41eMb&3-h%vn(^Efh z8)Up-812u4-~J)STQYv~dE#=$+kijdiGTPC#uG>%l_~$J^4;_a#)pUe`mfJi$N2TY z*Rf~(U-^IOlZ?LxyugE>^Hs)oFHa=x>Av{!)r^k=_txLkT*kKn zKgg5+4;{exb--=Kuj}t!HH=^Hi~n>UC`t^7d<4IrqXU&W^_{RTI3*#-m{@-e4e3dUg=Xl0D zfP3Xrxr*^VU;l@+GrqwWZ#aSRjlSWxt!8}C*MDCJ<6C_3flkJUeZwE`Vtmrq{{`KQ zZ}Y{k=wW<^Z}``*VSJ~r|Iha_zRMTCH^umF-|!#nWBf{A|36yG_|?An3+oua);Ih& z)-!&Sum8Lg8NbCBuRMwI+kC@cd@|#A`uaa|Bjb1b;_as}9?63K%Qit(^OHYpX8euP zL~^IC0xSIIV~pq4_~}o=6O8Ww?p(@_4r?T4&yibhTnHC<97h}&i_Ai9^+Z_6Uhr8hxqA_esLM&mn}{tF&QxbRQitF&G=!5Cz4pqn12fY#D^H~SPK1< z2Y>5w#uIgkd{qlFinxG!vcVm6M!4rQl#rQAY>!*Kv zPaosOY3RQ_@qcA4<6j1Twg+!n&v@;re))T41LMC3ezV8_?voh5sUPL6E8Q((dKU@5j_{NQ?=DtN^Y{$;vMS;tWzLyIr4^jG|aQ2c=% z1+cux7THF2AUhZdMZ%G+NOmL=$%*7f^0M09af;trngIxT7rPq5zM2tuv;z>#bNx|VTnH1hn@%o-ABiM8n&*2~MwzQ~>Fqt=5 zbpFaUH}9=9#?Iauz9@8Y@DgO6{qV+$_Ji#x0i}!J{S;H~`<74+hPPeJV5m$feBN(q zif!8&xhVVMtV_bXLYD?FL&`|P`RIx+#+J%{NSHE4G4PI!&KQ$0k}<)=X1u za%av(k&Cl0$=VgZG;~?;gJ4<{I}3CQWe7)od6&i(%D!iq0^;o)oytWzeBQ-rik<0A zN@Hv|@T1sSRJ^}M5YMkxEq)&x5LF;b0dEL3#@=sL>c-fX(_`x3U z>`Kw3)J(#YAjlY*;~6){bIid7%{yBzDGZ)z<#Z66Lo_*DN!g`*@NO5od3TH5yqm@D z+YtaslHI(U#ctlcVmI$rQHy>M9(i}l(W3XQWl?r1DBj5O=@_Z@5ex5S`L;5u9K^&M zTCM^*M8mwF)fAiZw$!HBSn#ZXYN}Ud3-QW&U2(iwnrW<~GA8dK+S|gntOZ1fx(QVv znDvA>7J^{b6Cx}DK^8Fwy24F30R%@Z>p+N7v|LKON7slk#~cUA3(1Q&=xF33H*d&M zk;;h&^`QjtP8}C=@6*dLITb1lyj;%c^3aT-L^H!x#<{Av~W~L3=w>T*2cz{pvt|z;Bmy_Ks*!84l#O^-0DXaSy8wuvU2!i)W zO~Fuy{7nG7IZDH(X9l)!adD8mpXwVVW#@3zHr`a-wX{^+Gb5D8)JLU3!JFt zM;``D1iP-X8}i05Q!C~4@un>a@RtaVH)%})dV~F26_|qIyKb4}0I+ zCHdwZZVruiwAsx&*zD#VYj*PvHM@C7no5?!=N)LRQ(-pVcxE?mG_#vGmf6i4$?WEh zV|MdKF}rzVnBBY)%x>QJWjAm1lC&w=ys_IDJ4ek^nUQyN+08q+?B*R?cJmG`yLm^J z-MjQ4Yc?XdBdB>04yIlOdqsRD_F8pejn|J7#pLgWg zeT$2qcib4i(}mxy-P9+N{CNj$+CK68QXy*Nx=-}>Q8P_=s0StQkH9hSW%To7$yZp#)4~2ilyS5HD|8)6!gOXn08Ey=oKS6uyBVNI7iA zUx8g=N0_{gZF=S2h4-)7&HL5t-lIceH}6-ooA;-Aw!!<+dLDVO&OdKMduGEET$di> zT=I@|GnQ|T?DJN%IsalGya(+8c=Oo=SYUgw>nvx*90YGedpPgL{^GaM3aVZaHzCRdj+M8t&A_=V zdGA`6CG+!^waHJF{C809^Io;Bl6!}nnHItn0|msJ+GY&iU}hS%Xf{v5@ZPsW^F@+d zj;)Mq(>6g7;U*AdNi)ao%t5MW3Xk{7sS?}v1~@w2D))`<3G9V%b!n^doS|3W{5-4wYtDZ_-E1X1(q$;>+E}IpNH>9pz7T}-!H)TB#c&QiLmc+ABsZQ2H#{d zvG2Zz;QLhgCbh)A`~Eb1e;=CyG)eXMJ)QA`KlgN28&pEyMO+(OR0U!87Py}P#_koZ ziR6Xa-8^52`{2g8pJ~!IQ*0N&_s-@-^83@~Y$o6L!uJ;Vriu4-IrTRR!DL3@0R|C5 z1*iU_F?QbmDEC()hzNpM;+KH)rf(dV8zjne;rpNom4NAz?{8j1zP|?Fi}%YnW&W@5 zy#l_eI?HCiZwY{}&6tXk=txvgE8EIp~-#!eAnJk`?N*xMq4>|UE{?M3NCV2v&VKdYdCp^o;h)#>K$ zuD15$({*sP;taly*ACSal(HhUV@ZXXvD>i*g_$X_V|B|Fh=jq6mJ*h1&dSoUclVx{ zt~1j@u6o=#UpNj%5+#m87s9qweFsD#>?qYYUK_lMzq3T)r}#Tp6yDC?rK0ew{9Pf6 z8Zm&}7ApQ^z-Y#c7z;#+fawj_U6uzT?He z44DBCV}igGgRu6CaK7R6`ySAC8kz%v2N&#eaWsIoTXD1#zQ-uO-HPByP_C3{GxCJ+ z1J3a4YC+r?pa}XT!!9>N9T;{?1{Hju_!Ubkb@dd!L>rqZ{Og_YGLUYPa7Rxc;deN3 zTvV~(PKmGYQ3<@y9sdzvc}TOUBtGJ1Sq_$OYZjTvz0O!jh)-x-CG(j;@nx2f>PUva zPz+j3L6?|Fjyr=SruAA*E{=K<+gu_hF0{doVF4!_FA)PrOX^kZOw=Nd&%^<&)1q_zxgo2Q*3TJeRf;v?c9hwUxL`Cl&%Z&F=4vmiJ($=-2z1z&Ft`n4( z@u>k~MIgFT*oe9;bxTv>NsPKm*pQaKUhPX)ipIe~$b16Kx=Lt*=F+u76FFR6 zCp6UxQ`d>cVN`?>2#2aY1+6QCldfaXmBEQ|M7m-)K`TC8Osaj#~g?ZWF zrv3@41ECnrl$a>%=7cJ?9)-}HsKty7KGwtv$VbnX?HxlS)Jl65Ba-OgONk<~zo=F0 zsj(r;hpsrXnYU9F(W&Uo^bf9Y@6jm)J)(jJt!H#%NY|$vlh`yhvAt(>xPN?TlA33( z30RdQPt(AXS>M`W1)Z+|8Ks>*M|)`Putiy55?xUint&B$RMC1c^~G%ZG|bFx^%%)4 zQaHuz1d0{VI*y{DCRV3gc+5?=auIhy_1a5`n{Ih2bwSItmohiq@{({tN$sWFO}D&M zs2XYI1)YlOe|5_=k$Mx+tFWg`XjvnhhiKgCQ^M-(ADL=zfqSiTw+;7CY|-*ur-Vi|M^iS$Vp#GS za#=UtKC*cf9(6CBq8v^3ZyL^Eoi%X=hWp(-smx4dCeuU2O*2Uqk7OU~M{P`xOl{qS zA(G~lHmq@A0R1Uy?BwXc=rGWaVqS13vT&Obdz^BDQJp*f;=dS%nnNHxp_nbBJP{}% zp9V&MQA(as498GLx<9S=G0hA&1?$cURwf|s z^oCSVdm3HK#1IC4Vr8BU3-`W}`SsP!wQa$Dvsg*k68S(*thoQ~5O>gOt!o{P7LR%3;%H4TB;t!W5BHQE4O!>brC z=??~%BA833z&baiwQxHdyBd#&bmf%HI5MjeDC7g5q*%@Cg!4A28MEMs;$Qv)aO6Km zKTnbNQHVn=alTs=H@G?y3i!-c^hF}H>cGXuUm%A-LAnL5Wl3@rq?_@5^oj;B7NooI z-FEysbfZEvq00yfDuaIpJ=d^Qe4)b~n%o~%*J@}M4P-SKaO<~D$7mFyVh1 z^wHYeizTEYHmyyaC<2n)*WTIMy|zyTMG*x}X+d2sx|zQ*I#5)S9uP$oo%{wrU7;ku z!=eax!>I2pQAFvK^juN&BEBgT#d)IWb*9e|MOn}pNuIbUD(3G}Q8bsop-aMjAd06& z#J+)E>WxtRv(PK`td#?+h+mB5RI^kBh3I=-AM%IEBz-rw_hQ+Nafuu$`5C28(imXD z8OPEowW^1{6Ov<<3TL6@X_H|tqVHAe`!M=$QQx)n-PzeDwMR*EG^y_f`fgNAE8=$} zaV_bdHi}~DOVmcUG;E15{h4L z`6aE#w`I`n&FzgH9c$s<>);@r#}mxaxvr5ozAxP^&FyeE!~Hb7Q|sY+M!T9d_b+U2 z;(m_ZlKXjfabPc*1d0D%I-7bZb?}Vmy<wqYqcja zu-enbpwynkpn?y?Z?@8})t-d1+S36mwI{)*+S7q6wI|`0+S3(3RoRCEiiOplE*7Qs zR4g))d!30?YEOl;+B5!5TP~E^Q!=pH(-nnMdrA&gdpbF^+Ea2UK?UtO)oM=(v)VI$ zu~kl5?Mb+)_H_7HYEQzOEw!gB2}Qo#X{1&R<)(Z4pw`*c$C^x2a}SSf!Z_n zD4JoFV(sbZUkCouUrQdqSnL)1qkMfI^Gjsm#a#X;f-VKA&J0meAoD1Ja{xFEU+} z>lV{Reb1?;i~5=!A{NJ7TW3ltfs_JK>7BGdBpsO>!k!{Lp$r#eX1-D-NPj zrI@MEH&r2flq!TYBU0P(M;~p+H*$)lwxhSXIgNI1*J|vIE?N!M1tI9u?8u`KTN8!tD)L9D2;#{R4&j;#OtDxJS`QO%d&Y=u4H=aBzbv33ncZifhz zZHf+_>Yy+>ax0A98X*n?BYEt?tv5O28Em&1UHOHCNPQ5V^AwK(ehL3X?pX-y09Z7W zt6>YYKr7(L@5E0A!Q^km$2NS3+)KeYun4PEFts3Lk^4DNrVfEI5Gb$VU;dSFe2{$I zfsgCS7Y-?dN!Q-lUtD}q&~liNeifD?vbg3ff(T@HrZ=on9ybQEij8|A9`ZpaZKah8 z3+kUhxAu3|Yg1WNfJ?~4X|lL&^$IZ1Jo1*1l_1*6SH7K}N&6yxEG3kq_{y0f#fhl3GJ(D8u#Gn%_z zbCYUZa!;c8&=kq4%vql~^Nu^V+48CjRVINfVLrS{3 z{x59_zH`-;uNI{1snpCbVD55~uf-BMwJ0@W? z<`P&-R7vJwMI$ngFwiT zVD?l(zOnKKEDl~W<#VGYp9xr!pnFyl>W?jy61o96`TPx4MQQhf<^TAkSt2;OY|z{4s$k8M>;s{h1M>)8QG;gy?u6KxD&eQBw!=V?=!q zQB{r3s4_YM6kNN5&}U0W!54?_KnHOql*p>1s6`HSN3pekY%5t$8rxzuvV2a349FLC z7g((Ok)YZRLYThG)!ca7=?;KPiD4L^P1r}^^ zV9L08SkY`2TVoN54q7;LYpj5u%=svkbh5dTwdOXF%R}vt1q|iCQR7{$M{Wx&=reJ~i6Pn+wtw|w!hJRHLea(TD z2P*XzCTR`O@Px$g|3QriW_@(jNw*!PW7?l)bL0`I+%Rbf2K2e7;C~tJ=3%*Yiwc$C zcv<*B`pKf7qv&TCKl$VgUKyD4@j(8I^!draoSOn+VrRRM>?=`SKd;V0Mf7CWItyi| z$g@yP&}X68nbK#W*sae(W#eTf891i*4Ds}y-8?ThL^j?LklZ*q#i-*b6P;v&cyuc5 z5TBg#!}#QsAI2xA{4nd}R5pxYC}D>;7Zx(7+ulyk&-+g7X|1!;I0F~fDQ_bzY@fXi zE^MBPfOC$XrCmYd2JBS9XVwipDmEr$N4?aX}rO`Dlf{Vi=V z${x)&1CYDD1gaxw^rdYv%AU2jD2PQe2xW`mOoX(>AXM36I6-NPA-(n@ke;$Ptx%;c z20@lBhSRUI#n2qu7Q@M*Y%wHv4J{mDIr))6@Wm^oVZ*7Y~3~YNX;zqZ97lx;B_u(HJ<*tErP;K~+*aLX3M6~D5@P%LbV;bKv?7>Y$Ea<4Oy$`(W6 zY>QF$vMm?N7DF*cQXdp=~iFhZ0oKo>Og$Az`+~D7(}uCvA&CxM_>w z@ULt!2)Ef{xRRi3F*J|1#c;7GTMW&@wiqrRWsAW)GBdEnDEHs7E^WvWVxm z&|KM$pxJ4>V{NDDIbgn`&2R)wG5GCRYp?blYell}SlgH!JJyQs-LY2mX?Lu3aK1a% z3bXB4D}rsuT64H|tnF0Cj&N6-}6egsWZoJY_+M14+5*9_Y^ z96rGn^?0$)V8s>2t7@3wIS4xJDhH9nt#MGTFc)gN=Lnh~UB_^kAI1^Y`hiw_Nd?=F zpji~_2%1H+yy{kJ9fX;{aMYqXZAZ{bOY(69t?a|LBWQ_Bs9Nb`LVN@*L96VvL7i1nmbJHy^2^VA@L37hBFBPhYt-P3L!*t6u5!(?ommk{^G#6q! zf@VWpN6<+5^gs6zw8ZNc(RKu_l*kbkr0ocr%BKGjw9@b4(8Se7;$~__jw5J^ zQEDgF5i}Kwbp%bh9Y@eq%r=F_hQvb@uJZ_*;_^F!rjTCe5i}K#{}D7B=63|Gv=Ujk z%}5+YIl<_!hj~%^xT`9h_QPx+O)SA-w&^&Xp{QC%JD?sGX%*rnsWzK6x}zMWe@YJzO-!Z-)B)5V;f&j|wH1d# zU-oU>L1YL#+Rpm2-2WYOu$i{={-^Y1{DRlead>e9`uT&QKMNKdhrH=Vtt`B@m)00r zZMd`#8Yc2WFLo88H)$Uf#`Z&()&Y7FP@$d=jN$eJWBbu9M1K|ZsM_Utf1;8Csf6AE zQ|4JAKYqHbd8H5^z(PRD?=(w(>uK5|jBf`@=Sd0HA@k&ko;G6%emihjEr|;66pBKg zg}}>-CZdiImFAfgO5ge;mc!PKNNVTl+kt`2#B~cuTFj3Hl$^f~5^l|!6>{d6;L00? zD2MgClygx4bxYS%IT=xV1j6`2u=HRl?H@`JKv=r2ej!-DoTOCco#|hBEDdfRmw1SXd0?~hmA|YC}|4-ai@l$=LHNl(+DG{~1CcfApRo*MYl3OP7&=%EM;Sel?_ub~#8w96u|>WjcH$OAnJ`>wp}{zra0#EVfUD-*YsHZ5UXg(m%jM@4B&8Aua_?w-Q{)E<5?p zfF#5vXdNN(FZljHv@@$sNc+cz_GgD_L5mP?qFUKDX4S5%cU$RLS2Xd=C;COf@y_Sx?6L@3QK}yQYAmM z6;^2&kt4X;^kFD`PBy5s%K|a4DzJmhijm& zIV(4cS?c+dn572k-YauB8R-E!o?8NRheYLAC;jZmodfDlNyUtJP+b;u4tco1h*tsI zC9%x5%z!wb$XlyxK;1@E@dlduY;ER2Pd|Af3Hd5x4oT&CY@8e7_1T>Nboxv^T_Hnx zaVF*dQ6skuxxZGHexB8`BJcc4NZaAM&2Rp`PM#n7{cATYRdFJ12mT+-C5v{YnNdr3 z7#@Ddpz{b zG{)88vriKISo0ld1^;16;uK_5EtIbepd+Oo^;JlMnCThke6{?&Dv)1DkkL11f@}o) z2eEqoSRg+}{qh_&d%s%q6l_G0UrVbn?m-xZ-+`m>$Mo|X{NS&3_DPrDybh&=I3G$` zRnJx-qk0+rV4$i-iZ_;}UdX10u%kTs84m^yts@C90~(cs8%W2jB+|)5Vw2(r108Ef z=pO)42r`t@qt|TdzxaLdA3>18C<}5SGTI57VYyZo#!muO3#BkW3o(!ndOp0U2X~we z4`-nJ+Da@-k0j~w*%di`nk_=&*V4a?+3!wMNb85jr_`0c z!C^W4dZ4b6g!NmhY7)1b4!<7gJeklKtY|QdU^+a@>Kwl?|KYVTYcAqCw-y;)ml+@0 zyj>Wd2v*HAehV2K4H*#oFl>CIYJNp+m^cn!PC}XhLlkE(X!@ENXRN75!TR|1bz!(@tKr_q0C@-9W@Ua6Q_=_86t@_8Ei29$MiJ8mok}_ltV%02VAE zdXa28a2|Dxbke*9hSub>y_+a=wmKS;xq7VqPB5?L^F9o+{?|Sp%&V5@02*KI6T$of z8JO9)YQL-7i<eEN$+Q?#3PosH+u3^lG_kRz1#cIm z(#fV1`#=sbZ)0C0v{Jp@O;9LlT3bhB3K#R>++Ii&FF<@G2Atk5UdrDAQG7Iiheh%6 z{GBC=Q~aHa2dwzJR1}}V-xVVM3a09}g-V`fyVg>Qz_i?ycZ?CpcCGqb+O_I$GD?l= zZ)w+B@-f@>P5=`GD!W$t(sr#SpSQRuh($68W!LIVgtTiVRN1vUL21`2y-K^*l83EO zrClpQmR+mUud-{^9NMnc$)W68C5N)7G)jJAMWF0j31z!hr*Cc7N(^k*>S9oKt;C>$ z50uR7_d@>;A_{a zAg!d+Pb=7Iq*6xPir8s#2!vU>qRn8}su=w2TD4cZU8^G5?OJV2Jvc*-tvz`eSB;{3 z?OGLmTDw*qoUdK0!fbY}ieR&A)f_InRy);U*BW1dS>|BLZ_qAnH!+pgU?4K>T1#N{ zYJXaR%G7Sx%5KxHwFHK+*3$~?Qg*GxtoD^)*GdkDU8_o`-L5tMG$y?rite#%Rb;ze ztEM>ZT0KOzYxMwZ78>;+mSJaHVYFP)Pb)YGY}e`_a=5xqXunpN3pKaLuGNpucCCIG zM^x(vTJa?nY`1H*D3)ETMYFu>R%)4$O1oCgX|rpMpMVW~EvwG{$$>3=&QB;_NrRq( z9!Ch-Nvd`0mfScsIf^$rh6Zq|Z48{cF}IK44GK&qsiuG$74f?en=UmXc27+<;wnPi zS+DQQQ!(h8)q{27=%6%Xv10EUMeE(1K}w|=hS`}|^u`VClmrn!3R8!^60+XrS0hSk zubQoM*<`nrrfy7hnCvRVYqDE9Nj_{QyNVIgx8#i^q(p+|dDM<9)3*N%RM!P#)^+cc zi|%n;49K=`7X)i-gO%mxG;b!0JGu|v3JU!$DU769A&2(qVC_lZ;my0>NlQBElxH+= z3(y%&>6ZI->UxBP!?NzTA!%8c@LJZrk|!5R?PKHYA;=@iA!XlGr!5`A0hB9 z8%XM#n~e8=z_5eIKUrX(PXwLg)e&zq6=lNVxQR^=l}S zx6GnhV=o$NHNtqrh#eq{d%AZ zE`?WhDMX(_5+nE*{Q-XHF1Vt*@H4p@cPrpu0R~B#0%5!!m=hnSax0>8Bk)=$!}&qY zKxIpJ18LRFKYd4rb5Y5Ykf-FJ5SQWHtnA1N>8cd7BRf7bDc`j;E)U|473xYJg3xJC z$|}~&gDaY-SUWM)=kxRr9=iIdlR2HJa^?WisROry@e(GyW383@&fP#bBx|CR}Af7RUDlV>PlQo`Ddq zc9g_D!J}4ENvxe?%KV;SM>om*940B5-xEA}6UqE@AZwZ5r)B^H17kPKTU?adAkG76O~z)Js^E|KgAuDf)rr^YI~gIH8C7 zluLP_iBC2W<7l%gPN5%6KCaL1NID}r0$|oE9z`A^Pg;bkZNF-bNTpChs z;waFCxNa7e&)F!SF63$aG$HEoWVC7%H`vQZ?~H#fq}xO{gb)eX3+QVh)h6x$VinNW zLaWzM0ezpSW&wRIbjkopJq!Dxx`4hGn%ed_3TO$FQ~`Z0gz}Lkv<`qSp?h=*O%Tae zLig$tx)gL=W;KgS=n<6A3gl_a78ohu_El9v7urimw}})kfHLL$bSQSX?82^tL>e5$ z^>pa?PU^y9MfT!)I<(=vR9r_B)ePoGp}O}_aiu}kMeq|{1awl=UIfqRBKQR8*hHO0 zMG)#rBwE`JWK zJ(=Wx0Z~;LuZNCkpq}evOi~Tw^-#;|_k;6ZknIKVMyP5bjod#Wx>}sPsmtnDAkD5a zISOU61bO=8=|b$rdc>zps6Ei&Vh$PChIN^|32{8jF0lK%mExlAMDk|j={v(1yXSE!{?Sp2(i%Xj0HN-}Ax64J^Tlv%i7djW zA(CB=B78Bts*8&7kWzaQz8F3+P10UNRI>ftTT0YHqV?p8sH0>J%!N;|P(OWu|W#Bl=dG4?XjID69S$f^Iaun7}GI z!~Aamx_tgKOLeYc%w_E*{BV{k;Yvw|It97FNs#8vr$OVCRkdgZin$gTuF{-EWjfx2 zD=v|zpCNZwEaWmh*j}bBLlb0mZx-tBvSNqGLT!aK5;%rrb;Q5RYHp`O-74iYGK=K2 z4RWf7oW3+F#DW90obujhm($v@K|DgN^l+q?7sem6VuwmeeFXBL5N^dkOIm--YF$mz zx*4b(isXg}dD}AfCc4(gK-ZP_wX9ev>3v=#(pI^DIw_<0OICgf^;ZR$_e1GCizI#< zWEDW3t{uZQ>n!oYxps*+ZlcRajgMsOb?2cFLW841ek5D1J5y3Tle0)XcS1ZgJsf!- z7Gwu;g**#6l)G4MqvP0_H0QN9XXjQLG@023L6Fx+s3vOI+Wa$a&OR_n9qDec<$JDF z0=%-DYTIoD+X6r7RPyu6qWd*Su$`DiawoyTDnYbiB)rj-JH1+=b`Qt< zM<%w?=ElR>T3s~<>p}9hmqc#vIX#@MR95qV>UrqH*=zbp%W*771!^+!jcnEKF&fSy z8ImMOh6NM2VEACJyG<;^-poK|=uGsVFK6TKcIx&{hD6BI_Z=d9IlJLl>OV&<5x$(g zx{IdryDbsEYKpL71MM1o5HbHF4LV0g$I}ydK%K2R=?!=c9R2%a*7+m}5XMQigTS5} zn$^kR$lP@>)LcS8_pZfHGks0b&!6aL!FuaZa9$R5p`Q%sW5d<~VK(i|`vPWidH2xI zVzB0%1J8Lk!^x+H!#ANQe;P0jfX!zv+kDCoZSyI=mCdL8v}``Z$Dq%L*CTL&EWaLM zza_R#T_EcR@ddJe7+)akhw%lnewcNEY2F>-56EV?8d0!Ga+_}Yw6+9XfCW-Tl?^61>LZ#9c^3E$rcKup}C{Gd9^Uy z^txIF1U$fU1q3zF-UXZ3watC)-CgOnS`qRgFJGQM@<G-DFCHaG*oGRI4)-0Ta;6k zmf_>O7~jXB%2wceF21SyR^*6ss>_lmSClWuw~RMmls7TGRFrq&Tc)i{l%K@(3Q@k9 zzbi%gIP)AJ%FpHRlSTPu{5>ivi_i((7OHxK?R~2$VyC??fo$)qzoose{+9N>`dixj zR$XY_VoHn&0+qcleQA5&s&86c(%x4Fq3nH~iIDcbgerSqCn)WGrB`Y1TXmgveW|qf zCCIY(b^2BIzM4bZ`#L$4y|3g@cBV$vV^##p-j`6e_jUT#_P)fx_P#C#W$#N2D)>Ov zHI`Jgy)U6`@9Th-y)VJ0y{`jT_P&H$_P(z8mA$WGVS8T}i?a7sEHaUMorzTTz6xi1 z->RS4a-r;fB?H_0x}s3_zLJCOeVrWI-dA!cK?UtO)%Ly;W_#bNFI(lL?R^P1?R_2o zmAx{yy|04Q zN>AH6hU_%C`h$s{ohEgPu+LMp8SH%(gP*;x_G-8HRV2H;uZ_uJ@2luudtXJL*4|eK z=WFk)Fq^%vBG~MGHHXXI*G_fV`&Kr=T4k{60_Q!p)u&M3C@qFyj9G>EQSJ7=RHk-& zUv``JzEyb0)w1_xm$LUIX4Br691eS5l}=U-1{RzuD*pnziw;Hi*!wE7-QHJIoc6vR zqOL)@W_T7|Fd+4Ku?$}03S-?Ux_t*hhh60$vKelTgKCAjP}4p3zJ7Ea!(o0HM^x(v zTJa?nOuHvKv<8b}+51{F%d2jsmi?);_tl&>d*8})^I;TQwZ~=@TfK*>m0rZMQEW90 z?o71S#ki_nAzq`{>ZRnvW)!O!kwhy|7>!e+^34J$5EZ-g9$S@MwmU=}S3!{06L;3~ zGMoAnnL5`!wkFYascfzZSd}AB)4ccCDnLfr+F?aGM|*JIV`~y!Q5Kqj6=hV>roYEl z;S{s2>O*413Xq4GsY5mIv31j})W%(qd5^7|Zh0wnLFPTSZo1_q;eyP2Y~6IrONA<8 zD=+9&VBU*d>XvCDwtH+{er)&Hx)9qvwl>6dk8Ncwj4ZAe~)eDO4t%yZB&1r+7?zx$_!chDo`y;?wbS_^r=wfwpt7DwaV?d z$5v&=evfVSqZF?59$UrbcaNM3NwPAku*jC<+%xQU~aL60>?c?$lBAu5Z zTH24}eIkALwQk3q{ii$WVZ}d2M(gPje)%X%QC$%S7G#UcUm)IqyQAT9nA*B^d-L`I zT#FM}V2H}iFecC)1>O@Jp4em+S*JUJhEBLUfdNG~yWU{c<=I9bZ35_a-7^ZUf;>m0 z^N6Un%BYaqYmkEc>K{{aOC2>;8M(aaHxH#~UlZyDriiG#7k*AvT$(7VpGhGEX&y?Q zdPr10hdud?)%0t$(2+<{-3AS)(L$@8P&MtJ8!fb^iBy-D&^N7M@~giiziGh|t)|^Y zqlH!|@#-t&_j~Z2sQ$D3Zoqd{^+*}<9EtCm>YvMREGPmC7FI989ugv^m={%-LJ7L2=hsU#A=td9u0-dMF?idqees)zU%Huc-dIa!~v$tIvgb0@x@4E!Beu zNC%~0Rdq!TIWQ9sEa<4t%##jEK~MGXm4i~ySN*y95}_1q5S1jB&;e5BO*C6ncT&ne zhNhuV8U++8cgc>2%5rMBA7jFH0iBKXwr+G7hf{_#ym#9(K01jDDMV1?(xZO1*qYwB zeL>GwBZCVERj}#gYMBaqPalaWEHyPY26cYAE>)MRPqp<=Ov-J)sE$$Byr%7wNPm$| zKl{OGi{rTNaO&;h#655_m9(NM@xXOZ(@w3-A^ zA>i<|7J`OouA|N;nBvh0XWmatQa;XrqgKEaK-vnpgyl{`1>zTQ0$HLqVkMm9KTX0V zWQA`_xJ3NI=ki6usX*)j+Y&AzD_~o~CE^z_C7c>GC!81&KC|k&fp($lpuw`BaeIBC z%$Y`=yvh)Rh033eZuiZlXTtT$Th#519-5wzZzt24Hp(1zp6*DOO%v%dhi^}$$!Q`@ zI=oS&)Jf||JEtaxhsK77GUF=obQ+H_Gdp!@%q@p-DwdXcI7%{wnF7WdQ{P& zU@AJbHPbh$+4!8O$kEZ8bjgqNyJ_taI+hOD7K{vR7jv?0?RB~UsCZQPXk=!?=I+8N7dru3#s^2w8jEnsluik~s7nU2T|7`R&Y1ZW$dExmpA!greE5v8YbXnyLOl6%!p; z92!@bQN{K6w`z2Fu)7zflbK9w(;iW#$4Dv$nwaWMhkAxzt5fH)wbDp591 zqDD7k@`ecTGcc9m{H8g7+!0W|lGN1o@Xbhgml*t8gG3 z?-i(ZZEA8nGjiJG7QtQq39T)y&8ePtG`Y#qfze?pSrnNHg0yDvGP)^){W(gMNa)5R zkv>A!^t3ZrVfV%$>(eTAHK@`|-2;>T!vM7+!_tRU>nJ1x6`-+tAjjkTjc;mF$@y<`YBnAYsqwcYThi!trwK4(i`tJ<2bj-nI+xQ2$UQ-N8crP`4-@Hz z7W!|76ei55{W*1jRam9dx|F%mR$A&>e5T~8?$VN=rQVAhy8Z!|lH(S|HGx;DELk@m z)b%)2B`RrU>`IPpYHjN-WJ;}8ZR;)^d6=fVkom9$Z0jy0WCd*NE*zP+2Ta|?<^}eI zOF7uWwC zs+rkBp0q(C*20t7!X7pnI?}e;F>_}5a3Vk-PIH7cl_fH2A5NZna$e-bPe&-#=~BByCWi-C8I`(Ht0zW2b&=;PEJ;0W^WjYBp1T}+=3gox1G7`Fy(DwaM|8PgYUdJNYlvSUV z1!th#?NhFQwLflA?&x@W>rS;d(-gbgcjZh`s$9Cg@KpKjMd%+!H8-TT7T)dEGcuYr z=+zDF@JxugGqXCBcRBUtImb^P?6cwCa}CbiZ`bAaY(!~vQJk3bGx zLkn~bCI^o`IssZ8;b7sR$6xklNIcT`3g6`7VMTIr`I#t>9nHg;{&DO}oMzTFlZ6Kf z8GyafPL0c($UI^4aN%3tX0SY3_!YRx#N81wdE()|hCoNs<+(vK4DL&aP4za@C7k;X zHBo`C&0Q7L$n|`?&%UtO0-2}Pe5=cfQ zx`7L7q%>x5OW=j|SVomeeQj;$mb23;yFLArsOuvlpf#MP36kbg(|EZToE=uudN@ow&K+K*qt`c_-dd*rv841{n>j3)!<$!|3o zcvXI@t>=+t#G|&Je*0ZRjKy`ObgYz;y7FwDUJ!>Jb-VJi^OkkZGGK#% z{V*lo7Uz51K6zxIV3)f=dz?qOL5`DrCfy)KO|r5@{f=ap%ET7uJDFXo0=B5%k?c}c zv&H#NW|wNVE$Vk9yQd@_alVt;70YoKmNH?{)3EN%o1p`D&w->yL|R2S*nDQf;0#q$ zu)NUtR)f{I+;KF0tG?y774)t8mb;FjZ`HTlb}W4>vz8l+#PQOh%vxSj4rSKz%qoc}vzEQ>(xJ>+?mIy`lv&Fi ztI46wTCVSq4rSJ|r&BtVSiyegHo`u`qUojpcI^1-LpnICZL)@r2{|asttO1K(4|AguC6T5ofZ}y?oyo4N-G4Y2HKDw zxjg}!VQuwHhgt8smDKiG)1_?20F;Vc29Ucy0cc&G44_~?10dy>44`;_0?;NBGJw+k z34rtt(5uM+D$G)_FNKcJjNne)0ZpO}7d3gqMz1*y_9^xWPoaw{9lke2$E>{Br>uF& z!81W`5R|By3Y$ZqIU_ay>4Y^?o=}xNYry@g%Rc?pK38YoF!r%V`-QQum3o>m_NiX` zg|V+y+b@j&z1r=q2m4UH{gTS{^KIAgnF66oPUD)c`0n!GxM?=cuxN^46N6lfICnf*h<)H%sTA&ukjNZwmJX3G2e)((62 z_bKB_L!E;;?SutmA%fXBF_2Kh4+P zb(yA#={ub1j#Lw0HIFjDR8U`5<=6Q4qxLJkFonE!A~Oinugv87{vlWrz?^GBupNb` z^l4K5{|f>`04+#dx+@4vE5b~Xrt9l%(|J=rrh9r9%6q83;Uw+hM6}k)499`8hS)cp z<@Rvcu+a?1fwEfGH=G80IB|D+94IS2{lZyRYY(Tw6^;|7k(ZW!Z$s>LGm71b&Ls9a zhhW`eccL?iz0M(6x7eNNOk%Hd2-YojCpweZ>t__Z6D6_JBKvKKeMYG}z?pt+Vzs$Pj0gRqWG)3e^#_Z4&}nIyEV$90X8a_<6lu|(P= ziFqf%bEN9UY?tQ?HNoVp`emEf^T*&hQT2d3W?Z)CiurRrUe8a!b4}GR-JW0fc>e0C zUe9!`%2?G~+Oxdvqv|P7hJUoh<8yxNhQ7|$&UDAn$QjDKjLy<#U<)N~3LbGzuyTQU z%Oy7oVr8BU3-`W}`SsP!Nxa3mKw7k^ZAZqhIB-|-XW!a!du=8dpRaDF>}>5@)!iZ< z4=+6;99^KJZ|QBvQ|`F6vN!D$N=?(VXI*mW2{+aq8$4(}zvlTvBR{_25b2b!d44&N zkJmg^BIJD`xQ&F9v3ybKo<+CceRFMBuynpWMLsE>H=?f^)$`}md4%+&IR7@Iu(-HP zh9_SGecs5QyI}Er$7`UM>Nnw|9(Qc&pBNgz0T`S?o)Fh8SbAkJP-cVe=R%q56So*k z?+XSGu(72{z%X-p3ec4yl#$Gxj3C|J+}GIA($XtF_8DX8lOfK80#mp$5vSqC#1jCY z$qtr?V-0kXv-9rYpvtq}u#}>m5J&x7h^2qZJ{b48261hAgQ2<9kcjvSl> z!wMUN7I{CxZ)6`_4|pTN;*VmsOHfu?+nEp=aCJJ(7{rs+z-VQhl961LLEaVcfDbJ~}cqFtM>EGjRsq72nuAwJFoKej_-R z)zf#nZGF0Hd3s&llDZ|e8#{*v2Zu9f^^a#Jz@oU)IH`@>NzsFi^q-a)-}pay<@ocs zf*t$uV&q&QCJq+j;t%5b@j3D#3^HpcD-6~D3**a?_nAs+b-$$ZxDwG@HKT3}vF+-FJ=vZ)`i+|C_;MkxYh3%-e!niP}xP*Lu z1wPduJuIci-dR$lR4z{;bElk-Ctb`U{WJ0@i?kW9zoQ?ZGk(IjDkr``7V3XNAmnjN zudNkbm9x5s3iWpYbz8YQN41smxgg1g)vqt!Gd`Y^U-ogx_836XZHVr6g!c>l<6^rp zr!Yps?*W5|eh(ak4kAY8_-u|U*v%BglQxE;@4~SmggD10(JDWeQxLrX3ELr4K^OfQ zx91cTQS2Y5z=bG&4IWN;6ED0V3Q9<90*=^u^z%Xd;O}a1%&wBB!rOzK{q6$XM~fq& zvipqxEAlBzUfn6JZul^M$R+<}2y6_JHT%vV>Qes=fD-ilxXNX#x*x{)QBJh-_s^J> z;m5i%RN(RvS7rE#t_-z+N;ae23gelayaFoz=ru^t7?S!0Tgm@I*NtZI zc@3F;9b!KC1E}^mIH}5}7x|QB(=;_SJgBX9l{Q2eKh2FVmW}g72xX7Gh<=*eyPg{6 zWi==_x;j-o4+SCrGd=$#74RNuJ zFfJ-AD4_t}PXXZ45|Rdvc;Q9o!UEYHeHZ}!Z7^nAmD;=^k;I_`(SL~$Q}5xi`()%3 zlfW}GtB0y#T+7oH@i+W-g2GaW>flOORYHM%zoi|3-z zC8*H}@nQU%T^%5aBOke%b19x&LbX+M`;UOa5>=}mx!5r-kH!y_ecu4YMP45`(Ka!; zJlfey)${`Z)ojz8gxzVAdIxg0>@p#qJ(9)1P`K>uyl3G|ke63I6p z&>vvky80Lv=q)Tzno7yRaX=oUHZCiUA0);32;}jSU7VK{ccn<2@r97Fw64_Sa` zEmXZ%00`0pw5GwYV)!0B8M})MYtWS>ZR7WcisNOp#vO#eLQD(#hjoCL7v~hee7O*3 z6JU<#A1=;~QZ!eCilJiG71W(4Cz4kpXFr9w_8!XxHH3UBeWg+nD;0iI;(DgW1s^Wr4`O<)!xGwUS15vzEb zq_iWCFEz5HxA;n$uA54xTsQU^FT~tO-o#<=c#7DFE7 z_aXcd`{_(vKEaK5KDN5Q}6G>e0d~MZ(5}7hVMn-VbRXuEi7OuULnv+gnBZh<`*&i*mF*zPBRCMp7g^E7yqlG#+=uJ~{ zL$wLdIt=!Y<9V9}hbatN$UZ!K146AL*d8s^9Ii(T?NoUY_8<oQ~RTZ>^2`Qti0O(Xd%1QqlLsQ&yOPd4die=dcnYg zQ$@u`FsJEIbo06{UD`sC?T;2}ifvwQRtno?nYt`>&9DLd=3mqk4&O3vRtjFqnpHv* zbl6oY1Wn{{YaCQ7%!Qind9=`vu4B-Zq0!-oBhnSa30m%Ts~)o=Md{aEV>Xa8o; zo|%1S_L(zh&mIqPPtH2W!@R6!l=^pM;;CggeTNq27Y(LYAs^k2x9(1lMtSBje5x6s zi5iipb-c6otUNQAUECgsXKtH|+f(n%O>=R3v|X0Ue*kq^aN@nb0~8BJVG3x^O0)+k z>e`w}2wuQ=JZ^OgSF*i^qX%DDa4a2Sd>c0wqN zjTwiE<%c^s3>@Pr;J~&}ithl$P>SyW#ZZdx07YL)=m5q18g#!dr-1*34^S+)(F1)4 zDCQHk4^-~}McvH)4^YhKnTs7x!CH>3zyXQ{FLRt|2TZhkftKPOpr~oTomiwBTbq7bx1bJft7NjrM1#hN8%qpglkk+0Eug+5_Ko1@DScD)q8PM=_yFrwX` z7COf;VZ!etp|`xe5<@A>Wrn-)1W%tYp8O2Xg7# zd_2ye)UE>hHW$fPeC;b`Yx8E&IQTZJ9J~pewV%jmY)R}>ul*dJl~?)#*0r|Yjp=Eb zQk&sYlaP7>T6&x=DU(&_I%m{0=lwKC-HpYjq>xxd!p%pKyWDyH~9VqfR{r}L!q6eMjz(h$7@-|UP& zjV1RIGLG0>61DDaH#j+?u1QoQ}w->C!buLw6KXKPRs=a9cYfs~dPzF9SoGox&jBwawBES_o^e zwvNc1&Rx!L!TVi;GLHr0cb#tGdh98to>Ab{1Ay= zpLijm*||k-^((}+JX&Rnd&2pt^HUgtBsj>KUa&Vo_kxoNEnmNO?Na)yy_hgK%7Onm zqWb2)n2?oA=<|e{a84o4ZBoul38|U9g@e7QQU5Q_5mS^D@a2O3g zXEZz;kW#gAs9~xh3vIix3;vboTMaKezJ|?Vg|)FNemQZ}0#Wg$&=%!h9aizniPzj9 zD*mdc;#Z7{?-mvFD{Q=(b*f<=RD9_JO6_!2d~mjC#ovFCV)UCncLrhe(7eeTH`elttVWmAG%R1z z*tB+H$vP&iTDs=bd}2QPJ4zJ}#H&Rl{9U;atxMpafp0hoJ2AUV;1o0A7if9HPx$9g z_%moW7zUARF#n`}BN8#+kq6Kl_>PEEIM#7au-}p8!hA=TYyBNrF1_!_11KI@^T(U4 z3o6PksGU_k^TOH*tQN?uDw1<AD*q09eJxgc?e*7G{$uuf zGaC7nC4L2hH&klf8$t6e@d=1GEb$X4<9$nfn4k(yz{lj2!s~-yN{T2Y@C_qT6;y#U zqwo#KDO*roiA5^K>&p4lxqUy8*NdhTPAU8&Sf*E2%m9(93c8cv!BkxMj^oT)RDGr7 zyTkju$WN@BQVZXAoSLf2`DGVuB%M+Civ;&8Ex)n$W(dbcmScN>qXZm>HAl7O*cA24 z;0MCqC}qrFP_?MCyqd*qj}|_h=oZ88gNKEsW>$?(&n$evt0+GX9?oPlAp+mp6Gk-W zk-7-ml@ms^`A$-s@G5-)nak z6#m0;W>(F&l`CZBgsz#1ulQ(^AmuY=OJiGwnqF1Aa2{2R^fp1}lvhfu2>ntpM(W`)bSnnz<{21z+4;9JXC@TCf9|!OH{vy_CPPGU;SS;Gs#GztU(1kg1 zYlL7$dD;AO2`fPg-0Y7&-SH5E6edltnlYhr)+MB+Ba@z^=`538qDi^6NG{c+C==u) zO%4<0IWs0`a-<gd8hcnzTg#aO0`l8!mNgidRxFI+IEcFz2o1!(6cX@!fH&s+qs zIS5V{owr0(!8#lPzh@lfNK0iDLbw@&H4Emmce26%<8_Yl08%B(tl8CUzOniT~>e zgVti3@KltEl0fe;v@{j;PD4wDLGLoO6bpK{p(n8#p!XPhvZ41H`bF>W zhCX2E3F8fL&;quGhb&;Lc-R8Ajz=tDD|yrcww8K?q1CpUdT;@-_0$6kfURhYHX>yc zY)y?-DJ!uxZHxFHCbYEelBcXWik1Rpz zPLJeG-Q|(&t-C#vU2cy@vfu3WNZ$T^9?1&t_efUbK*Zlz2?IK*@5u#aYCj`(QS z=4hnw*Pfl5z+reySmsv1q~mOJ04*{vKtvluw+cNSmeT-j7AP@5y9Fj1pu+;C2I#cF zBm;D50JfX}>#;e2P_f+>vE}q62CacKxz}<@S(LOjfKXDOMQrig1Sm(u9C?m!7ZOuo zP3{nqD$(>#P0yUG$z4KHA)4N8=@L!vvGhbu@3nNPruSKTlBV}-8oB_@1|0AMtp7m^ zm=X?I+LUnE(ky`zj`#seIBEe?=CQCU*;_Ux(S}0}l~uZC%>qyn7HQGQ%()h56@bdH zNSj4UEYfa~i5BUwNU23SEi%a>T^ixzpVg5*5`?6aSja7{$0BZNy%y1>NgoM9(n&1j z)?iyw;h%k@g#&22Fjey*i=m!U_?S1@oWSwDTjnfyoYG#(JUN{@twL}ni!=+u37JJ& zG|$2r7HAc~NMUu`0#b;y2c!_`@Jk`k>6gM5b_Jvm*&L8Uq}wlrK#yMvdr5CV3X!b= zDMb4GQV4AGOA$o|q!8H=kV0gqUkZU;en8ZnUU-A=4$-9U5uP%cx^2n`84McPW|>CH zoJ*KmG74|@-9;MSR$(zVQ8US0QyWDATJ_{pTSYofe^K z5~NEb+BDYaejkM7K3T{uttTtgSb20=HeDdQ#nvE1VSN^IE3r)wF_2QJ?Lv!%6ncly z+C&PlQv?!YN|W{Xv)FGqCsHGOgvq#z4-4LtiELxDynu?~l*eDoFu&oP$a=R5i!q#< zX(We;Hk<;q3c$_}gC|IvMQF+dX}1Usryv~`p&b*X(;~E4f^=y_8_qIqID-&d(QP5O zw4Ttr^hBzx*RtsXrPl``3hT3wTZwIgh~bn44MFYEdYZiz&;DWdI_*!17bL}W)1`pw&kEjY&nN4V9Pmd0V#(nITAo9 z<)}q$(Z|BtW%t{3vd?fz4VwkAhEt#x4QazENUI>$a0=9BAu(bCwOdGxm_QvC5+f#1 zr-j5`3Dl(_V>nF@3SrWPEasKjVj|?F>Eh=T($l$kkiq z8y#3p03d6I6=m~gUZg8j$~>UUxSGtBLf`Ui34n8?;PUc{`K4uiY{2*4k6XzX2V$SnOIIkKgV|I8*>U?lKK3;Io`Qwtin5vT!^4-1VpYuVcft6;_eKgQBn*{= z1*?~TiSB&XDRXZme^NqrG5ui0xAoV~V8r7sp24OEol@UVIXG`#PRlSYoe`uSZMP~~cZ5P*IS*BLIC5e^d0qpg4 z>l)>d)3UlXaOZt~aPnB^5HvGv00gNs<3KA@5K#pVq3XwvDs@w(=@diGHd>J_gUb0Z zl9uf(Lc7U*8Gh+*!myDXD_0;bqX{Ffv1w@o{0EOkQnQHPNBl}0;D}&Qk<@fT{|N|z z8S&*gQB`8U$7jQpqjp(i-SSW4&(YkY)CctE@ZtjKI01=A**m_?KY46yBd;#!pIh-K zX*95;bNPp<$rs_zfZHR<8~FdXBT4+@P7xXO||Y35NhZ|H07jdllj1{IIZi{s%+f_0stm zKb$%Akl+7+l=VLt`a6%8ll<1ap??nhACRAm#hhcb6_E1#A6VM;KN$K)PYZk>=#(rz z|AV2Qcno|K=oSW41LzCfbl;V`cc6DVCYjm4&L?sMIzGrACQpgY{CfmA7tKyew8wGQ_yiH zi`_2dIFtD}Iduv)>4-x$X8A6lk2%34Fi~ZG0@hTW!j{!yZ}7U>@@3pqXEMMmn?UXK z4Na?FHp?odLC%8s4j;d>+|c-ihO?s=KTWy>ti&ed*6l)0J)gHyX#QaH8KDK*O* zmNqS4Wg5iIRW}VhacV-IPA#unw&C)!mC{(IJwEWn3lehF`52|fBL9o_^!%^Qa6Yv~ zKD1JMc7J&*?iWr7d*fV8b5iD_c~rXS6MbJIZzJwZl&14V<;1v91C>^hYA+&wn2o-X>U2RBwnl5?Qk1budTI;PdUuc+n>H z!L1G#{!ppAU2R?+tIaj*mqI(&Ck{PX^m!K4z`T7veO{mVx$~&ci;?E)^ZLXKs;JLL z0S?CWp=m>7ZA0DV2!ooKn#}|YF5@iXMgyjDvQcYh8#fv7cMyTVM3|c;s#~yi@-s5E zSiZiYscz$^nOw|#0?xyOFcU}&Ig1YXCi|BQS{KkC0v&KS+Mn`?GvF!`3-KqVH8Oyn z_$lp?0c-hxXJnu-ZH^3j3e1ChB7CQ!H+&m^ zj2T07LE!-`Qosp{*0%7Q-qV2YQ`01|OdLMoZp2jUE`?PgM`snkJb0Y=@^W&pJ)$$~ z8T3Hv#nqRW8&VLroW|vhXfRgG91c6+R$jMUBY6Oj=x70dGw%zp(l6 zP~pN0FUx9}0PQ*~x~#^yK*EWPWYu(;QnUy)uSQdF9lO_4HK#{#9RoLKZy@09B!q+| zf~V8N9xrb>T%DL~Zi{HWT4!udEWE+vl|>%8TXPr9l9gKY2Gp1orzmhQF%yK*PgC(=``?+Ha^b z!wvTmNhM8gc$a8exZzu(DJu-lB?gdmxR!vNQN`LJ^HB`M+tEFB2eVGb;BcLcac!N9 zdD}cEKW1_q(@g*%C(e8ymmUhBePg7CTUW7 zwoWZUYJrzZa+r{kmn(TAy;KQ{<<~du$k?KbVZ9s#xlsixQEM4xb1}@ADAgvxT0k3T zfHk9-Cd<)_2ISGSJ8N__J-w-^VfC^NO?8bGa@s>=M5LH@&p}L1H{dvgYOoTa8k(k? zBM6`uBV+mUy2eKAEyiBU#?|W?iYHa4n0-DoH)6^X8IcwMv6yv*Nf@FNDjI7Lcdm{n zRDe5O6|l(>o#xitw8N`6SRFNtjZG~e#xFl`C<1}d}$N}w<6#k#w85!_EB;`Y1J`@3( z^fQ~0+Ydy zPA|V$X{jFStAz*ZY9>gD9y)!-{OScNF@)AEtbxC1xk^$w-!@hHmcL4~7FJf)E~uV9 zuVxlr40J0f6Rnx$;b>3=l*|To`g1QvrrNTq$_2G$Giosv_wq{$h4@mv#!0IFE~qm` z+-ggbw8hBu+9^qQKRLn8xRIaPi9gyggurO>o|`|H7pRLfee>{>n%3wT$ab?hx0US%@O1kxY=iH zXlQJ5BhC%;1OyXC>I8;8Y+PB_FntX}W;E5UsDkB%ywSnrnO7k6g$Zl6W@mAZAjfFQ@%BuvprWF1R zrqHQGI7?8K0nJnuzl--QlumIAieJYXb3?=WhB6)Ya&hrdI8bw?VTOP# zt6$Spwsg&!WlKfkWfq^abj`|8+6tSd#d?`m*@WrKa5H_<*4Tua4UJgcUExcrFTMrA zU|s!QxSnei^93a&%pBa5FMAXVecxe>Rwkwt1%Q?dzMHcS;f5AG}q zFh1u}HIUYC9dsg-tMMsRe~jS!2LL#1al$XPsWAllRuAs&CWj1VmHN$12~h@z3%$`S zvG}P0zRxvAT$v73EaLQ{gfz=6TonJ#%fh#~Jdw%mBUoiH*Tl=^dWPV077Q3@e`*}i9tCNu9CRWy6QMZO)mDk|dU(57jV$q#WLXpd4`&>o2<@k0|(Pk&% zM3>`288bHZ7sjVMJJ8rQGU zpS|S_L(B2OprUIN3WOv0@nOs0BA)3iDeQ4J!=53<-*rr(7P~GzeNS>in(&sbTDops z-5U4w>F3ka4<_UE;BlCYn5p7t<2CM6P8Ap6gTkGd`hIz*QculS>VNP`m5^S7*0Fz4 z(_(>?^GV{+V&@7(nmA!R!iFN(JNOM+g<_d@_PKB3z3(g}4fcIwzb+{?YxL*w?HxGc zOTcU=s!N9A?`Pu;p#u(dgU*$+?(3p^tuaAvcw)JFNx>$B>xP52K?Dc+yNw+ z$bgT1!TK9l$#Z%@B6B5wz~p-)N&G+g6%vm`lK6iTlkNOjzL0Oz^XDk<(0sUw$c33d z%e9^*$)z`c&S1Te^`uK3Cpx>TVt#E^#XLJ9_5jY09hKP!W)_U2B{ErkxyJW!9{efS z2`cM(Os%?|Yq5H7ttkW zG{w_Im?6qV8p~wT9O0{y>q=qM*Hyx$%M?>j+LlRRaj;B6OR~AkelcQIRD-&VIqWm9 zKD*Dq&Wp!9Q!C~|zg&nWfqj!Cnw{((kCn^1Es_jguKKoFUJ~sAUM}!cUfK% zaFxh<787b|*j#L(XC0*j%;z#HDd_?8@e(vs7S5#$R4uF$Li&JSP?s(+Ur@RGGis`t zJ5Sn6e*@lect7Zsdb!^-gkyA2WwJoZOy1lGNMT$xo%^>=!ewanwGu45E5ui%+0E+>_!-vEPi0&Ee+H~U;Y-dC^FbJc+_66Gn^?THG`Bhkc#NJ`|rHkp9@7^{1zT+RXE!1Qhv{G074Tj zy4SvoTb$%f=Vm+&nPbQre8*=Z4p-jdj5s9=QP&tK{377b0v}YrzHzm@ ziz1|A>d>9b9Q6mntJg2z&>$}%&cg^WOZ+JDraG){IgdE0>4b(&;4?UGR8HlsfP!y+ zUa6-q>{sRGc&*?E`7IGFly;)|%+s*er}W6lr&8(LkfxQ+@eKY+=TKuW0ru-WqIG_h zuwUnJBqaOb66#!39!VWSWFioyZasy)d zY5h%&ZW)EC%un&h^FlOhf=ORt(kW0=5|5wv($}nCclj{>Q7HowU&abrBBQ&?Y)U3s ziAT@@k{&_sL`t`Fq)bk9-qv%Zp>~cW7iNwm*Lsd5m);yHi_;#;%ErTu(;m5ws4Px< zUI>%lQ zRatXzy@&O|^#Y6MsI1HEb-v14W3NwASsU&3aFx|;uTN1~ZT5PZ%IdV&*Ql&+dws3S z+G?-Arm}cClGLA1`R6QwC{bCw50Zi?QCSBq0awYKX?Q{%F3$Zq))9=WWNx>&kwCjj z=Kcx`2fk2ExjVe62`4MP8N%UnmGpCPigH+U_*^CZ9GsZ+MkyoUDw*5sZJ5xml2Q!5 znQugf?U}h-y^3;%bT~8jMiC*O?wj*SSy##2Hjh`kO6KlHqXMCt$ggK=bd@CKca^lX z>nfS+o1ke|NwWA{C3E+AYSONfWH7Fhy!2cpb2ocU)vl7c|APZXe4(1iA9R%@;<-wa z3c5-X@wrM`Qk2tCNYdvjnS0c$fN_<~#Zs^@R8#JL9|!OH{vr`+T_s6)u97)JPQVx# zM^L80idVAMlPFhi$fDfco{~5fOqDDW;|FgEmMB5W$UOGoz$?XQrrVH3ymmttkuV{P z{P&4+rZCMHvWTQFWRZyRLKYd)ge<#E zg)B0X1fis@0Uk=~bNqLMqh_1%_(K*^N=2D81L-?Wx(x@k%g{C&&~8K9U_g5eZDRrL zHM9){w9n8s63~7_+dx1E4DAb9q$@PR3t40UTgAgRi>>1k3)o5?wScYVF$>sgZi*P8 zww}!vuoZ2wfURk(0em5g{6>`)r(IawkVPz_tOBl5xTPjVtU*u2KMHAodUdiFvPiO$ ze>pO`uBydV9IN<8KZiCE)3{h%KilF=!1;$Ra5Vk?JU#=3uMMCkQ3=S;Q8ClI!_gETRz1h~imc~wR()%opUEQSjYg+b` zO9Kx00oMPZ1xyKtENx0SY-yH26&&#clyKAnrp#kuRkF8iN-}D&QG=QVpdu{Nq7i?{ zBC8C`(k3kI9u{f0i0tQPlRGRT+qsE!T0}N(6Y0{3*+8!QNDyMfx-I0E)?*R3v|fwo z(xi_BAxi4AkXwUoNx9A5L`eqFc44ZvA&YW-Cq(`k8V zngr?6h&GKT;7kyb`(z;+N6FWd6>6+Jx-6S6klkWy5TdX?3%QlpCWt>|5i2ehQVQE4 z>DojJuu}uRkVRHMCfv|&U4~dm$+5=*Fk%AiwE(P`0Q)Qeqb0z84Tz=GnmG_a*p`D9 zfvuEGhb&;rIcxzbhblP|Kq%#?MQqW>LfS2n!JTciLQ5xwH49=bra&zk3WO}Ox^eTh z36nLNlCRxDV#fsPu#gxsfjTWDR!g8R4H?5}dQb?HE@Uw=oszZ3LSC7@7BXc@7Ybq0 zhb-n*WLtLbbKb}*Vb1NsWz3-sSrqKIC6v}uOcez~7KPYoR@yXMFl14PkA|ZoAdVI3 zEDo{JoOA`nu_Bwpe6%s$0dZvO3A54C^ajO=sSNYc-1G&+iMb53aV&2SiW8d|;xi$O z{JImn87M#uXR+UKnvg}zWp3u9r30Y)v z>H?+L+ngGrus#d9mDnbTKV%W*h~bn(^3Sm6o%cp3^AMn?6Ck0 zngDw(0D~sLJ`2El39w%SVmNKcBC8p)uq_8Ij~BAYu-I}ATMj9QDmfBBDCMX{Y|+QU z+GY3Kbh6P34WQJpSrBVD1!~byAY_r%jhnAcn5^NHeC-wzBPLLXg~W&n)M+8HR|0iu z$QVu=vdHR57b#uH^7%s+SzWm`>$O~_OzA=)O!|<;yozi)*>5;a$RZYC45tlQ6dI(o zIW6OaPv(*~WKoEXCZ|oa1w$5v_-J!F0^-DQjtjDxkVS#ov00nLe9YV(5J$G2FdM<% zVC}?khWQBg1;mNr471VvZ4ZhQ!x`pduiP0BCx$bCh~XTka_&ILqMk&y7~KZnIfDw} z_g6{8O9HP`$cSsMw#j-PuDKv4b4*;9;yTO!W=}?0uEitStooTF=lyG_6d@~q<@(6^ zU?nKDoCS-2)|_CX962wwVgXhDCxIL}&m`~2`Cwj|LCbm#I3PTBjZP-ennNFT?&R+A z=IHEH?UHJqG?AcuS=P|YJ=&_bgc;b6%xVvdZ;Rym+z4bzKri&zBj*Fj>?50HQN%rR zK9J6vzE#q_Bj-aEWG~oZSacP4hO5Xqf?fx@s7iEzRUm&QsYJaJbWxQ(az6Kd4h?!!e!O$nh|P>;3&-d$c~ye#GpW;8 z#MWt>mu4FeE9inNW9zxYB$h8ix9Ls&bk+`&ICn)q{j$>}R$)74OtD=iv1VyMBX6^p7^{tLo48`_ z+J5dsk3Ts!cdt$EZ^Uo)5@U1rd5N+2V4Ig1dk40AiLv_M;U!Lv(UN^S)zq(8y|Q6r z?A_UAaxZM`_vY>PC&xBvk3TuKQG0DNWXHB@pD#7GS^I4&D;C?Z12!3{XT~)9pf7bw zOzI(D>RBCa9cYBjNq0pJ>MWPZQSr&m|DDj^ zRu*jfT8e^Fa$mz2Oy74{6kb!<4RpxGqIP|J-+6b!3QVpaQkXd_h!d;kzzauQs^|XgL!e3bB+fDCn5pH@H zQXD)#kPR3@PcDT6Xm4cjh!JD*1Cg8#CP^fx{J;V9x0R%~8wtl49nDl^6IKetFiYttkol`K~*p^#*-zHXTUwxz`}LXQOM5?Ag%O3MTz%4r58_ zy7>!vea@*k?Ox--94}pP>h%tsPKU!w%edqHi=0kBL+*IxbvmHrH(yrjYuI8sW+fa` zlTU^U=odG)v0i&fPE5{ls^F|h_F4ET)egt5e;X~a$^Kh%9-elgL$kN5U-@(Op=CvQ)j-BL z+}{t=YR!~35lm_@of3DWeTm$y;|{%=riKm6;Tn6LlQ-%NNE|NADm4dfe(FCQwF5br zD{ViBA%DT2>EuYAjP#G%9g(<~>BH_odI|n4lJrF;y&Gv;1L35p+#YiKMm;M!|E42{K`M2qpdAMhIO;>HN;m<{O^e%=9IC^crv~JFK zI?1`t^-vSDmEvc+=bg^!6WBk$jkMH@kozkLr#TD^qw!0700jP><0C0Nz>Rq&Et+#Z zRQvz*H>0#4{e3bhsJ~AJh4lCJ!T(Qx(*NLrMg5fo``<$+2KD#Qi6Q+xe4^Fg*niLQ z%Wb%U@oU24m;wCekeoC81NhA$XPw6ZtklDBR!>w@bMW_HWbghLV~N&Z*--oGLNK2G zx>A#eVE==+bHc=Tu0$h~mf%nF+fE{;ekw_jHX)qHaY4gB=ml+< zKZ9wD%n>4TC+WV=+b(yK1f`88TloxqtnpZpSG7<+J&q?)vk3n9%p^BbD7lMn8mn=R zzicwgO}yxWg<5JAnMuhvN4YzsW=deo#hHKc>P^v0M6|w}AnQrmn+du}MPG($QuQsp zXz7>g7S@}ECJlk8LhJ*ER0DgW2bv`(1X4$*PcitSxn^}oX}~U1spv$Ht8)F7i`K7c zT6%e%yLJT8;T&1C3Blc^{~^0ev)sTAI%r;2)kW1aH`cQ58(4SyqJPi8k!L03F}1cz z*NefOUmiGec0z`ri&m^Cn_oTCOZ)nuk&6)cxeS)W80&x0JNy4JW4&f|UMXMS3f@-g z0nF*QWBQ#iU=|uk?P|r9Nl1&D4fXYFu2Rm;k)flVgPo4riupUU--lm{POVwLp<#I) zc_vPE5L#;wSO)q6Fx-m0iNya5T*Z?byP$(bXwsjc##0v?H4f@ejp$Pq^Q)Jx!xm}h zkIBi!P9l~!nEeB)QBoyd5)#LhP*+_3NHN2~%{R4zNt2L-p&38D@hEhFnSyO_TqCU@*S z>fJm{owCu)I6Hrk_$7nl50J+l1p!DmH$O#rSKCG*7^#2jR@4&+3Q4=f1AA?sPgZ&*Mn647JEHh z5HBYFzu zM<}TyBuN}TtR&yYJCo11@y?G>Qg=uaCuluZl58%cYfx_hVV$-H5K8KE{C9)iINOBB zzwwTx`#0Wc+HPvwW%%u$w%vxdTiW&*+U{uEYiPTnZJ(j-ezyIFw%gedJzL86ZM-vp zxAD#Z-o`rv*g77uGHfM}TEN!wm<4P#5xHF#YwL*<*EC=&iUZd)U~AfH0N=*D!gsu` zPEV$GVR1L!QGmPgP7~rjgtIw(qmT|xy*i_}@lLqCjdw1|o4U(mW^di?k?eANJd*up zuSfFs@AF7jc)v%o8V4f&?qW9Hxn-M;cOK2k9PuQWjdz82d&AOfyki#QD_xB|En<`W z8}GO6V=vgIs3{nE5+ak7{ zp2VOvFdOeoJ}HZmw%UAxP*R^oZ1LL!@NK-K4DpU;s6_9KLpXQR-o`sA5jzoe zGGe)F1-TpV3=M~6ibEuKoeqCx(um})Y4|3SMl5&I;uS5bKrnX?C;ZiLbe2FBAfUSkP{L6Qm@Q@cgP6PieeMZ_tYNT)@_{g_CXMvNP@?ju2{1YF$~@@>2`ZFfuSwLH2s=_5gi zlKL#<)?iyw;TGR$;c&(w4^WZ2@viV`UpmM4?i8j6Hr^4iZ>4(U9g*P1JK)-sZalG^u-p$8Nj}84Ma(oWaRk<~rA=6jSrnw*BEF4xCKpYU@N`-pnkGTIG@=cm z-FPS2EF|~Ia?vr*I7F&Z5h4op;t;9A#{2T9B1F?`&*bYgjhRlw$ zof`0MytDc-47+t1{*8Br14c|_?zJ4SVgl^50F0IZ`!yhz(r&!7njs6@a?tX48}AH@ zE$6W1kaDP!BLRd`j#|VPeJrG1v+<6ijlq-}HfIyD7E_=W4FxvdNsWxn6s9&|vPM&& zb_>J-}H? zI0b39h;QSa$wfORJe`(@HcOB$jc6;$rD)u}AjCV>Z6V*ryHI1PvR=!k3zS|Tgea`f zLT)9t3F6;)$BK*LluGW9bZs~V*r@^E#yhJYvn6e}F2ld^&Tzn>iHNLSnB3>e7%goTdkbFzG@T z^KZPfx^ipQYq?CB(uG2p^dXCR71?&O-*B3ZcPzjdPP_3g)Ng5XTE+>V%mVGkyAT^q zPMc;6ZoCWe(dKjn#IXsTRKX;y4%@}7`Hjn0uR&PC^$qsZl+Hb; zW~Qx`sRCB`EMlrLr>4RprUpQ;WyPxl=(442RxiW(qS$`4Xz3aWf^TYs4Nx|Fo-P!t zh88i(0m8%AH`J|L&JS$ET)uw9jx6F@uPhLPb+k*d)#Wb5g~ZETiXSttQ3YRwMogo` zS;6x&$4aX%Q*gTzQmvcaU@?^#nIP^L3@D%aj5Tl6Opon2{rHC%0h|Iq!b=oEU z^avPgPZ1BN8$~<;MeqbGe1eOU9`T4##A{H*y-SlGB#d?CN2|A z42cs>Y=tJ0ac6rzQ0lDD+b$7}(S-hFjr~vcOB)-N^Y|(GrJ|AKNlI;stG@B1=^I!5 zU8!eWjRgBfiPtv{pKAKX8PG&mT=k6|&;Q($o9DE z8_%1*G4vnslW{c?>>CrkzVX~x(>Jb#Cicfw-`HpD#(rp`>C*oD1~n1t8}E%ZePatW zqBuK=n`g=!rf+=jL#6)dY9!bw$9s+TQB=-(4oOqR-h-vcJ-JiSR7In2X< z84ld$r$Bs$!o^}-#8mP3ri$M*RV=Yp+-s|dQ2lBnWqgc_4qUj^d)X^oS8tyO=<2=V z0j7Gd`m5K4TJ=%%{kS;TU-fQC)*5`wRBxiK-i^sdgZCk89uC*axEB|5aN$<(=H!s} zZt(zJy<0uNRIfGJr@iwqKUhW4Q*qITix}-aZmRbSQ@v7Ky&u@>or|n}lyMF&_WP^% zBd>6+y*>}n)%&prnCd<0t6tiLkodwYIOzJUywWr9Q)$bA?0glQD?u$0WCM^Nzvie0 zP#Xnl1@h>AN1YFfd_#T%LZ#gY`0>{PPsuB-!cV330(tNaN410LZpr!#kUQRV)G-YB zqBF^}2gt#f9Ca8uK9F2*0eSIdM~z3063KPcAV-n@q41=`So{X3Vx%HH55FOQ<`Efb zqYV5EL_de0fqB@`Z3p0I3(isGegcF_TVP;v?jyH`R|3B4501JPoSX1dX&Vjl1yGj> zayyXQ-*VJg)aGpbhWrSGN_znC-G6k{B^ZKB@Kb3&Fvv7eGX&uYZEZNjqYHw*Bf@@f zkZK58AkBLl$c=A1>J8+0M{<1xv6G@fnO^e%j~LG=kzY>;`Nss))~ zkoO?tFCwSRAT$&=3bGK$nnR8v)gs8{Kvw+8QKW7Wl;1?hu?=f8kZGO1KSeg}k-N#zUjhnQS{kI6L0A(+?4^UazwU5xhCJ#MX9-(i+>L?tZqaUGW zA<#ZT|C&6b=C62!J~9P@eUH$;CF@7%OTg1=P)6lpM;$^94$BR!19I-49aVX5UgN06Q;Jof-O{jZK%0cxcn-vh!9{sMCBm0Ujs!kgTT^c#ie zw?KH4+dzFw5EvKf8l9l-Bcjwd0mZ|D`yhtyQovIXM0a_a zS^WmN)%>8KoE?J(4RiP`{}b-jCfw*$L>@688l0aG()aO(v*eLiyTSxsbDkZPDwBq^ z3n2Rx?C0Nyk`Lgg(k=xu41oro1GQTap6_+S2iTww>UlxF4um(i2h>(Uu$y0Qi!C&EZWs32_3xQgob~QgcE4vdpr#07Zwjfi1>sHM_{suRAP8>?N0aZSaBq4%jFdfS;I+6ZPh9M% z&Qa#344Q$~S#!vd!U#atA|6S@CX+JgoLQ@<<(2kp5s##mlqrPDxQI7r`O3>1YOj#5 zea;7I`sQFkCr(tj1UjfkTfT*TwsTIg{rbOw@MR0@zqM9%@1*CSqWC`61g%_#y*-1G zx^BbTWeBU}ypvvXHto+gqz$e&->nE=^o49F@1nB^{Bp&Ip?6~ ziz=^=YE}Bx*c{broC+?yQ(;0957s0Ly4Z;J9Do{MaMgGsT4#qsMdQ4>EA4o=KN=k& zYyTHQ3(VUZ(&hcpGbVFPd>QG!F>!yi<`RyH+W_}JCLW09jY$K?qu@vnjv6y29*CYX zjU1u;W;{F)Enmdcoh(6a;&-B{Ls*rUfkgAsq5{;l1;6MCAf{S^chV(tK~&llPC8v8 z8^mQMB^8Sm+Ree)9vvdniT6;5{dZxUm`UE-`_QQ8Ffsb_X?BP$Fhi`OthQ`b9pcQv z`$c?R@M-9l%;+fT9)r)tR1Vq4l#1?Cx#gT;F0g*uBN~r|VlB*JGP4#@P0J9Z!2AJ!dRN zxAvI?b*35HaoyA566*H!7oz_LJ)I49d;0#U?&*Be#nogb_o!#SF>5QS#TtY0j6LnQ zr{E9u)KVE~7v6f`-*=*D{FmX)g`QL6inN%wHPvx%2cRJg(<&erLhc zTxY>}?*PWehdRJ3>HZGzO8UP=2f$te*PrFI%~9hmiVhIh-JZtYeQkNi*J`*~$C<&0 zPpExu5rgkG+jV-x&5rkGdp=vIxjtKH_K~=|+kf}&HujYGpYAOs`KQ~bdz`mBFss@7 z@6+zd{`=iA$-CciJ&i>_4|MeIDc&?T-tC&Vzu`1@e*^4VT)&ypuGux1-%t3rSY!1~ z(cCRwxXpaD$Jg5_9MSD$#kz@n$-bW6o|!++KEUF=<>HIsw!FvJ@_0Ape1y5{==YX* zraZ12j@{XThHoF@HJnqr_!{LOdZV0g;<)3!)z)Xy^T*p^9@qCAfgl6-{7=5l{$Mfh z`P>um_cQbL>{Eu}e;YAg-|jbjYyum}KS^&ph{T`tXUB`wzh?cq%ZKrgN*ORXF=Y$sNj3ihY@OzXi76}Bh~aXv zipZrGQ?}?jWMzel9aVIjy-rX?j2$a@qAJ>AuLr6k#*P(ykSb#A*h=Ods)~MT@!_iI z1$(_r6}@4vuT@3xOV)XRg~EWCD>9z)?N8WrC&f2aXd1;MS2X8eU=k7HY0Tf#|0rOI^;tLs zY@q{ibus-PfUDDvcL1)J8heOguj8f0o*lW>q?R4$09>87{{wK{G~0MYBQfHp_jl0f z4wHD?18}v#;~aqNB_96(T#u*U18}|Meh|Q$QgUz4tt5QM}8i$iTxjdYs#FsJhseZCg*Vvz}0z=djPI4IkwI%5npm_ty}%c zu_u+bxyi>n0M|(G{{UQ_c$@=pb>eXjz}1PzIRMv9jMZhgsc_Bl4!|{enH-zD*XHj3 z09=!|esyflJ}+nNJ=o?Y#@>PLUSh2NcX)}h=fv)G6OVfUuCDQM55V;$$2Mt?5ihx8 z8@1OaALjsEBO9r)&DwAC9`68LFLQqf;CiY39f0el_ICiTNj>fXxHkQG2jIHt$2|bo zqh0)vT=M&4r^Pz{bpTe_mWuD*%q zswVomb&@%TBt;D?z&62+!*K?RK88i4qOUXGf{<7s97$$q?z*q_aEpbYZrOY`n!+kMd zDSC;B_RfJJX(R3;xk(Lsr-Nr&#NU@JHvYaPSmsD`*Jswu ztX?#;T;lID-NxVNwHtq*go(dD+!tG%azrh@`1@qV8%`O@L~6N+amhJ`H1YQ>B`vAa zlpBA4xG&JR#NTH+x|sxSpMYp*n;bvFuxrf$gyGa$%(KorIg|>B>Cd+`w>d&4oTAS_YIdX{=Oe!ownN2gol#)9RJ;5^t^4tgXKce zKVlLa+6K4ZX=oeUewU$bX#3rUwvp}k7}^H5-)m?a*M6U&ZCLyLhPF}d4;b1Pf1l0b z`n9RyAnlN0S-BmOs$-;*-l=IX{=QX+j#9r{OP2ttWZz?H#4RPg z*U|`EN_wBA5u%jzeoaeoR8hqNKTraWgBEb(?@J9NGAbn;w&^T^DmdZ?DB-9DOqs{b zliV8C3G6MKl8hQ`DE(#uY*18|)S?l8{C%qoo2gA$Y(!LMYPX0R5x>JC5}TAfofeTO zq(r(jVxpnyJ`#jVz}0ObU;KTm99yGa%cDz^J`#i|sn0@g4Ynl>|D_i{S_aT|VRGZ| z4}Zg#F5x*-Sa=}*J^?!$(DC<)*vR=rTGE9_Vy0FTXcfRnVRhRyhlzPlq+Jjzg-C~A z3V}|)6t=J{Ace^0fE3ZEUkZU9zZCY8-hdP$TLV&v^!cR_*yfiaF;N3jBqVA;3Xz?D zDFk-;0a17QaQ_JjI{rSDY2)vQ376oayh%f%W$wgx&Je`(@rb&=4jcC(oY5F@%N=h!T9?I@?zn)OFr}`FBX1>g~X7F^iB(j)e@*nL&k90 z`1>N?#iR>aKCjFk3wdSsTF8_sT_}V}AF`NNk!{(--}gpV33F~2u2B5_kY*{ZrI_^% z#@`RI(X6y-wqX4I5FZUkM?f4a(pem0qdDmciep7Khxv5;eShu9))QuDq7#uu}uR`1@8r zZv1@%*tqz6bfGW|Zv1`20fQzo_gM~DF9G&z0D2(6#vBMBY|BB5*m4e8z?O5^0#Xj8 z90?$la?~QW=wqRk3KM_dXoZGTYS?@-5oadU)F@ZWQB=$<6E)5wYY2)upkuD}($ntq*_E^X(v)4kVOzA=)O!|<;yozi)*>5;a z{C(CV6n{U|Z)tN{#tEOyC2jou5F1TSn`R5f-w*N8=5z$au?d~yf@~)KexP=2*5)uD zGj|8Xk*z1pMzA+nJ29MLK7xG#abh^bY#htmgW|++hWTg|cLv0X;S3;RILE0G{4&dL zoEsW#2=AvPruYaqrno*mS?I~7wN2{p&fpOv#*B~;zaSrp3@nZ2jxgKY{ei`gB{1Z; zqyz(t|07WXi|ai4du8PX{+y2`joO-$kZ*<7)RfKkCqF)P)H5jwd8!bfZOv!;&rA%4 zPx+a?JWR|3=_{G&wVS_kS)E6D~zE#OU-%#=II&);#8TFAq6_KXmZK!E(d zEJrqAQ5R=I7mO|uSN);^xK9X>~F9EYECU54v`u(%xRq>p6%qaT8R*ocH0Eib#mYHyVkP&ZVjzLV8+#HRDRX znUizEn4^x`0Z6G)@uNAm9ZqWMjJ0qqbTxNsKywu(WdY@VoR@RDdL5cz=B|+PKF*sm zjmrC5ylILJrKaA8re;kr<85$AQxk)ly7L5RYQT9o1_7DB6VlY3CumKbh;*e!$4{SP zL#e6Wb&h(_)zoQ$K2=!-&yPT_`tK8R#;Mbx3ufOO($#;TaP|!Ls_CLDDm_jn!fYsY z^<~CyEU~=`uMGB00hVk2g4tDbE)FQ`)_m-)u7NU`e@jSNx8{GYjLN!Pl!YlnyeNwe zrLsy8rtnf%S?FQ0%DSL>=B$9m?#a)Yq^^QSD5N{2v3v5T&7sD=AsUM#^Uj7+V}FIl zo^&-9G+H&&D*~GOc|MHR{m=w6KN8Z^&-1m>`hjRFj*J!?N=FUP*+!>UR4$BRa;I(uX-1nVCKg{ zn%Z)r?p2?}Td!h6sj110j{2>usbH^KSTh|Sk_=62C!l*zM6ZfYQ;OMpL%P~~qV82E zBOS4tpEpSxDrBDTP@5XOPm8{k(=cS^vrZUl~ zO4qMD`-%#R$K!Pek-y_dX>2l%l~C7gz^jf`+Q1P(rBz-~6;Rw=#rY+oxUWKSRd{dC zuu8kD_*|Ki#?=_y108V;o{xQBO_R(R9ON5==vd*`!Dol%PY@M-7b>EF7w}89YI=6q zIWh)+jKsK764 zeNe=!er0VNuKU%6qAWfg;$+UiR#I6RS7QL4X$IjyzU!KAk{EhW!BkB-u?T(;;3;``Zw#bFE`JQFvIUZp%02U0n(N1BQHKcNmvIPBNelOy$HJvsw&al~QVSar6NAI#r?u4dtbm!4V;MFTynZuVF% zU%H0pv;2A#BLC2AkANK>>JRA4bb5HWTII)xe4mn9dDgu5Y)k;G6;u-o%OkXJBROFV&%MSJID8FJmO6o znb1ZA+W0-RvEz8!@C}utRvW*EHZn4hQ^nCxDKOgDj6gnf&#`?YFjPwYF_)Zgl$xRP z3DhxO)DcH^bhH^NU%uW^dtG$|?C2!#2yf*)T56sur<7skFy6E=9@^ky>eOaOEkDcC-qoX3{9Y-6!p>oh_<5_59cf1XiIYt`|H{sKj ztBt@=IWsU+{yE7!Ro;g>4#!*PsDwH=0Xwe+2VYL>w{uMK50!f+o1v0hjwwf!Q;s-# z#x5|OBlTuSJ#aj2_=ZZK)y8?y#(2?298JI$8*RJ@ZH$?2`$k}>ObHB?Ur#ne<#MQ_ zD&9KB5;Ih`+~TMoy6Ol_InMGAm3M9DxEnVLL}i8@{2^a;7mH zKY}*e;%%s`GTNBd>Zo71+6WAlvjRiq-ZRZmc@665jW>0yF+(No8;)8~W;;hf9TUd; z$I4Sy9Rp@!&Jl0wXfnOyC8*=I}<(9pmFo z9nGeDOmB14wKHw^2&=<4S~|`)>Uaq1s1kL=(P(Kg>KO7(M-7-|)e#&m!F90joozqov!bX=z!dq;4z1m9bJ za;|x{{1o~aFZzh1nOKh*Ef3%6sNJqU0>-o?@ZR#W?H+%GI;!GL9a~NJxZ>N6`uzE} zdxX{D8!bnzI?`uj<`HkBrO&9Ntiw?UTy+FS3wj6C;eNdT##A#}&V)YNL?7KaT_a9B zI#ZJKO7juoA>%Gbt-ru_k4Mo!h5KzcVNg8RlIw@2I2hKVPZzrnLyNj$GF{sZoBQNo!iY{7a2Zh=s45>z&jr zV$YJXp$EJ*JBIVrRWakrzVp&F|w@1{BfqA7>_+^%YP|*hg7u^w2QwIRX zFS8tkiarVWj5{OhZg6&!dl3i~{Vm{W-;Ss~fZiZn2SP;;0-oOyQEve{LU;oR75xNo z?OhRd6j1UYz&C?XQPf5?-W^ec0Ob+B7lewQjz2fu6H(28?j-ye2o){IpN`ImIzJ_^ zbP0Z$KLMelpU0nv?v1FiX?dkn@yq-T2o-I>pC8{BQR@J0BK#T%6}=gMesO<9^#FRB z@OvOsv zw0SaqDp~?0y*r{VL6w%_2PFVWd^nVu(qrAP5o z(W?z|Bd8WZS`AVJYM3DR8RST2Ug-z;sc0{d!;eBT+Oh&a6@3QC+dUCA9Ml*=_5eBf zy@(ox8!{F@6@3fHJ{-1lHmGTW90jub`w_JlIbM}qgA$e6ffIr5gibs0Q_%t-eg7Fj zM4`OWCj>bINYCR?8`_;LZJ!3D>jx3_9%TGQV{1g^A$^$etN?P$4A@o7-Sw0YJLZD{8DmV7K1dz zAk9Fi)yI%ytK_;f2I-DLo{T|u#UQW7Actd+NOHLJtQcfe3^FAKIX?zj5`(OZK{mx8 z--54%fk3n|CATPuq2V;;AV~|vQXbsk|2na{_3e@+DQs?n8$cz|dK@74o z2H6;c+yaC)suJZ?OIe*U$YU|c_88>(7~}vDj^$EFJx3&e5QC&(RuJULk3q%)p?>lq zW2DHL8iP~;pE~A>RMAT0*-*D``BlofD@)JKt^pqX05hTLUt(ky<&|#7FZ&7*w<9Izdq}y> zmy**1;6DJ|X;^a}1<+xD9)LNI0Js-GCkO($-vPmY(Vrrv?N>T)2U7HejSuraP)`c- zCU|b%g{csz#{~Hs5I){nxlKe=6sAyJ_v?uIxDZc9K$#DL$o>ibdsX(6m4SFxA0zno68UL)769JNW2?!Ov9DknJ9Z{nJjS)tk5%~CTF@Qi# z7UWhSk3ElR5h$W6igBSH{ar*|0ZJaz)%uYt%u zfsE$<`m-$85z&lC8mXfkpR`?=0}1#?z_P|-ZV3x5$&j{tg17{>rP z{QHP{71Vw~&H?i7-iSH?>YyO=fc){rhTRz=6eLZnWJ~Gpt*oAdL38D8o^IRYk^e15mBiWCdik8%zZPWl0l^iay^iW z129Vv^b&q5dIyl1e}G~^y(7p&K&HP1<%8NU2q$H1)L6(EkDqSTZ-BB<7G zL?W0FV)F2X_n=s0VSO{3L1f>9KQmCp+#lj1`U7O+n134S+eP#*fxPrzI@cr2m4s%f z=sv(*==*E7AuIbATtqJe&nth8s5wYKA3waX0eSIAL@fYyi6G5D{^xHI zH4hX~6}=M(n>ZEJG(oz7G(8zn9iUhiOdpVEx9if+0FwDv5O^~M%<8uTBD1dkAAz#^ z7G?FtmFcxgP{XzXm+{qlnrKjP=Mo9Ypp_{JDX3 zxC|H32f=dzUM>$I{XP6(tbxq_CtkBbeJIGYK*~OjsK0}YKI_;fvkxnNM54I_Bx=|2??qiBumfy28itM;LoEdKKn^rJdKNJ2l%ev77@M$ zuq1?lf=fuC#0H2YfVF93NFET)_RpeV{VY|gXwgzj6)Rd) ztZ1oHwG}NYDpso0(iRmhwbZ3`p)Pf!E!yvQ&dl895n^0W-^)dl+&OdZ+&O2?oH=vm z%uL!r7yviL=-S#rfuah4`u!G(jOXy{8LG#7csNM)$OIk@ce{c21b*PK0EC9SKO(i4 zAtwPsU$Jp>3*_;;jUWyouQP#2hmH>et-3y@()T|hz6 zl5hl}CQ)MTCFVk(fTY{sF|@OmCCT%jhk!t*wMTc(ReV+0dLL#a4q;m_Yc6()X3)`- zO--#`oo!v6WY}q*l>?FjWD8azKc%7Z>}JjLodHQH1PWlMo3;|~1h5TI+ei=CW~%L= z2W-yO4#?sfTg=if9gvzyuhye9`j>{)e(i6Dt|g)F{qUou-2lj+VUtuNwU8lq0rHnP zU7L#3@eKJ5AbaC=tq7@NhU^1mcY>}JB1KRw?NvZ_ChFP%q_P-t7?1~jx<+qMS@2AO zH`|kR?R2ER$&g$L$wg{7L83}R&I3hsLgsmg4DFe=o+PBul#p8nNC{a7hMu^FX$u*8T+B3{rS9}BxI5)Ax|m^c^z%`rfgEX z4tZKiNbx*VhwQUUNbW!>A(iw%60(vWNJ6&afmD)BLjEQtq#UKuKh`1N&(Jlh`$OE0 zq(d$lpldH9^(sS1LcTXp*Pch}?+hUcxe$|_$B^315R#CUgLLh6r2fSak`RLIL255U zNJ7pFhD%6CX1Ii$l@+ZLG88gT60%Q^)ygjENkWQD30XN%>W~(+*#X(4b_uy)pcrL- zWl6||18t*BYCuZJ$@D-H(nb#?Asg`!CLwDEic#jbb_rRMt!q^GvD9Z-hnz83*D8^k z&k&N3#W}im3Q}_!LK1R1mMRL7Dq;vp$f6;-wh*b)8A1|5kf}&bX9!71)zEMWIb~S5 zgv=Q3kPsXsqeY1wvJ!lt(*Z6@h}C}nBPAi&60eEXL3o^Io1$^;ptK>p3u`|bYY*De zU-h*rmC;TZp=p_tp zd^Z!l( zPmb00Ddr^{A$3K9dG{;koebus4(dkg?zb36Qg_@aU87HI5sW)EdZcbEC|U@{Elh!; zTd%rnwL|JED#Q^Nf_ZxfrH$k+y9~^m2<9c>2JjAf2FBh&1;)MO>{Hubg*sB#ST{(7Wpr{2*)zf0NaX(gFnL;^)4lJ!}st3~qKi351 z=&>7&p*K76<41Nm%{diL{uH4EljdliHNjFo!S4`WNSaIOdGjcDz^O>jnqN}Nu&>t= ztcYNh1%z}~69MKkpiuK%7R(<lLW61XQmBj`Cbmj(93PZ=#~qhELSJJ9L}7;QobG-$@NWVwbc^;n|y@vAz}#hsFjvKj?p%Ng0&!3Nq4g0JJuFjLsjp03SgG7ex=x*Mep9LC%Ks zSZ(IDN~@f1=Q$mQs#yL=ZrU(rdD?sgBa%u%uF363a>ujqHzPB-v9R9G>_>Bj(S0fB z*_gd6S1|idWJDEf-yDva9Y}ft!5IJgN%yS9;i-zX_YaY*eF2PE%dDMbvG)EUg0&}A z5o;$oSi570U~LWO*;xDF5W(8-B16-@5j|3yG!pI^kn`V+SnY-z6l>40ORYF;RWbLr zp=l#nZhr|@>>=iIzA3r44V}nF{|Cgvrnb(;X1nZe9hwv*eGse;Qxv}#Di~afjHr^` zD@O&2hJu}g2F7X`Hz@`?)B+vQs@QwuNGZD=#E2l+i(HerH;xpt`)gufM_r?xwKt6v zvb!&wwLcvxSnF9ptc@bs-8mXAL6CG}AXfX;&5E@S*%b%6D(3!pl$71UV8ujcE?v@K zviHZMgzU~oc5+8UbF)J^Y#1eEx0Q13gWR>F1cTQzgX^P5Ih;2Jb1X3Ugh8>|Ww$5> zFR?2JbqK6t@q44vMhW!*W>hkZ#WAraliwRvcoM0A517eq4UJ3Mm)qs|(5R#=RuM4K z9c=!$WOFIm?$Km9Tsju(xUfKLg0WiK7R6?#ioi_5Fk+=(v85tj8ZA`B zI$~c(n?ptXW3*5azX)gT%cF$^Kg+D8FGq=kA%7g!C_&EmGQry06>CWcnx2^jbfJdg z?R8_NA^bi#v5|O7*{1AXH&z(ICoKYVyAarJ7u=0wg%MmsnRfkf{aC@>?;<0r6mZ1^ ztX6}Uzs!o&cKt$e*P(#Lk-mz(x8+F%d;?gqhuKT_nV9^&El()m<4+_0c7!o_Yo1WR zizwI5;9ukk2Cqbhrr{i^Xc6B)0d6+~Nh5M%wdd|t494j{miWs1z7&Uloi9BV*Mb)( zXF`Alg301v=NIsOg)a#fFSbkYefdH^c)tcGJ&s(`+E75?B0OxQ2V(3VdLV=GO*}Xn z;ko>Nyhfadm&HGt4Mm9_*@K2C165OUW3?x?%Z5l?00K=tA{&D55>u_QdR$r_kA}0r z6e^>CA?DSxMM?=(O|MsvEB*?NdP{%^$#*o%rQ<}iT*#b_BJG?DZjb>tXh^KK<~}9f z4(-fGH!F7DJx*%pE5V7>EC@Gco1%U9IH8>%BOWdf8~g4VC$#fFDATSy?j0wTN9yS$ zwYL3{p3>uM7IcK#J8Bx*8ygzi>zZrkwS>yr8_y2qj?1m8p3_+0-WqBO)pxeHwlvmv z)Rcuf&gyJ!t10bT9GbPL1{jkH>A7~+qT0E|wF?Wz7mS}+!v&yF&YoMme0eQ}c?f7t zReOC+M`!b-!WPO{R@YS9USIzS?-hULn>Z0W1s=IUwoQPzA+V&(aoJtowF7b4mN(V9 z(-aVK!xk89b>Zk?hiwxeUG*Avi%;Ixfw(2g!H=y2#nn)7nnxo)(m<3v%mw@?E1gqb z>A2S@?}351K+?gH2L_5;Bl|>$nOQyCe$sy46GwEIC;C!{0XuNRXn9L#sC`LYeMrlD zO>`IsM0J?dXzVby6Z6qwzz+=M&Wlj;ejXT5=w)JW3@EcZEKmizm3 zW4xooyf3eb?-Q1LWmT2q+TgrfgW=+FYfy;?8U0Z=!1QwrFv=Hi*B}Rj0}7lXaxgf( zj64mR79Wi)AvIu)xp3_|M%*WdbB~c;m%Jy3Pi1EqTmsR^3#a`7UewO6npxQ%>Zs@2 zo$~%Vg6$6nMA;t+(Z~=QGcDn8Ty>TAz{ml4=qWa4JTS7DZ#verx6oUnPI%E5IxBx`l{pl4AI3V(HBqaGel1@iGI585Ixl-`sV4P zr9X^DMdq=zI>xu!D)!0asiXsEyA|^IujM_SJfMiQ+PhK6f#4xal~;fRq^lW)zY?=xvL9x~5W%;O`d>7)i1o{WKSu zG(S42uh2Z%r1`3%zCyD#eBV8}uh49b-WM156`GGTW&3GKb03(6Of-qUc}kx#$SuwN zkG?bYvQ+oo$M>0*w)*t@auyQ(eHuqgD`V`@6GTfVMxjG3NN!VUf78^fyhBXBLJdgK zCfeSy?(oK7MSiL{wNuM`WAOA6u@2KG_~DE>T$OVKKUU=^enjJ1 zOwhI#qjulg*Xgd#2^Na}VG79AIVa2z0uqgDmqFXwB^c68)Zwi;!J;sh+?sQeT)XT8 zeI`8Y@YhH7nO~cIrVoe+#T`~V15x0RcH8uI%EWM+nHpLzRF;V>EZr7U7Ozrn|th-wzE= z4jX8GKlEf7;ob*k_s-y<-;K0p_s2)0qvr$=Wo~t(bym42FaPZkayL4z_3E^rmyrMN z2(fK3lg@L?q_fyEi8YyYeqBnN8HJXA`N)2JCJ3A-_!sT#^TJIg*XKV-w$|sPo$!jP zaw{<5Ra;;JNk+5<*9A`mQD%SP0Y!C~J4eV(tXe9;)$Y~&J4cA!t0`?A9rjZj@_#u( z>|9N;?OM(M)d;a`wJ&rSo7~*!w>k_3y+obdP?V18P%pRNPnoyFFE9Ir2RYhlFE4dm z-I`}!-P%`ZC#y@GFPUfF)7l4?O}O339jMj~%u888eAG_Y&4I!^Upe1AUs+2%;$UTD zii4H=#xmOM8MbA#SNmCpHXU^vbprrdL#8~?%v{+Gj|^9ab}GQ8+3?74ao$r(UBeRF zSuXjH4j0z9!)n+yysuadbL`gUEh(1O@P0H}4gayMhVs%WFtbJQK?A~`CkMxgX?kBU z8m2f5rVl1t22=Dm`&4_gUsK$dntiIH*?(7THGA~WE!mr`#)u1tn{!Kon}fuK!{ywv zsk6c1qxtUeZswL3nWIGXPcsUN9o=S{B|3eAcH1;#n~nBp_upc_W3f|bOtZ|&l4vw5 z%j{;QTohDV<<-NKeHs1Z?QwR+ z@tSSC?F*#a^v3EbeaX}~&Y?E0ozkbqiz2(o|M$2)M!QYs*B@`u-Ur6YB8Slb{CI1u zjD8mk1r(`)^3@#E1p}}-O1_#ST`)@=2gc_g%<0Aj^Us{VGel0Z>x=JAvc`$%A0j7F zmr)-4%{J1be_Fw$n-2W@CRwU7`kUP`LjKv-?0tcBo5UZokskdL?;Ia5E3zb>!T_Rf ziGn7`<`RVnK~^K=<{Wvzzn01w<`}s-N1W`RvZSHDuEoAkachn^)!#9Z{FymQM!)nF zIA)UHJHe8kK0&)pYizdB-UrNT=Uno>6D+fuyfsm$Hojt48*+c3XiGL$abZwOsB>9CTc`cv!Tgs8i_3x>%Hx&6%Eayi9mrv0|EzD#$sI=aE*tHAKzTT= z?7tjmDUax1^CAslYK~2V%{4EAn`&dzV7cZ+YQt`D{B&?PYhE|^C7n@dpO^o6YM(MV z3hfi~LpIv`fX-mr&6)XSHk}duYhH4Lv6`qnpKY#ri5ydJJfAJsyc+788`~V##*5kA zta-hZ-G{6VM{Ln+wiV+(U}(;*@!% zHtxw*D*!2BccAD0I$M|(nT2>cvjD#wladFr{R72m4t*gIufP$F_G?>b=>v*_!_kzY z*k_}?4=4&}DBeG9iX!@#3h81!r6?}XREi=MVAHs`JhS^~?X{WREEWDBQ&|>$fp^w2 z>&Bpsch)lN#-PbNM-1Z)!EShWV^Hz#y=V;hCQTx@iB(oq6kt9lca&Z+Dwwb0y`%B4 z@1X6lZ%Mg~b)T`Kt*)a(%e!NgI^IIl=zQd;^P`eL+uI%v^toEz1EYguRKwHF4pB!o zt)PaHU0I;zy)rsDw$IUBsO5cVqdVH|3hL;UcAwRCW2^~Cw6CnQmO~$(HNT`3{rt`` zRv1mR+tP}3WlO(3(wcPlfnlB8v~pN~b4;Ha)@=@IHLR~4YYpptV0>d&Z6);l{yb}Z z>jQee(4prK=UIBb4=6jw+Qc8mSjw&s*s)AI#!4ySl=?CPYvs~O)qL# z-#wvE4ePuCgogF?1$}B*FLDg)+Y0*Bu+ELHT$7hg=u^Ww(~e>NnTdUBSQq^q!}^7` ze%=R$b*5Vm>%S|ohIKl3Eb0~-Kd=@WvFuV(IitXK{^0l1gA>(qW8a{@&_?}TeUADf z8}-lhA?oS;L|Sxg5B*uxx&IqBXjoJeqV~WhQ=mN{_Eu z&=G3ysA*_#Y-nt+Yp$8s5-MwNJUf&-F1MNu;jwXLSK zYjJ4Sq8eaKDx~MyS&M4t7S}E;7+)}cVhtC7LOFYG@$%)hvr8&!1+=EBy}qWSvw2cs z3uP>;YpPw|(bhP=UMnw|pIb7wsyw%JLTO%JZfR?CTVqqGJ$K=8u53K`b^IDJ3fUEe`0v5^^)Gr_Krkvd_FivX8xpY( zdE>rMe;@P4-A;f1=#8VoW1saJNl3^2o`C=G#=Sv*-|)s!39;{c<5I!@*#CKrG58xt zzhc+ux~yLRyAgJ~PWPlP^LR4m&#anRt!Wwb+oSdWm&nS_M;7sO-dB-F4>RY_pEq9< zz!?jwzNUE@j0+xS&RbBe>019x96pRvv!}>c7tF1gSNheNWwHR7z&CCah=W&oBxc#1 zlG>{3lIoeYsy5t|HfTxN*W|Y?Tw5(Hps1$Kb+e!)Gv>{&)?&h-RST*rXU;9t46Q%4 z2sp{zJ;!K)v(&Sp1N6Q^kAq*gx~aIP;Z400Nv>J)d4b zSw0iIjGt#Pd^SH#GLZSMqz z5roO&ipCJEs(M}}QxKo|C##r=Kolf_cB*VHzmEicad;NVfJqqTkEZ+?Wn5A|JOnK16{ggixUA!$eCfNFgArxa}2W5+JKRPBM!CTcfZFRY_|d5GrY%141RO4=ZUh zU>g+HBvsNz2ZT!6EZ^TN)5S8qPo}5H^nRJ1D$@sK`Z$?>QKkzfO2Eqs zplWzf0aO*=Q~*`ScN9QX@{j_kS{_yaRn3)N5*DyQ)pL~ssEV#u09Dg95>TjWy4IWd zs3q!C!JKuBQd&NfIJ-$EW>I3ZOhByBmR@@=JPwepBD=J_k_C6Cl`KT=E-Oimy4y;U zwC=HzByxMLB+1P_D@o12-%3)24_Ha6#*1FNxD-qT=w%C|fa>z5Elrhq$Cjqr9P(z~ zX=%d(>V}6IWlnij>HMl{qJK5(q&YL^$n+Xcm&~3~AOUL?pilzVDZnHNSg!y@60ku5 zCQHCZ0l=J(0921n4hRvmSwYlyw!}EK0h7E{Vez-9q`MptDruX7sLyX_Kw0_1nRAKc z9h}5SE0Q}oNh}fRT_Qbmj!5q2Br!y!_o#HCNbgnYNg};ZrHe#*ze-OQ=>sASULZ{b zyl4kd{a;o9`GtcjEx+)lO4Appgm>%!D&dd<$ZsAFXC+C?N`tx`*iZqZhWN6I0mKLe zSuG$l=P1A$1`sn8WUYb}D#$tonWP}=6{JW(HYmts1=%PdU<*T7Mw}obY_kHHU)!P} z=GV3=i1-@Ih!aF5ZBrn#2HTCy2W-8CI?xVAnool)x_W%()3$u--+R~~!6-=jl6vUM z6dw2HmoHS1RSY3pRzX$^oCPx!U=0IgDOBCHj#3D+&QS_M*4s-Vzy^CMMBzq9DFoT% zD1{)K?WGW4i@g+*lC6$X2y&OB6oPECmqLK;_EMOUj#3D+(@_dRcG*iIz-~K$*`1R4 zeOn8VO5MvirLalB{M0aoK}vQN8;5LjG1BVP%*SnIkm6m#C{ia1r2f>5LMbv}4FjZB zWXM_tA$7%&bqYdyks<39gp?ISHYf&NCxZ@0Me11-py&DBpI+r0ieSeuvY<~ z#2Bzo0ieYguwMb7v>0$e09aEB&b;V=5G^k&i2BY!1yJ94Qvvup#FBR$5Gv)6f~Zd) z4&!bickT?E!sHsRVu;e13|cKfLS-^!4MUX9WYAg#Vl~E~bqd6Kj6v%ah!q)wHYgBl zEe35AAgMT|1ckv^gcQvB<`xCAzPVL_KwA@zMrviPKvTuh7uJR2k>XhID2~uJgrku<+2|~eDzYgY zk95ptM{$IdIcdp#*hsPLOP2f8wErt&QhT`ogkuOvjUl4+Y&aHoBCj)i~04YvR@8+~noDA5b08nTQ*sB0g zXbjk=08nTQ*slQ4UJN)O0IWC#XI^wbh?bWXM1AL=0;uo2sQ~;PV#zxW2$gb3LDZ)Y zhjW+2Z{-M^;^Z2xVu(_l3|cKfLUA%=4MUXTWYAg#VkO3)bqd5vj6v%ah?N+FHYgD5 zD+X;8AgMT|1ckv^gcQvB<`xCAzPVL_%#F!=d5=WMm9dlYWM?I)&@!qayDeusGbbaHop)vQflB*GPz*pdOHkFEug(WgR)%@I z*n(z%O=Z;_6n>>3cCb^qo-sBWp8w5lZ*)0PemnrJK)=~zfO&Q7kfk&Rf-Dk2>(7wfp7sWsuWe+ z6^=q3R``JyRWc9Y1+ssIm?%6!iz-Dm;p%zKMg{Q@?jE$?BFQE_j7`MHRXSrxK80bh zfx1Ruh<4EJbzp03oyeA)(lf8I+KH{OO`Jcwg0$yK5glvI#>qNT%}3WdZ? z;T$S0shC43>%&oqo5DK;lq#$bp~=E=h@HYcL^w>$<`^wlfNp5(g<9~dSQ#sle4^#l zj!sCk?42{3&VoDKgvw8pHMWQ9I~!YDfEX{{#JXR3OFhy_B8{cQP63dUNg$Nfb=ECv zZ0KADG&wIIG&?vT-mYwKY;AAsTmi%^v-}xd?H!#Jp_ZjwfHbwJ0B6Q<@j`WbT}#K3 zPdwUQE^>RLUw8@Tpk=f>*TGpM_L~gVM^(i@lzzPA~~s ztj1=xx3{*J3a*@%xz6jUtZN6KkX@6x!Rt8MX5mYFb>!C7z++v+J6cgyl7; zJW;Im(lV7%vKWnHE3HXoRCRTPHL-Y+` z_Sb@&@bTfaoJCceA6kkEVBwuUDOgPQ0a>LCPI+? z5up>I`CTn7jV(({(L+coq^NUJepU9zMeTKMvV7Se8OaJh0ab#Ws=DU3rcl+g#wDF7 z8HLL3SQcukTQM6Xo=P`0L40IwWOuZxJEOI$rJ=5!y1wd-z6)dw<&oT)-wMrH@TMNE`hLe1pj}f!J z_3Tjl3VXkk%~w)i4?fy6WGgPhfEPMF)ZSVFj!;OGIkrlG{8o|{{N`{3F^D=y-d45M z$-#ivwm`BFT}Orj(;Hm*U>?Z&62NX)70tY5aUu8H-pq>f>8>N-fB z$WIH9P_y#8C0(7Z=r4`+RfskMrYV__hqLRNh&h0!YQf`1m`o+$yspj?i22#vD}W(C zN?GVYl_6LS4N95Gug`6Tl3Ef%O^FV?BdcJ+OHM1NDrmuT@iAGGmeQ(uXg@?vQAOlu z%I8TFLKY3PsIa8|ELq!lE%;BXwyf@$H_pyGtFa}7!K`ty=-CU@pv|pT+FIA%(M`6j z@|?QmwpY2%gJ(6>EhYWZ)uC(BtbrYz!wS6(apdk8kj> zv4g49(q(lmEup4b_3B%3DKE$B8G}!&sw_8wR~MwL9;o~I1u|n4@-L^s-*W$%(=;fZ*jfsb=Y*$ zm|Ea7-1&`bXNdjGlEWBzI8i=l2#U0YkotibN_F&}#LAb(&^t?kSA zoHFJzuSruCWJ;C!pHs%%?bXw@Zz2{=#t?cVI)-q~Hv&bcftbXxvD(rHlC))GbWM-1 z1BAMX+1Q%rPu}z#Pt81C8+W>h-U2*ZZzj3DJRyA;H^B{OXxa|A1eDBP zo^ad=)C7rj)C6o_0C`^3cEDy5%xr_p6KX@m+AcuNHdvb=+Te!-v}utaBnY10LhuGy zEw$~TrJCo8gnolIpycfUYuc@zDCrCn&j=K40zv;BAFG}6sA`IzgFI7#z?u#rW*z!9 zL3W1Ug9q{OkEoV-DnWFHDT}R^cq(Cb#p&QzJHgDBcq-wvZ&FL#0I1m#`(#VJL_k|h zJR@7;zXZ2h;#t`e#r5bsb(k252KsYCQaTl#)+hn{6Oz&hplMe|OKZJ@*7_+3I(}lT zHtx5owXU|emd#etJe&RLBf0OCgIATd7TfHfelqo)djN;}S^@#z>|Y%EEkN%P$ZW7% z`~_2piGv$#4fZp?=sI%=Xlt-7e$jOr0JpWw&;4O7bDLka%r~N?Wj56XidLaz+6rQ| z^2b%nkP%|`BfFKTc^*nhAH_{`bx70Rv^C8`DJPUr)BFx_*)$KOG%WoCK<@%%_L`k3 zq7kx}I2+-S6wwHi0N1qAXkqZ|#et$LLC~_oSZ(%h#o$?X2D2Me^IVjkp39t_1rDUb zF{sqkMd`)I6K8)#98<>R>U6=z=fc={NxER;JIuy!M++N21RH0Ajn_?rN&bXnW6A{} zkInH#b&Z{BQX5*((%Hz~0CJCc4hMo$G%~yEmT4LlGppXR9}frSoJy?y4)PMH0K)&q z8KgOGAyAdDaXtu?%{~RNM+sJKS?(VMs%r@MH31h6InM`yWi13vXe3GgQM5Dx@$K&* zrnM+mdr37x{Cd>{rL8SX8ke#~dDWocC}w#UIB>uw$yW^$I-(MAX?4QL$skf^_ooYDD|9M9G2-Yo{U(8SenRXIMzTbxP)l*4qHSL}(vJwZv zW<6G$0V~^E&%|0_N6p*?r4=*hjhkCMdCF-M$DLYJ9l}BY<`o_0Q|+v(8JKjJSJuEM zkFlttwXPx5E_MvAz;a1*t+jD*Nyp-*PqJz7iOI3rhBWN_^M-92G_D0JVlVYtaJ6Od zTCmz!fM2njy#~1kVz+vY74&zT*Sn;twGMj@V|;`_MI>QnPe}ai(R|J7S=W5@62oIO z-*?rsq4|EGo)a`5eT{JvHQz0GzMRVRX}(`7c(UeuP(An8e7{rAxti}8^*mJby`-MY zG~Zk5d9mjEKs}$Y`4YYITi7z@8>kZ4GUgku68E9n1uF3$T}$2*qiKg@{NML_N-GzX zmy!3=e<{`*DKZ!?U3y+vjrC?YQt7#*d_D(rBvAr;AplRMM_PWzf|CD6KxbFdbAT~s zi*klD&MYo-G(FE2&-wIRCY~qK^PD-eI25CZ5;Mf}RC+EENYnj4N9D?DE3qL3`_ic1 zNR@GFwoH|9s>1(E&O?cWTIs)!ljUN!+8Io7MLCCdEawE`9K6HM<40Vvf((l4pih@p zRn0{3h>nd{oUAP2W&G8gnp-7OYdrp6>gGN(idMw8KnMz{gHARfyEC82@j*W}PU6U^f?C zURqvKQLzB&Jq`>CAlR!g<}55BjD4IgD=kO56zTmcU9||Q12R=Av0t>M3HxQ0X6%D1 zr3!n~1aSU4oSacfwZqGYVzlJ3hNfjP*Q@7OpnWuIpX#qw&crig&&Li7DVy`fW=Iyz z`4uciESuZ}B%El=Dj`wpxgz+8WnRP{CHenm@sc(ja@h;# ziB6D9CDEor3S}Cu5`{>xxR=ckI~Q5r(b2fKu)tR>#4bU4i6x#>^cKrJrzRma-TrMt zKAFC-=&K7vsg)|l{i|A~W^z9~&HqoU-c)oA<;zVINVZW@2FwvFJGJEWAZ^1WIMYQv-iFDq@V-T?532-yb9f5rKvNWn1m=s{hDo^QHcU#$ZJ7Qiopoon*tTI3 zs%;x47h`S1lu5Y_Q>B;^W|?gprvJNECnJuZM%ZeLCG{+!3KWETm(T_ZLcMsk$4Msj zR_Fy$l5HEN9YQ6obKp=(>%&Uo@E?U`+lDDiVhEMA$$>*9Z4N7m`uG-wW!r`+OJWF> zbe98%O4{bJw+3mr?TlmJhDoKAm#RIEyJWuF;<#I;)egr!GOac^?v-h^zj2>TtL=^Z zWm@fSJRs9*bE8nQsE^v*2t~^kDzLU;N`R{3n+ikK@f`(Fl{};Xs+NZpKvi?4R~D-3 zxk>?4MOQ0;s_7aDux-P%cX5hqTgNEoHca|NX*q^6G^xztQD}?T-U}(*ZL7$(wqf$C zl%#guW#v+%?zWO7t$VB_iQHZ*NpiE#N>cOhw~|!h16Go%@uJr*E^-^DSrxer(@Ili z-myw3pxPYr`hRD2OSuh`UXhXW#0-pv1h8$xq_m8iCxo?(000HD6JVVJSlck=D-^>{ z7#kD@g{u=_qX3AId1z~jv*ULpq!5tJ3ZlNVCB~@@DsD`I04KHzG!T!4Z)ZL%s-X+*D6 zS`7F|BT}8xV#udsh>#`%#F#Gug#d^_9{~9UG3+BPzaU0^r0EM(f*AKDfJ!(d>R741 zc{rSvBrPiq$p*C(auowqY&_Leq9EqiwknAD8q0_iL?vxgAhQPB4gX8F-a;K{2P2u= zF#R9c@~MCCVf)6h4U@Q`tN{vHUzI`-=Qd2nSzz0SNdU(-OnWIrz&b}M1X<6JN>K^{ zHZVYzLKJQk7;;M}K{h!`A;@NXDFoPJFNLIJtD_Wx+~p{RAlvMv5MaB#6lSEO6oTw@ zltPeQ_EHG2+YVrMr}%$hYXLU58Aoly3{x1SWLKp!bLr>{o=B`t^}l5+gQLh9Me0O> z#I~+u8zz+knWlZ@jIx$d03mh7kaY@T+lDFMBGtq=8x#(yCWdSj5TOXwHcWm^fw-L% zmie_U{lkdmp-Z8O53=YxK~&f_1u`qKogwyZm{bG%HcUzrhvW{)UHk$VB-6V^k-S%( z$=ag;&|wVNs{l}94A`dt&|(bOuK;Q<~iDz9RQ(wGcdEkKTKm|SVOb)AvcG7<@oS=2fO zVm-!K>lKI<8G|+`5Nj<4Z4@A>IMp^x#V1idi;%*zzPUw#tZ!~rAo)!ep)eTBkb+qi z*$z;QIYlX?H+L|WREKICrc-Wt1HkGWs;^LHY8z%48mX1F0?oM%GYpRu$9hL`RFMri zVQ8dIHad$VvNna|k&fByD2~v!grkwB+3GBgRb@CHshe$%;#ggVqfuYp;Vh1IW*DB_ zhH2*=>rKZ8SaIgq6{p;WNw3LWAGuEM$ZeQ}VBdymSDbPiCZR~hDSSG^8N${i1J*D= zDo%#1RS;5T3|Xfjwr!YH4BjF=#yA@k4(Tk0Y!ncoCB@dVO->L?y#kqE+Y&aHmfJA- zgD|PMc$RwgrU0?fE09@xXn=htA$%d95`9aV0f;s zvbr+KlyF_)^VFGT74Ukhf0Knrk|yRUWiuC+m(Ij863*Dl(Na~w_!Ztb1dMZ%1IGX3 zi9^76DlfJnetd^FwkU0&Mr)vbbMaEI;`Pwd*7lIt&JcG#j`_UYlNj(A`ufg5kw+V9 zF(>BOglK=sR(7{G2a0aRlJ@4~VzsV4NeHDxD0kclut6|O#2DZ1iB0jGPf-E6_|a0Z zv?)cXZ*XaGOQ2{jcyjWzSnb+BDlYW{8^T0tK^x*35mI@dH#X?G0}RUr!{R$ubksMU zrFkCkCZ&;{U*1D&%GSXc`4G#At&MFL z#k>-VuZSV|!V+4|j`zO~l#+__8Av2)DfATzTEPV)IS%GBZjEOYRz9N|2W*4QC^zYC?*q-pfdGW^6* zSf9CF-;+P4s00}C?ICRE^^DI55dK$zpHPcNnS~dY;3t8$JgJ0;DAqiM{(kf-{YyZ$ zl=`S(Ffodh!au;^)Tb4LlRzcO98T6JCTgA;iTypqf;#YvUO5jxn)XJbrg^nj@Z00j zj70p#U;Kj|Qr+6x)KNocy$h|}=^L>BI(JcP`&o;zv2|IlIPtxvuD!XYv8BGI z{u94gQ&-nszYOl3V`BlSgYHWaQc#7%@y~9o51AT?4!*C!2^URW*dzLReE;+LR=0=x z(?K4`mc*ldwx%Mqv<`crkImP6QfhN}RB8X>zFf1owYBpL{CrDmdu_*(hPE%T3LVfp z$EM{!{p9A@^@&ekH=MPjX=N3Si)%$JckSHP_U5{#@yj&NhwHa(i%sS{>Lc!P8H+O^p^73~NdK&B6 zYhk;fhz?vhQd^I0j;$?b{yB~H_4Lx>uEr)DA7aAy>DD_YaC0n<5Lkw!py}PDj!uj- zOH9DYNaHm#{j4Xf>Q8u9)GrIwpJig?t?0lRD%KmBD{vTr#h#tIj8C3CW%+Wvq+j*Y z<@d$jy~k^YEt|mSJY<~OBbv>urS*0AYEwZi2t9iWz%f@+G56@;R3meQ??o{)uJMWt z!5S0%YMcP$l!6W%5n{qek!cLBPo8Xo{xG7st&2Z5)r1}Jwl#;t{vZh9OIw;)?E*cP ziTuq_lSax0+_-^i{YIPvUc0y>R8N`wlF2W55e#b986w7scW+Ycl-Z)~MBY*T`i#+?Q@5Vc`+v_bh{c89TdG=Qy3OKXr_#FD|jl}=IB_Ek-fBB8DD)U`Ds(r4< zE)B)xrY3Yc5_QpZ{~7GavRC&vWt>$@qf_njM(XeJciwjR!Prv;oQ90r2D)RYy|xp_ z9w0w~^REi~4BsWhl~Pd? znOl$TEN0es!vxEbxnB<}uwF~z0xPs?7`V7NByEMO%ltJ?q z|3KY~ISb}5HHn6iG-5!;fE=Ez3<@xGNuvHRkPY4I&&(Lm&xjjfBn&W8bWeeilw%k< z14c0RJ>Txn=)cj#ROh~L_eYVFXiDTQ)?-Em4P$afMk`RlM_3~e2tnj%DdhV>-UC={hQtiiC(8Gco?ir~)2bX-{m~sSBiuJWM zp0EtHD7R3|bZskuVukPMD}Z8+?`SK4zV255#j;}eD}W+TtpM65f6L^WUANP5v79Ft z0kKd@YmM?{xe}Ok#~YY;k9N9iR35K_?Z?TOY|7vKIhpc3nF4l0Ly9e>?&Sx=j%DIHtp(NcS1W2u04*5lGGsLC#-5 zPEv-?@DDeP^n4>R)riyo-ylrpJ?RnKQs)WM-jOYp%7T~1XdaYg8)O1Zv*VNn=d*uEjcXh&Dop4ttKJMzo z5k})tw;R>9(M~V17IDAYZSs;jDBcfTadW8R!}UszzE=okCHXTBNksUP0AuI;hG~R2?_XnCLSoD$z*O zbBaMb^sfbJh=jxO?RFU{Fnqb-p$}|GO*f_gxrmbf zhXiHU8G^EbqF;lue!4NrNFIV_o|J7E84wDS!hO82?~m@jK6j=Yy)#|8`2Iz%>)6-- zkIhLL?y6EZ$B;>L$lcf|FZuf%SC!=HB$0g%iMx3a$27R-l3)TU&f9R$CE=;NV8*9A zm!yY} zqaQ_H_tB5Z9HiK7^rOh?Df%(Fhv-M~HliPY%d?l;z64&0BMdO){~{#tCse1Pul1>#q0<>fyCf0!MU~Y=TIapHdFd^pC8B7Tzfutev0#I z4tPfKhDm^UTj%p0xP2(XG?V4#$;g$PeS-Q2XwM#K8f(Pm8pZ&MolSseCV~lz|3B{C zeX~ zVI0R)qQ?z{TP+LjCgda~QRb-N1ad6~e9&?U`dR&HvoyA4r}&L*y&}a(>kn~8-1Jyv zCKg~@^@@~?RDF3$hLNcI(v7%M0oTvPizv>IKA_+5?ZJ5b7QJc2jmM*Bl-CE|=5fTv z2sdKG^mJsuDXCynr|+#ycS zwN8!|fgU3BbrtCG*&Qouk8!{e)xAGHR(qCbgI}gW6;bf@{Jtm!==o#BaaWYf}{Yzya z!BbQFnLsCk?g`*^Jskl%cmOU0ARciG$&iYquZuq!>G)>S&%7y^9zlE#eiaOk(|_ls z7u4BO61d+2_K!eTYZWXzmtuB`3E|K@U-AIMIML9P4Pyd8=|P+qmSq?N$x7}iZSUpBOZ*KkbxN0z*z2mO7x@%?V%n=qW570(ma|>3XgseGzTXcS;1kDoY?HK z86Z3_h~XvOFh*hw#&M%*7gk%DH92LGB&`F-$$T4v=dbx{WWky_hs;e z4Yb|{D2uo_el)V?I?Dw~{{l(rIJ79)(77AO;W=o;4Tq#B4Tsdj4mI>|rSKr}L zk&Zorj(;jT{7{nXc&YPpcd64|>U5Vn8|&L!LrtOj&i2+8TvUk5Upvm~Y;CKd}yBoMn%NBd%caksMEbUlMjb-Z_b=l zsE$VZOmEJt>#V~9orv&$u)kP}6nAP;j@sUSk6QJ#ZEyc{+uy&mYpQSXJmKf`J3M;% za}GjQL%4aJomyDsMi31rHpD;JpH@~63M>1Lc)#I;>l3pe?3gXaVwq8Z$iqaMx5nv9 z2h&o(Kzdw}lIr7m`=N*>dF-j|g!n5+9*|?CQoJSZ{2Y}r$>@jp^nq!#rX1JLI9Weu zu#uQz`1Q_VM!bH03Rn;v%6^K=*%77F@9^f1lwkGV$cczmf3W{YUa5My;OG?z;AoI< zD)J9Rr1~xA$Vl}R{mJ-g9I3wf97L+?PsIQ!b$V=juc!SltKStT@%awe6LY431z%Ea=3_FBoaH|viU5HPZRGl zDb(MWY9LD3fUJQ(i&Kou6vV%eA&E@L0>N1`A&j1(x+k0e5AebTe(AaX;lq(t19Uw- zkg6xc9Yua8wQf;#nslS0*PGA9*mC04B9U*01mFIW$i0|0l7MNGDKI;Rf~9fIlxGxR z$>eIy2P`8P3}ys{%UwT-{mk~?$LlfmxbTV>%@LabM#e%Uu@a;YKyi6S+=z^fF}O^t zjHEAKKb^Q7lZ|py^#O?2&K0?Nz#o-QM^G4}Qq!PJjD*}V2vi9e37KOc%k&p7>e)tI zCbBZ2f1qhe{|pQ0UIek|@%U;!=jsQ}AB0?QAOpT)BVj1yA_)~htJB6AG;W-}5}vAr zAxVZ0OZ_+mLmc*zMMr)ZdK|u?>-o$Dk{542Z==Y<3;cck_-y)%$bh&!BVi(5LizgL zbZ$nL9#f#lHzSGjF%tCT>{NXq0xUowGZN&NLnM%l1K#@hjU=AGm zLkxehVI;%F&uH*>qbfOk>;|p4(* zQg)r7?0ry1+7Q~Sh$$Kxv7_U!1V!IVg_ft#IE;FFL27U&>oQVr-%14Z1&tK;4Y+y` zG-FQbG5i6~CVF&>q-U1&6 zKqSf5ji0B-z(^YfnrG@s=;K5A3H@7#J;3srOwt?g=N)etDL0Z_$+6A;+^x(2e=fLdD(v$SAXiWKPDg`Y$!myf-8Dpa4bfdgbk`7%9S7Vs z#1GeF$K-r=A4bOAoE@F+8lt;~h|6Vo*=!lM>$z))$8Zg?hm}HeeQ}FnUtgpVyS+9_ zR}o+0DV;&TqjOn_TMsQO7M8XcAGxsf<}9AVe2C+^M~^XlyUxT?$xt}Fhp-=sBG2)FKQuM)08Yt% z+1@lU&))qN%>Sf!*Z%yJ4Q_w7omuk6KwU<~h-eS;#@c}RZ zv&wZi{w67lPr`u%bv6#!P9?|D*RU=EH~xU}K`en}2X#F#96v_fNyKy`9m}ljkj!RD zk4y%%&1MGt5wmH`DYK1)lR!Dby)nNepDP{rvkc3X1WHJA{7oY!#6#qYNb-h@rJXzA5IkVT{U<6CZhk`-Zi>+0(6h`D?%Wj|m7sd`DKZNR8CcS@(V0z2M=JZ{l zceHRh%*3WTmh(s^Yl$H1X-O6q-k~W4S~|`jE)NCh_FsA(FKG)2^0(UW}t9 z@#pZHHs#RP9Q?&UoILc2gF8Oai#2t1?e)th71EcF!LU%q+P$NubWT-y6@rJ)ZmbU> zXjsGz&&7Efu78L)lshgLho^rsFM(n)pT15kt({#`Q7fRt-I|Kf(z^N;$GCyJ{d!e< z{W1D1LW$2rPa2_ z^oh=LQXU&jFXOIy2}ifzlgf?*1y_e8#q-(II3oICHe!B4zr)A*V>sF#RT+yoT~%99 z;gM9(q^tj#Jm*+RtHfzpSij4~c5z{g?T#QaiUb)?P_&*;t-2Nq;2z&lo&`M`LG(=h z1~&_xd7FfTj_A-GEbM0)o{>C>dxb5@7hFrywIp3j@)K-TbS=qcnwQtmHpe#CbuPos z8V@JmP3q`uXb3Ga0VgBf*wSgHpY^zwq-#mKmgJ|hBx@IUgz8Om@_K*I=H!01TQ+?; z%}GUyuqm(i^Ukj&Y`nZl2lnS0UfN`U)fMa#pw$rU3DETf+LUwNU~x{1IC3e1=o`C~ z>H8o2^hww_lSL%bO`u+^2W28MHtwX!wA0H+=k(+7uY{4q@!-v;eGZ<0p!qd6;9hbK zIM;x44LH|;Yi(|BZGnv?Y_fA2>+9>K`66WKN3;E@?s z-`XCkt#6(@8GMPklAJW|{d!=9d%qq@NQ17P_r(aS#*_0SzDX)tqBBu)? zZ>E3-pYXZ@T1HS^zb$6y5D_v|EdY05m#jzFk1wji5vrH9unaU$t=m{TD_Jjup|dC!9i}vF$c}Bo6ezp&KK!MjAdG z7n0o{0lsjF^_!TDt>RfYtvtKGIv>|v;hZz6aIPCG*An6xh8rvQF%M&PS2&e7&2^Bu z4zl}V54r}>m5Ft^i6>go*PVxLn|& z5s_s#z&VvfTW>t+I0PdBJI3mVWZ;}V+`XMNfF4HRVW4^#K&Pt_gpMK8^{a3onlTbv zns69dRdTA&mxmuC4oio{lrrLQLfS}Q@^E^b2f#EO>y|SHUat}H)w~7dZT5FX5ZC-o z?9#h|g4z(%MqC5a{LSO@#*C#Cf;{;X7Y`Ykg==a?B6l9xlZ9LCffgJNvWLY_W3rQR zZ=+X>!*6#N#pmJK{ldM-aA1EC&g)~oi{i5}(T>d)o=;yl_WkoV+)~^j+qkrLZfkpU zT@%J25owmpd1av`bzM!Jw45oxPsiA|?wa6lG1T2^v7)0h)Ld(hrr?jx>nKa>>*|+< znhI*MZhZC>fQ4V{9$omm>RVm^*nP22iDSdfMLcp{s5R0bC74WQpAYhCvB0OYUGve# zjL*S*lon!~+*09eo92!-IM3pL^6Hb1#NO`F4zL}x>vQsteMXwGJBmDtBC;?;Y%5Lh zi!;#&>SXks{y8roce|zJ*bT?WkhNaPT8r&XO^C1IafcP?e+H9XKTB}^L7WPqPcZ!0 zb%E2yVS7G>OKbI{Oe{JZ`i-Iffa&_PfO&lSxi}^?DVK9@3Z?is>uJscEKdJvXgVKI zjAJqf>hXbr*u;(~81`Z^BT^!WH|A9RgN&d9-4-<~1r>c4pM#>VN-Xrp}U^h*hP`AASCVqMLXN4IOJ zO|VDV`r1t_hR~zE>>2^#)xUz`F?`tB&Vu*pq&CBZu9@e$@jux<|4%<8(r~T0^RR8Pc`G^^&kb2SnKD!zvv@E6@JH4u`g=~rb&!&G(1I^2hYUf0)R4{7lx)$ZMxVf~>W; zTMPE5XN(B>b;DrYC=u7ZgrCMWFFUZez}-gWhQYdSerws{%Wht_*Yh@bwsxOPcUrsQ zK_b6po8^Yj$<5#6z9ybiTeXENnFzrWCcBbQvI*0J0Z0!ic$2 z5c3m18DEi3%tk@XO>~!8#1nI?Am;K>(Ll^yf|%O`G4igiT>!GkMOdG?R}gb>%ty2g zt{rop1$zv4gdTN4&$dgmTWz*e5VK}16Ju`~y4NtmTIP>}n8)%zqGi7D)BAce&g>V& zyef#Xw+x*zA7L%?ydY*XZk>&M)qGG8vr7;Y-ZBr)q80tg(Y>PIqZQT7ilndyy+_!C z-Rh)&3I6UU&z&BJdx+DMaBBcBLOwl`1PJSpH+`+v=fg7oV%!w0dp7}b1TJLAqLltU z1fRwX#a41!;eU}<;%Ox_LBG0dv;yfvWjR0X!cKFbJuTPfH+K!AJL~n^sElk;!~=Zz zBtH6fr$D~cCl>PG?Hr5`iWSpCw3IIv>o4gLE2bBzMbrfS{r17Qq_-INHtO&Gzy8Bg zQU=R^$=EJ6(D3Era|UiMrm)yi1pvv~-(l7M_g$jY9SY>r@9P?b_w)j$;5Q1Mpx-SC z1xOHTc*ZjaekdamernYkw?D zdDkjsHA+d)6Y{xo`xQJvzoBaogZ|7MPtZ5X^Z|w9)35EqrOSOxm+5yEN`k(+V-REk_hCa8z~(_>@hh!2{((1eqjrJFSZ!sz z+c6kL#TFzP{sBg6F~7GjU$%0pzNt!tYur4}1U)%lfd0;!0aZ-ZudEcHcMDDNSUo3& z?ibf*8i~56SX?xiFce?O9K+xE(Qt`s=>PcoU?Ww8irlKc9H;NEDhzvj6uqtLcsS4e z)Fsv3VGa=Ad2h7&or@Ql-+97%`)=_zE`-lVRlyD1iI_0Lo5S(h-uUU52c_yy8-BX6 zVuFf6i3ONlxR@#t3X`;#saN1c1ztCqYM{VL3cP75gXPtm@;l#+{d~T2=du1yF32?e z`b~6)dk#D8!KtB&c4_a+Yf2^VcVc^iTS(<19wNuOJ8^F5rko$9NSx{PtpxpbtDIu>t*iX<7GPIClwf~6d3WW*)gRn7kD?D<`EcdK zl@DQDxb_E);qLficwPGgg7BHx+wS<{jxX-`;*KxY#M~WU-0_7qf;+yr{twqbCVXG6 ze@ySzPwUEuD<9J9@5+bG2k-jVl{@?>eoeVv;OY-of4KU?U7!2deoa?@IM#Sw`_#2h z-SvGDe)4hROkDfJwLe_@!?izL`@@YNQ#01j#P99er>=e4)4HlFAFh13^1*S%ZhSHe z!pB>8clC#>KV1Fc>W@zvx8v#$SAV$r!_^+ z7-b|5K{-^}1Y9q!_X|iq5i>rDVS0hLP|V*Ko`?fTWS{EI^EZKyb2GNYrF&yV2@>*j zya{O%IM-V^67oL_=Ujnvm4zcA?^-yk1~p6|K_v>8U6S_<;6JfB%Vn8CDHGdM;D$8h&`9fSS8Lvlrxk|2}K?uyVmx6r6}x~ z#DFSb13`TH>xlu(jpF?Zyh$KFmN-g5ZlGd3qSLr_Qk-!4#HT}k8hLV+(x*MyxF2;^ zkG>Jd=~_zZf6BWPr>|Tgl+yPtrSzs$N|#wm=}o6ny2VmTPgzPS%b@`7^YyHhX{ zQ%d*v!j;k!zHXJ$t-hX=l3ORQR7x(Nl$Mr*+{cioeSCY&jbDb_V~(mFJo4Ogx;|#F zPyuh!+2DTN8_3EU(l0A(;J}f=jFGAGf5S7J8FD_~fE_us)tt=g?eDmNB_rF=lQS{~ z8b%X4hLd$~wh@;JXY+IHY`*E+{fG4X#>vI-_yT8WzsXrfT&@w1gRu=`0Nl@Igr9&L z8}<0F>E9ZJoS132Z+(a?1}0EGe)OTdfyt0K z{oyc(p&yWt-4P~T&k>0p{ex7rKn4UX57%DeO!*OX?Im&N?-52%{~1irHE9?y(?Czq zN9!mMlX~5QRRKNjWFzjxbeu|##TCkdgz4!VzcVnx`pz0b=|%lODOwIw4s-(119aIF z#9tqE3gmLk8O|LPNnKka+?e5*}?%nOV?&X>tjrH#3nsmFUd%322xn@LNu4%u! zeZzQXm`a4-uUQtuCf}dM{hIQclH(0&-bdKIXR`${^0H9rUOAD7A)jxA5mPCMk(Y&r z6LTL=Eh6R`*V6wfX#w{ha#4MTLl46MJxeZ1OYc>Mrt3pO%Sj*VhPwP2)HN9 zY=Iq-Wl-E9`@mqokp<_q&+Erv{8(hsut(7Fqa11kpV}{c08rj}5MidpUO~;nxu!_n zA6d=ulpx?QOn|sgHo}@7?fb0gp2Q zKD8DesXFOpLCqT6#x4(}h_DXvsvzLuh$Y~lAmD1gjXV;2^y`9vUqvhdZwdl_JCgeV zg>OWdSMNW9fQu(F0TJ$^^ulY8(3(wx7`ZOdpIrGwScJ7qtRUtd2Qh<*mHq>5RVAm)-HRseE)b)<^fXhF=)f|v-`W)lT5I|VTjuFZ-BG0!-N ziBvJ0Du{V>vc1nl>iTz?Am&9uOoWTsY(dPw9mGVcm{ka3t}2cO+pJm;bC)0{!o}<~ zLCkL*#6+r?)d*t#5fx(AAc$Eth5Jl|i`glDQ7b+k;R zP63t+VqS3&6RBc$o*?G^9-FLCnP`M1wZlB#7B0h>399Y_lNd9tSazDrQ>*F;7Q@nB66a zdB@Q*k*dwM31TiekrlvbEMs6#v?*pweY)n=rqVuIz!Q;+eEcgtzGgv3sJ)}6p}n!8 zvHf$}N%%#4w)+kJV(*Rjs+TUmFV?>Irb(O-yG-+N)^EyayMKHvuNocJupv7O@zVp7 z4P&x6jOYno8pdHlhJJg^U?XmFo{@mP+IkB1_U2{rSwRP}lb#QL_31xo8)PI;NW}(v zJs{3cy@nSy@qU7S;OkQu|Jvbx{hjj@#XAZ5t2Kq#Nt`4;ci}KUf9r5fWfIPW^(Bk* zV(;YRh>(-0KQ;$v%MSD<=W|)VVmFsMNcK0U;2>G#iI?t~D(jV~@B9j?j*J3PVICN{ zv>(j0XWTwbzG3Kl%LX&kL$fEL%gQ{R}y-GB=mzb2X|Zb&9XAjc2k)n+4A2Bg3yaAorDhYiMmTJ zqMf)l_em~3LR=KJq%G(3aKb{j_}`cKZ(I0W&JVF$o#azL*gTE_KjMX&QjjxEg7iGr7fbqZ>Nd6tZC^lII~)P=Y9Ddd>9on^nW)?j2#N&0f}+H z#CT9)JghLbON<94#{J-m;IF9c_jr*{Rrak4M`N5~Hiqb0k2&~r2l2-yUu)Gj-)NQ{ zNq+M!=8r>Sq%hce4@r2$q8ycuW0R35gjOiY{d}yoQj#01&?s3-N&ZzT1R>DZQqQyr z^n+5h>-V>b274ey2-=P|N4NMZpOUR)xlNYx2UUt}Y}AT7=(aqe zC?2bJ7IdX5=oMMeI$6+bToBZ+kitI}Qa@DHxt02tO$u*Or934|xmlL7k4tfg7+2@D zv7$Ox(K+QuZ7-$#@0Zv+!>~#D1E-ja+{Fi=vl98`LZP5V#`pMCa;2c(qB3k%e~~u= zLN#3Tf1*8}_lx$p_WzC;iH__*M+`q-Zj^~1-QOdOqEA}gVu#q-N*To>)yrm_<}4+7 z^pr%F#eaTFnm1R(hyx^F`&J^4ChKBGnMf}vqzw}3ZxZRcm;%vG)3~s^M~ki}PWFFf z5f0rKJw|=)VO7v}S7tJJcun?Hs5(9@;+!NO zCF0+Ei}*vUWqL00KyMK*vzqWICC(SbJQ6!i32uWT=0>r|A&HTQ|LQH`PvUx6;_lue z{=2t`KaKyWPoF8MzTIyko~Njmf-9+(i2Hkscu7hxOZ-)D5nt#n;@Z?+e)_)NBEH&N z#H-SJ`RSb>iFko%nLoywD&-2*GIt6$wNxn*@qfKV+!EKz5})ZU;zjYjEb-3XBL1nj zh;R26@rMb$tz&Ny|MZcF8$=UcpJWQfZK?_Xj7X>5F=PN|3+HG6nvw$ak8i67jv>BK|JX zG=Pp$;z9B0Ut1*}R-bm-uoCf=-XiX>K7EuDy#p-Hf86KZ82ok|*Z3D}Ew1qoXOdDT z(}nE2#=q+E-A*T5<6p6-+j)m;{44gj#=qf}Qy$m&S3=S4biy_Mdt{Gm{44gj#=p&6 zagBeupVMyG_vYC({$1lA8|huozu}cj1g_^_jWFHX^seW>d-k}Vf1yZwUhi;?eFL(abHjdmWRDy6(>;6Kupc+<#|`^&kNRZmv`FcQZVwN2!+sQd+^`=rR^2`7 zQwc@4Hobe)r(#dH4t>}7SM2H5rgy`BdSs95`R|cEuIJzN{JWli_nd#{#R|>~0o-%` zl?rv9NF=xCy65~W_H=9Ay2gKx>~W2M#U9uAH=}vnbN-c3bUWp7&-w3>J?=UGM~mVA zxNtY--wpdQyzV7mA~ebM{M!!qb&dbtoXz7J|7xV}c5dVv|B5}X@$VY{y$j`cjepf= zx}6)j#{b7P@{fk^8vm~G?;8IfadEGE+K(`U8aBU-cQ+_%|cck7mGs8n|oxyT-q3{JX|K$Huu~Kc-E8yMLM*se86=UC+N7 zsa?;%xsUgv-tOadWB!%&bZh6iG5)K#{9c6|8C5`Pua55p)hf2 z!DTVU3R0m|sB8SY#=jDZo~JyoruK4f+2b1jb_4#?JiErfYy7*$zia%v#=mR)$LaT3-Z$6tPtHk0%m^=l zHG|Kj|M^DoYSvanAt&cF4_A}@Kw`M2VUbXsrAK1L+Yza0C4 zt|Uh}lkYm}haxS`zc~Nm{EPE1&c8VS;{1#AUzvZuizIRE1OD=*~Z$EiuktjAA6X>j85*V*@zJa5$~67h>;gBO{^AeQRzyZ9@n z;(m=e3tCM2LEwY?Te7d*`92`3n{Qt0cGDn!byUR1G{v`O5udUY!}2hQpBWWVKJul{ zV#-IpoZGSTkuR+j`|V^C`RJ>>>a(DD!+~*eK3D_={y{>mii4 z{aEotUh>G>eyn&ReR_G@PqcV$)y5@n`?2DQyyTGwehZ369{7zr##1U>od04Reiz4e z?2Ac@^DoYSD&dFUp)bzAR*J&k4E{z%aO=G=;(r&5ct?6PisJn1k=bt-U~&F~*V)Je zzg8(CFL~t5zZFlUPcO%Q3W`UL{m8K&Irfu1q!V*KNRIs!+Ms4Ez?YqWcUQld zbTPaAE{^Q{%g(>-{Ht9J^Ay2*iruG|oqxMzx=ig2#;`}>m zB+kFQ?I)ESt0xnA;MdL(k%x5TfnO`0NS|KL{9Exv`t-8%Z^aYo)8AF>hkNDNPeD1# zu^%g*$Xf(*=D(nL3Dr0<=CwfbwjX`JqwxEKWar|7~IRC-BdE|j#s}zww{fp(nr$gRW5K)}}g5nY9--<_^|6oI3&iq@Y z2>bN+0E|Z>F3)~$M|S?BzGy3F{^iWSocXtR2MeF(5$E5|wc`AX^KU<}Uf8D>=ik~) z_?9M#J$8v zoPRrqi1RPbzc~N;$+#2UTd0@7La^@sFyo! z$BHL>i{Mbax4%@H@}B=<-tF(=xbN^UCN1yzFX+?Du^&116L*wf-t%u4j>x0@a_q;7 zCvt0BcK!>BN1T5v9&!GI4gE*6pAIQ}$s@;ptoDR`dfEAxo&TxTYwY%vIRE1O$8G38 zkqmB+$*~{jaUkAwh=U=VRF(>qmPygra_jn55ia_mQr{m8K&HS?Yg z3&E*vasG2=3iDxebEsW*{;hZ-FL~t5zZFlUPybKF9_5!a{{`hJ$9}AMCj}2!#@rYY=U-2xh2L=`&c9VNasGo1{SRet zCKf)*FK7O(_C)&ha_q<6A(5T`kdyB^{BByDe{ufB`4{J3oPWEnit`^l!0_>6-_7%I zv54aQTQw8sUz~sItHxaNn8$PPD)uP9IR93l;{1#ApGub5x%P%N>cw;B9=$ouBgcNM zc)q;a70*ck8Ftit}%cD^iZ){9Eye z^Y3iN$=iO)_1x>8=PxELXa2R^Ay12Y%&&UwPoyF2Lap zeRGCM-u7d~6M2S79{9E53A=B`4VIn%g5nY9KUzHE{EPFyCTVu{lhg5K-ci!7V_!^K zoPTlt#rYTKUz~rt0E_bN;-wUIdg;{1#AFV4T(nqFh) z2=fwF^Aewh0OP@!KTTMhG>{m?lQg2d?Z?V7@;P2{{;hbz-mN(Q+L75GEgo_H#rc;9 ze$_feOS?yUib>0{AH8PD z+kTu4D|3|~ullsJcjQ%qeB{fDC-N#m-t%w86Zwp+eB`U3c;q8rRy>iOqkQD6pm^jX zUsgPk?*x^PeAy!;F&_kwk9^5TzT_ic)<_DU54s_HAgeIqg z@8ZbLzwG?W1HWp`k~9C>6!u4Zw`T*4(`DlPM~g?Ce{ufB`4{J3oc}myzErq4|8Y)! z9Ncy6i%E;~FV4R>|Kj}1+kT>bdUMGm@Ampt;o zZ$a_M1HbaXZ&?z)*T;{mbe^|#o%vGJu47+JTAY7z{>Awh=U<$EyHbnuFYo!ck2)28 zMWs0Z)@H={53UI1*iWg)d*blr*pE2>sib**zr5$)&b9KY&s0(#_|;dfg-_`JxH5Pi zx-gKI1?s^I@^pB8- zIRDzui+O#&yystwr|>7aD`L+Ur;>a z{EPD+;p~>W+wbBRbJWMhkz+q{>_?9M$gv-B{_RQ~d2J-lzZH)-|Kj`?cVk4He`_<5 z*GA&}i}NqezwG>*`yG*|d7c_S+J}2(=U;aIas3wQw92s`y8uUu=k3{-au+@oCCAyX-mN(Q^1yF# z-mRSZw>A^G2QJ5c3W`UL{m8K&IrbyRe&pECIJ?}Qgb5Shk$r1f@D%uFJB5CEwfjC? zdE1Y^YAt+RMUMSg?TPg1<=BrEPvnOF$J1+*DXnI2D~Ko``Lg1Pbc5w1Uj@bUp^3pO z$qK(e=+R;k-&|EB#g7(?_>*E0<=BtAdw(El+4*;O^@~ZnyZXhXW#?aZ{$=N1cK&7O z-})z!R|#_L$BHNNDnXooD;{zFgHutm^IuRYWanRY{$=N1cK&7OUv~a^zvGT{uwfPR z-qN$No&fP9*>`Qr&cE|{L?fQxWVh)Gi$`|;t$z~f)634k6;Gs3FUNigibtIPg5nY9 zUz~q&{>Awh=U<$EasItjvaqZE`C@%~asI8_5$V%kUhHWeasI6w#rY35^yMR81(iaM z{T#?qAGfX?`zhwAkBd{xQ6Cpaj{V57A363T$A0A4k6qH`*pEE$Yo9-{L9Y2?EK5lzwG=+?$h5@QRGv%KPVPacK)qb78dxe0OL&E z`^E={@5K3c&eR$4$j-mjp2$lc+4*;O?++v`JOA#kelclxSHGCF?EK5lzwG?W&cE#Z z+a+Cg{$=N1cK+3#WTba1&cB^0BE=)l|A9FCZe4Nyi*fh^oE0qzFX^pIcwRE$rN+Xo zg;#@6cVcJ9aPQD?XU|YyPv212?#?X(z4b$V=k(Srt7&U*>gygF?CtOE9vK=O=<6Qt ztnVFu!^q&C&bqxjdpB(F1jg!BOlLN1∨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

K&=K^w;z^TXIu1Dj4ftMMh)hVMIR2wF;u+`XZ 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%0AR?&0DwFJ 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 literal 0 HcmV?d00001 diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/Makefile b/tutorials/stm32/nucleo_n657x0_q/minimal/Makefile new file mode 100644 index 00000000..bd3c9a4c --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/Makefile @@ -0,0 +1,61 @@ +# Copyright (c) 2026 Cesanta Software Limited +# Environment setup: https://mongoose.ws/docs/getting-started/build-environment/ + +CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion +CFLAGS += -Wformat-truncation -fno-common -Wconversion -Wno-sign-conversion +CFLAGS += -g3 -Os -ffunction-sections -fdata-sections +CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_n6/Include +CFLAGS += -mcpu=cortex-m55 -mthumb -mfloat-abi=soft -mfpu=fpv5-d16 -mcmse +CFLAGS += $(CFLAGS_EXTRA) +LDFLAGS ?= -nostdlib -nostartfiles --specs nosys.specs -lc -lgcc -Wl,--gc-sections + +SOURCES = cmsis_n6/Source/Templates/gcc/startup_stm32n657xx.s +SOURCES += main.c hal.c + +FSBL_SOURCES = cmsis_n6/Source/Templates/gcc/startup_stm32n657xx_fsbl.s +FSBL_SOURCES += fsbl.c + +TOP = ../../../.. +CFLAGS += -I$(TOP) +SOURCES += $(TOP)/mongoose.c + +all: fsbl.signed.bin firmware.bin + +firmware.elf: cmsis_core cmsis_n6 hal.h link.ld Makefile $(SOURCES) + arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -Tlink.ld -o $@ + +fsbl.elf: cmsis_core cmsis_n6 hal.h fsbl.ld Makefile $(FSBL_SOURCES) + arm-none-eabi-gcc $(FSBL_SOURCES) $(CFLAGS) $(LDFLAGS) -Tfsbl.ld -o $@ + +%.bin: %.elf + arm-none-eabi-objcopy -O binary $< $@ + @echo + @echo "To flash:" + @echo " 1. set the BOOT1 jumper to position 1, click reset button" + @echo " 2. run 'make flash'" + @echo " 3. set the BOOT1 jumper to position 0, click reset button" + @echo " NOTE: STM32_Programmer_CLI and STM32_SigningTool_CLI should be in your PATH" + +fsbl.signed.bin: fsbl.bin + STM32_SigningTool_CLI -s -nk -of 0x80000000 -t fsbl -hv 2.3 -align -bin $^ -o $@ + +flash: fsbl.signed.bin firmware.bin + STM32_Programmer_CLI -c port=swd mode=HOTPLUG -el MX25UM51245G_STM32N6570-NUCLEO.stldr -d firmware.bin 0x70100000 -hardRst + STM32_Programmer_CLI -c port=swd mode=HOTPLUG -el MX25UM51245G_STM32N6570-NUCLEO.stldr -d fsbl.signed.bin 0x70000000 -hardRst + +gdb: fsbl.elf + arm-none-eabi-gdb -q -ex='set confirm off' -ex 'target remote :61234' -ex 'load' $^ + +# Directory where STM32_Programmer_CLI binary lives +CUBEPROG_DIR ?= $(dir $(shell which STM32_Programmer_CLI)) +gdb_server: + ST-LINK_gdbserver --port-number 61234 --log-level 1 --swd --verify --stm32cubeprogrammer-path $(CUBEPROG_DIR) --apid 1 --initialize-reset + +cmsis_core: + git clone -q -c advice.detachedHead=false --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@ + +cmsis_n6: + git clone -q -c advice.detachedHead=false --depth 1 -b v1.3.0 https://github.com/STMicroelectronics/cmsis-device-n6 $@ + +clean: + rm -rf *.bin *.map *.elf diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.c b/tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.c new file mode 100644 index 00000000..0214527a --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.c @@ -0,0 +1,132 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved +#include "hal.h" + +#define APP_BASE 0x70100000U // Should match link.ld + +uint32_t SystemCoreClock; +void SystemInit(void) { + hal_system_init(); + if (!hal_clock_init(HAL_SYS_FREQUENCY)) { + for (;;) (void) 0; + } +} + +static void xip_init(void) { + enum { + XSPI_AF = 9U, + XSPI_FLASH_SIZE_BITS = 26U, // 64 MiB MX25UM51245G + XSPI_KERNEL_DIV = HAL_XSPI_IC3_DIV, // PLL1 / div, capped at 50 MHz + XSPI_CSHT_CYCLES = 3U, + XSPI_REQ2ACK_CYCLES = 1U, + XSPI_READ_OPCODE = 0x0CU, // JEDEC 4-byte fast read + XSPI_READ_DUMMY_CYCLES = 8U, + }; + static const uint16_t xspi_pins[] = { + PIN('N', 4), PIN('N', 6), PIN('N', 8), PIN('N', 0), + PIN('N', 3), PIN('N', 5), PIN('N', 1), PIN('N', 9), + PIN('N', 2), PIN('N', 10), PIN('N', 11), + }; + const uint32_t clear_flags = + XSPI_FCR_CTCF | XSPI_FCR_CTEF | XSPI_FCR_CSMF | XSPI_FCR_CTOF; + + // Explicitly enable every clock this XIP path depends on. + RCC->AHB4ENSR = RCC_AHB4ENSR_PWRENS | RCC_AHB4ENSR_GPIONENS; + RCC->APB4ENSR2 = RCC_APB4ENSR2_SYSCFGENS; + (void) RCC->AHB4ENR; + (void) RCC->APB4ENR2; + + RCC->AHB5RSTSR = RCC_AHB5RSTSR_XSPIMRSTS | RCC_AHB5RSTSR_XSPI2RSTS; + RCC->AHB5RSTCR = RCC_AHB5RSTCR_XSPIMRSTC | RCC_AHB5RSTCR_XSPI2RSTC; + RCC->AHB4RSTSR = RCC_AHB4RSTSR_GPIONRSTS; + RCC->AHB4RSTCR = RCC_AHB4RSTCR_GPIONRSTC; + + PWR->SVMCR1 |= PWR_SVMCR1_VDDIO4SV; + PWR->SVMCR2 |= PWR_SVMCR2_VDDIO5SV; + PWR->SVMCR3 |= PWR_SVMCR3_VDDIO2SV | PWR_SVMCR3_VDDIO3SV; + + SYSCFG->VDDIO2CCCR = SYSCFG_VDDIO2CCCR_CS | SYSCFG_VDDIO2CCCR_RAPSRC_3 | + SYSCFG_VDDIO2CCCR_RANSRC_0 | SYSCFG_VDDIO2CCCR_RANSRC_1 | + SYSCFG_VDDIO2CCCR_RANSRC_2; + SYSCFG->VDDIO3CCCR = SYSCFG_VDDIO3CCCR_CS | SYSCFG_VDDIO3CCCR_RAPSRC_3 | + SYSCFG_VDDIO3CCCR_RANSRC_0 | SYSCFG_VDDIO3CCCR_RANSRC_1 | + SYSCFG_VDDIO3CCCR_RANSRC_2; + SYSCFG->VDDIO4CCCR = SYSCFG_VDDIO4CCCR_CS | SYSCFG_VDDIO4CCCR_RAPSRC_3 | + SYSCFG_VDDIO4CCCR_RANSRC_0 | SYSCFG_VDDIO4CCCR_RANSRC_1 | + SYSCFG_VDDIO4CCCR_RANSRC_2; + SYSCFG->VDDIO5CCCR = SYSCFG_VDDIO5CCCR_CS | SYSCFG_VDDIO5CCCR_RAPSRC_3 | + SYSCFG_VDDIO5CCCR_RANSRC_0 | SYSCFG_VDDIO5CCCR_RANSRC_1 | + SYSCFG_VDDIO5CCCR_RANSRC_2; + SYSCFG->VDDCCCR = SYSCFG_VDDCCCR_CS | SYSCFG_VDDCCCR_RAPSRC_3 | + SYSCFG_VDDCCCR_RANSRC_0 | SYSCFG_VDDCCCR_RANSRC_1 | + SYSCFG_VDDCCCR_RANSRC_2; + + // Mirror the Cube FSBL topology: XSPI2 kernel clock is IC3 fed from PLL1. + CLRSET(RCC->IC3CFGR, RCC_IC3CFGR_IC3SEL | RCC_IC3CFGR_IC3INT, + (((uint32_t) (XSPI_KERNEL_DIV - 1U) << RCC_IC3CFGR_IC3INT_Pos) & + RCC_IC3CFGR_IC3INT)); + RCC->DIVENSR = RCC_DIVENSR_IC3ENS; + CLRSET(RCC->CCIPR6, RCC_CCIPR6_XSPI2SEL, RCC_CCIPR6_XSPI2SEL_1); + + RCC->AHB5ENSR = RCC_AHB5ENSR_XSPIMENS | RCC_AHB5ENSR_XSPI2ENS; + (void) RCC->AHB5ENR; + + for (size_t i = 0; i < sizeof(xspi_pins) / sizeof(xspi_pins[0]); i++) { + hal_gpio_init(xspi_pins[i], HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_VERY_HIGH, HAL_GPIO_PULL_NONE, XSPI_AF); + } + + // Keep XIP bring-up small and predictable: fixed 1-1-1 JEDEC 4-byte read. + XSPI2->CR = (uint32_t) ((4U - 1U) << XSPI_CR_FTHRES_Pos); + XSPI2->DCR1 = ((uint32_t) XSPI_CSHT_CYCLES << XSPI_DCR1_CSHT_Pos) | + XSPI_DCR1_MTYP_0 | + ((uint32_t) XSPI_FLASH_SIZE_BITS << XSPI_DCR1_DEVSIZE_Pos); + XSPI2->DCR2 = 0U; + XSPI2->DCR3 = 0U; + XSPI2->DCR4 = 0U; + XSPIM->CR = XSPIM_CR_CSSEL_OVR_EN | + ((uint32_t) XSPI_REQ2ACK_CYCLES << XSPIM_CR_REQ2ACK_TIME_Pos); + XSPI2->CR |= XSPI_CR_EN; + XSPI2->TCR = XSPI_READ_DUMMY_CYCLES | XSPI_TCR_SSHIFT; + XSPI2->DLR = 0U; + XSPI2->CCR = + XSPI_CCR_IMODE_0 | XSPI_CCR_ADMODE_0 | XSPI_CCR_ADSIZE | XSPI_CCR_DMODE_0; + XSPI2->IR = XSPI_READ_OPCODE; + XSPI2->AR = 0U; + XSPI2->FCR = clear_flags; + + // In reset topology XSPI2 is wired to XSPIM port 2 already. + CLRSET(XSPI2->CR, XSPI_CR_FMODE, XSPI_CR_FMODE); +} + +static void jump_to_app(void) { + // Lit blue pin + hal_gpio_output(PIN('G', 8)); + hal_gpio_write(PIN('G', 8), false); + + // Read stack and app entry point from the app vector table + uint32_t sp = *(volatile uint32_t *) (APP_BASE + 0U); + uint32_t pc = *(volatile uint32_t *) (APP_BASE + 4U); + + // Switch to the app's vector table only after the first XIP reads succeed. + SCB->VTOR = APP_BASE; + __DSB(); + __ISB(); + + // Lit green pin + hal_gpio_output(PIN('G', 0)); + hal_gpio_write(PIN('G', 0), false); + + __set_MSP(sp); + ((void (*)(void)) pc)(); // Jump to the application entry point + for (;;) (void) 0; // Hang +} + +int main(void) { + xip_init(); + jump_to_app(); + return 0; +} + +void _init(void) { +} diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.ld b/tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.ld new file mode 100644 index 00000000..71e71505 --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/fsbl.ld @@ -0,0 +1,20 @@ +ENTRY(Reset_Handler); +MEMORY { + ROM (xrw) : ORIGIN = 0x34180400, LENGTH = 255K + RAM (xrw) : ORIGIN = 0x341C0000, LENGTH = 256K +} +_estack = ORIGIN(RAM) + LENGTH(RAM); +_sstack = _estack - 4096; + +SECTIONS { + .vectors : { KEEP(*(.isr_vector)) } > ROM + .text : { *(.text* .text.*) } > ROM + .rodata : { *(.rodata*) } > ROM + + .data : { _sdata = .; *(.first_data) *(.data SORT(.data.*)) _edata = .; } > RAM AT > ROM + _sidata = LOADADDR(.data); + + .bss : { _sbss = .; *(.bss SORT(.bss.*) COMMON) _ebss = .; } > RAM + . = ALIGN(8); + _end = .; +} diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/hal.c b/tutorials/stm32/nucleo_n657x0_q/minimal/hal.c new file mode 100644 index 00000000..bd09d907 --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/hal.c @@ -0,0 +1,124 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "hal.h" + +bool hal_timer_expired(volatile uint64_t *t, uint64_t period, uint64_t now) { + uint64_t diff = now - *t; // Wrap-safe elapsed time since last expiry + if (period == 0) return false; // Avoid division by zero + if (diff < period) return false; // Period has not elapsed yet + *t += (diff / period) * period; // Preserve cadence, skip missed periods + return true; +} + +static volatile uint64_t s_ticks; // Milliseconds since boot +void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms + s_ticks++; +} + +uint64_t hal_get_tick(void) { + return s_ticks; +}; + +uint32_t SystemCoreClock = HAL_SYS_FREQUENCY; +void SystemInit(void) { + SystemCoreClock = HAL_SYS_FREQUENCY; // FSBL intitialised the clock for us + SysTick_Config(SystemCoreClock / 1000U); +} + +void ExitRun0Mode(void) { +} + +struct stat; +__attribute__((weak)) int _fstat(int fd, struct stat *st) { + (void) fd, (void) st; + return -1; +} + +extern unsigned char _end[]; // End of data section, start of heap. See link.ld +static unsigned char *s_current_heap_end = _end; + +size_t hal_ram_used(void) { + return (size_t) (s_current_heap_end - _end); +} + +size_t hal_ram_free(void) { + unsigned char endofstack; + return (size_t) (&endofstack - s_current_heap_end); +} + +void *_sbrk(int incr) { + unsigned char *prev_heap; + unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256); + prev_heap = s_current_heap_end; + // Check how much space we got from the heap end to the stack end + if (s_current_heap_end + incr > heap_end) return (void *) -1; + s_current_heap_end += incr; + return prev_heap; +} + +__attribute__((weak)) int _open(const char *path) { + (void) path; + return -1; +} + +__attribute__((weak)) int _close(int fd) { + (void) fd; + return -1; +} + +__attribute__((weak)) int _isatty(int fd) { + (void) fd; + return 1; +} + +__attribute__((weak)) int _lseek(int fd, int ptr, int dir) { + (void) fd, (void) ptr, (void) dir; + return 0; +} + +__attribute__((weak)) void _exit(int status) { + (void) status; + for (;;) asm volatile("BKPT #0"); +} + +__attribute__((weak)) void _kill(int pid, int sig) { + (void) pid, (void) sig; +} + +__attribute__((weak)) int _getpid(void) { + return -1; +} + +__attribute__((weak)) int _write(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _read(int fd, char *ptr, int len) { + (void) fd, (void) ptr, (void) len; + return -1; +} + +__attribute__((weak)) int _link(const char *a, const char *b) { + (void) a, (void) b; + return -1; +} + +__attribute__((weak)) int _unlink(const char *a) { + (void) a; + return -1; +} + +__attribute__((weak)) int _stat(const char *path, struct stat *st) { + (void) path, (void) st; + return -1; +} + +__attribute__((weak)) int mkdir(const char *path, int mode) { + (void) path, (void) mode; + return -1; +} + +__attribute__((weak)) void _init(void) { +} diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/hal.h b/tutorials/stm32/nucleo_n657x0_q/minimal/hal.h new file mode 100644 index 00000000..4fe25647 --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/hal.h @@ -0,0 +1,427 @@ +// Copyright (c) 2022-2026 Cesanta Software Limited + +#pragma once + +#include + +#include +#include +#include +#include + +extern bool hal_timer_expired(volatile uint64_t *t, uint64_t prd, uint64_t now); +extern uint64_t hal_get_tick(void); +extern size_t hal_ram_free(void); +extern size_t hal_ram_used(void); +extern uint32_t SystemCoreClock; + +#define BIT(x) (1UL << (x)) +#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set)) +#define PIN(bank, num) ((((bank) - 'A') << 8) | (num)) +#define PINNO(pin) (pin & 255) +#define PINBANK(pin) (pin >> 8) + +// UM3417 7.12 +#ifndef HAL_ETH_PINS +#define HAL_ETH_PINS \ + PIN('F', 4), PIN('F', 5), PIN('F', 7), PIN('F', 10), PIN('F', 11), \ + PIN('F', 12), PIN('F', 13), PIN('F', 14), PIN('F', 15), PIN('G', 11), +#endif + +#ifndef HAL_SYS_FREQUENCY +#define HAL_SYS_FREQUENCY (600U * 1000U * 1000U) +#endif + +#if ((HAL_SYS_FREQUENCY % (8U * 1000U * 1000U)) != 0U) +#error "HAL_SYS_FREQUENCY must be a multiple of 8 MHz" +#endif + +#if (HAL_SYS_FREQUENCY == 0U || HAL_SYS_FREQUENCY > (1600U * 1000U * 1000U)) +#error "HAL_SYS_FREQUENCY must be between 8 MHz and 1600 MHz" +#endif + +enum { + HAL_HSI_FREQUENCY = 64000000U, + HAL_PLL1_MAX_FREQUENCY = 1600000000U, + HAL_PLL1_M = 1U, + HAL_PLL1_P1 = 1U, + HAL_PLL1_P2 = 1U, + HAL_ETH_TARGET_FREQUENCY = 100000000U, + HAL_XSPI_TARGET_FREQUENCY = 50000000U, + HAL_HPRE = 4U, + HAL_PPRE1 = 1U, + HAL_PPRE2 = 1U, + HAL_PPRE4 = 1U, + HAL_PPRE5 = 1U, +}; + +#define HAL_SYSCLK_IC_DIV (HAL_PLL1_MAX_FREQUENCY / HAL_SYS_FREQUENCY) +#define HAL_PLL1_FREQUENCY (HAL_SYS_FREQUENCY * HAL_SYSCLK_IC_DIV) +#define HAL_PLL1_N (HAL_PLL1_FREQUENCY / HAL_HSI_FREQUENCY) +#define HAL_PLL1_N_FRAC \ + ((uint32_t) (((((uint64_t) HAL_PLL1_FREQUENCY) % HAL_HSI_FREQUENCY) << 24) / \ + HAL_HSI_FREQUENCY)) +#define HAL_AHB_FREQUENCY (HAL_SYS_FREQUENCY / HAL_HPRE) +#define HAL_APB1_FREQUENCY (HAL_AHB_FREQUENCY / HAL_PPRE1) +#define HAL_APB2_FREQUENCY (HAL_AHB_FREQUENCY / HAL_PPRE2) +#define HAL_ETH_IC12_DIV \ + ((HAL_PLL1_FREQUENCY + HAL_ETH_TARGET_FREQUENCY - 1U) / \ + HAL_ETH_TARGET_FREQUENCY) +#define HAL_ETH_KERNEL_FREQUENCY (HAL_PLL1_FREQUENCY / HAL_ETH_IC12_DIV) +#define HAL_XSPI_IC3_DIV \ + ((HAL_PLL1_FREQUENCY + HAL_XSPI_TARGET_FREQUENCY - 1U) / \ + HAL_XSPI_TARGET_FREQUENCY) +#define HAL_XSPI_KERNEL_FREQUENCY (HAL_PLL1_FREQUENCY / HAL_XSPI_IC3_DIV) + +enum { + HAL_GPIO_MODE_INPUT = 0U, + HAL_GPIO_MODE_OUTPUT = 1U, + HAL_GPIO_MODE_AF = 2U, + HAL_GPIO_MODE_ANALOG = 3U, +}; +enum { + HAL_GPIO_OTYPE_PUSH_PULL = 0U, + HAL_GPIO_OTYPE_OPEN_DRAIN = 1U, +}; +enum { + HAL_GPIO_SPEED_LOW = 0U, + HAL_GPIO_SPEED_MEDIUM = 1U, + HAL_GPIO_SPEED_HIGH = 2U, + HAL_GPIO_SPEED_VERY_HIGH = 3U, +}; +enum { + HAL_GPIO_PULL_NONE = 0U, + HAL_GPIO_PULL_UP = 1U, + HAL_GPIO_PULL_DOWN = 2U, +}; + +static inline GPIO_TypeDef *hal_gpio_bank(uint16_t pin) { + uint8_t bank = (uint8_t) PINBANK(pin); + return (GPIO_TypeDef *) (GPIOA_BASE + 0x400 * bank); // Using secure base +} + +static inline void hal_gpio_enable_clock(uint16_t pin) { + const uint32_t bank = (uint32_t) PINBANK(pin); + RCC->AHB4ENR |= BIT(bank); + (void) RCC->AHB4ENR; // Read back to ensure the write completes before access +} + +static inline void hal_gpio_set_secure_nonpriv(uint16_t pin) { + const uint32_t mask = BIT((uint32_t) PINNO(pin)); + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + gpio->SECCFGR |= mask; // Secure + gpio->PRIVCFGR &= ~mask; // Clear privileged-only protection +} + +static inline void hal_gpio_init(uint16_t pin, uint8_t mode, uint8_t otype, + uint8_t speed, uint8_t pull, uint8_t af) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + const uint32_t n = (uint32_t) PINNO(pin); + const uint32_t shift2 = n * 2U; + const uint32_t shift4 = (n & 7U) * 4U; + if (gpio == NULL || n > 15U) return; + hal_gpio_enable_clock(pin); + CLRSET(gpio->OTYPER, BIT(n), ((uint32_t) (otype & 0x1U)) << n); + CLRSET(gpio->OSPEEDR, 3UL << shift2, ((uint32_t) (speed & 0x3U)) << shift2); + CLRSET(gpio->PUPDR, 3UL << shift2, ((uint32_t) (pull & 0x3U)) << shift2); + if (mode == HAL_GPIO_MODE_AF) { + CLRSET(gpio->AFR[n >> 3], 0xFUL << shift4, + ((uint32_t) (af & 0xFU)) << shift4); + } + CLRSET(gpio->MODER, 3UL << shift2, ((uint32_t) (mode & 0x3U)) << shift2); +} + +static inline void hal_gpio_toggle(uint16_t pin) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + const uint32_t mask = BIT(PINNO(pin)); + if (gpio == NULL) return; + gpio->BSRR = mask << ((gpio->ODR & mask) ? 16U : 0U); +} + +static inline int hal_gpio_read(uint16_t pin) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + if (gpio == NULL) return 0; + return (gpio->IDR & BIT(PINNO(pin))) ? 1 : 0; +} + +static inline void hal_gpio_write(uint16_t pin, bool val) { + GPIO_TypeDef *gpio = hal_gpio_bank(pin); + if (gpio == NULL) return; + gpio->BSRR = BIT(PINNO(pin)) << (val ? 0U : 16U); +} + +static inline void hal_gpio_input(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_INPUT, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, HAL_GPIO_PULL_NONE, 0U); +} + +static inline void hal_gpio_output(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_OUTPUT, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, HAL_GPIO_PULL_NONE, 0U); +} + +static inline void hal_gpio_af(uint16_t pin, uint8_t af, uint8_t pull) { + hal_gpio_init(pin, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, pull, af); +} + +static inline void hal_gpio_analog(uint16_t pin) { + hal_gpio_init(pin, HAL_GPIO_MODE_ANALOG, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_LOW, HAL_GPIO_PULL_NONE, 0U); +} + +static inline bool hal_uart_init(USART_TypeDef *uart, uint16_t tx, uint16_t rx, + unsigned long baud) { + uint32_t freq = 0U; + // uint32_t ready = USART_ISR_TEACK | USART_ISR_REACK; + + if (baud == 0U) return false; + + if (uart == USART1) { + RCC->APB2ENSR = RCC_APB2ENSR_USART1ENS; + (void) RCC->APB2ENR; + CLRSET(RCC->CCIPR13, RCC_CCIPR13_USART1SEL, 0U); + RCC->APB2RSTSR = RCC_APB2RSTSR_USART1RSTS; + RCC->APB2RSTCR = RCC_APB2RSTCR_USART1RSTC; + freq = HAL_APB2_FREQUENCY; + } else if (uart == USART2) { + RCC->APB1ENSR1 = RCC_APB1ENSR1_USART2ENS; + (void) RCC->APB1ENR1; + CLRSET(RCC->CCIPR13, RCC_CCIPR13_USART2SEL, 0U); + RCC->APB1RSTSR1 = RCC_APB1RSTSR1_USART2RSTS; + RCC->APB1RSTCR1 = RCC_APB1RSTCR1_USART2RSTC; + freq = HAL_APB1_FREQUENCY; + } else if (uart == USART3) { + RCC->APB1ENSR1 = RCC_APB1ENSR1_USART3ENS; + (void) RCC->APB1ENR1; + CLRSET(RCC->CCIPR13, RCC_CCIPR13_USART3SEL, 0U); + RCC->APB1RSTSR1 = RCC_APB1RSTSR1_USART3RSTS; + RCC->APB1RSTCR1 = RCC_APB1RSTCR1_USART3RSTC; + freq = HAL_APB1_FREQUENCY; + } else { + return false; + } + + hal_gpio_init(tx, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, 0, 7u); + hal_gpio_init(rx, HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_HIGH, 0, 7u); + + uart->CR1 = uart->CR2 = uart->CR3 = uart->PRESC = 0; + uart->BRR = (uint32_t) ((freq + baud / 2U) / baud); + uart->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; + + return false; +} + +static inline bool hal_uart_write_byte(USART_TypeDef *uart, uint8_t byte) { + uart->TDR = byte; + for (volatile uint32_t n = 0; n < 999U; n++) { + if ((uart->ISR & USART_ISR_TXE_TXFNF) != 0U) return true; + } + return false; +} + +static inline void hal_uart_write_buf(USART_TypeDef *uart, char *buf, + size_t len) { + while (len-- > 0 && hal_uart_write_byte(uart, *(uint8_t *) buf++)) { + } +} + +static inline int hal_uart_read_ready(USART_TypeDef *uart) { + return (uart->ISR & USART_ISR_RXNE_RXFNE) ? 1 : 0; +} + +static inline uint8_t hal_uart_read_byte(USART_TypeDef *uart) { + return (uint8_t) (uart->RDR); +} + +static inline unsigned int hal_div2prescval(unsigned int div) { + // STM32N6 encodes AHB/APB prescalers as log2(divider): 0 -> /1, 1 -> /2 ... + unsigned int val = 0; + while (div > 1U) { + div >>= 1U; + val++; + } + return val; +} + +static inline bool hal_rng_init(void) { + RCC->AHB3ENR |= RCC_AHB3ENR_RNGEN; + RNG->CR &= ~RNG_CR_RNGEN; + CLRSET(RNG->CR, RNG_CR_CED | RNG_CR_CONDRST, RNG_CR_CONDRST); + RNG->CR &= ~RNG_CR_CONDRST; + while (RNG->CR & RNG_CR_CONDRST) (void) 0; + RNG->CR |= RNG_CR_RNGEN; + if (RNG->SR & RNG_SR_SEIS) return false; + while ((RNG->SR & RNG_SR_DRDY) == 0) (void) 0; + return true; +} + +static inline uint32_t hal_rng_read(void) { + while ((RNG->SR & RNG_SR_DRDY) == 0) (void) 0; + return RNG->DR; +} + +static inline void hal_eth_set_secure(uint32_t cid, uint32_t master_index, + uint32_t slave_index, bool priv) { + const uint32_t slave_reg = (slave_index >> 28) & 0xFU; + const uint32_t slave_mask = BIT(slave_index & 0x1FU); + + RIFSC->RIMC_ATTRx[master_index] = + ((cid & 0x7U) << RIFSC_RIMC_ATTRx_MCID_Pos) | RIFSC_RIMC_ATTRx_MSEC | + (priv ? RIFSC_RIMC_ATTRx_MPRIV : 0); + + RIFSC->RISC_SECCFGRx[slave_reg] |= slave_mask; + if (priv) { + RIFSC->RISC_PRIVCFGRx[slave_reg] |= slave_mask; + } else { + RIFSC->RISC_PRIVCFGRx[slave_reg] &= ~slave_mask; + } +} + +static inline void hal_ethernet_init(void) { + uint16_t pins[] = {HAL_ETH_PINS}; + + // Hold ETH1 in reset while clock path is configured + RCC->AHB5RSTSR = RCC_AHB5RSTSR_ETH1RSTS; + (void) RCC->AHB5RSTSR; + + // IC12 from the PLL1-based clock tree used by hal_clock_init() + CLRSET(RCC->IC12CFGR, RCC_IC12CFGR_IC12SEL | RCC_IC12CFGR_IC12INT, + RCC_IC12CFGR_IC12SEL_1 | ((((uint32_t) (HAL_ETH_IC12_DIV - 1U)) + << RCC_IC12CFGR_IC12INT_Pos) & + RCC_IC12CFGR_IC12INT)); + RCC->DIVENSR = RCC_DIVENSR_IC12ENS; + (void) RCC->DIVENR; + + // Keep ETH1SEL_2, ETH1CLKSEL_1. Clear ETH1REFCLKSEL ETH1GTXCLKSEL + CLRSET(RCC->CCIPR2, + RCC_CCIPR2_ETH1CLKSEL | RCC_CCIPR2_ETH1SEL | RCC_CCIPR2_ETH1REFCLKSEL | + RCC_CCIPR2_ETH1GTXCLKSEL, + RCC_CCIPR2_ETH1CLKSEL_1 | RCC_CCIPR2_ETH1SEL_2); + (void) RCC->CCIPR2; + + // Enable ETH1 clocks + RCC->AHB5ENSR = RCC_AHB5ENSR_ETH1MACENS | RCC_AHB5ENSR_ETH1TXENS | + RCC_AHB5ENSR_ETH1RXENS | RCC_AHB5ENSR_ETH1ENS; + (void) RCC->AHB5ENR; + + // Release reset + RCC->AHB5RSTCR = RCC_AHB5RSTCR_ETH1RSTC; + (void) RCC->AHB5RSTSR; + + // Set ETH1 in secure privileged mode + hal_eth_set_secure(1U, 6U, 0x1000001CU, true); + + // Configure pins in RMII AF + for (size_t i = 0; i < sizeof(pins) / sizeof(pins[0]); i++) { + hal_gpio_init(pins[i], HAL_GPIO_MODE_AF, HAL_GPIO_OTYPE_PUSH_PULL, + HAL_GPIO_SPEED_VERY_HIGH, HAL_GPIO_PULL_NONE, 11); + } + + NVIC_EnableIRQ(ETH1_IRQn); +} + +static inline bool hal_clock_init(uint32_t cpu_freq) { + uint32_t cpu_divider = 0U; + + // Keep the PLL high enough for the SYS/XSPI tree, then derive CPUCLK from + // IC1. HAL_SYS_FREQUENCY is restricted to 8 MHz steps so PLL1 DIVNFRAC stays + // exact. + if (cpu_freq == 0U || (cpu_freq % 8000000U) != 0U) return false; + if ((HAL_PLL1_FREQUENCY % cpu_freq) != 0U) return false; + cpu_divider = HAL_PLL1_FREQUENCY / cpu_freq; + if (cpu_divider == 0U || cpu_divider > 256U) return false; + + RCC->AHB4ENSR = RCC_AHB4ENSR_PWRENS; + (void) RCC->AHB4ENR; + + PWR->CR1 &= ~(PWR_CR1_SDEN | PWR_CR1_VDD18SMPSVMEN); + CLRSET(PWR->VOSCR, PWR_VOSCR_VOS, PWR_VOSCR_VOS); + for (volatile uint32_t n = 0; n < 1000000U; n++) { + const uint32_t voscr = PWR->VOSCR; + const uint32_t requested = (voscr & PWR_VOSCR_VOS) >> PWR_VOSCR_VOS_Pos; + const uint32_t applied = (voscr & PWR_VOSCR_ACTVOS) >> PWR_VOSCR_ACTVOS_Pos; + if ((voscr & PWR_VOSCR_VOSRDY) != 0U || requested == applied) break; + } + + CLRSET(RCC->HSICFGR, RCC_HSICFGR_HSIDIV, 0U); + RCC->CR |= RCC_CR_HSION; + while ((RCC->SR & RCC_SR_HSIRDY) == 0U) (void) 0; + + if ((RCC->CFGR1 & RCC_CFGR1_CPUSWS) == RCC_CFGR1_CPUSWS || + (RCC->CFGR1 & RCC_CFGR1_SYSSWS) == RCC_CFGR1_SYSSWS) { + CLRSET(RCC->CFGR1, RCC_CFGR1_CPUSW | RCC_CFGR1_SYSSW, 0U); + while ((RCC->CFGR1 & RCC_CFGR1_CPUSWS) != 0U) (void) 0; + while ((RCC->CFGR1 & RCC_CFGR1_SYSSWS) != 0U) (void) 0; + } + + RCC->CR &= ~RCC_CR_PLL1ON; + while ((RCC->SR & RCC_SR_PLL1RDY) != 0U) (void) 0; + CLRSET( + RCC->PLL1CFGR1, + RCC_PLL1CFGR1_PLL1SEL | RCC_PLL1CFGR1_PLL1DIVM | RCC_PLL1CFGR1_PLL1DIVN, + (((uint32_t) HAL_PLL1_M << RCC_PLL1CFGR1_PLL1DIVM_Pos) & + RCC_PLL1CFGR1_PLL1DIVM) | + (((uint32_t) HAL_PLL1_N << RCC_PLL1CFGR1_PLL1DIVN_Pos) & + RCC_PLL1CFGR1_PLL1DIVN)); + RCC->PLL1CFGR3 |= RCC_PLL1CFGR3_PLL1MODSSDIS; + RCC->PLL1CFGR3 &= ~(RCC_PLL1CFGR3_PLL1MODDSEN | RCC_PLL1CFGR3_PLL1DACEN); + CLRSET(RCC->PLL1CFGR2, RCC_PLL1CFGR2_PLL1DIVNFRAC, + ((uint32_t) HAL_PLL1_N_FRAC << RCC_PLL1CFGR2_PLL1DIVNFRAC_Pos) & + RCC_PLL1CFGR2_PLL1DIVNFRAC); + CLRSET(RCC->PLL1CFGR3, + RCC_PLL1CFGR3_PLL1MODSSRST | RCC_PLL1CFGR3_PLL1DACEN | + RCC_PLL1CFGR3_PLL1MODDSEN | RCC_PLL1CFGR3_PLL1PDIV1 | + RCC_PLL1CFGR3_PLL1PDIV2 | RCC_PLL1CFGR3_PLL1PDIVEN, + (((uint32_t) HAL_PLL1_P1 << RCC_PLL1CFGR3_PLL1PDIV1_Pos) & + RCC_PLL1CFGR3_PLL1PDIV1) | + (((uint32_t) HAL_PLL1_P2 << RCC_PLL1CFGR3_PLL1PDIV2_Pos) & + RCC_PLL1CFGR3_PLL1PDIV2) | + RCC_PLL1CFGR3_PLL1MODSSRST | RCC_PLL1CFGR3_PLL1PDIVEN | + (HAL_PLL1_N_FRAC != 0U + ? RCC_PLL1CFGR3_PLL1MODDSEN | RCC_PLL1CFGR3_PLL1DACEN + : 0U)); + RCC->CR |= RCC_CR_PLL1ON; + while ((RCC->SR & RCC_SR_PLL1RDY) == 0U) (void) 0; + + CLRSET(RCC->CFGR2, + RCC_CFGR2_HPRE | RCC_CFGR2_PPRE1 | RCC_CFGR2_PPRE2 | RCC_CFGR2_PPRE4 | + RCC_CFGR2_PPRE5, + ((uint32_t) hal_div2prescval(HAL_HPRE) << RCC_CFGR2_HPRE_Pos) | + ((uint32_t) hal_div2prescval(HAL_PPRE1) << RCC_CFGR2_PPRE1_Pos) | + ((uint32_t) hal_div2prescval(HAL_PPRE2) << RCC_CFGR2_PPRE2_Pos) | + ((uint32_t) hal_div2prescval(HAL_PPRE4) << RCC_CFGR2_PPRE4_Pos) | + ((uint32_t) hal_div2prescval(HAL_PPRE5) << RCC_CFGR2_PPRE5_Pos)); + CLRSET(RCC->IC2CFGR, RCC_IC2CFGR_IC2SEL | RCC_IC2CFGR_IC2INT, + (((uint32_t) (HAL_SYSCLK_IC_DIV - 1U) << RCC_IC2CFGR_IC2INT_Pos) & + RCC_IC2CFGR_IC2INT)); + CLRSET(RCC->IC1CFGR, RCC_IC1CFGR_IC1SEL | RCC_IC1CFGR_IC1INT, + (((uint32_t) (cpu_divider - 1U) << RCC_IC1CFGR_IC1INT_Pos) & + RCC_IC1CFGR_IC1INT)); + CLRSET(RCC->IC6CFGR, RCC_IC6CFGR_IC6SEL | RCC_IC6CFGR_IC6INT, + (((uint32_t) (HAL_SYSCLK_IC_DIV - 1U) << RCC_IC6CFGR_IC6INT_Pos) & + RCC_IC6CFGR_IC6INT)); + CLRSET(RCC->IC11CFGR, RCC_IC11CFGR_IC11SEL | RCC_IC11CFGR_IC11INT, + (((uint32_t) (HAL_SYSCLK_IC_DIV - 1U) << RCC_IC11CFGR_IC11INT_Pos) & + RCC_IC11CFGR_IC11INT)); + RCC->DIVENSR = RCC_DIVENSR_IC1ENS | RCC_DIVENSR_IC2ENS | RCC_DIVENSR_IC6ENS | + RCC_DIVENSR_IC11ENS; + + // Keep the system buses on the Cube-compatible IC2/IC6/IC11 path so XIP + // timings stay unchanged, and drive only CPUCLK from IC1. + CLRSET(RCC->CFGR1, RCC_CFGR1_CPUSW | RCC_CFGR1_SYSSW, + RCC_CFGR1_CPUSW | RCC_CFGR1_SYSSW); + while ((RCC->CFGR1 & RCC_CFGR1_CPUSWS) != RCC_CFGR1_CPUSWS) (void) 0; + while ((RCC->CFGR1 & RCC_CFGR1_SYSSWS) != RCC_CFGR1_SYSSWS) (void) 0; + + SystemCoreClock = cpu_freq; + return true; +} + +static inline void hal_system_init(void) { + SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU + __DSB(); + __ISB(); +} diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/link.ld b/tutorials/stm32/nucleo_n657x0_q/minimal/link.ld new file mode 100644 index 00000000..b8976094 --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/link.ld @@ -0,0 +1,21 @@ +ENTRY(Reset_Handler); +MEMORY { + flash (rx) : ORIGIN = 0x70100000, LENGTH = 64M - 1M + sram (rwx) : ORIGIN = 0x34000000, LENGTH = 2048K +} +_estack = ORIGIN(sram) + LENGTH(sram); +_sstack = _estack - 4096; + +SECTIONS { + .vectors : { KEEP(*(.isr_vector)) } > flash + .text : { *(.text* .text.*) } > flash + .rodata : { *(.rodata*) } > flash + + /* Note the .iram section, for functions copied to RAM */ + .data : { _sdata = .; *(.first_data) *(.iram .iram* .iram.*) *(.data SORT(.data.*)) _edata = .; } > sram AT > flash + _sidata = LOADADDR(.data); + + .bss : { _sbss = .; *(.bss SORT(.bss.*) COMMON) _ebss = .; } > sram + . = ALIGN(8); + _end = .; +} diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/main.c b/tutorials/stm32/nucleo_n657x0_q/minimal/main.c new file mode 100644 index 00000000..7ec52c91 --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/main.c @@ -0,0 +1,78 @@ +// Copyright (c) 2026 Cesanta Software Limited +// All rights reserved + +#include "hal.h" +#include "mongoose.h" + +#define DEBUG_UART USART1 +#define UART_TX PIN('E', 5) +#define UART_RX PIN('E', 6) + +#define LED_1 PIN('G', 0) // Green LED +#define LED_2 PIN('G', 8) // Blue LED +#define LED_3 PIN('G', 10) // Red LED + +// Redirect stdout debug output to UART +int _write(int fd, char *ptr, int len) { + if (fd == 1) hal_uart_write_buf(DEBUG_UART, ptr, (size_t) len); + return len; +} + +// Blink green LED every 500ms +static void blink_task(void) { + static uint64_t blink_timer = 0; + if (hal_timer_expired(&blink_timer, 500, hal_get_tick())) { + hal_gpio_toggle(LED_1); + } +} + +uint64_t mg_millis(void) { + return hal_get_tick(); +} + +bool mg_random(void *buf, size_t len) { + for (size_t n = 0; n < len; n += sizeof(uint32_t)) { + uint32_t r = hal_rng_read(); + memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r)); + } + return true; +} + +static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) { + if (ev == MG_EV_HTTP_MSG) { // New HTTP request received + struct mg_http_message *hm = (struct mg_http_message *) ev_data; + if (mg_match(hm->uri, mg_str("/api/tick"), NULL)) { + mg_http_reply(c, 200, "", "{%m:%llu}\n", MG_ESC("tick"), hal_get_tick()); + } else { + mg_http_reply(c, 200, "", "Hi from Mongoose, tick %llu\n", + hal_get_tick()); + } + } +} + +int main(void) { + hal_uart_init(DEBUG_UART, UART_TX, UART_RX, 115200); + hal_rng_init(); + + // Initialise pins and turn them off: they are active high + hal_gpio_output(LED_1), hal_gpio_write(LED_1, true); + hal_gpio_output(LED_2), hal_gpio_write(LED_2, true); + hal_gpio_output(LED_3), hal_gpio_write(LED_3, true); + + printf("Initialised. CPU clock: %lu MHz\r\n", SystemCoreClock / 1000000); + printf("APB1: %u, APB2: %u\r\n", HAL_APB1_FREQUENCY, HAL_APB2_FREQUENCY); + + hal_ethernet_init(); + + // Start a minimal web server + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL); + + for (;;) { + mg_mgr_poll(&mgr, 0); + blink_task(); + } + + return 0; +} diff --git a/tutorials/stm32/nucleo_n657x0_q/minimal/mongoose_config.h b/tutorials/stm32/nucleo_n657x0_q/minimal/mongoose_config.h new file mode 100644 index 00000000..a65f3cdd --- /dev/null +++ b/tutorials/stm32/nucleo_n657x0_q/minimal/mongoose_config.h @@ -0,0 +1,34 @@ +#pragma once + +// See https://mongoose.ws/docs/getting-started/build-options/ +#define MG_ARCH MG_ARCH_ARMGCC +#define MG_TLS MG_TLS_BUILTIN +// #define MG_OTA MG_OTA_STM32H7 + +#define MG_ENABLE_TCPIP 1 +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define MG_ENABLE_CUSTOM_RANDOM 1 +#define MG_ENABLE_DRIVER_STM32N 1 +#define MG_ENABLE_PACKED_FS 1 + +// #define MG_DRIVER_MDC_CR 4 // RMII MDC clock divider, from 0 to 5 +// #define MG_TCPIP_PHY_ADDR 0 // PHY address + +// For static IP configuration, define MG_TCPIP_{IP,MASK,GW} +// By default, those are set to zero, meaning that DHCP is used +// +// #define MG_TCPIP_IP MG_IPV4(192, 168, 0, 10) // IP +// #define MG_TCPIP_GW MG_IPV4(192, 168, 0, 1) // Gateway +// #define MG_TCPIP_MASK MG_IPV4(255, 255, 255, 0) // Netmask + +// Construct MAC address from the MCU unique ID +#define MGUID ((uint32_t *) 0x56009014UL) // Unique 96-bit chip ID +#define MG_SET_MAC_ADDRESS(mac) \ + do { \ + mac[0] = 2; \ + mac[1] = MGUID[0] & 255; \ + mac[2] = (MGUID[0] >> 10) & 255; \ + mac[3] = (MGUID[0] >> 19) & 255; \ + mac[4] = MGUID[1] & 255; \ + mac[5] = MGUID[2] & 255; \ + } while (0)