Add nucleo-c5a3zg

This commit is contained in:
cpq committed 2026-10-21 10:16:02 +01:00
1 parent 38c326644f
commit c775f31ca7
17 files changed
+4448 -146

No files matched your search

+5 -64
View File
@@ -32,6 +32,7 @@
#if MG_ENABLE_TCPIP && !defined(MG_ENABLE_DRIVER_STM32F) && \
!defined(MG_ENABLE_DRIVER_STM32H) && !defined(MG_ENABLE_DRIVER_STM32N) && \
!defined(MG_ENABLE_DRIVER_STM32C) && \
!defined(MG_ENABLE_DRIVER_CYW) && !defined(MG_ENABLE_DRIVER_CYW_SDIO) && \
!defined(MG_ENABLE_DRIVER_ST67W6)
#if defined(STM32F1) || defined(STM32F2) || defined(STM32F4) || defined(STM32F7)
@@ -40,6 +41,8 @@
#define MG_ENABLE_DRIVER_STM32H 1
#elif defined(STM32N6)
#define MG_ENABLE_DRIVER_STM32N 1
#elif defined(STM32C5)
#define MG_ENABLE_DRIVER_STM32C 1
#else
#error Select a driver in mongoose_config.h
#endif
@@ -56,70 +59,8 @@
#define MG_OTA MG_OTA_STM32H5
#elif !defined(MG_OTA) && defined(STM32H7)
#define MG_OTA MG_OTA_STM32H7
#endif
// OTA rollback timer via IWDG. Fixed 10 s hang-detection window (prescaler
// /1024, LSI ~32 kHz: reload = 10 * 32000 / 1024 = 312). mg_ota_poll() feeds
// the watchdog every 500 ms while in MG_OTA_TESTING state; if the event loop
// hangs for 10 s, the IWDG fires and the device rolls back.
// STM32H7 names the peripheral IWDG1; all others use IWDG.
// The total evaluation period is set by MG_OTA_ROLLBACK_TIMEOUT_SECONDS.
// STM32H7 names the watchdog peripheral IWDG1; all other families use IWDG.
#if defined(IWDG1) && !defined(IWDG)
#define MG_IWDG IWDG1
#else
#define MG_IWDG IWDG
#endif
// PR=6 → /256 prescaler, RLR=1250 → ~10 s at LSI 32 kHz.
// Works on F4/F7/H5/H7; uses direct register writes so it is safe before HAL_Init().
#ifndef MG_OTA_ROLLBACK_TIMER_START
#define MG_OTA_ROLLBACK_TIMER_START() \
do { \
MG_IWDG->KR = 0xCCCCU; /* start + LSI */ \
MG_IWDG->KR = 0x5555U; /* unlock PR/RLR */ \
MG_IWDG->PR = 6U; /* /256 */ \
MG_IWDG->RLR = 1250U; /* 10 s */ \
while (MG_IWDG->SR & (IWDG_SR_PVU | IWDG_SR_RVU)) (void) 0; \
MG_IWDG->KR = 0xAAAAU; /* reload */ \
} while (0)
#endif
// Feed (reload) the IWDG. Called from mg_ota_poll() every 500 ms.
#ifndef MG_OTA_ROLLBACK_TIMER_FEED
#define MG_OTA_ROLLBACK_TIMER_FEED() (MG_IWDG->KR = 0xAAAAU)
#endif
// OTA state in a backup register that survives warm resets but clears on POR.
// STATE_GET reads work without any setup. STATE_SET enables the RTC APB clock
// and unlocks backup domain write access via direct register writes, so it is
// safe to call from any context (before or after HAL_Init).
// H5 (TAMP->BKP0R), H7 (RTC->BKP0R), F4/F7 (RTC->BKP0R).
#ifndef MG_OTA_STATE_GET
#if defined(PWR_DBPCR_DBP)
#define MG_OTA_DBP_ENABLE() (PWR->DBPCR |= PWR_DBPCR_DBP)
#elif defined(PWR_CR1_DBP)
#define MG_OTA_DBP_ENABLE() (PWR->CR1 |= PWR_CR1_DBP)
#else
#define MG_OTA_DBP_ENABLE() (PWR->CR |= PWR_CR_DBP)
#endif
#if defined(TAMP)
#define MG_OTA_STATE_GET() \
(RCC->APB3ENR |= RCC_APB3ENR_RTCAPBEN, TAMP->BKP0R)
#define MG_OTA_STATE_SET(v) \
(RCC->APB3ENR |= RCC_APB3ENR_RTCAPBEN, MG_OTA_DBP_ENABLE(), \
(TAMP->BKP0R = (uint32_t) (v)), TAMP->BKP0R)
#elif defined(RCC_APB4ENR_RTCAPBEN)
#define MG_OTA_STATE_GET() (RTC->BKP0R)
#define MG_OTA_STATE_SET(v) \
(RCC->APB4ENR |= RCC_APB4ENR_RTCAPBEN, MG_OTA_DBP_ENABLE(), \
(RTC->BKP0R = (uint32_t) (v)))
#else
#define MG_OTA_STATE_GET() (RTC->BKP0R)
#define MG_OTA_STATE_SET(v) \
(RCC->APB1ENR |= RCC_APB1ENR_PWREN, MG_OTA_DBP_ENABLE(), \
(RTC->BKP0R = (uint32_t) (v)))
#endif
#elif !defined(MG_OTA) && defined(STM32C5)
#define MG_OTA MG_OTA_STM32C5
#endif
// use HAL-defined execute-in-ram section
+6 -3
View File
@@ -2,6 +2,7 @@
#if MG_ENABLE_TCPIP && (MG_ENABLE_DRIVER_STM32H || MG_ENABLE_DRIVER_MCXN || \
MG_ENABLE_DRIVER_STM32N)
// STM32C: vendor modded single-queue Synopsys v5.4, same settings as STM32H
// STM32H: vendor modded single-queue Synopsys v4.2
// STM32N: dual-queue GbE Synopsys v5.2 with no hash table option, 64-bit AXI
// MCXNx4x: dual-queue Synopsys v5.2 with no hash table option
@@ -310,7 +311,7 @@ static uint32_t s_rxno;
#if MG_ENABLE_DRIVER_MCXN
void ETHERNET_IRQHandler(void);
void ETHERNET_IRQHandler(void) {
#elif MG_ENABLE_DRIVER_STM32H
#elif MG_ENABLE_DRIVER_STM32H && !MG_ENABLE_DRIVER_STM32C
void ETH_IRQHandler(void);
void ETH_IRQHandler(void) {
#else
@@ -339,8 +340,10 @@ void ETH1_IRQHandler(void) {
}
ETH->DMACSR =
MG_BIT(7) | MG_BIT(8); // Clear possible RBU RPS while processing
ETH->DMACRDTPR =
(uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT - 1]; // and resume RX
// Resume RX: tail is the last descriptor given back to DMA. It must differ
// from the DMA current descriptor, or some DMAs, e.g. STM32C5, stay suspended
ETH->DMACRDTPR = (uint32_t) (uintptr_t) &s_rxdesc[(s_rxno + ETH_DESC_CNT - 1) %
ETH_DESC_CNT];
}
struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
+11 -2
View File
@@ -4,6 +4,13 @@
#if !defined(MG_ENABLE_DRIVER_STM32H)
#define MG_ENABLE_DRIVER_STM32H 0
#endif
#if !defined(MG_ENABLE_DRIVER_STM32C)
#define MG_ENABLE_DRIVER_STM32C 0
#endif
#if MG_ENABLE_DRIVER_STM32C // STM32C5: STM32H5 MAC, the IRQ is ETH1
#undef MG_ENABLE_DRIVER_STM32H
#define MG_ENABLE_DRIVER_STM32H 1
#endif
#if !defined(MG_ENABLE_DRIVER_MCXN)
#define MG_ENABLE_DRIVER_MCXN 0
#endif
@@ -43,9 +50,11 @@ struct mg_tcpip_driver_stm32h_data {
#define MG_DRIVER_MDC_CR 4
#endif
#if MG_ENABLE_DRIVER_STM32H && MG_ARCH == MG_ARCH_CUBE && !defined(MG_ENABLE_ETH_IRQ)
#if MG_ENABLE_DRIVER_STM32H && !MG_ENABLE_DRIVER_STM32C && \
MG_ARCH == MG_ARCH_CUBE && !defined(MG_ENABLE_ETH_IRQ)
#define MG_ENABLE_ETH_IRQ() NVIC_EnableIRQ(ETH_IRQn)
#elif MG_ENABLE_DRIVER_STM32N && MG_ARCH == MG_ARCH_CUBE && !defined(MG_ENABLE_ETH_IRQ)
#elif (MG_ENABLE_DRIVER_STM32N || MG_ENABLE_DRIVER_STM32C) && \
MG_ARCH == MG_ARCH_CUBE && !defined(MG_ENABLE_ETH_IRQ)
#define MG_ENABLE_ETH_IRQ() NVIC_EnableIRQ(ETH1_IRQn)
#elif !defined(MG_ENABLE_ETH_IRQ)
#define MG_ENABLE_ETH_IRQ()
+1 -1
View File
@@ -6,7 +6,7 @@
struct mg_health mg_health_record MG_HEALTH_RAM;
// STM32 H723 support. Needs the _estack symbol from the linker script
#if MG_ENABLE_HEALTH && (defined(STM32H7_DEV_ID) || defined(STM32H5))
#if MG_ENABLE_HEALTH && (defined(STM32H7_DEV_ID) || defined(STM32H5) || defined(STM32C5))
// Fault handler body. Runs in exception context: no printf, no malloc, no
// blocking calls. Copies the unwind registers and raw stack into the health
// record, then resets.
+2 -2
View File
@@ -9,11 +9,11 @@
#define MG_HEALTH_MAGIC {'M', 'G', 'H', '3'} // '3' is the layout version
#endif
#if !defined(MG_HEALTH_RAM) && (defined(STM32H7_DEV_ID) || defined(STM32H5))
#if !defined(MG_HEALTH_RAM) && (defined(STM32H7_DEV_ID) || defined(STM32H5) || defined(STM32C5))
#define MG_HEALTH_RAM __attribute__((section(".mg_health")))
#endif
#if !defined(MG_HEALTH_DATA_SIZE) && (defined(STM32H7_DEV_ID) || defined(STM32H5))
#if !defined(MG_HEALTH_DATA_SIZE) && (defined(STM32H7_DEV_ID) || defined(STM32H5) || defined(STM32C5))
#define MG_HEALTH_DATA_SIZE 250
#endif
+1
View File
@@ -34,6 +34,7 @@
#define MG_OTA_STM32H7 2 // STM32 H7
#define MG_OTA_STM32H7_DUAL_CORE 3 // STM32 H7 dual core
#define MG_OTA_STM32F 4 // STM32 F7/F4/F2
#define MG_OTA_STM32C5 5 // STM32 C5, same flash controller as H5
#define MG_OTA_CH32V307 100 // WCH CH32V307
#define MG_OTA_U2A 200 // Renesas U2A16, U2A8, U2A6
#define MG_OTA_RT1020 300 // IMXRT1020
+1 -1
View File
@@ -2,7 +2,7 @@
#include "log.h"
#include "ota.h"
#if MG_OTA == MG_OTA_STM32H5
#if MG_OTA == MG_OTA_STM32H5 || MG_OTA == MG_OTA_STM32C5
static bool mg_stm32h5_write(void *, const void *, size_t);
static bool mg_stm32h5_swap(void);