mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-19 11:09:42 +00:00
Add tutorials
This commit is contained in:
1 parent
a6f08e0576
commit
592d0e2790
35 files changed
+4436
No files matched your search
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.*
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -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 <stm32f756xx.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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();
|
||||
}
|
||||
@@ -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 = .;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.*
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -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 <stm32h563xx.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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 = .;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.*
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -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 <stm32h723xx.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -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 = .;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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.
|
||||
@@ -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
|
||||
BIN
Binary file not shown.
@@ -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
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -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 = .;
|
||||
}
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
// Copyright (c) 2022-2026 Cesanta Software Limited
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stm32n657xx.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -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 = .;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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)
|
||||
Reference in new issue
Block a user