From ceda2d6ee029eda533025b278817286aa493dfc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Tue, 3 Feb 2026 19:40:57 +0100 Subject: [PATCH 01/19] Implemented new Ethernet module --- Inc/HALAL/HALAL.hpp | 49 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/Inc/HALAL/HALAL.hpp b/Inc/HALAL/HALAL.hpp index e4d095d4..d1f6ea1a 100644 --- a/Inc/HALAL/HALAL.hpp +++ b/Inc/HALAL/HALAL.hpp @@ -3,45 +3,46 @@ #include "HALAL/Models/GPIO.hpp" #include "HALAL/Models/Pin.hpp" -#include "HALAL/Models/HALconfig/HALconfig.hpp" #include "HALAL/Models/DMA/DMA.hpp" +#include "HALAL/Models/HALconfig/HALconfig.hpp" -#include "HALAL/Services/DigitalOutputService/DigitalOutputService.hpp" #include "HALAL/Services/DigitalInputService/DigitalInputService.hpp" +#include "HALAL/Services/DigitalOutputService/DigitalOutputService.hpp" #include "HALAL/Services/Flash/Flash.hpp" #include "HALAL/Services/Flash/FlashTests/Flash_Test.hpp" #include "HALAL/Services/ADC/ADC.hpp" -#include "HALAL/Services/PWM/PWM/PWM.hpp" -#include "HALAL/Services/PWM/DualPWM/DualPWM.hpp" #include "HALAL/Services/PWM/DualCenterPWM/DualCenterPWM.hpp" -#include "HALAL/Services/PWM/PhasedPWM/PhasedPWM.hpp" +#include "HALAL/Services/PWM/DualPWM/DualPWM.hpp" #include "HALAL/Services/PWM/DualPhasedPWM/DualPhasedPWM.hpp" +#include "HALAL/Services/PWM/PWM/PWM.hpp" +#include "HALAL/Services/PWM/PhasedPWM/PhasedPWM.hpp" -#include "HALAL/Services/PWM/PWM.hpp" #include "HALAL/Services/PWM/DualPWM.hpp" +#include "HALAL/Services/PWM/PWM.hpp" -#include "HALAL/Services/Time/TimerWrapper.hpp" -#include "HALAL/Services/Time/Scheduler.hpp" #include "HALAL/Services/Time/RTC.hpp" +#include "HALAL/Services/Time/Scheduler.hpp" +#include "HALAL/Services/Time/TimerWrapper.hpp" -#include "HALAL/Services/InputCapture/InputCapture.hpp" -//#include "HALAL/Services/Encoder/Encoder.hpp" -#include "HALAL/Services/Encoder/NewEncoder.hpp" +// #include "HALAL/Services/Encoder/Encoder.hpp" #include "HALAL/Services/EXTI/EXTI.hpp" +#include "HALAL/Services/Encoder/Encoder.hpp" +#include "HALAL/Services/Encoder/NewEncoder.hpp" +#include "HALAL/Services/InputCapture/InputCapture.hpp" +#include "HALAL/Services/Communication/FDCAN/FDCAN.hpp" +#include "HALAL/Services/Communication/I2C/I2C.hpp" #include "HALAL/Services/Communication/SPI/SPI.hpp" #include "HALAL/Services/Communication/UART/UART.hpp" -#include "HALAL/Services/Communication/I2C/I2C.hpp" -#include "HALAL/Services/Communication/FDCAN/FDCAN.hpp" #include "HALAL/Services/CORDIC/CORDIC.hpp" #include "HALAL/Services/FMAC/FMAC.hpp" -#include "HALAL/Models/MPUManager/MPUManager.hpp" #include "HALAL/Models/MPU.hpp" +#include "HALAL/Models/MPUManager/MPUManager.hpp" #include "HALAL/Services/InfoWarning/InfoWarning.hpp" #include "HALAL/Services/Watchdog/Watchdog.hpp" @@ -50,34 +51,32 @@ #include "HALAL/Models/MDMA/MDMA.hpp" #include "HALAL/Models/Packets/MdmaPacket.hpp" -#include "HALAL/HardFault/HardfaultTrace.h" #include "HALAL/Benchmarking_toolkit/DataWatchpointTrace/DataWatchpointTrace.hpp" +#include "HALAL/HardFault/HardfaultTrace.h" #ifdef STLIB_ETH -#include "HALAL/Models/Packets/Packet.hpp" +#include "HALAL/Models/Packets/ForwardOrder.hpp" #include "HALAL/Models/Packets/Order.hpp" #include "HALAL/Models/Packets/OrderProtocol.hpp" -#include "HALAL/Models/Packets/ForwardOrder.hpp" +#include "HALAL/Models/Packets/Packet.hpp" #include "HALAL/Models/IPV4/IPV4.hpp" #include "HALAL/Models/MAC/MAC.hpp" -#include "HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp" +#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" +#include "HALAL/Services/Communication/Ethernet/NewEthernet.hpp" #include "HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp" #include "HALAL/Services/Communication/Ethernet/TCP/Socket.hpp" -#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" +#include "HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp" #include "HALAL/Services/Communication/SNTP/SNTP.hpp" #endif namespace HALAL { #ifdef STLIB_ETH - void start(MAC mac, - IPV4 ip, - IPV4 subnet_mask, - IPV4 gateway, - UART::Peripheral& printf_peripheral); +void start(MAC mac, IPV4 ip, IPV4 subnet_mask, IPV4 gateway, + UART::Peripheral &printf_peripheral); #else - void start(UART::Peripheral& printf_peripheral); +void start(UART::Peripheral &printf_peripheral); #endif } // namespace HALAL \ No newline at end of file From 3027edf56d5aaee2c6f5bccfdf82868e69a9c33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Tue, 3 Feb 2026 22:06:00 +0100 Subject: [PATCH 02/19] added pinsets --- .../Communication/Ethernet/NewEthernet.hpp | 177 ++++++++++++++++++ LWIP/Target/ethernetif.c | 125 +++++++------ 2 files changed, 241 insertions(+), 61 deletions(-) create mode 100644 Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp new file mode 100644 index 00000000..73915620 --- /dev/null +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -0,0 +1,177 @@ +#pragma once + +#include "stm32h7xx_hal.h" + +#include "C++Utilities/CppUtils.hpp" +#include "HALAL/Models/MAC/MAC.hpp" +#include "HALAL/Services/Communication/Ethernet/EthernetHelper.hpp" +#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" +#include "ethernetif.h" +#include "lwip.h" + +namespace ST_LIB { +extern void compile_error(const char *msg); + +extern uint32_t EthernetLinkTimer; +extern struct netif gnetif; +extern ip4_addr_t ipaddr, netmask, gw; +extern uint8_t IP_ADDRESS[4], NETMASK_ADDRESS[4], GATEWAY_ADDRESS[4]; + +struct EthernetDomain { + + struct EthernetPins { + const GPIODomain::Pin &MDC; + const GPIODomain::Pin &REF_CLK; + const GPIODomain::Pin &MDIO; + const GPIODomain::Pin &CRS_DV; + const GPIODomain::Pin &RXD0; + const GPIODomain::Pin &RXD1; + const GPIODomain::Pin &TXD1; + const GPIODomain::Pin &TX_EN; + const GPIODomain::Pin &TXD0; + + constexpr auto asArray() { + return std::array{ + &MDC, &REF_CLK, &MDIO, &CRS_DV, &RXD0, &RXD1, &TXD1, &TX_EN, &TXD0}; + } + }; + + constexpr static EthernetPins PINSET_H10{.MDC = PC1, + .REF_CLK = PA1, + .MDIO = PA2, + .CRS_DV = PA7, + .RXD0 = PC4, + .RXD1 = PC5, + .TXD1 = PB13, + .TX_EN = PG11, + .TXD0 = PG13}; + constexpr static EthernetPins PINSET_H11{.MDC = PC1, + .REF_CLK = PA1, + .MDIO = PA2, + .CRS_DV = PA7, + .RXD0 = PC4, + .RXD1 = PC5, + .TXD1 = PB13, + .TX_EN = PB11, + .TXD0 = PB12}; + + struct Entry { + std::string local_mac; + std::string local_ip; + std::string subnet_mask; + std::string gateway; + }; + + struct Ethernet { + using domain = EthernetDomain; + + EthernetPins pins; + Entry e; + + consteval Ethernet(EthernetPins pins, string local_mac, string local_ip, + string subnet_mask, string gateway) + : pins{pins}, e{local_mac, local_ip, subnet_mask, gateway} {} + + template consteval std::size_t inscribe(Ctx &ctx) const { + for (const auto &pin : pins.asArray()) { + auto gpio = GPIODomain::GPIO( + pin, GPIODomain::OperationMode::ALT_PP, GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, GPIODomain::Alternate::AF11); + gpio.inscribe(ctx); + } + + return ctx.template add(e, this); + } + }; + + static constexpr std::size_t max_instances{1}; + + struct Config { + std::string local_mac; + std::string local_ip; + std::string subnet_mask; + std::string gateway; + }; + + template + static consteval array build(span pins) { + array cfgs{}; + for (std::size_t i = 0; i < N; ++i) { + const auto &e = pins[i]; + cfgs[i].local_mac = e.local_mac; + cfgs[i].local_ip = e.local_ip; + cfgs[i].subnet_mask = e.subnet_mask; + cfgs[i].gateway = e.gateway; + } + + return cfgs; + } + + // Runtime object + struct Instance { + private: + public: + constexpr Instance() {} + void update() { + ethernetif_input(&gnetif); + sys_check_timeouts(); + + if (HAL_GetTick() - EthernetLinkTimer >= 100) { + EthernetLinkTimer = HAL_GetTick(); + ethernet_link_check_state(&gnetif); + + if (gnetif.flags == 15) { + netif_set_up(&gnetif); + } + } + }; + }; + + template struct Init { + static inline std::array instances{}; + + static void init(std::span cfgs) { + for (std::size_t i = 0; i < N; ++i) { + const EthernetDomain::Config &e = cfgs[i]; + + __HAL_RCC_ETH1MAC_CLK_ENABLE(); + __HAL_RCC_ETH1TX_CLK_ENABLE(); + __HAL_RCC_ETH1RX_CLK_ENABLE(); + + HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(ETH_IRQn); + + MAC local_mac{e.local_mac}; + IPV4 local_ip{e.local_ip}; + IPV4 subnet_mask{e.subnet_mask}; + IPV4 gateway{e.gateway}; + + ipaddr = local_ip.address; + netmask = subnet_mask.address; + gw = gateway.address; + IP_ADDRESS[0] = ipaddr.addr & 0xFF; + IP_ADDRESS[1] = (ipaddr.addr >> 8) & 0xFF; + IP_ADDRESS[2] = (ipaddr.addr >> 16) & 0xFF; + IP_ADDRESS[3] = (ipaddr.addr >> 24) & 0xFF; + NETMASK_ADDRESS[0] = netmask.addr & 0xFF; + NETMASK_ADDRESS[1] = (netmask.addr >> 8) & 0xFF; + NETMASK_ADDRESS[2] = (netmask.addr >> 16) & 0xFF; + NETMASK_ADDRESS[3] = (netmask.addr >> 24) & 0xFF; + GATEWAY_ADDRESS[0] = gw.addr & 0xFF; + GATEWAY_ADDRESS[1] = (gw.addr >> 8) & 0xFF; + GATEWAY_ADDRESS[2] = (gw.addr >> 16) & 0xFF; + GATEWAY_ADDRESS[3] = (gw.addr >> 24) & 0xFF; + gnetif.hwaddr[0] = local_mac.address[0]; + gnetif.hwaddr[1] = local_mac.address[1]; + gnetif.hwaddr[2] = local_mac.address[2]; + gnetif.hwaddr[3] = local_mac.address[3]; + gnetif.hwaddr[4] = local_mac.address[4]; + gnetif.hwaddr[5] = local_mac.address[5]; + MX_LWIP_Init(); + + instances[i] = Instance{}; + } + } + }; +}; +} // namespace ST_LIB \ No newline at end of file diff --git a/LWIP/Target/ethernetif.c b/LWIP/Target/ethernetif.c index a842d94f..8c86585c 100644 --- a/LWIP/Target/ethernetif.c +++ b/LWIP/Target/ethernetif.c @@ -466,67 +466,70 @@ u32_t sys_now(void) void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(ethHandle->Instance==ETH) - { - /* USER CODE BEGIN ETH_MspInit 0 */ - - /* USER CODE END ETH_MspInit 0 */ - /* Enable Peripheral clock */ - __HAL_RCC_ETH1MAC_CLK_ENABLE(); - __HAL_RCC_ETH1TX_CLK_ENABLE(); - __HAL_RCC_ETH1RX_CLK_ENABLE(); - - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_GPIOG_CLK_ENABLE(); - /**ETH GPIO Configuration - PC1 ------> ETH_MDC - PA1 ------> ETH_REF_CLK - PA2 ------> ETH_MDIO - PA7 ------> ETH_CRS_DV - PC4 ------> ETH_RXD0 - PC5 ------> ETH_RXD1 - PB13 ------> ETH_TXD1 - PG11 ------> ETH_TX_EN - PG13 ------> ETH_TXD0 - */ - GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = RMII_TXD1_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = RMII_TX_EN_Pin|RMII_TXD0_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); - - /* Peripheral interrupt init */ - HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(ETH_IRQn); - /* USER CODE BEGIN ETH_MspInit 1 */ - - /* USER CODE END ETH_MspInit 1 */ - } + // This section has been commented out to avoid re-initialization of GPIOs and NVIC + // that are already configured in the HALAL/Services/Communication/Ethernet/NewEthernet.hpp module. + + // GPIO_InitTypeDef GPIO_InitStruct = {0}; + // if(ethHandle->Instance==ETH) + // { + // /* USER CODE BEGIN ETH_MspInit 0 */ + + // /* USER CODE END ETH_MspInit 0 */ + // /* Enable Peripheral clock */ + // __HAL_RCC_ETH1MAC_CLK_ENABLE(); + // __HAL_RCC_ETH1TX_CLK_ENABLE(); + // __HAL_RCC_ETH1RX_CLK_ENABLE(); + + // __HAL_RCC_GPIOC_CLK_ENABLE(); + // __HAL_RCC_GPIOA_CLK_ENABLE(); + // __HAL_RCC_GPIOB_CLK_ENABLE(); + // __HAL_RCC_GPIOG_CLK_ENABLE(); + // /**ETH GPIO Configuration + // PC1 ------> ETH_MDC + // PA1 ------> ETH_REF_CLK + // PA2 ------> ETH_MDIO + // PA7 ------> ETH_CRS_DV + // PC4 ------> ETH_RXD0 + // PC5 ------> ETH_RXD1 + // PB13 ------> ETH_TXD1 + // PG11 ------> ETH_TX_EN + // PG13 ------> ETH_TXD0 + // */ + // GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin; + // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + // GPIO_InitStruct.Pull = GPIO_NOPULL; + // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + // HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + // GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin; + // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + // GPIO_InitStruct.Pull = GPIO_NOPULL; + // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + // HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + // GPIO_InitStruct.Pin = RMII_TXD1_Pin; + // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + // GPIO_InitStruct.Pull = GPIO_NOPULL; + // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + // HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct); + + // GPIO_InitStruct.Pin = RMII_TX_EN_Pin|RMII_TXD0_Pin; + // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + // GPIO_InitStruct.Pull = GPIO_NOPULL; + // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; + // HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + // /* Peripheral interrupt init */ + // HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); + // HAL_NVIC_EnableIRQ(ETH_IRQn); + // /* USER CODE BEGIN ETH_MspInit 1 */ + + // /* USER CODE END ETH_MspInit 1 */ + // } } void HAL_ETH_MspDeInit(ETH_HandleTypeDef* ethHandle) From 20c14a57f4f2d2c83267bce4a213119e9c05f65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Tue, 3 Feb 2026 22:45:25 +0100 Subject: [PATCH 03/19] Fixed compile bugs --- .../Communication/Ethernet/NewEthernet.hpp | 81 ++++++++++++++----- Inc/ST-LIB.hpp | 28 ++++--- 2 files changed, 76 insertions(+), 33 deletions(-) diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index 73915620..0757253f 100644 --- a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -9,14 +9,14 @@ #include "ethernetif.h" #include "lwip.h" -namespace ST_LIB { -extern void compile_error(const char *msg); - extern uint32_t EthernetLinkTimer; extern struct netif gnetif; extern ip4_addr_t ipaddr, netmask, gw; extern uint8_t IP_ADDRESS[4], NETMASK_ADDRESS[4], GATEWAY_ADDRESS[4]; +namespace ST_LIB { +extern void compile_error(const char *msg); + struct EthernetDomain { struct EthernetPins { @@ -30,9 +30,9 @@ struct EthernetDomain { const GPIODomain::Pin &TX_EN; const GPIODomain::Pin &TXD0; - constexpr auto asArray() { - return std::array{ - &MDC, &REF_CLK, &MDIO, &CRS_DV, &RXD0, &RXD1, &TXD1, &TX_EN, &TXD0}; + constexpr std::array, 9> + asArray() const { + return {MDC, REF_CLK, MDIO, CRS_DV, RXD0, RXD1, TXD1, TX_EN, TXD0}; } }; @@ -56,10 +56,10 @@ struct EthernetDomain { .TXD0 = PB12}; struct Entry { - std::string local_mac; - std::string local_ip; - std::string subnet_mask; - std::string gateway; + const char *local_mac; + const char *local_ip; + const char *subnet_mask; + const char *gateway; }; struct Ethernet { @@ -68,15 +68,54 @@ struct EthernetDomain { EthernetPins pins; Entry e; - consteval Ethernet(EthernetPins pins, string local_mac, string local_ip, - string subnet_mask, string gateway) - : pins{pins}, e{local_mac, local_ip, subnet_mask, gateway} {} + std::array gpios; + + consteval Ethernet(EthernetPins pins, const char *local_mac, + const char *local_ip, + const char *subnet_mask = "255.255.0.0", + const char *gateway = "192.168.1.1") + : pins{pins}, e{local_mac, local_ip, subnet_mask, gateway}, + gpios{ + GPIODomain::GPIO(pins.MDC, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.REF_CLK, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.MDIO, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.CRS_DV, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.RXD0, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.RXD1, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.TXD1, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.TX_EN, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.TXD0, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), + } {} template consteval std::size_t inscribe(Ctx &ctx) const { - for (const auto &pin : pins.asArray()) { - auto gpio = GPIODomain::GPIO( - pin, GPIODomain::OperationMode::ALT_PP, GPIODomain::Pull::None, - GPIODomain::Speed::VeryHigh, GPIODomain::Alternate::AF11); + for (const auto &gpio : gpios) { gpio.inscribe(ctx); } @@ -87,10 +126,10 @@ struct EthernetDomain { static constexpr std::size_t max_instances{1}; struct Config { - std::string local_mac; - std::string local_ip; - std::string subnet_mask; - std::string gateway; + const char *local_mac; + const char *local_ip; + const char *subnet_mask; + const char *gateway; }; template diff --git a/Inc/ST-LIB.hpp b/Inc/ST-LIB.hpp index 70f2ae38..11d8c96b 100644 --- a/Inc/ST-LIB.hpp +++ b/Inc/ST-LIB.hpp @@ -83,11 +83,10 @@ template struct BuildCtx { } }; -using DomainsCtx = BuildCtx; +using DomainsCtx = + BuildCtx; template struct Board { static consteval auto build_ctx() { @@ -110,6 +109,7 @@ template struct Board { constexpr std::size_t dinN = domain_size(); constexpr std::size_t mdmaPacketN = domain_size(); constexpr std::size_t sdN = domain_size(); + constexpr std::size_t ethN = domain_size(); // ... struct ConfigBundle { @@ -120,12 +120,13 @@ template struct Board { std::array din_cfgs; std::array mdma_packet_cfgs; std::array sd_cfgs; + std::array eth_cfgs; // ... }; return ConfigBundle{ - .mpu_cfgs = MPUDomain::template build( - ctx.template span()), + .mpu_cfgs = + MPUDomain::template build(ctx.template span()), .gpio_cfgs = GPIODomain::template build(ctx.template span()), .tim_cfgs = @@ -136,8 +137,9 @@ template struct Board { ctx.template span()), .mdma_packet_cfgs = MdmaPacketDomain::template build( ctx.template span()), - .sd_cfgs = SdDomain::template build( - ctx.template span()), + .sd_cfgs = SdDomain::template build(ctx.template span()), + .eth_cfgs = EthernetDomain::template build( + ctx.template span()), // ... }; } @@ -152,6 +154,7 @@ template struct Board { constexpr std::size_t dinN = domain_size(); constexpr std::size_t mdmaPacketN = domain_size(); constexpr std::size_t sdN = domain_size(); + constexpr std::size_t ethN = domain_size(); // ... MPUDomain::Init::init(); @@ -161,11 +164,12 @@ template struct Board { GPIODomain::Init::instances); DigitalInputDomain::Init::init(cfg.din_cfgs, GPIODomain::Init::instances); - MdmaPacketDomain::Init::init(cfg.mdma_packet_cfgs, - MPUDomain::Init::instances); + MdmaPacketDomain::Init::init( + cfg.mdma_packet_cfgs, MPUDomain::Init::instances); SdDomain::Init::init(cfg.sd_cfgs, MPUDomain::Init::instances, DigitalInputDomain::Init::instances); + EthernetDomain::Init::init(cfg.eth_cfgs); // ... } @@ -188,7 +192,7 @@ template struct Board { constexpr std::size_t idx = owner_index_of(); constexpr std::size_t N = domain_size(); - + if constexpr (std::is_same_v) { return Domain::template Init::instances[idx]; } else { From ceeb297130290df3f57eec27b846d507246b40a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Wed, 4 Feb 2026 00:40:54 +0100 Subject: [PATCH 04/19] moved new ethernet directly below HAL to ensure compilation in all presets --- Inc/HALAL/{Services/Communication/Ethernet => }/NewEthernet.hpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Inc/HALAL/{Services/Communication/Ethernet => }/NewEthernet.hpp (100%) diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/NewEthernet.hpp similarity index 100% rename from Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp rename to Inc/HALAL/NewEthernet.hpp From 79252976d83e4880c15951c882319a4b9aee468c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Wed, 4 Feb 2026 00:46:16 +0100 Subject: [PATCH 05/19] moved new ethernet directly below HAL to ensure compilation in all presets --- Inc/HALAL/HALAL.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Inc/HALAL/HALAL.hpp b/Inc/HALAL/HALAL.hpp index d1f6ea1a..cdc56aba 100644 --- a/Inc/HALAL/HALAL.hpp +++ b/Inc/HALAL/HALAL.hpp @@ -62,8 +62,8 @@ #include "HALAL/Models/IPV4/IPV4.hpp" #include "HALAL/Models/MAC/MAC.hpp" +#include "HALAL/NewEthernet.hpp" #include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" -#include "HALAL/Services/Communication/Ethernet/NewEthernet.hpp" #include "HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp" #include "HALAL/Services/Communication/Ethernet/TCP/Socket.hpp" #include "HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp" From c57b726428384b9b3f967987ba4c11b73b645e6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Wed, 4 Feb 2026 09:26:50 +0100 Subject: [PATCH 06/19] Added dummy EthernetDomain to compile without Ethernet --- Inc/HALAL/HALAL.hpp | 3 +- .../Communication/Ethernet}/NewEthernet.hpp | 34 +++++++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) rename Inc/HALAL/{ => Services/Communication/Ethernet}/NewEthernet.hpp (92%) diff --git a/Inc/HALAL/HALAL.hpp b/Inc/HALAL/HALAL.hpp index cdc56aba..b598221a 100644 --- a/Inc/HALAL/HALAL.hpp +++ b/Inc/HALAL/HALAL.hpp @@ -53,6 +53,7 @@ #include "HALAL/Benchmarking_toolkit/DataWatchpointTrace/DataWatchpointTrace.hpp" #include "HALAL/HardFault/HardfaultTrace.h" +#include "HALAL/Services/Communication/Ethernet/NewEthernet.hpp" #ifdef STLIB_ETH #include "HALAL/Models/Packets/ForwardOrder.hpp" #include "HALAL/Models/Packets/Order.hpp" @@ -61,8 +62,6 @@ #include "HALAL/Models/IPV4/IPV4.hpp" #include "HALAL/Models/MAC/MAC.hpp" - -#include "HALAL/NewEthernet.hpp" #include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" #include "HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp" #include "HALAL/Services/Communication/Ethernet/TCP/Socket.hpp" diff --git a/Inc/HALAL/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp similarity index 92% rename from Inc/HALAL/NewEthernet.hpp rename to Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index 0757253f..492317f2 100644 --- a/Inc/HALAL/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -3,6 +3,8 @@ #include "stm32h7xx_hal.h" #include "C++Utilities/CppUtils.hpp" + +#ifdef STLIB_ETH #include "HALAL/Models/MAC/MAC.hpp" #include "HALAL/Services/Communication/Ethernet/EthernetHelper.hpp" #include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" @@ -29,11 +31,6 @@ struct EthernetDomain { const GPIODomain::Pin &TXD1; const GPIODomain::Pin &TX_EN; const GPIODomain::Pin &TXD0; - - constexpr std::array, 9> - asArray() const { - return {MDC, REF_CLK, MDIO, CRS_DV, RXD0, RXD1, TXD1, TX_EN, TXD0}; - } }; constexpr static EthernetPins PINSET_H10{.MDC = PC1, @@ -133,10 +130,10 @@ struct EthernetDomain { }; template - static consteval array build(span pins) { + static consteval array build(span config) { array cfgs{}; for (std::size_t i = 0; i < N; ++i) { - const auto &e = pins[i]; + const auto &e = config[i]; cfgs[i].local_mac = e.local_mac; cfgs[i].local_ip = e.local_ip; cfgs[i].subnet_mask = e.subnet_mask; @@ -148,8 +145,6 @@ struct EthernetDomain { // Runtime object struct Instance { - private: - public: constexpr Instance() {} void update() { ethernetif_input(&gnetif); @@ -213,4 +208,23 @@ struct EthernetDomain { } }; }; -} // namespace ST_LIB \ No newline at end of file +} // namespace ST_LIB + +#else +namespace ST_LIB { +// Dummy EthernetDomain when STLIB_ETH is not defined +struct EthernetDomain { + static constexpr std::size_t max_instances{0}; + struct Entry {}; + struct Config {}; + template + static consteval array build(span config) { + return {}; + } + struct Instance {}; + template struct Init { + static void init(std::span cfgs) {} + }; +}; +} // namespace ST_LIB +#endif // STLIB_ETH \ No newline at end of file From af7bca06bf54fb91d5f0b3440bd6b4c716678ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Wed, 4 Feb 2026 23:51:13 +0100 Subject: [PATCH 07/19] Added drivers for two phys --- CMakeLists.txt | 123 ++- Inc/HALAL/HALAL.hpp | 8 +- Inc/HALAL/Models/Packets/ForwardOrder.hpp | 80 +- .../Communication/Ethernet/Ethernet.hpp | 43 - .../Communication/Ethernet/LWIP/Ethernet.hpp | 45 + .../Ethernet/{ => LWIP}/EthernetHelper.hpp | 0 .../Ethernet/{ => LWIP}/EthernetNode.hpp | 0 .../Ethernet/LWIP/TCP/ServerSocket.hpp | 228 +++++ .../Ethernet/LWIP/TCP/Socket.hpp | 120 +++ .../Ethernet/LWIP/UDP/DatagramSocket.hpp | 46 + .../Communication/Ethernet/NewEthernet.hpp | 68 +- .../Communication/Ethernet/PHY/phy_driver.h | 17 + .../Ethernet/TCP/ServerSocket.hpp | 198 ----- .../Communication/Ethernet/TCP/Socket.hpp | 111 --- .../Ethernet/UDP/DatagramSocket.hpp | 48 -- Inc/ST-LIB.hpp | 10 +- LWIP/App/lwip.c | 170 ++-- LWIP/Target/ethernetif.c | 798 +++--------------- .../Communication/Ethernet/EthernetNode.cpp | 24 - .../Ethernet/{ => LWIP}/Ethernet.cpp | 3 +- .../Ethernet/LWIP/EthernetNode.cpp | 24 + .../Ethernet/{ => LWIP}/TCP/OrderProtocol.cpp | 0 .../Ethernet/LWIP/TCP/ServerSocket.cpp | 309 +++++++ .../Ethernet/LWIP/TCP/Socket.cpp | 322 +++++++ .../Ethernet/LWIP/UDP/DatagramSocket.cpp | 96 +++ .../Communication/Ethernet/PHY/ksz8041.c | 38 + .../Communication/Ethernet/PHY/lan8742.c | 57 ++ .../Communication/Ethernet/PHY/phy_select.c | 13 + .../Ethernet/TCP/ServerSocket.cpp | 285 ------- .../Communication/Ethernet/TCP/Socket.cpp | 297 ------- .../Ethernet/UDP/DatagramSocket.cpp | 87 -- 31 files changed, 1746 insertions(+), 1922 deletions(-) delete mode 100644 Inc/HALAL/Services/Communication/Ethernet/Ethernet.hpp create mode 100644 Inc/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp rename Inc/HALAL/Services/Communication/Ethernet/{ => LWIP}/EthernetHelper.hpp (100%) rename Inc/HALAL/Services/Communication/Ethernet/{ => LWIP}/EthernetNode.hpp (100%) create mode 100644 Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.hpp create mode 100644 Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.hpp create mode 100644 Inc/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.hpp create mode 100644 Inc/HALAL/Services/Communication/Ethernet/PHY/phy_driver.h delete mode 100644 Inc/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp delete mode 100644 Inc/HALAL/Services/Communication/Ethernet/TCP/Socket.hpp delete mode 100644 Inc/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp delete mode 100644 Src/HALAL/Services/Communication/Ethernet/EthernetNode.cpp rename Src/HALAL/Services/Communication/Ethernet/{ => LWIP}/Ethernet.cpp (97%) create mode 100644 Src/HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.cpp rename Src/HALAL/Services/Communication/Ethernet/{ => LWIP}/TCP/OrderProtocol.cpp (100%) create mode 100644 Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.cpp create mode 100644 Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.cpp create mode 100644 Src/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.cpp create mode 100644 Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c create mode 100644 Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c create mode 100644 Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c delete mode 100644 Src/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.cpp delete mode 100644 Src/HALAL/Services/Communication/Ethernet/TCP/Socket.cpp delete mode 100644 Src/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ec2a3c7..fd82f13a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,27 @@ enable_testing() option(USE_ETHERNET "Enable ethernet peripheral" OFF) option(TARGET_NUCLEO "Targets the STM32H723 Nucleo development board" OFF) +# ============================ +# PHY selection (Ethernet) +# ============================ + +if(USE_ETHERNET) + + if(TARGET_NUCLEO) + # Nucleo boards always use LAN8742 + set(SELECTED_PHY "LAN8742") + else() + if(NOT DEFINED PHY_TYPE) + message(FATAL_ERROR + "USE_ETHERNET=ON and TARGET_NUCLEO=OFF but PHY_TYPE not set (KSZ8041 or LAN8742)") + endif() + set(SELECTED_PHY "${PHY_TYPE}") + endif() + + message(STATUS "${PROJECT_NAME} PHY: ${SELECTED_PHY}") + +endif() + message(STATUS "${PROJECT_NAME} Ethernet: ${USE_ETHERNET}") message(STATUS "${PROJECT_NAME} Nucleo: ${TARGET_NUCLEO}") message(STATUS "${PROJECT_NAME} Crosscompiling: ${CMAKE_CROSSCOMPILING}") @@ -133,8 +154,8 @@ if(CMAKE_CROSSCOMPILING) ) if(USE_ETHERNET) + set(LWIP_DIR ${STM32CUBEH7}/Middlewares/Third_Party/LwIP) - set(LAN8742_DIR ${STM32CUBEH7}/Drivers/BSP/Components/lan8742) file(GLOB LWIP_SOURCES ${LWIP_DIR}/src/core/*.c @@ -143,11 +164,38 @@ if(CMAKE_CROSSCOMPILING) ${LWIP_DIR}/src/api/*.c ${LWIP_DIR}/src/netif/*.c ${LWIP_DIR}/system/*.c - ${LAN8742_DIR}/lan8742.c ) - file(GLOB_RECURSE USER_LWIP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/LWIP/*.c) + set(USER_LWIP_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/LWIP/App/lwip.c + ${CMAKE_CURRENT_LIST_DIR}/LWIP/Target/ethernetif.c + ) + + # PHY-specific source (HALAL) + if(SELECTED_PHY STREQUAL "LAN8742") + set(PHY_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c + ) + elseif(SELECTED_PHY STREQUAL "KSZ8041") + set(PHY_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c + ) + else() + message(FATAL_ERROR "Unknown PHY: ${SELECTED_PHY}") + endif() + + list(APPEND LWIP_SOURCES + ${PHY_SOURCES} + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c + ) + + file(GLOB_RECURSE USER_LWIP_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/LWIP/*.c + ) + endif() + + file(GLOB_RECURSE USER_LWIP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/LWIP/*.c) endif() # ============================ @@ -156,19 +204,55 @@ endif() file(GLOB_RECURSE HALAL_C_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/*.c) file(GLOB_RECURSE HALAL_CPP_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/*.cpp) -set(HALAL_ETH_REGEX ".*/HALAL/(Models/(IPV4|MAC)|Services/Communication/(Ethernet|SNTP))/.*") +set(HALAL_ETH_CORE_REGEX + ".*/HALAL/Services/Communication/Ethernet/[^/]+\\.(c|cpp)$" +) + +set(HALAL_C_ETH_CORE ${HALAL_C_ALL}) +list(FILTER HALAL_C_ETH_CORE INCLUDE REGEX "${HALAL_ETH_CORE_REGEX}") -set(HALAL_C_ETH ${HALAL_C_ALL}) -list(FILTER HALAL_C_ETH INCLUDE REGEX "${HALAL_ETH_REGEX}") +set(HALAL_CPP_ETH_CORE ${HALAL_CPP_ALL}) +list(FILTER HALAL_CPP_ETH_CORE INCLUDE REGEX "${HALAL_ETH_CORE_REGEX}") -set(HALAL_CPP_ETH ${HALAL_CPP_ALL}) -list(FILTER HALAL_CPP_ETH INCLUDE REGEX "${HALAL_ETH_REGEX}") +set(HALAL_ETH_LWIP_REGEX + ".*/HALAL/Services/Communication/Ethernet/LWIP/.*" +) + +set(HALAL_C_ETH_LWIP ${HALAL_C_ALL}) +list(FILTER HALAL_C_ETH_LWIP INCLUDE REGEX "${HALAL_ETH_LWIP_REGEX}") + +set(HALAL_CPP_ETH_LWIP ${HALAL_CPP_ALL}) +list(FILTER HALAL_CPP_ETH_LWIP INCLUDE REGEX "${HALAL_ETH_LWIP_REGEX}") + +set(HALAL_C_ETH_PHY "") + +if(USE_ETHERNET) + list(APPEND HALAL_C_ETH_PHY + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c + ) + + if(USE_PHY_LAN8742) + list(APPEND HALAL_C_ETH_PHY + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c + ) + endif() + + if(USE_PHY_KSZ8041) + list(APPEND HALAL_C_ETH_PHY + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c + ) + endif() +endif() set(HALAL_C_NO_ETH ${HALAL_C_ALL}) -list(FILTER HALAL_C_NO_ETH EXCLUDE REGEX "${HALAL_ETH_REGEX}") +list(FILTER HALAL_C_NO_ETH EXCLUDE REGEX + ".*/HALAL/Services/Communication/Ethernet/.*" +) set(HALAL_CPP_NO_ETH ${HALAL_CPP_ALL}) -list(FILTER HALAL_CPP_NO_ETH EXCLUDE REGEX "${HALAL_ETH_REGEX}") +list(FILTER HALAL_CPP_NO_ETH EXCLUDE REGEX + ".*/HALAL/Services/Communication/Ethernet/.*" +) # ============================ # C++ Utilities @@ -225,10 +309,15 @@ add_library(${STLIB_LIBRARY} STATIC $<$,$>:${LWIP_SOURCES}> $<$,$>:${USER_LWIP_SOURCES}> - $<$:${HALAL_C_NO_ETH}> - $<$:${HALAL_CPP_NO_ETH}> - $<$,$>:${HALAL_C_ETH}> - $<$,$>:${HALAL_CPP_ETH}> + ${HALAL_C_NO_ETH} + ${HALAL_CPP_NO_ETH} + + ${HALAL_C_ETH_CORE} + ${HALAL_CPP_ETH_CORE} + + $<$:${HALAL_C_ETH_LWIP}> + $<$:${HALAL_CPP_ETH_LWIP}> + $<$:${HALAL_C_ETH_PHY}> $<$:${CPP_UTILITIES_C}> $<$:${CPP_UTILITIES_CPP}> @@ -264,6 +353,9 @@ target_compile_definitions(${STLIB_LIBRARY} PUBLIC $<$:USE_HAL_DRIVER> $<$:STM32H723xx> + $<$,$>:USE_PHY_LAN8742> + $<$,$>:USE_PHY_KSZ8041> + $<$>:TESTING_ENV> $<$:STLIB_ETH> @@ -322,7 +414,8 @@ target_include_directories(${STLIB_LIBRARY} PUBLIC $<$,$>:${LWIP_DIR}/src/include/compat/stdc> $<$,$>:${LWIP_DIR}/system/arch> $<$,$>:${STM32CUBEH7}/Drivers/BSP/Components> - $<$,$>:${STM32CUBEH7}/Drivers/BSP/Components/lan8742> + $<$,$,$>:${STM32CUBEH7}/Drivers/BSP/Components/lan8742> + $<$,$>:${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet> $<$,$>:${CMAKE_CURRENT_LIST_DIR}/LWIP/App> $<$,$>:${CMAKE_CURRENT_LIST_DIR}/LWIP/Target> diff --git a/Inc/HALAL/HALAL.hpp b/Inc/HALAL/HALAL.hpp index b598221a..70f7a33e 100644 --- a/Inc/HALAL/HALAL.hpp +++ b/Inc/HALAL/HALAL.hpp @@ -62,10 +62,10 @@ #include "HALAL/Models/IPV4/IPV4.hpp" #include "HALAL/Models/MAC/MAC.hpp" -#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" -#include "HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp" -#include "HALAL/Services/Communication/Ethernet/TCP/Socket.hpp" -#include "HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.hpp" #include "HALAL/Services/Communication/SNTP/SNTP.hpp" #endif diff --git a/Inc/HALAL/Models/Packets/ForwardOrder.hpp b/Inc/HALAL/Models/Packets/ForwardOrder.hpp index 6f37ad3a..1a7fb5d2 100644 --- a/Inc/HALAL/Models/Packets/ForwardOrder.hpp +++ b/Inc/HALAL/Models/Packets/ForwardOrder.hpp @@ -1,50 +1,50 @@ #pragma once +#include "HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.hpp" - -#include "HALAL/Services/Communication/Ethernet/TCP/Socket.hpp" - -template requires NotCallablePack -class ForwardOrder : public StackPacket, public Order{ +template + requires NotCallablePack +class ForwardOrder : public StackPacket, public Order { public: - ForwardOrder(uint16_t id,Socket& forwarder, Types*... values) : StackPacket(id,values...) ,forwarding_socket{forwarder}{orders[id] = this;} - - void process() override { - return; - } - - void parse(uint8_t* data) override { - return; - } - void parse(OrderProtocol* socket, uint8_t* data) override{ - struct pbuf* packet = pbuf_alloc(PBUF_TRANSPORT, get_size(), PBUF_POOL); - pbuf_take(packet, data, get_size()); - forwarding_socket.tx_packet_buffer.push(packet); - forwarding_socket.send(); - } - size_t get_size() override { - return StackPacket::get_size(); - } - uint16_t get_id() override { - return StackPacket::get_id(); - } - + ForwardOrder(uint16_t id, Socket &forwarder, Types *...values) + : StackPacket(id, values...), + forwarding_socket{forwarder} { + orders[id] = this; + } + + void process() override { return; } + + void parse(uint8_t *data) override { return; } + void parse(OrderProtocol *socket, uint8_t *data) override { + struct pbuf *packet = pbuf_alloc(PBUF_TRANSPORT, get_size(), PBUF_POOL); + pbuf_take(packet, data, get_size()); + forwarding_socket.tx_packet_buffer.push(packet); + forwarding_socket.send(); + } + size_t get_size() override { + return StackPacket::get_size(); + } + uint16_t get_id() override { + return StackPacket::get_id(); + } private: - void set_callback(void(*callback)(void))override{ - return; - } - uint8_t* build() override { - return StackPacket::build(); - } - void set_pointer(size_t index, void* pointer) override{ - StackPacket::set_pointer(index, pointer); - } - // socket in charge of forwarding the order - Socket& forwarding_socket; + void set_callback(void (*callback)(void)) override { return; } + uint8_t *build() override { + return StackPacket::build(); + } + void set_pointer(size_t index, void *pointer) override { + StackPacket::set_pointer(index, pointer); + } + // socket in charge of forwarding the order + Socket &forwarding_socket; }; #if __cpp_deduction_guides >= 201606 -template requires NotCallablePack -ForwardOrder(uint16_t id,Socket& fwd, Types*... values)->ForwardOrder<(!has_container::value)*total_sizeof::value, Types...>; +template + requires NotCallablePack +ForwardOrder(uint16_t id, Socket &fwd, Types *...values) + -> ForwardOrder<(!has_container::value) * + total_sizeof::value, + Types...>; #endif diff --git a/Inc/HALAL/Services/Communication/Ethernet/Ethernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/Ethernet.hpp deleted file mode 100644 index cf194662..00000000 --- a/Inc/HALAL/Services/Communication/Ethernet/Ethernet.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * EthernetNode.cpp - * - * Created on: Nov 23, 2022 - * Author: stefa - */ - -#pragma once - -#include "C++Utilities/CppUtils.hpp" -#include "HALAL/Models/PinModel/Pin.hpp" -#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" -#include "lwip.h" -#include "ethernetif.h" -#include "HALAL/Services/Communication/Ethernet/EthernetHelper.hpp" -#include "HALAL/Models/MAC/MAC.hpp" - -#ifdef HAL_ETH_MODULE_ENABLED - -#define ETHERNET_POOLS_BASE_ADDRESS 0x30000000 - -#define TCP_INACTIVITY_TIME_UNTIL_KEEPALIVE_MS 500 -#define TCP_KEEPALIVE_TRIES_UNTIL_DISCONNECTION 10 -#define TCP_SPACE_BETWEEN_KEEPALIVE_TRIES_MS 100 - -class Ethernet{ -public: - static bool is_ready; - static bool is_running; - - static void inscribe(); - static void start(string local_mac, string local_ip, string subnet_mask, string gateway); - static void start(MAC local_mac, IPV4 local_ip, IPV4 subnet_mask, IPV4 gateway); - - /** - * @brief handles the received messages by ethernet - */ - static void update(); - -private: -}; - -#endif diff --git a/Inc/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp new file mode 100644 index 00000000..f53aee01 --- /dev/null +++ b/Inc/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp @@ -0,0 +1,45 @@ +/* + * EthernetNode.cpp + * + * Created on: Nov 23, 2022 + * Author: stefa + */ + +#pragma once + +#include "C++Utilities/CppUtils.hpp" +#include "HALAL/Models/MAC/MAC.hpp" +#include "HALAL/Models/PinModel/Pin.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetHelper.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" +#include "ethernetif.h" +#include "lwip.h" + +#ifdef HAL_ETH_MODULE_ENABLED + +#define ETHERNET_POOLS_BASE_ADDRESS 0x30000000 + +#define TCP_INACTIVITY_TIME_UNTIL_KEEPALIVE_MS 500 +#define TCP_KEEPALIVE_TRIES_UNTIL_DISCONNECTION 10 +#define TCP_SPACE_BETWEEN_KEEPALIVE_TRIES_MS 100 + +class Ethernet { +public: + static bool is_ready; + static bool is_running; + + static void inscribe(); + static void start(string local_mac, string local_ip, string subnet_mask, + string gateway); + static void start(MAC local_mac, IPV4 local_ip, IPV4 subnet_mask, + IPV4 gateway); + + /** + * @brief handles the received messages by ethernet + */ + static void update(); + +private: +}; + +#endif diff --git a/Inc/HALAL/Services/Communication/Ethernet/EthernetHelper.hpp b/Inc/HALAL/Services/Communication/Ethernet/LWIP/EthernetHelper.hpp similarity index 100% rename from Inc/HALAL/Services/Communication/Ethernet/EthernetHelper.hpp rename to Inc/HALAL/Services/Communication/Ethernet/LWIP/EthernetHelper.hpp diff --git a/Inc/HALAL/Services/Communication/Ethernet/EthernetNode.hpp b/Inc/HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp similarity index 100% rename from Inc/HALAL/Services/Communication/Ethernet/EthernetNode.hpp rename to Inc/HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp diff --git a/Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.hpp b/Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.hpp new file mode 100644 index 00000000..b5d6b0ff --- /dev/null +++ b/Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.hpp @@ -0,0 +1,228 @@ +/* + * ServerSocket.hpp + * + * Created on: 14 nov. 2022 + * Author: stefa + */ +#pragma once + +#ifdef STLIB_ETH + +#include "HALAL/Models/Packets/Order.hpp" +#include "HALAL/Models/Packets/OrderProtocol.hpp" +#include "HALAL/Models/Packets/Packet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" +#ifdef HAL_ETH_MODULE_ENABLED + +#define PBUF_POOL_MEMORY_DESC_POSITION 8 + +/** + * @brief class that handles a single point to point server client connection, + * emulating the server side. + * + * The flow of this class goes as follows: + * + * 1. When the constructor is called, the listener is activated and starts + * working immediately + * + * 2. After a client issues a connection to the ServerSocket and Ethernet#update + * is executed, the ServerSocket accepts the request + * + * 3. Accepting the request raises an interrupt that calls accept_callback, + * which closes the listener socket (on server_control_block) and opens the + * connection socket (on client_control_block) + * + * 4. The connection goes on until one of the ends closes it, which calls the + * ErrorHandler to send the board into fault as a default behaviour. + * + * @see Ethernet#update + */ +class ServerSocket : public OrderProtocol { +public: + enum ServerState { INACTIVE, LISTENING, ACCEPTED, CLOSING, CLOSED }; + + static unordered_map listening_sockets; + IPV4 local_ip; + uint32_t local_port; + IPV4 remote_ip; + ServerState state; + static uint8_t priority; + + struct KeepaliveConfig { + uint32_t inactivity_time_until_keepalive_ms = + TCP_INACTIVITY_TIME_UNTIL_KEEPALIVE_MS; + uint32_t space_between_tries_ms = TCP_SPACE_BETWEEN_KEEPALIVE_TRIES_MS; + uint32_t tries_until_disconnection = + TCP_KEEPALIVE_TRIES_UNTIL_DISCONNECTION; + } keepalive_config; + + ServerSocket(); + + ServerSocket(ServerSocket &&other); + + /** + * @brief ServerSocket constructor that receives the server ip on the net as a + * binary value. + * + * @param local_ip the server ip on. + * @param local_port the port number that the server listens for connections. + */ + ServerSocket(IPV4 local_ip, uint32_t local_port); + ServerSocket(IPV4 local_ip, uint32_t local_port, + uint32_t inactivity_time_until_keepalive_ms, + uint32_t space_between_tries_ms, + uint32_t tries_until_disconnection); + /** + * @brief ServerSocket constructor that uses the EthernetNode class as a + * parameter + * + * @param local_node the EthernetNode to listen to + * + * @see EthernetNode + */ + ServerSocket(EthernetNode local_node); + ~ServerSocket(); + + void operator=(ServerSocket &&other); + + /** + * @brief ends the connection between the server and the client. + */ + void close(); + + /** + * @brief saves the order data into the tx_packet_buffer so it can be sent + * when a connection is accepted + * + * @param order the order to send, which contains the data and id of the + * message + * @return true if the data could be allocated in the buffer, false otherwise + */ + bool add_order_to_queue(Order &order); + /** + * @brief puts the order data into the tx_packet_buffer and sends all the data + * in the buffer to the client + * + * @param order the order to send, which contains the data and id of the + * message + * @return true if the data was sent successfully, false otherwise + */ + bool send_order(Order &order) override { + if (state != ACCEPTED) { + return false; + } + struct memp *next_memory_pointer_in_packet_buffer_pool = + (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; + if (next_memory_pointer_in_packet_buffer_pool == nullptr) { + if (client_control_block->unsent != nullptr) { + tcp_output(client_control_block); + } else { + memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], + next_memory_pointer_in_packet_buffer_pool); + } + return false; + } + + uint8_t *order_buffer = order.build(); + if (order.get_size() > tcp_sndbuf(client_control_block)) { + return false; + } + + struct pbuf *packet = + pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); + pbuf_take(packet, order_buffer, order.get_size()); + tx_packet_buffer.push(packet); + send(); + return true; + } + + /** + * @brief sends all the binary data saved in the tx_packet_buffer to the + * connected client. + * + * This function is the one that actually handles outgoing communication, + * sending one by one the packets in the tx_packet_buffer The messages in the + * buffer are all immediately sent after calling this function, unless an + * error of any kind happened, in which case ErrorHandler is raised + */ + void send(); + + /** + * @brief function that returns wether or not a client is connected to the + * ServerSocket + * + * This functions returns a comparison to the state of the ServerSocket, + * checking wether or not it is on the ACCEPTED state This function is + * equivalent to doing instance->state == ServerSocket#ACCEPT + * + * @return true if a connection with the client was established, false + * otherwise + */ + bool is_connected(); + +private: + struct tcp_pcb *server_control_block = nullptr; + queue tx_packet_buffer; + queue rx_packet_buffer; + struct tcp_pcb *client_control_block; + + /** + * @brief process the data received by the client orders. It is meant to be + * called only by Lwip on the receive_callback + * + * reads all the data received by the server in the ethernet buffer, packet by + * packet. Then, for each packet, it processes it depending on the order id + * (default behavior is not process) and removes it from the buffer. This + * makes so the receive_callback (and thus the Socket) can only process + * declared orders, and ignores all other packets. + */ + void process_data(); + /** + * @brief the callback for the listener socket receiving a request for + * connection into the ServerSocket. + * + * This function is called on an interrupt when a packet containing a + * connection request to the same port of the listener socket is received. + * accept_callback builds the pcb that acts as the connection socket and saves + * it in the client_control_block pointer It then closes the listener socket + * and makes the server_control_block point to nullptr. + * + * server_control_block shouldn't be accessed in any way while the + * ServerSocket is in the ServerSocket#ACCEPT state, as it will lead into a + * nullptr exception. This in an intended behavior as there shouldn't be more + * than one listener socket on the same port, and a ServerSocket shouldn't be + * able to handle more than one connection by design. + */ + static err_t accept_callback(void *arg, + struct tcp_pcb *incomming_control_block, + err_t error); + + /** + * @brief callback that handles receiving a packet. + * + * On a received packet on an ACCEPTED state receive_callback calls the + * ServerSocket process_data, which calls the Packet process_data() if it is + * inscribed as an Order. + */ + static err_t receive_callback(void *arg, struct tcp_pcb *client_control_block, + struct pbuf *packet_buffer, err_t error); + static void error_callback(void *arg, err_t error); + + /** + * @brief callback called each 500ms to do housekeeping tasks + * + * The housekeeping tasks made now are basically checks to ensure no data + * remains unsent and that the ServerSocket is not left in a middle state + * (such as CLOSING) + */ + static err_t poll_callback(void *arg, struct tcp_pcb *client_control_block); + static err_t send_callback(void *arg, struct tcp_pcb *client_control_block, + u16_t len); + + static void config_keepalive(tcp_pcb *control_block, + ServerSocket *server_socket); +}; + +#endif // HAL_ETH_MODULE_ENABLED +#endif // STLIB_ETH diff --git a/Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.hpp b/Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.hpp new file mode 100644 index 00000000..e25d3f69 --- /dev/null +++ b/Inc/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.hpp @@ -0,0 +1,120 @@ +/* + * Socket.hpp + * + * Created on: 14 nov. 2022 + * Author: stefa + */ +#pragma once + +#include "HALAL/Models/Packets/Order.hpp" +#include "HALAL/Models/Packets/OrderProtocol.hpp" +#include "HALAL/Models/Packets/Packet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" +#ifdef HAL_ETH_MODULE_ENABLED + +#define PBUF_POOL_MEMORY_DESC_POSITION 8 + +class Socket : public OrderProtocol { +private: + tcp_pcb *connection_control_block; + tcp_pcb *socket_control_block; + queue tx_packet_buffer; + queue rx_packet_buffer; + void process_data(); + static err_t connect_callback(void *arg, struct tcp_pcb *client_control_block, + err_t error); + static err_t receive_callback(void *arg, struct tcp_pcb *client_control_block, + struct pbuf *packet_buffer, err_t error); + static err_t poll_callback(void *arg, struct tcp_pcb *client_control_block); + static err_t send_callback(void *arg, struct tcp_pcb *client_control_block, + uint16_t length); + static void error_callback(void *arg, err_t error); + + static err_t + connection_poll_callback(void *arg, struct tcp_pcb *connection_control_block); + static void connection_error_callback(void *arg, err_t error); + static void config_keepalive(tcp_pcb *control_block, Socket *socket); + +public: + enum SocketState { INACTIVE, CONNECTED, CLOSING }; + + IPV4 local_ip; + uint32_t local_port; + IPV4 remote_ip; + uint32_t remote_port; + + SocketState state; + + static unordered_map connecting_sockets; + bool pending_connection_reset = false; + bool use_keep_alives{true}; + struct KeepaliveConfig { + uint32_t inactivity_time_until_keepalive_ms = + TCP_INACTIVITY_TIME_UNTIL_KEEPALIVE_MS; + uint32_t space_between_tries_ms = TCP_SPACE_BETWEEN_KEEPALIVE_TRIES_MS; + uint32_t tries_until_disconnection = + TCP_KEEPALIVE_TRIES_UNTIL_DISCONNECTION; + } keepalive_config; + + Socket(); + Socket(Socket &&other); + Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, + uint32_t remote_port, bool use_keep_alives = true); + Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, + uint32_t remote_port, uint32_t inactivity_time_until_keepalive_ms, + uint32_t space_between_tries_ms, uint32_t tries_until_disconnection); + Socket(EthernetNode local_node, EthernetNode remote_node); + ~Socket(); + + void operator=(Socket &&other); + void close(); + + void reconnect(); + void reset(); + + /* + * @brief puts the order data into the tx_packet_buffer so it can be sent when + * a connection is accepted + * @return true if the data could be allocated in the buffer, false otherwise + */ + bool add_order_to_queue(Order &order); + + /* + * @brief puts the order data into the tx_packet_buffer and sends it + * @return true if the data was sent successfully, false otherwise + */ + + bool send_order(Order &order) override { + if (state != CONNECTED) { + reconnect(); + return false; + } + struct memp *next_memory_pointer_in_packet_buffer_pool = + (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; + if (next_memory_pointer_in_packet_buffer_pool == nullptr) { + if (socket_control_block->unsent != nullptr) { + tcp_output(socket_control_block); + } else { + memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], + next_memory_pointer_in_packet_buffer_pool); + } + return false; + } + + uint8_t *order_buffer = order.build(); + if (order.get_size() > tcp_sndbuf(socket_control_block)) { + return false; + } + + struct pbuf *packet = + pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); + pbuf_take(packet, order_buffer, order.get_size()); + tx_packet_buffer.push(packet); + send(); + return true; + } + void send(); + bool is_connected(); +}; +#endif diff --git a/Inc/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.hpp b/Inc/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.hpp new file mode 100644 index 00000000..af0c62bb --- /dev/null +++ b/Inc/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.hpp @@ -0,0 +1,46 @@ +#pragma once +#include "HALAL/Models/Packets/Packet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" + +#ifdef HAL_ETH_MODULE_ENABLED +#define PBUF_POOL_MEMORY_DESC_POSITION 8 + +class DatagramSocket { +public: + struct udp_pcb *udp_control_block; + + IPV4 local_ip; + uint32_t local_port; + IPV4 remote_ip; + uint32_t remote_port; + bool is_disconnected = true; + DatagramSocket(); + DatagramSocket(DatagramSocket &&other); + DatagramSocket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, + uint32_t remote_port); + DatagramSocket(EthernetNode local_node, EthernetNode remote_node); + ~DatagramSocket(); + + void operator=(DatagramSocket &&); + + void reconnect(); + + static void receive_callback(void *args, struct udp_pcb *udp_control_block, + struct pbuf *packet_buffer, + const ip_addr_t *remote_address, u16_t port); + bool send_packet(Packet &packet) { + uint8_t *packet_buffer = packet.build(); + + struct pbuf *tx_buffer = pbuf_alloc(PBUF_TRANSPORT, packet.size, PBUF_RAM); + pbuf_take(tx_buffer, packet_buffer, packet.size); + udp_send(udp_control_block, tx_buffer); + pbuf_free(tx_buffer); + + return true; + } + + void close(); +}; + +#endif diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index 492317f2..29d64d31 100644 --- a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -5,11 +5,14 @@ #include "C++Utilities/CppUtils.hpp" #ifdef STLIB_ETH +#include "DigitalOutput2.hpp" #include "HALAL/Models/MAC/MAC.hpp" -#include "HALAL/Services/Communication/Ethernet/EthernetHelper.hpp" -#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetHelper.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" +extern "C" { #include "ethernetif.h" #include "lwip.h" +} extern uint32_t EthernetLinkTimer; extern struct netif gnetif; @@ -31,6 +34,7 @@ struct EthernetDomain { const GPIODomain::Pin &TXD1; const GPIODomain::Pin &TX_EN; const GPIODomain::Pin &TXD0; + const GPIODomain::Pin &PHY_RST; }; constexpr static EthernetPins PINSET_H10{.MDC = PC1, @@ -41,7 +45,8 @@ struct EthernetDomain { .RXD1 = PC5, .TXD1 = PB13, .TX_EN = PG11, - .TXD0 = PG13}; + .TXD0 = PG13, + .PHY_RST = PG0}; constexpr static EthernetPins PINSET_H11{.MDC = PC1, .REF_CLK = PA1, .MDIO = PA2, @@ -50,13 +55,16 @@ struct EthernetDomain { .RXD1 = PC5, .TXD1 = PB13, .TX_EN = PB11, - .TXD0 = PB12}; + .TXD0 = PB12, + .PHY_RST = PF14}; struct Entry { const char *local_mac; const char *local_ip; const char *subnet_mask; const char *gateway; + + size_t phy_reset_id; }; struct Ethernet { @@ -65,14 +73,15 @@ struct EthernetDomain { EthernetPins pins; Entry e; - std::array gpios; + std::array rmii_gpios; + DigitalOutputDomain::DigitalOutput phy_reset; consteval Ethernet(EthernetPins pins, const char *local_mac, const char *local_ip, const char *subnet_mask = "255.255.0.0", const char *gateway = "192.168.1.1") : pins{pins}, e{local_mac, local_ip, subnet_mask, gateway}, - gpios{ + rmii_gpios{ GPIODomain::GPIO(pins.MDC, GPIODomain::OperationMode::ALT_PP, GPIODomain::Pull::None, GPIODomain::Speed::VeryHigh, @@ -81,8 +90,8 @@ struct EthernetDomain { GPIODomain::Pull::None, GPIODomain::Speed::VeryHigh, GPIODomain::AlternateFunction::AF11), - GPIODomain::GPIO(pins.MDIO, GPIODomain::OperationMode::ALT_PP, - GPIODomain::Pull::None, + GPIODomain::GPIO(pins.MDIO, GPIODomain::OperationMode::ALT_OD, + GPIODomain::Pull::Up, GPIODomain::Speed::VeryHigh, GPIODomain::AlternateFunction::AF11), GPIODomain::GPIO(pins.CRS_DV, GPIODomain::OperationMode::ALT_PP, @@ -108,15 +117,24 @@ struct EthernetDomain { GPIODomain::GPIO(pins.TXD0, GPIODomain::OperationMode::ALT_PP, GPIODomain::Pull::None, GPIODomain::Speed::VeryHigh, - GPIODomain::AlternateFunction::AF11), - } {} + GPIODomain::AlternateFunction::AF11)}, + phy_reset{pins.PHY_RST} {} template consteval std::size_t inscribe(Ctx &ctx) const { - for (const auto &gpio : gpios) { + for (const auto &gpio : rmii_gpios) { gpio.inscribe(ctx); } - return ctx.template add(e, this); + const auto phy_reset_id = phy_reset.inscribe(ctx); + Entry entry{ + .local_mac = this->e.local_mac, + .local_ip = this->e.local_ip, + .subnet_mask = this->e.subnet_mask, + .gateway = this->e.gateway, + .phy_reset_id = phy_reset_id, + }; + + return ctx.template add(entry, this); } }; @@ -127,6 +145,8 @@ struct EthernetDomain { const char *local_ip; const char *subnet_mask; const char *gateway; + + size_t phy_reset_id; }; template @@ -138,11 +158,11 @@ struct EthernetDomain { cfgs[i].local_ip = e.local_ip; cfgs[i].subnet_mask = e.subnet_mask; cfgs[i].gateway = e.gateway; + cfgs[i].phy_reset_id = e.phy_reset_id; } return cfgs; } - // Runtime object struct Instance { constexpr Instance() {} @@ -154,7 +174,7 @@ struct EthernetDomain { EthernetLinkTimer = HAL_GetTick(); ethernet_link_check_state(&gnetif); - if (gnetif.flags == 15) { + if (netif_is_link_up(&gnetif) && !netif_is_up(&gnetif)) { netif_set_up(&gnetif); } } @@ -164,17 +184,28 @@ struct EthernetDomain { template struct Init { static inline std::array instances{}; - static void init(std::span cfgs) { + static void init(std::span cfgs, + std::span do_instances) { for (std::size_t i = 0; i < N; ++i) { const EthernetDomain::Config &e = cfgs[i]; + /* --- RESET PHY (KSZ8041) --- */ + // RESET_N pin low then high + do_instances[e.phy_reset_id].turn_off(); // RESET_N = 0 + HAL_Delay(10); + do_instances[e.phy_reset_id].turn_on(); // RESET_N = 1 + HAL_Delay(10); + + /* --- CLOCKS ETH --- */ __HAL_RCC_ETH1MAC_CLK_ENABLE(); __HAL_RCC_ETH1TX_CLK_ENABLE(); __HAL_RCC_ETH1RX_CLK_ENABLE(); + /* --- NVIC --- */ HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); HAL_NVIC_EnableIRQ(ETH_IRQn); + /* --- IP / MAC --- */ MAC local_mac{e.local_mac}; IPV4 local_ip{e.local_ip}; IPV4 subnet_mask{e.subnet_mask}; @@ -183,24 +214,31 @@ struct EthernetDomain { ipaddr = local_ip.address; netmask = subnet_mask.address; gw = gateway.address; + IP_ADDRESS[0] = ipaddr.addr & 0xFF; IP_ADDRESS[1] = (ipaddr.addr >> 8) & 0xFF; IP_ADDRESS[2] = (ipaddr.addr >> 16) & 0xFF; IP_ADDRESS[3] = (ipaddr.addr >> 24) & 0xFF; + NETMASK_ADDRESS[0] = netmask.addr & 0xFF; NETMASK_ADDRESS[1] = (netmask.addr >> 8) & 0xFF; NETMASK_ADDRESS[2] = (netmask.addr >> 16) & 0xFF; NETMASK_ADDRESS[3] = (netmask.addr >> 24) & 0xFF; + GATEWAY_ADDRESS[0] = gw.addr & 0xFF; GATEWAY_ADDRESS[1] = (gw.addr >> 8) & 0xFF; GATEWAY_ADDRESS[2] = (gw.addr >> 16) & 0xFF; GATEWAY_ADDRESS[3] = (gw.addr >> 24) & 0xFF; + gnetif.hwaddr[0] = local_mac.address[0]; gnetif.hwaddr[1] = local_mac.address[1]; gnetif.hwaddr[2] = local_mac.address[2]; gnetif.hwaddr[3] = local_mac.address[3]; gnetif.hwaddr[4] = local_mac.address[4]; gnetif.hwaddr[5] = local_mac.address[5]; + gnetif.hwaddr_len = 6; + + /* --- LwIP / ETH init --- */ MX_LWIP_Init(); instances[i] = Instance{}; diff --git a/Inc/HALAL/Services/Communication/Ethernet/PHY/phy_driver.h b/Inc/HALAL/Services/Communication/Ethernet/PHY/phy_driver.h new file mode 100644 index 00000000..2d6c83ac --- /dev/null +++ b/Inc/HALAL/Services/Communication/Ethernet/PHY/phy_driver.h @@ -0,0 +1,17 @@ +#pragma once +#include + +typedef enum { + PHY_LINK_DOWN = 0, + PHY_10_HALF, + PHY_10_FULL, + PHY_100_HALF, + PHY_100_FULL +} phy_link_state_t; + +typedef struct { + void (*init)(void); + phy_link_state_t (*get_link_state)(void); +} phy_driver_t; + +extern const phy_driver_t *phy_driver; \ No newline at end of file diff --git a/Inc/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp b/Inc/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp deleted file mode 100644 index 19dd4acc..00000000 --- a/Inc/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp +++ /dev/null @@ -1,198 +0,0 @@ -/* - * ServerSocket.hpp - * - * Created on: 14 nov. 2022 - * Author: stefa - */ -#pragma once - -#ifdef STLIB_ETH - -#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" -#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" -#include "HALAL/Models/Packets/Packet.hpp" -#include "HALAL/Models/Packets/Order.hpp" -#include "HALAL/Models/Packets/OrderProtocol.hpp" -#ifdef HAL_ETH_MODULE_ENABLED - -#define PBUF_POOL_MEMORY_DESC_POSITION 8 - -/** -* @brief class that handles a single point to point server client connection, emulating the server side. -* -* The flow of this class goes as follows: -* -* 1. When the constructor is called, the listener is activated and starts working immediately -* -* 2. After a client issues a connection to the ServerSocket and Ethernet#update is executed, the ServerSocket accepts the request -* -* 3. Accepting the request raises an interrupt that calls accept_callback, which closes the listener socket (on server_control_block) and opens the connection socket (on client_control_block) -* -* 4. The connection goes on until one of the ends closes it, which calls the ErrorHandler to send the board into fault as a default behaviour. -* -* @see Ethernet#update -*/ -class ServerSocket : public OrderProtocol{ -public: - - enum ServerState{ - INACTIVE, - LISTENING, - ACCEPTED, - CLOSING, - CLOSED - }; - - static unordered_map listening_sockets; - IPV4 local_ip; - uint32_t local_port; - IPV4 remote_ip; - ServerState state; - static uint8_t priority; - - - struct KeepaliveConfig{ - uint32_t inactivity_time_until_keepalive_ms = TCP_INACTIVITY_TIME_UNTIL_KEEPALIVE_MS; - uint32_t space_between_tries_ms = TCP_SPACE_BETWEEN_KEEPALIVE_TRIES_MS; - uint32_t tries_until_disconnection = TCP_KEEPALIVE_TRIES_UNTIL_DISCONNECTION; - }keepalive_config; - - ServerSocket(); - - - ServerSocket(ServerSocket&& other); - - /** - * @brief ServerSocket constructor that receives the server ip on the net as a binary value. - * - * @param local_ip the server ip on. - * @param local_port the port number that the server listens for connections. - */ - ServerSocket(IPV4 local_ip, uint32_t local_port); - ServerSocket(IPV4 local_ip, uint32_t local_port, uint32_t inactivity_time_until_keepalive_ms, uint32_t space_between_tries_ms, uint32_t tries_until_disconnection); - /** - * @brief ServerSocket constructor that uses the EthernetNode class as a parameter - * - * @param local_node the EthernetNode to listen to - * - * @see EthernetNode - */ - ServerSocket(EthernetNode local_node); - ~ServerSocket(); - - void operator=(ServerSocket&& other); - - /** - * @brief ends the connection between the server and the client. - */ - void close(); - - - - /** - * @brief saves the order data into the tx_packet_buffer so it can be sent when a connection is accepted - * - * @param order the order to send, which contains the data and id of the message - * @return true if the data could be allocated in the buffer, false otherwise - */ - bool add_order_to_queue(Order& order); - /** - * @brief puts the order data into the tx_packet_buffer and sends all the data in the buffer to the client - * - * @param order the order to send, which contains the data and id of the message - * @return true if the data was sent successfully, false otherwise - */ - bool send_order(Order& order) override{ - if(state != ACCEPTED){ - return false; - } - struct memp* next_memory_pointer_in_packet_buffer_pool = (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; - if(next_memory_pointer_in_packet_buffer_pool == nullptr){ - if(client_control_block->unsent != nullptr){ - tcp_output(client_control_block); - }else{ - memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], next_memory_pointer_in_packet_buffer_pool); - } - return false; - } - - uint8_t* order_buffer = order.build(); - if(order.get_size() > tcp_sndbuf(client_control_block)){ - return false; - } - - struct pbuf* packet = pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); - pbuf_take(packet, order_buffer, order.get_size()); - tx_packet_buffer.push(packet); - send(); - return true; - } - - - /** - * @brief sends all the binary data saved in the tx_packet_buffer to the connected client. - * - * This function is the one that actually handles outgoing communication, sending one by one the packets in the tx_packet_buffer - * The messages in the buffer are all immediately sent after calling this function, unless an error of any kind happened, in which case ErrorHandler is raised - */ - void send(); - - /** - * @brief function that returns wether or not a client is connected to the ServerSocket - * - * This functions returns a comparison to the state of the ServerSocket, checking wether or not it is on the ACCEPTED state - * This function is equivalent to doing instance->state == ServerSocket#ACCEPT - * - * @return true if a connection with the client was established, false otherwise - */ - bool is_connected(); - -private: - struct tcp_pcb* server_control_block = nullptr; - queue tx_packet_buffer; - queue rx_packet_buffer; - struct tcp_pcb* client_control_block; - - /** - * @brief process the data received by the client orders. It is meant to be called only by Lwip on the receive_callback - * - * reads all the data received by the server in the ethernet buffer, packet by packet. - * Then, for each packet, it processes it depending on the order id (default behavior is not process) and removes it from the buffer. - * This makes so the receive_callback (and thus the Socket) can only process declared orders, and ignores all other packets. - */ - void process_data(); - /** - * @brief the callback for the listener socket receiving a request for connection into the ServerSocket. - * - * This function is called on an interrupt when a packet containing a connection request to the same port of the listener socket is received. - * accept_callback builds the pcb that acts as the connection socket and saves it in the client_control_block pointer - * It then closes the listener socket and makes the server_control_block point to nullptr. - * - * server_control_block shouldn't be accessed in any way while the ServerSocket is in the ServerSocket#ACCEPT state, as it will lead into a nullptr exception. - * This in an intended behavior as there shouldn't be more than one listener socket on the same port, and a ServerSocket shouldn't be able to handle more than one connection by design. - */ - static err_t accept_callback(void* arg, struct tcp_pcb* incomming_control_block, err_t error); - - /** - * @brief callback that handles receiving a packet. - * - * On a received packet on an ACCEPTED state receive_callback calls the ServerSocket process_data, - * which calls the Packet process_data() if it is inscribed as an Order. - */ - static err_t receive_callback(void* arg, struct tcp_pcb* client_control_block, struct pbuf* packet_buffer, err_t error); - static void error_callback(void *arg, err_t error); - - /** - * @brief callback called each 500ms to do housekeeping tasks - * - * The housekeeping tasks made now are basically checks to ensure no data remains unsent and that the ServerSocket is not left in a middle state (such as CLOSING) - */ - static err_t poll_callback(void *arg, struct tcp_pcb *client_control_block); - static err_t send_callback(void *arg, struct tcp_pcb *client_control_block, u16_t len); - - static void config_keepalive(tcp_pcb* control_block, ServerSocket* server_socket); - -}; - -#endif //HAL_ETH_MODULE_ENABLED -#endif //STLIB_ETH diff --git a/Inc/HALAL/Services/Communication/Ethernet/TCP/Socket.hpp b/Inc/HALAL/Services/Communication/Ethernet/TCP/Socket.hpp deleted file mode 100644 index 0f68a1f3..00000000 --- a/Inc/HALAL/Services/Communication/Ethernet/TCP/Socket.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Socket.hpp - * - * Created on: 14 nov. 2022 - * Author: stefa - */ -#pragma once - -#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" -#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" -#include "HALAL/Models/Packets/Packet.hpp" -#include "HALAL/Models/Packets/Order.hpp" -#include "HALAL/Models/Packets/OrderProtocol.hpp" -#include "HALAL/Models/Packets/Packet.hpp" -#ifdef HAL_ETH_MODULE_ENABLED - -#define PBUF_POOL_MEMORY_DESC_POSITION 8 - -class Socket : public OrderProtocol{ -private: - tcp_pcb* connection_control_block; - tcp_pcb* socket_control_block; - queue tx_packet_buffer; - queue rx_packet_buffer; - void process_data(); - static err_t connect_callback(void* arg, struct tcp_pcb* client_control_block, err_t error); - static err_t receive_callback(void* arg, struct tcp_pcb* client_control_block, struct pbuf* packet_buffer, err_t error); - static err_t poll_callback(void* arg, struct tcp_pcb* client_control_block); - static err_t send_callback(void* arg, struct tcp_pcb* client_control_block, uint16_t length); - static void error_callback(void *arg, err_t error); - - static err_t connection_poll_callback(void* arg, struct tcp_pcb* connection_control_block); - static void connection_error_callback(void *arg, err_t error); - static void config_keepalive(tcp_pcb* control_block, Socket* socket); -public: - enum SocketState{ - INACTIVE, - CONNECTED, - CLOSING - }; - - IPV4 local_ip; - uint32_t local_port; - IPV4 remote_ip; - uint32_t remote_port; - - SocketState state; - - static unordered_map connecting_sockets; - bool pending_connection_reset = false; - bool use_keep_alives{true}; - struct KeepaliveConfig{ - uint32_t inactivity_time_until_keepalive_ms = TCP_INACTIVITY_TIME_UNTIL_KEEPALIVE_MS; - uint32_t space_between_tries_ms = TCP_SPACE_BETWEEN_KEEPALIVE_TRIES_MS; - uint32_t tries_until_disconnection = TCP_KEEPALIVE_TRIES_UNTIL_DISCONNECTION; - }keepalive_config; - - Socket(); - Socket(Socket&& other); - Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, uint32_t remote_port,bool use_keep_alives = true); - Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, uint32_t remote_port, uint32_t inactivity_time_until_keepalive_ms, uint32_t space_between_tries_ms, uint32_t tries_until_disconnection); - Socket(EthernetNode local_node, EthernetNode remote_node); - ~Socket(); - - void operator=(Socket&& other); - void close(); - - void reconnect(); - void reset(); - - /* - * @brief puts the order data into the tx_packet_buffer so it can be sent when a connection is accepted - * @return true if the data could be allocated in the buffer, false otherwise - */ - bool add_order_to_queue(Order& order); - - /* - * @brief puts the order data into the tx_packet_buffer and sends it - * @return true if the data was sent successfully, false otherwise - */ - - bool send_order(Order& order) override{ - if(state != CONNECTED){ - reconnect(); - return false; - } - struct memp* next_memory_pointer_in_packet_buffer_pool = (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; - if(next_memory_pointer_in_packet_buffer_pool == nullptr){ - if(socket_control_block->unsent != nullptr){ - tcp_output(socket_control_block); - }else{ - memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], next_memory_pointer_in_packet_buffer_pool); - } - return false; - } - - uint8_t* order_buffer = order.build(); - if(order.get_size() > tcp_sndbuf(socket_control_block)){ - return false; - } - - struct pbuf* packet = pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); - pbuf_take(packet, order_buffer, order.get_size()); - tx_packet_buffer.push(packet); - send(); - return true; - } - void send(); - bool is_connected(); -}; -#endif diff --git a/Inc/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp b/Inc/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp deleted file mode 100644 index 4909427b..00000000 --- a/Inc/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once -#include "HALAL/Models/Packets/Packet.hpp" -#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" -#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" - -#ifdef HAL_ETH_MODULE_ENABLED -#define PBUF_POOL_MEMORY_DESC_POSITION 8 - -class DatagramSocket { - public: - struct udp_pcb* udp_control_block; - - IPV4 local_ip; - uint32_t local_port; - IPV4 remote_ip; - uint32_t remote_port; - bool is_disconnected = true; - DatagramSocket(); - DatagramSocket(DatagramSocket&& other); - DatagramSocket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, - uint32_t remote_port); - DatagramSocket(EthernetNode local_node, EthernetNode remote_node); - ~DatagramSocket(); - - void operator=(DatagramSocket&&); - - void reconnect(); - - - static void receive_callback(void* args, struct udp_pcb* udp_control_block, - struct pbuf* packet_buffer, - const ip_addr_t* remote_address, u16_t port); - bool send_packet(Packet& packet) { - uint8_t* packet_buffer = packet.build(); - - struct pbuf* tx_buffer = - pbuf_alloc(PBUF_TRANSPORT, packet.size, PBUF_RAM); - pbuf_take(tx_buffer, packet_buffer, packet.size); - udp_send(udp_control_block, tx_buffer); - pbuf_free(tx_buffer); - - return true; - } - - void close(); -}; - -#endif diff --git a/Inc/ST-LIB.hpp b/Inc/ST-LIB.hpp index 11d8c96b..727abe9f 100644 --- a/Inc/ST-LIB.hpp +++ b/Inc/ST-LIB.hpp @@ -157,6 +157,13 @@ template struct Board { constexpr std::size_t ethN = domain_size(); // ... +#ifdef HAL_IWDG_MODULE_ENABLED + Watchdog::check_reset_flag(); +#endif + HAL_Init(); + HALconfig::system_clock(); + HALconfig::peripheral_clock(); + MPUDomain::Init::init(); GPIODomain::Init::init(cfg.gpio_cfgs); TimerDomain::Init::init(cfg.tim_cfgs); @@ -169,7 +176,8 @@ template struct Board { SdDomain::Init::init(cfg.sd_cfgs, MPUDomain::Init::instances, DigitalInputDomain::Init::instances); - EthernetDomain::Init::init(cfg.eth_cfgs); + EthernetDomain::Init::init( + cfg.eth_cfgs, DigitalOutputDomain::Init::instances); // ... } diff --git a/LWIP/App/lwip.c b/LWIP/App/lwip.c index f720f7e2..d807bdc6 100644 --- a/LWIP/App/lwip.c +++ b/LWIP/App/lwip.c @@ -1,28 +1,28 @@ /* USER CODE BEGIN Header */ /** ****************************************************************************** - * File Name : LWIP.c - * Description : This file provides initialization code for LWIP - * middleWare. - ****************************************************************************** - * @attention - * - * Copyright (c) 2023 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + * File Name : LWIP.c + * Description : This file provides initialization code for LWIP + * middleWare. + ****************************************************************************** + * @attention + * + * Copyright (c) 2023 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "lwip.h" #include "lwip/init.h" #include "lwip/netif.h" -#if defined ( __CC_ARM ) /* MDK ARM Compiler */ +#if defined(__CC_ARM) /* MDK ARM Compiler */ #include "lwip/sio.h" #endif /* MDK ARM Compiler */ #include "ethernetif.h" @@ -55,48 +55,46 @@ uint8_t GATEWAY_ADDRESS[4]; /* USER CODE END 2 */ /** - * LwIP initialization function - */ -void MX_LWIP_Init(void) -{ -/* USER CODE BEGIN IP_ADDRESSES */ -/* USER CODE END IP_ADDRESSES */ + * LwIP initialization function + */ +void MX_LWIP_Init(void) { + /* USER CODE BEGIN IP_ADDRESSES */ + /* USER CODE END IP_ADDRESSES */ /* Initilialize the LwIP stack without RTOS */ lwip_init(); /* IP addresses initialization without DHCP (IPv4) */ IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]); - IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]); - IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]); + IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1], NETMASK_ADDRESS[2], + NETMASK_ADDRESS[3]); + IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], + GATEWAY_ADDRESS[3]); /* add the network interface (IPv4/IPv6) without RTOS */ - netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); + netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, + ðernet_input); /* Registers the default network interface */ netif_set_default(&gnetif); - if (netif_is_link_up(&gnetif)) - { + if (netif_is_link_up(&gnetif)) { /* When the netif is fully configured this function must be called */ netif_set_up(&gnetif); - } - else - { + } else { /* When the netif link is down this function must be called */ netif_set_down(&gnetif); } - /* Set the link callback function, this function is called on change of link status*/ + /* Set the link callback function, this function is called on change of link + * status*/ netif_set_link_callback(&gnetif, ethernet_link_status_updated); /* Create the Ethernet link handler thread */ -/* USER CODE BEGIN 3 */ - if(!netif_is_link_up(&gnetif)){ - HAL_NVIC_SystemReset(); - } -/* USER CODE END 3 */ + /* USER CODE BEGIN 3 */ + + /* USER CODE END 3 */ } #ifdef USE_OBSOLETE_USER_CODE_SECTION_4 @@ -107,23 +105,21 @@ void MX_LWIP_Init(void) #endif /** - * @brief Ethernet Link periodic check - * @param netif - * @retval None - */ -static void Ethernet_Link_Periodic_Handle(struct netif *netif) -{ -/* USER CODE BEGIN 4_4_1 */ -/* USER CODE END 4_4_1 */ + * @brief Ethernet Link periodic check + * @param netif + * @retval None + */ +static void Ethernet_Link_Periodic_Handle(struct netif *netif) { + /* USER CODE BEGIN 4_4_1 */ + /* USER CODE END 4_4_1 */ /* Ethernet Link every 100ms */ - if (HAL_GetTick() - EthernetLinkTimer >= 100) - { + if (HAL_GetTick() - EthernetLinkTimer >= 100) { EthernetLinkTimer = HAL_GetTick(); ethernet_link_check_state(netif); } -/* USER CODE BEGIN 4_4 */ -/* USER CODE END 4_4 */ + /* USER CODE BEGIN 4_4 */ + /* USER CODE END 4_4 */ } /** @@ -137,59 +133,54 @@ static void Ethernet_Link_Periodic_Handle(struct netif *netif) * Handle timeouts if LWIP_TIMERS is set and without RTOS * Handle the llink status if LWIP_NETIF_LINK_CALLBACK is set and without RTOS */ -void MX_LWIP_Process(void) -{ -/* USER CODE BEGIN 4_1 */ -/* USER CODE END 4_1 */ +void MX_LWIP_Process(void) { + /* USER CODE BEGIN 4_1 */ + /* USER CODE END 4_1 */ ethernetif_input(&gnetif); -/* USER CODE BEGIN 4_2 */ -/* USER CODE END 4_2 */ + /* USER CODE BEGIN 4_2 */ + /* USER CODE END 4_2 */ /* Handle timeouts */ sys_check_timeouts(); Ethernet_Link_Periodic_Handle(&gnetif); -/* USER CODE BEGIN 4_3 */ - if(gnetif.flags == 15){ - netif_set_up(&gnetif); + /* USER CODE BEGIN 4_3 */ + if (gnetif.flags == 15) { + netif_set_up(&gnetif); } -/* USER CODE END 4_3 */ + /* USER CODE END 4_3 */ } /** - * @brief Notify the User about the network interface config status - * @param netif: the network interface - * @retval None - */ -static void ethernet_link_status_updated(struct netif *netif) -{ - if (netif_is_up(netif)) - { -/* USER CODE BEGIN 5 */ -/* USER CODE END 5 */ - } - else /* netif is down */ + * @brief Notify the User about the network interface config status + * @param netif: the network interface + * @retval None + */ +static void ethernet_link_status_updated(struct netif *netif) { + if (netif_is_up(netif)) { + /* USER CODE BEGIN 5 */ + /* USER CODE END 5 */ + } else /* netif is down */ { -/* USER CODE BEGIN 6 */ -/* USER CODE END 6 */ + /* USER CODE BEGIN 6 */ + /* USER CODE END 6 */ } } -#if defined ( __CC_ARM ) /* MDK ARM Compiler */ +#if defined(__CC_ARM) /* MDK ARM Compiler */ /** * Opens a serial device for communication. * * @param devnum device number * @return handle to serial device if successful, NULL otherwise */ -sio_fd_t sio_open(u8_t devnum) -{ +sio_fd_t sio_open(u8_t devnum) { sio_fd_t sd; -/* USER CODE BEGIN 7 */ + /* USER CODE BEGIN 7 */ sd = 0; // dummy code -/* USER CODE END 7 */ + /* USER CODE END 7 */ return sd; } @@ -202,10 +193,9 @@ sio_fd_t sio_open(u8_t devnum) * * @note This function will block until the character can be sent. */ -void sio_send(u8_t c, sio_fd_t fd) -{ -/* USER CODE BEGIN 8 */ -/* USER CODE END 8 */ +void sio_send(u8_t c, sio_fd_t fd) { + /* USER CODE BEGIN 8 */ + /* USER CODE END 8 */ } /** @@ -214,18 +204,18 @@ void sio_send(u8_t c, sio_fd_t fd) * @param fd serial device handle * @param data pointer to data buffer for receiving * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - may be 0 if aborted by sio_read_abort + * @return number of bytes actually received - may be 0 if aborted by + * sio_read_abort * * @note This function will block until data can be received. The blocking * can be cancelled by calling sio_read_abort(). */ -u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len) -{ +u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len) { u32_t recved_bytes; -/* USER CODE BEGIN 9 */ + /* USER CODE BEGIN 9 */ recved_bytes = 0; // dummy code -/* USER CODE END 9 */ + /* USER CODE END 9 */ return recved_bytes; } @@ -238,14 +228,12 @@ u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len) * @param len maximum length (in bytes) of data to receive * @return number of bytes actually received */ -u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len) -{ +u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len) { u32_t recved_bytes; -/* USER CODE BEGIN 10 */ + /* USER CODE BEGIN 10 */ recved_bytes = 0; // dummy code -/* USER CODE END 10 */ + /* USER CODE END 10 */ return recved_bytes; } #endif /* MDK ARM Compiler */ - diff --git a/LWIP/Target/ethernetif.c b/LWIP/Target/ethernetif.c index 8c86585c..b8670841 100644 --- a/LWIP/Target/ethernetif.c +++ b/LWIP/Target/ethernetif.c @@ -1,292 +1,113 @@ /* USER CODE BEGIN Header */ /** - ****************************************************************************** - * File Name : ethernetif.c - * Description : This file provides code for the configuration - * of the ethernetif.c MiddleWare. - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ + ****************************************************************************** + * File Name : ethernetif.c + * Description : Ethernet interface glue code (PHY-agnostic) + ****************************************************************************** + */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ -#include "main.h" -#include "lwip/opt.h" +#include "ethernetif.h" +#include "HALAL/Services/Communication/Ethernet/PHY/phy_driver.h" +#include "lwip/ethip6.h" #include "lwip/mem.h" #include "lwip/memp.h" +#include "lwip/opt.h" #include "lwip/timeouts.h" -#include "netif/ethernet.h" +#include "main.h" #include "netif/etharp.h" -#include "lwip/ethip6.h" -#include "ethernetif.h" -#include "lan8742.h" +#include "netif/ethernet.h" #include -/* Within 'USER CODE' section, code will be kept by default at each generation */ -/* USER CODE BEGIN 0 */ - -/* USER CODE END 0 */ - -/* Private define ------------------------------------------------------------*/ - /* Network interface name */ #define IFNAME0 's' #define IFNAME1 't' -/* ETH Setting */ -#define ETH_DMA_TRANSMIT_TIMEOUT ( 20U ) -#define ETH_TX_BUFFER_MAX ((ETH_TX_DESC_CNT) * 2U) -/* ETH_RX_BUFFER_SIZE parameter is defined in lwipopts.h */ - -/* USER CODE BEGIN 1 */ -uint64_t last_tick; -/* USER CODE END 1 */ - -/* Private variables ---------------------------------------------------------*/ -/* -@Note: This interface is implemented to operate in zero-copy mode only: - - Rx buffers are allocated statically and passed directly to the LwIP stack - they will return back to ETH DMA after been processed by the stack. - - Tx Buffers will be allocated from LwIP stack memory heap, - then passed to ETH HAL driver. - -@Notes: - 1.a. ETH DMA Rx descriptors must be contiguous, the default count is 4, - to customize it please redefine ETH_RX_DESC_CNT in ETH GUI (Rx Descriptor Length) - so that updated value will be generated in stm32xxxx_hal_conf.h - 1.b. ETH DMA Tx descriptors must be contiguous, the default count is 4, - to customize it please redefine ETH_TX_DESC_CNT in ETH GUI (Tx Descriptor Length) - so that updated value will be generated in stm32xxxx_hal_conf.h - - 2.a. Rx Buffers number must be between ETH_RX_DESC_CNT and 2*ETH_RX_DESC_CNT - 2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must - passed to ETH DMA in the init field (heth.Init.RxBuffLen) - 2.c The RX Ruffers addresses and sizes must be properly defined to be aligned - to L1-CACHE line size (32 bytes). -*/ - -/* Data Type Definitions */ -typedef enum -{ - RX_ALLOC_OK = 0x00, - RX_ALLOC_ERROR = 0x01 -} RxAllocStatusTypeDef; - -typedef struct -{ +#define ETH_DMA_TRANSMIT_TIMEOUT (20U) + +/* RX zero-copy structures */ +typedef enum { RX_ALLOC_OK = 0, RX_ALLOC_ERROR } RxAllocStatusTypeDef; + +typedef struct { struct pbuf_custom pbuf_custom; uint8_t buff[(ETH_RX_BUFFER_SIZE + 31) & ~31] __ALIGNED(32); } RxBuff_t; -/* Memory Pool Declaration */ -#define ETH_RX_BUFFER_CNT 12U -LWIP_MEMPOOL_DECLARE(RX_POOL, ETH_RX_BUFFER_CNT, sizeof(RxBuff_t), "Zero-copy RX PBUF pool"); +#define ETH_RX_BUFFER_CNT 12U +LWIP_MEMPOOL_DECLARE(RX_POOL, ETH_RX_BUFFER_CNT, sizeof(RxBuff_t), "RX_POOL"); -/* Variable Definitions */ static uint8_t RxAllocStatus; -#if defined ( __ICCARM__ ) /*!< IAR Compiler */ - -#pragma location=0x30000000 -ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ -#pragma location=0x30000100 -ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ - -#elif defined ( __CC_ARM ) /* MDK ARM Compiler */ - -__attribute__((at(0x30000000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ -__attribute__((at(0x30000100))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ - -#elif defined ( __GNUC__ ) /* GNU Compiler */ - -ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */ -ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */ - +/* DMA descriptors (D1 / AXI SRAM) */ +#if defined(__GNUC__) +ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] + __attribute__((section(".RxDecripSection"))); +ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] + __attribute__((section(".TxDecripSection"))); #endif -/* USER CODE BEGIN 2 */ -#if defined ( __ICCARM__ ) /*!< IAR Compiler */ -#pragma location = 0x30000200 -extern u8_t memp_memory_RX_POOL_base[]; - -#elif defined ( __CC_ARM ) /* MDK ARM Compiler */ -__attribute__((at(0x30000200)) extern u8_t memp_memory_RX_POOL_base[]; - -#elif defined ( __GNUC__ ) /* GNU Compiler */ -__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[]; - +#if defined(__GNUC__) +__attribute__(( + section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[]; #endif -/* USER CODE END 2 */ -/* Global Ethernet handle */ ETH_HandleTypeDef heth; ETH_TxPacketConfig TxConfig; -/* Private function prototypes -----------------------------------------------*/ -int32_t ETH_PHY_IO_Init(void); -int32_t ETH_PHY_IO_DeInit (void); -int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal); -int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal); -int32_t ETH_PHY_IO_GetTick(void); - -lan8742_Object_t LAN8742; -lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init, - ETH_PHY_IO_DeInit, - ETH_PHY_IO_WriteReg, - ETH_PHY_IO_ReadReg, - ETH_PHY_IO_GetTick}; - -/* USER CODE BEGIN 3 */ - -/* USER CODE END 3 */ - -/* Private functions ---------------------------------------------------------*/ +/* Private prototypes */ void pbuf_free_custom(struct pbuf *p); -/* USER CODE BEGIN 4 */ - -/* USER CODE END 4 */ - /******************************************************************************* - LL Driver Interface ( LwIP stack --> ETH) -*******************************************************************************/ -/** - * @brief In this function, the hardware should be initialized. - * Called from ethernetif_init(). - * - * @param netif the already initialized lwip network interface structure - * for this ethernetif - */ -static void low_level_init(struct netif *netif) -{ - HAL_StatusTypeDef hal_eth_init_status = HAL_OK; - /* Start ETH HAL Init */ - + * LOW LEVEL INIT + ******************************************************************************/ +static void low_level_init(struct netif *netif) { heth.Instance = ETH; heth.Init.MACAddr = &netif->hwaddr[0]; heth.Init.MediaInterface = HAL_ETH_RMII_MODE; heth.Init.TxDesc = DMATxDscrTab; heth.Init.RxDesc = DMARxDscrTab; - heth.Init.RxBuffLen = 1536; - - /* USER CODE BEGIN MACADDRESS */ + heth.Init.RxBuffLen = ETH_RX_BUFFER_SIZE; - /* USER CODE END MACADDRESS */ - - hal_eth_init_status = HAL_ETH_Init(&heth); + if (HAL_ETH_Init(&heth) != HAL_OK) { + Error_Handler(); + } - memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig)); - TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD; + memset(&TxConfig, 0, sizeof(TxConfig)); + TxConfig.Attributes = + ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD; TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC; TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT; - /* End ETH HAL Init */ - - /* Initialize the RX POOL */ LWIP_MEMPOOL_INIT(RX_POOL); #if LWIP_ARP || LWIP_ETHERNET - - /* set MAC hardware address length */ netif->hwaddr_len = ETH_HWADDR_LEN; - - /* set MAC hardware address */ - netif->hwaddr[0] = heth.Init.MACAddr[0]; - netif->hwaddr[1] = heth.Init.MACAddr[1]; - netif->hwaddr[2] = heth.Init.MACAddr[2]; - netif->hwaddr[3] = heth.Init.MACAddr[3]; - netif->hwaddr[4] = heth.Init.MACAddr[4]; - netif->hwaddr[5] = heth.Init.MACAddr[5]; - - /* maximum transfer unit */ + memcpy(netif->hwaddr, heth.Init.MACAddr, ETH_HWADDR_LEN); netif->mtu = ETH_MAX_PAYLOAD; + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; +#endif - /* Accept broadcast address and ARP traffic */ - /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ - #if LWIP_ARP - netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; - #else - netif->flags |= NETIF_FLAG_BROADCAST; - #endif /* LWIP_ARP */ - -/* USER CODE BEGIN PHY_PRE_CONFIG */ - -/* USER CODE END PHY_PRE_CONFIG */ - /* Set PHY IO functions */ - LAN8742_RegisterBusIO(&LAN8742, &LAN8742_IOCtx); - - /* Initialize the LAN8742 ETH PHY */ - LAN8742_Init(&LAN8742); - - if (hal_eth_init_status == HAL_OK) - { - /* Get link state */ - ethernet_link_check_state(netif); + if (phy_driver && phy_driver->init) { + phy_driver->init(); } - else - { - HAL_NVIC_SystemReset(); - Error_Handler(); - } -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -/* USER CODE BEGIN LOW_LEVEL_INIT */ - -/* USER CODE END LOW_LEVEL_INIT */ } -/** - * @brief This function should do the actual transmission of the packet. The packet is - * contained in the pbuf that is passed to the function. This pbuf - * might be chained. - * - * @param netif the lwip network interface structure for this ethernetif - * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) - * @return ERR_OK if the packet could be sent - * an err_t value if the packet couldn't be sent - * - * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to - * strange results. You might consider waiting for space in the DMA queue - * to become available since the stack doesn't retry to send a packet - * dropped because of memory failure (except for the TCP timers). - */ - -static err_t low_level_output(struct netif *netif, struct pbuf *p) -{ - uint32_t i = 0U; - struct pbuf *q = NULL; - err_t errval = ERR_OK; +/******************************************************************************* + * TX + ******************************************************************************/ +static err_t low_level_output(struct netif *netif, struct pbuf *p) { ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT]; + struct pbuf *q; + uint32_t i = 0; - memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef)); - - for(q = p; q != NULL; q = q->next) - { - if(i >= ETH_TX_DESC_CNT) - return ERR_IF; + memset(Txbuffer, 0, sizeof(Txbuffer)); + for (q = p; q != NULL; q = q->next) { Txbuffer[i].buffer = q->payload; Txbuffer[i].len = q->len; - - if(i>0) - { - Txbuffer[i-1].next = &Txbuffer[i]; - } - - if(q->next == NULL) - { - Txbuffer[i].next = NULL; - } - + if (i > 0) + Txbuffer[i - 1].next = &Txbuffer[i]; i++; } @@ -295,491 +116,146 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) TxConfig.pData = p; HAL_ETH_Transmit(&heth, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT); - - return errval; + return ERR_OK; } -/** - * @brief Should allocate a pbuf and transfer the bytes of the incoming - * packet from the interface into the pbuf. - * - * @param netif the lwip network interface structure for this ethernetif - * @return a pbuf filled with the received packet (including MAC header) - * NULL on memory error - */ -static struct pbuf * low_level_input(struct netif *netif) -{ +/******************************************************************************* + * RX + ******************************************************************************/ +static struct pbuf *low_level_input(struct netif *netif) { struct pbuf *p = NULL; - if(RxAllocStatus == RX_ALLOC_OK) - { + if (RxAllocStatus == RX_ALLOC_OK) { HAL_ETH_ReadData(&heth, (void **)&p); } return p; } -/** - * @brief This function should be called when a packet is ready to be read - * from the interface. It uses the function low_level_input() that - * should handle the actual reception of bytes from the network - * interface. Then the type of the received packet is determined and - * the appropriate input function is called. - * - * @param netif the lwip network interface structure for this ethernetif - */ -void ethernetif_input(struct netif *netif) -{ +void ethernetif_input(struct netif *netif) { struct pbuf *p = NULL; - do - { - p = low_level_input( netif ); - if (p != NULL) - { - if (netif->input( p, netif) != ERR_OK ) - { + do { + p = low_level_input(netif); + if (p != NULL) { + if (netif->input(p, netif) != ERR_OK) { pbuf_free_custom(p); } } - } while(p!=NULL); + } while (p != NULL); } -#if !LWIP_ARP -/** - * This function has to be completed by user in case of ARP OFF. - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if ... - */ -static err_t low_level_output_arp_off(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) -{ - err_t errval; - errval = ERR_OK; - -/* USER CODE BEGIN 5 */ - -/* USER CODE END 5 */ - - return errval; - -} -#endif /* LWIP_ARP */ - -/** - * @brief Should be called at the beginning of the program to set up the - * network interface. It calls the function low_level_init() to do the - * actual setup of the hardware. - * - * This function should be passed as a parameter to netif_add(). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - */ -err_t ethernetif_init(struct netif *netif) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - -#if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; -#endif /* LWIP_NETIF_HOSTNAME */ - - /* - * Initialize the snmp variables and counters inside the struct netif. - * The last argument should be replaced with your link speed, in units - * of bits per second. - */ - // MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); - +/******************************************************************************* + * NETIF INIT + ******************************************************************************/ +err_t ethernetif_init(struct netif *netif) { netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; - /* We directly use etharp_output() here to save a function call. - * You can instead declare your own function an call etharp_output() - * from it if you have to do some checks before sending (e.g. if link - * is available...) */ - #if LWIP_IPV4 -#if LWIP_ARP || LWIP_ETHERNET -#if LWIP_ARP netif->output = etharp_output; -#else - /* The user should write its own code in low_level_output_arp_off function */ - netif->output = low_level_output_arp_off; -#endif /* LWIP_ARP */ -#endif /* LWIP_ARP || LWIP_ETHERNET */ -#endif /* LWIP_IPV4 */ - +#endif #if LWIP_IPV6 netif->output_ip6 = ethip6_output; -#endif /* LWIP_IPV6 */ - +#endif netif->linkoutput = low_level_output; - - /* initialize the hardware */ low_level_init(netif); - return ERR_OK; } -/** - * @brief Custom Rx pbuf free callback - * @param pbuf: pbuf to be freed - * @retval None - */ -void pbuf_free_custom(struct pbuf *p) -{ - struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p; - LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf); - - /* If the Rx Buffer Pool was exhausted, signal the ethernetif_input task to - * call HAL_ETH_GetRxDataBuffer to rebuild the Rx descriptors. */ - - if (RxAllocStatus == RX_ALLOC_ERROR) - { - RxAllocStatus = RX_ALLOC_OK; - } -} - -/* USER CODE BEGIN 6 */ - -/** -* @brief Returns the current time in milliseconds -* when LWIP_TIMERS == 1 and NO_SYS == 1 -* @param None -* @retval Current Time value -*/ -u32_t sys_now(void) -{ - return HAL_GetTick(); -} - -/* USER CODE END 6 */ - -/** - * @brief Initializes the ETH MSP. - * @param ethHandle: ETH handle - * @retval None - */ - -void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle) -{ - // This section has been commented out to avoid re-initialization of GPIOs and NVIC - // that are already configured in the HALAL/Services/Communication/Ethernet/NewEthernet.hpp module. - - // GPIO_InitTypeDef GPIO_InitStruct = {0}; - // if(ethHandle->Instance==ETH) - // { - // /* USER CODE BEGIN ETH_MspInit 0 */ - - // /* USER CODE END ETH_MspInit 0 */ - // /* Enable Peripheral clock */ - // __HAL_RCC_ETH1MAC_CLK_ENABLE(); - // __HAL_RCC_ETH1TX_CLK_ENABLE(); - // __HAL_RCC_ETH1RX_CLK_ENABLE(); - - // __HAL_RCC_GPIOC_CLK_ENABLE(); - // __HAL_RCC_GPIOA_CLK_ENABLE(); - // __HAL_RCC_GPIOB_CLK_ENABLE(); - // __HAL_RCC_GPIOG_CLK_ENABLE(); - // /**ETH GPIO Configuration - // PC1 ------> ETH_MDC - // PA1 ------> ETH_REF_CLK - // PA2 ------> ETH_MDIO - // PA7 ------> ETH_CRS_DV - // PC4 ------> ETH_RXD0 - // PC5 ------> ETH_RXD1 - // PB13 ------> ETH_TXD1 - // PG11 ------> ETH_TX_EN - // PG13 ------> ETH_TXD0 - // */ - // GPIO_InitStruct.Pin = RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin; - // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - // GPIO_InitStruct.Pull = GPIO_NOPULL; - // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - // HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); - - // GPIO_InitStruct.Pin = RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin; - // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - // GPIO_InitStruct.Pull = GPIO_NOPULL; - // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - // HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - // GPIO_InitStruct.Pin = RMII_TXD1_Pin; - // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - // GPIO_InitStruct.Pull = GPIO_NOPULL; - // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - // HAL_GPIO_Init(RMII_TXD1_GPIO_Port, &GPIO_InitStruct); - - // GPIO_InitStruct.Pin = RMII_TX_EN_Pin|RMII_TXD0_Pin; - // GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - // GPIO_InitStruct.Pull = GPIO_NOPULL; - // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - // GPIO_InitStruct.Alternate = GPIO_AF11_ETH; - // HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); - - // /* Peripheral interrupt init */ - // HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); - // HAL_NVIC_EnableIRQ(ETH_IRQn); - // /* USER CODE BEGIN ETH_MspInit 1 */ - - // /* USER CODE END ETH_MspInit 1 */ - // } -} - -void HAL_ETH_MspDeInit(ETH_HandleTypeDef* ethHandle) -{ - if(ethHandle->Instance==ETH) - { - /* USER CODE BEGIN ETH_MspDeInit 0 */ - - /* USER CODE END ETH_MspDeInit 0 */ - /* Disable Peripheral clock */ - __HAL_RCC_ETH1MAC_CLK_DISABLE(); - __HAL_RCC_ETH1TX_CLK_DISABLE(); - __HAL_RCC_ETH1RX_CLK_DISABLE(); - - /**ETH GPIO Configuration - PC1 ------> ETH_MDC - PA1 ------> ETH_REF_CLK - PA2 ------> ETH_MDIO - PA7 ------> ETH_CRS_DV - PC4 ------> ETH_RXD0 - PC5 ------> ETH_RXD1 - PB13 ------> ETH_TXD1 - PG11 ------> ETH_TX_EN - PG13 ------> ETH_TXD0 - */ - HAL_GPIO_DeInit(GPIOC, RMII_MDC_Pin|RMII_RXD0_Pin|RMII_RXD1_Pin); - - HAL_GPIO_DeInit(GPIOA, RMII_REF_CLK_Pin|RMII_MDIO_Pin|RMII_CRS_DV_Pin); - - HAL_GPIO_DeInit(RMII_TXD1_GPIO_Port, RMII_TXD1_Pin); - - HAL_GPIO_DeInit(GPIOG, RMII_TX_EN_Pin|RMII_TXD0_Pin); - - /* Peripheral interrupt Deinit*/ - HAL_NVIC_DisableIRQ(ETH_IRQn); - - /* USER CODE BEGIN ETH_MspDeInit 1 */ - - /* USER CODE END ETH_MspDeInit 1 */ - } -} - /******************************************************************************* - PHI IO Functions -*******************************************************************************/ -/** - * @brief Initializes the MDIO interface GPIO and clocks. - * @param None - * @retval 0 if OK, -1 if ERROR - */ -int32_t ETH_PHY_IO_Init(void) -{ - /* We assume that MDIO GPIO configuration is already done - in the ETH_MspInit() else it should be done here - */ - - /* Configure the MDIO Clock */ - HAL_ETH_SetMDIOClockRange(&heth); - - return 0; -} - -/** - * @brief De-Initializes the MDIO interface . - * @param None - * @retval 0 if OK, -1 if ERROR - */ -int32_t ETH_PHY_IO_DeInit (void) -{ - return 0; -} - -/** - * @brief Read a PHY register through the MDIO interface. - * @param DevAddr: PHY port address - * @param RegAddr: PHY register address - * @param pRegVal: pointer to hold the register value - * @retval 0 if OK -1 if Error - */ -int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal) -{ - if(HAL_ETH_ReadPHYRegister(&heth, DevAddr, RegAddr, pRegVal) != HAL_OK) - { - HAL_NVIC_SystemReset(); - return -1; - } - - return 0; -} - -/** - * @brief Write a value to a PHY register through the MDIO interface. - * @param DevAddr: PHY port address - * @param RegAddr: PHY register address - * @param RegVal: Value to be written - * @retval 0 if OK -1 if Error - */ -int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal) -{ - if(HAL_ETH_WritePHYRegister(&heth, DevAddr, RegAddr, RegVal) != HAL_OK) - { - HAL_NVIC_SystemReset(); - return -1; + * PHY-AGNOSTIC LINK CHECK + ******************************************************************************/ +static uint8_t eth_link_up = 0; +void ethernet_link_check_state(struct netif *netif) { + phy_link_state_t state = phy_driver->get_link_state(); + + if (state == PHY_LINK_DOWN) { + if (eth_link_up) { + eth_link_up = 0; + HAL_ETH_Stop(&heth); + netif_set_link_down(netif); + netif_set_down(netif); + } + return; } - return 0; -} - -/** - * @brief Get the time in millisecons used for internal PHY driver process. - * @retval Time value - */ -int32_t ETH_PHY_IO_GetTick(void) -{ - return HAL_GetTick(); -} + /* Link UP */ + if (!eth_link_up) { + ETH_MACConfigTypeDef macconf; + HAL_ETH_GetMACConfig(&heth, &macconf); -/** - * @brief Check the ETH link state then update ETH driver and netif link accordingly. - * @retval None - */ -void ethernet_link_check_state(struct netif *netif) -{ - ETH_MACConfigTypeDef MACConf = {0}; - int32_t PHYLinkState = 0; - uint32_t linkchanged = 0U, speed = 0U, duplex = 0U; - - PHYLinkState = LAN8742_GetLinkState(&LAN8742); - - if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN)) - { - HAL_ETH_Stop(&heth); - netif_set_down(netif); - netif_set_link_down(netif); - } - else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN)) - { - switch (PHYLinkState) - { - case LAN8742_STATUS_100MBITS_FULLDUPLEX: - duplex = ETH_FULLDUPLEX_MODE; - speed = ETH_SPEED_100M; - linkchanged = 1; + switch (state) { + case PHY_100_FULL: + macconf.Speed = ETH_SPEED_100M; + macconf.DuplexMode = ETH_FULLDUPLEX_MODE; break; - case LAN8742_STATUS_100MBITS_HALFDUPLEX: - duplex = ETH_HALFDUPLEX_MODE; - speed = ETH_SPEED_100M; - linkchanged = 1; + case PHY_100_HALF: + macconf.Speed = ETH_SPEED_100M; + macconf.DuplexMode = ETH_HALFDUPLEX_MODE; break; - case LAN8742_STATUS_10MBITS_FULLDUPLEX: - duplex = ETH_FULLDUPLEX_MODE; - speed = ETH_SPEED_10M; - linkchanged = 1; + case PHY_10_FULL: + macconf.Speed = ETH_SPEED_10M; + macconf.DuplexMode = ETH_FULLDUPLEX_MODE; break; - case LAN8742_STATUS_10MBITS_HALFDUPLEX: - duplex = ETH_HALFDUPLEX_MODE; - speed = ETH_SPEED_10M; - linkchanged = 1; + case PHY_10_HALF: + macconf.Speed = ETH_SPEED_10M; + macconf.DuplexMode = ETH_HALFDUPLEX_MODE; break; default: - break; + return; } - if(linkchanged) - { - /* Get MAC Config MAC */ - HAL_ETH_GetMACConfig(&heth, &MACConf); - MACConf.DuplexMode = duplex; - MACConf.Speed = speed; - HAL_ETH_SetMACConfig(&heth, &MACConf); - HAL_ETH_Start(&heth); - netif_set_up(netif); - netif_set_link_up(netif); - } - } + HAL_ETH_SetMACConfig(&heth, &macconf); + HAL_ETH_Start(&heth); + + netif_set_link_up(netif); + netif_set_up(netif); + eth_link_up = 1; + } } -void HAL_ETH_RxAllocateCallback(uint8_t **buff) -{ -/* USER CODE BEGIN HAL ETH RxAllocateCallback */ +/******************************************************************************* + * RX/TX CALLBACKS + ******************************************************************************/ +void HAL_ETH_RxAllocateCallback(uint8_t **buff) { struct pbuf_custom *p = LWIP_MEMPOOL_ALLOC(RX_POOL); - if (p) - { - /* Get the buff from the struct pbuf address. */ + if (p) { *buff = (uint8_t *)p + offsetof(RxBuff_t, buff); p->custom_free_function = pbuf_free_custom; - /* Initialize the struct pbuf. - * This must be performed whenever a buffer's allocated because it may be - * changed by lwIP or the app, e.g., pbuf_free decrements ref. */ pbuf_alloced_custom(PBUF_RAW, 0, PBUF_REF, p, *buff, ETH_RX_BUFFER_SIZE); - } - else - { + } else { RxAllocStatus = RX_ALLOC_ERROR; *buff = NULL; } -/* USER CODE END HAL ETH RxAllocateCallback */ } -void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, uint16_t Length) -{ -/* USER CODE BEGIN HAL ETH RxLinkCallback */ - - struct pbuf **ppStart = (struct pbuf **)pStart; - struct pbuf **ppEnd = (struct pbuf **)pEnd; - struct pbuf *p = NULL; - - /* Get the struct pbuf from the buff address. */ - p = (struct pbuf *)(buff - offsetof(RxBuff_t, buff)); +void HAL_ETH_RxLinkCallback(void **pStart, void **pEnd, uint8_t *buff, + uint16_t len) { + struct pbuf *p = (struct pbuf *)(buff - offsetof(RxBuff_t, buff)); p->next = NULL; - p->tot_len = 0; - p->len = Length; - - /* Chain the buffer. */ - if (!*ppStart) - { - /* The first buffer of the packet. */ - *ppStart = p; - } - else - { - /* Chain the buffer to the end of the packet. */ - (*ppEnd)->next = p; - } - *ppEnd = p; + p->len = len; + p->tot_len = len; - /* Update the total length of all the buffers of the chain. Each pbuf in the chain should have its tot_len - * set to its own length, plus the length of all the following pbufs in the chain. */ - for (p = *ppStart; p != NULL; p = p->next) - { - p->tot_len += Length; - } + if (!*pStart) + *pStart = p; + else + ((struct pbuf *)*pEnd)->next = p; - /* Invalidate data cache because Rx DMA's writing to physical memory makes it stale. */ - SCB_InvalidateDCache_by_Addr((uint32_t *)buff, Length); + *pEnd = p; + uint32_t addr = (uint32_t)buff & ~0x1F; + uint32_t size = len + ((uint32_t)buff - addr); + size = (size + 31) & ~0x1F; -/* USER CODE END HAL ETH RxLinkCallback */ + SCB_InvalidateDCache_by_Addr((uint32_t *)addr, size); } -void HAL_ETH_TxFreeCallback(uint32_t * buff) -{ -/* USER CODE BEGIN HAL ETH TxFreeCallback */ - - pbuf_free((struct pbuf *)buff); +void HAL_ETH_TxFreeCallback(uint32_t *buff) { pbuf_free((struct pbuf *)buff); } -/* USER CODE END HAL ETH TxFreeCallback */ +void pbuf_free_custom(struct pbuf *p) { + LWIP_MEMPOOL_FREE(RX_POOL, p); + if (RxAllocStatus == RX_ALLOC_ERROR) + RxAllocStatus = RX_ALLOC_OK; } -/* USER CODE BEGIN 8 */ - -/* USER CODE END 8 */ - +u32_t sys_now(void) { return HAL_GetTick(); } \ No newline at end of file diff --git a/Src/HALAL/Services/Communication/Ethernet/EthernetNode.cpp b/Src/HALAL/Services/Communication/Ethernet/EthernetNode.cpp deleted file mode 100644 index 48963b63..00000000 --- a/Src/HALAL/Services/Communication/Ethernet/EthernetNode.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * EthernetNode.cpp - * - * Created on: Nov 23, 2022 - * Author: stefa - */ -#include "HALAL/Services/Communication/Ethernet/EthernetNode.hpp" -#ifdef HAL_ETH_MODULE_ENABLED - -EthernetNode::EthernetNode(IPV4 ip, uint32_t port):ip(ip), port(port){} - -bool EthernetNode::operator==(const EthernetNode& other) const{ - return ip.address.addr == other.ip.address.addr && port == other.port; -} - -std::size_t hash::operator()(const EthernetNode& key) const -{ - using std::size_t; - using std::hash; - using std::string; - - return (hash()(key.ip.address.addr)) ^ (hash()(key.port) << 1); -} -#endif diff --git a/Src/HALAL/Services/Communication/Ethernet/Ethernet.cpp b/Src/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.cpp similarity index 97% rename from Src/HALAL/Services/Communication/Ethernet/Ethernet.cpp rename to Src/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.cpp index effbec95..7ea237fb 100644 --- a/Src/HALAL/Services/Communication/Ethernet/Ethernet.cpp +++ b/Src/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.cpp @@ -5,7 +5,7 @@ * Author: stefa */ -#include "HALAL/Services/Communication/Ethernet/Ethernet.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp" #include "ErrorHandler/ErrorHandler.hpp" #include "HALAL/Models/MPUManager/MPUManager.hpp" @@ -18,7 +18,6 @@ extern uint8_t IP_ADDRESS[4], NETMASK_ADDRESS[4], GATEWAY_ADDRESS[4]; bool Ethernet::is_ready = false; bool Ethernet::is_running = false; - void Ethernet::start(string local_mac, string local_ip, string subnet_mask, string gateway) { start(MAC(local_mac), IPV4(local_ip), IPV4(subnet_mask), IPV4(gateway)); diff --git a/Src/HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.cpp b/Src/HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.cpp new file mode 100644 index 00000000..3a49e7e3 --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.cpp @@ -0,0 +1,24 @@ +/* + * EthernetNode.cpp + * + * Created on: Nov 23, 2022 + * Author: stefa + */ +#include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" +#ifdef HAL_ETH_MODULE_ENABLED + +EthernetNode::EthernetNode(IPV4 ip, uint32_t port) : ip(ip), port(port) {} + +bool EthernetNode::operator==(const EthernetNode &other) const { + return ip.address.addr == other.ip.address.addr && port == other.port; +} + +std::size_t hash::operator()(const EthernetNode &key) const { + using std::hash; + using std::size_t; + using std::string; + + return (hash()(key.ip.address.addr)) ^ + (hash()(key.port) << 1); +} +#endif diff --git a/Src/HALAL/Services/Communication/Ethernet/TCP/OrderProtocol.cpp b/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/OrderProtocol.cpp similarity index 100% rename from Src/HALAL/Services/Communication/Ethernet/TCP/OrderProtocol.cpp rename to Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/OrderProtocol.cpp diff --git a/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.cpp b/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.cpp new file mode 100644 index 00000000..9e3fa163 --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.cpp @@ -0,0 +1,309 @@ +/* + * ServerSocket.cpp + * + * Created on: Nov 23, 2022 + * Author: stefa + */ +#ifdef STLIB_ETH +#include "HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.hpp" +#include "ErrorHandler/ErrorHandler.hpp" +#include "lwip/priv/tcp_priv.h" +#ifdef HAL_ETH_MODULE_ENABLED + +uint8_t ServerSocket::priority = 1; +unordered_map ServerSocket::listening_sockets = {}; + +ServerSocket::ServerSocket() = default; + +ServerSocket::ServerSocket(IPV4 local_ip, uint32_t local_port) + : local_ip(local_ip), local_port(local_port) { + if (not Ethernet::is_running) { + ErrorHandler("Cannot declare UDP socket before Ethernet::start()"); + return; + } + tx_packet_buffer = {}; + rx_packet_buffer = {}; + state = INACTIVE; + server_control_block = tcp_new(); + tcp_nagle_disable(server_control_block); + ip_set_option(server_control_block, SOF_REUSEADDR); + err_t error = tcp_bind(server_control_block, &local_ip.address, local_port); + + if (error == ERR_OK) { + server_control_block = tcp_listen(server_control_block); + state = LISTENING; + listening_sockets[local_port] = this; + tcp_accept(server_control_block, accept_callback); + } else { + memp_free(MEMP_TCP_PCB, server_control_block); + ErrorHandler("Cannot bind server socket, error %d", (int16_t)error); + } + OrderProtocol::sockets.push_back(this); +} + +ServerSocket::ServerSocket(IPV4 local_ip, uint32_t local_port, + uint32_t inactivity_time_until_keepalive_ms, + uint32_t space_between_tries_ms, + uint32_t tries_until_disconnection) + : ServerSocket(local_ip, local_port) { + keepalive_config.inactivity_time_until_keepalive_ms = + inactivity_time_until_keepalive_ms; + keepalive_config.space_between_tries_ms = space_between_tries_ms; + keepalive_config.tries_until_disconnection = tries_until_disconnection; +} + +ServerSocket::ServerSocket(ServerSocket &&other) + : local_ip(move(other.local_ip)), local_port(move(other.local_port)), + state(other.state), + server_control_block(move(other.server_control_block)) { + listening_sockets[local_port] = this; + tx_packet_buffer = {}; + rx_packet_buffer = {}; +} + +void ServerSocket::operator=(ServerSocket &&other) { + local_ip = move(other.local_ip); + local_port = move(other.local_port); + server_control_block = move(other.server_control_block); + state = other.state; + listening_sockets[local_port] = this; + tx_packet_buffer = {}; + rx_packet_buffer = {}; + if (not(std::find(OrderProtocol::sockets.begin(), + OrderProtocol::sockets.end(), + this) != OrderProtocol::sockets.end())) + OrderProtocol::sockets.push_back(this); +} + +ServerSocket::~ServerSocket() { + // el destructor no destruye + auto it = std::find(OrderProtocol::sockets.begin(), + OrderProtocol::sockets.end(), this); + if (it == OrderProtocol::sockets.end()) + return; + else + OrderProtocol::sockets.erase(it); + tcp_abort(client_control_block); + tcp_abort(server_control_block); + while (!tx_packet_buffer.empty()) { + free(tx_packet_buffer.front()); + tx_packet_buffer.pop(); + } + while (!rx_packet_buffer.empty()) { + free(rx_packet_buffer.front()); + rx_packet_buffer.pop(); + } +} + +ServerSocket::ServerSocket(EthernetNode local_node) + : ServerSocket(local_node.ip, local_node.port) {}; + +void ServerSocket::close() { + // Clean all callbacks + tcp_arg(client_control_block, nullptr); + tcp_sent(client_control_block, nullptr); + tcp_recv(client_control_block, nullptr); + tcp_err(client_control_block, nullptr); + tcp_poll(client_control_block, nullptr, 0); + + tcp_close(client_control_block); + while (!tx_packet_buffer.empty()) { + pbuf_free(tx_packet_buffer.front()); + tx_packet_buffer.pop(); + } + while (!rx_packet_buffer.empty()) { + pbuf_free(rx_packet_buffer.front()); + rx_packet_buffer.pop(); + } + + tcp_pcb_remove(&tcp_active_pcbs, client_control_block); + tcp_free(client_control_block); + + listening_sockets[local_port] = this; + state = CLOSED; + + priority--; +} + +void ServerSocket::process_data() { + while (!rx_packet_buffer.empty()) { + struct pbuf *packet = rx_packet_buffer.front(); + rx_packet_buffer.pop(); + uint8_t *new_data = (uint8_t *)(packet->payload); + tcp_recved(client_control_block, packet->tot_len); + uint16_t id = Packet::get_id(new_data); + if (Order::orders.contains(id)) { + Order::orders[id]->store_ip_order(remote_ip.string_address); + Order::process_data(this, new_data); + } + pbuf_free(packet); + } +} + +bool ServerSocket::add_order_to_queue(Order &order) { + if (state == ACCEPTED) { + return false; // yet to decide if add_order_to_queue should send the order + // when used after the connection is accepted or just return + // false + } + struct memp *next_memory_pointer_in_packet_buffer_pool = + (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; + if (next_memory_pointer_in_packet_buffer_pool == nullptr) { + memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], + next_memory_pointer_in_packet_buffer_pool); + return false; + } + + uint8_t *order_buffer = order.build(); + + struct pbuf *packet = pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); + pbuf_take(packet, order_buffer, order.get_size()); + tx_packet_buffer.push(packet); + return true; +} + +void ServerSocket::send() { + pbuf *temporal_packet_buffer; + err_t error = ERR_OK; + while (error == ERR_OK && !tx_packet_buffer.empty() && + tx_packet_buffer.front()->len <= tcp_sndbuf(client_control_block)) { + temporal_packet_buffer = tx_packet_buffer.front(); + error = tcp_write(client_control_block, temporal_packet_buffer->payload, + temporal_packet_buffer->len, TCP_WRITE_FLAG_COPY); + if (error == ERR_OK) { + tx_packet_buffer.pop(); + tcp_output(client_control_block); + memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], + temporal_packet_buffer); + } else { + ErrorHandler("Cannot write to socket, error: %d", error); + } + } +} + +bool ServerSocket::is_connected() { + return state == ServerSocket::ServerState::ACCEPTED; +} + +err_t ServerSocket::accept_callback(void *arg, + struct tcp_pcb *incomming_control_block, + err_t error) { + if (listening_sockets.contains(incomming_control_block->local_port)) { + ServerSocket *server_socket = + listening_sockets[incomming_control_block->local_port]; + + server_socket->state = ACCEPTED; + server_socket->client_control_block = incomming_control_block; + server_socket->remote_ip = IPV4(incomming_control_block->remote_ip); + server_socket->rx_packet_buffer = {}; + + tcp_setprio(incomming_control_block, priority); + tcp_nagle_disable(incomming_control_block); + ip_set_option(incomming_control_block, SOF_REUSEADDR); + + tcp_arg(incomming_control_block, server_socket); + tcp_recv(incomming_control_block, receive_callback); + tcp_sent(incomming_control_block, send_callback); + tcp_err(incomming_control_block, error_callback); + tcp_poll(incomming_control_block, poll_callback, 0); + config_keepalive(incomming_control_block, server_socket); + + tcp_close(server_socket->server_control_block); + priority++; + + return ERR_OK; + } else + return ERROR; +} + +err_t ServerSocket::receive_callback(void *arg, + struct tcp_pcb *client_control_block, + struct pbuf *packet_buffer, err_t error) { + ServerSocket *server_socket = (ServerSocket *)arg; + server_socket->client_control_block = client_control_block; + + if (packet_buffer == nullptr) { // FIN has been received + server_socket->state = CLOSING; + return ERR_OK; + } + + if (error != ERR_OK) { // Check if packet is valid + if (packet_buffer != nullptr) { + pbuf_free(packet_buffer); + } + return error; + } else if (server_socket->state == ACCEPTED) { + server_socket->rx_packet_buffer.push(packet_buffer); + server_socket->process_data(); + return ERR_OK; + } + + else if (server_socket->state == CLOSING) { // Socket is already closed + while (not server_socket->rx_packet_buffer.empty()) { + pbuf_free(server_socket->rx_packet_buffer.front()); + server_socket->rx_packet_buffer.pop(); + } + server_socket->rx_packet_buffer = {}; + pbuf_free(packet_buffer); + return ERR_OK; + } + return ERR_OK; +} + +void ServerSocket::error_callback(void *arg, err_t error) { + ServerSocket *server_socket = (ServerSocket *)arg; + server_socket->close(); + ErrorHandler("Socket error: %d. Socket closed", error); +} + +err_t ServerSocket::poll_callback(void *arg, + struct tcp_pcb *client_control_block) { + ServerSocket *server_socket = (ServerSocket *)arg; + server_socket->client_control_block = client_control_block; + + if (server_socket == nullptr) { // Polling non existing pcb, fatal error + tcp_abort(client_control_block); + return ERR_ABRT; + } + + while (not server_socket->tx_packet_buffer.empty()) { // TX FIFO is not empty + server_socket->send(); + } + + while (not server_socket->rx_packet_buffer.empty()) { // RX FIFO is not empty + server_socket->process_data(); + } + + if (server_socket->state == CLOSING) { // pcb has been polled to close + server_socket->close(); + } + + return ERR_OK; +} + +err_t ServerSocket::send_callback(void *arg, + struct tcp_pcb *client_control_block, + u16_t len) { + ServerSocket *server_socket = (ServerSocket *)arg; + server_socket->client_control_block = client_control_block; + if (!server_socket->tx_packet_buffer.empty()) { + server_socket->send(); + } else if (server_socket->state == CLOSING) { + server_socket->close(); + } + return ERR_OK; +} + +void ServerSocket::config_keepalive(tcp_pcb *control_block, + ServerSocket *server_socket) { + control_block->so_options |= SOF_KEEPALIVE; + control_block->keep_idle = + server_socket->keepalive_config.inactivity_time_until_keepalive_ms; + control_block->keep_intvl = + server_socket->keepalive_config.space_between_tries_ms; + control_block->keep_cnt = + server_socket->keepalive_config.tries_until_disconnection; +} + +#endif // HAL_ETH_MODULE_ENABLED +#endif // STLIB_ETH diff --git a/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.cpp b/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.cpp new file mode 100644 index 00000000..ece56991 --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.cpp @@ -0,0 +1,322 @@ +/* + * Socket.cpp + * + * Created on: Nov 23, 2022 + * Author: stefa + */ +#include "HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.hpp" +#include "ErrorHandler/ErrorHandler.hpp" +#ifdef HAL_ETH_MODULE_ENABLED + +unordered_map Socket::connecting_sockets = {}; + +Socket::Socket() = default; + +Socket::Socket(Socket &&other) + : connection_control_block(move(other.connection_control_block)), + remote_port(move(remote_port)), state(other.state) { + EthernetNode remote_node(other.remote_ip, other.remote_port); + connecting_sockets[remote_node] = this; +} + +void Socket::operator=(Socket &&other) { + connection_control_block = move(other.connection_control_block); + remote_port = move(other.remote_port); + state = other.state; + EthernetNode remote_node(other.remote_ip, other.remote_port); + connecting_sockets[remote_node] = this; + if (std::find(OrderProtocol::sockets.begin(), OrderProtocol::sockets.end(), + this) == OrderProtocol::sockets.end()) + OrderProtocol::sockets.push_back(this); +} + +Socket::~Socket() { + auto it = std::find(OrderProtocol::sockets.begin(), + OrderProtocol::sockets.end(), this); + if (it == OrderProtocol::sockets.end()) + return; + else + OrderProtocol::sockets.erase(it); +} + +Socket::Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, + uint32_t remote_port, bool use_keep_alive) + : local_ip(local_ip), local_port(local_port), remote_ip(remote_ip), + remote_port(remote_port), use_keep_alives{use_keep_alive} { + if (not Ethernet::is_running) { + ErrorHandler("Cannot declare TCP socket before Ethernet::start()"); + return; + } + state = INACTIVE; + tx_packet_buffer = {}; + rx_packet_buffer = {}; + EthernetNode remote_node(remote_ip, remote_port); + + connection_control_block = tcp_new(); + tcp_bind(connection_control_block, &local_ip.address, local_port); + tcp_nagle_disable(connection_control_block); + tcp_arg(connection_control_block, this); + tcp_poll(connection_control_block, connection_poll_callback, 1); + tcp_err(connection_control_block, connection_error_callback); + + connecting_sockets[remote_node] = this; + tcp_connect(connection_control_block, &remote_ip.address, remote_port, + connect_callback); + OrderProtocol::sockets.push_back(this); +} + +Socket::Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, + uint32_t remote_port, + uint32_t inactivity_time_until_keepalive_ms, + uint32_t space_between_tries_ms, + uint32_t tries_until_disconnection) + : Socket(local_ip, local_port, remote_ip, remote_port) { + keepalive_config.inactivity_time_until_keepalive_ms = + inactivity_time_until_keepalive_ms; + keepalive_config.space_between_tries_ms = space_between_tries_ms; + keepalive_config.tries_until_disconnection = tries_until_disconnection; +} + +Socket::Socket(EthernetNode local_node, EthernetNode remote_node) + : Socket(local_node.ip, local_node.port, remote_node.ip, remote_node.port) { +} + +void Socket::close() { + tcp_arg(socket_control_block, nullptr); + tcp_sent(socket_control_block, nullptr); + tcp_recv(socket_control_block, nullptr); + tcp_err(socket_control_block, nullptr); + tcp_poll(socket_control_block, nullptr, 0); + + while (!tx_packet_buffer.empty()) { + pbuf_free(tx_packet_buffer.front()); + tx_packet_buffer.pop(); + } + while (!rx_packet_buffer.empty()) { + pbuf_free(rx_packet_buffer.front()); + rx_packet_buffer.pop(); + } + + tcp_close(socket_control_block); + state = INACTIVE; +} + +void Socket::reconnect() { + EthernetNode remote_node(remote_ip, remote_port); + if (!connecting_sockets.contains(remote_node)) { + connecting_sockets[remote_node] = this; + } + tcp_connect(connection_control_block, &remote_ip.address, remote_port, + connect_callback); +} + +void Socket::reset() { + EthernetNode remote_node(remote_ip, remote_port); + if (!connecting_sockets.contains(remote_node)) { + connecting_sockets[remote_node] = this; + } + state = INACTIVE; + tcp_abort(connection_control_block); + connection_control_block = tcp_new(); + + tcp_bind(connection_control_block, &local_ip.address, local_port); + tcp_nagle_disable(connection_control_block); + tcp_arg(connection_control_block, this); + tcp_poll(connection_control_block, connection_poll_callback, 1); + tcp_err(connection_control_block, connection_error_callback); + + tcp_connect(connection_control_block, &remote_ip.address, remote_port, + connect_callback); +} + +void Socket::send() { + pbuf *temporal_packet_buffer; + err_t error = ERR_OK; + while (error == ERR_OK && !tx_packet_buffer.empty() && + tx_packet_buffer.front()->len <= tcp_sndbuf(socket_control_block)) { + temporal_packet_buffer = tx_packet_buffer.front(); + error = tcp_write(socket_control_block, temporal_packet_buffer->payload, + temporal_packet_buffer->len, TCP_WRITE_FLAG_COPY); + if (error == ERR_OK) { + tx_packet_buffer.pop(); + tcp_output(socket_control_block); + memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], + temporal_packet_buffer); + } else { + if (error == ERR_MEM) { + close(); + ErrorHandler( + "Too many unacked messages on client socket, disconnecting..."); + } else { + ErrorHandler("Cannot write to client socket. Error code: %d", error); + } + } + } +} + +void Socket::process_data() { + while (!rx_packet_buffer.empty()) { + struct pbuf *packet = rx_packet_buffer.front(); + rx_packet_buffer.pop(); + uint8_t *new_data = (uint8_t *)(packet->payload); + tcp_recved(socket_control_block, packet->tot_len); + uint16_t id = Packet::get_id(new_data); + if (Order::orders.contains(id)) { + Order::orders[id]->store_ip_order(remote_ip.string_address); + Order::process_data(this, new_data); + } + + pbuf_free(packet); + } +} + +bool Socket::add_order_to_queue(Order &order) { + if (state == Socket::SocketState::CONNECTED) { + return false; + } + struct memp *next_memory_pointer_in_packet_buffer_pool = + (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; + if (next_memory_pointer_in_packet_buffer_pool == nullptr) { + memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], + next_memory_pointer_in_packet_buffer_pool); + return false; + } + + uint8_t *order_buffer = order.build(); + + struct pbuf *packet = pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); + pbuf_take(packet, order_buffer, order.get_size()); + Socket::tx_packet_buffer.push(packet); + return true; +} + +bool Socket::is_connected() { return state == Socket::SocketState::CONNECTED; } + +err_t Socket::connect_callback(void *arg, struct tcp_pcb *client_control_block, + err_t error) { + IPV4 remote_ip; + remote_ip.address = client_control_block->remote_ip; + EthernetNode remote_node(remote_ip, client_control_block->remote_port); + + if (connecting_sockets.contains(remote_node)) { + Socket *socket = connecting_sockets[remote_node]; + connecting_sockets.erase(remote_node); + + socket->socket_control_block = client_control_block; + socket->state = CONNECTED; + + tcp_nagle_disable(client_control_block); + tcp_arg(client_control_block, socket); + tcp_recv(client_control_block, receive_callback); + tcp_poll(client_control_block, poll_callback, 0); + tcp_sent(client_control_block, send_callback); + tcp_err(client_control_block, error_callback); + if (socket->use_keep_alives) + config_keepalive(client_control_block, socket); + + return ERR_OK; + } else + return ERROR; +} + +err_t Socket::receive_callback(void *arg, struct tcp_pcb *client_control_block, + struct pbuf *packet_buffer, err_t error) { + Socket *socket = (Socket *)arg; + socket->socket_control_block = client_control_block; + if (packet_buffer == nullptr) { // FIN is received + socket->state = CLOSING; + return ERR_OK; + } + if (error != ERR_OK) { + if (packet_buffer != nullptr) { + pbuf_free(packet_buffer); + } + return error; + } else if (socket->state == CONNECTED) { + socket->rx_packet_buffer.push(packet_buffer); + tcp_recved(client_control_block, packet_buffer->tot_len); + socket->process_data(); + pbuf_free(packet_buffer); + return ERR_OK; + } else { + tcp_recved(client_control_block, packet_buffer->tot_len); + socket->tx_packet_buffer = {}; + pbuf_free(packet_buffer); + return ERR_OK; + } +} + +err_t Socket::poll_callback(void *arg, struct tcp_pcb *client_control_block) { + Socket *socket = (Socket *)arg; + socket->socket_control_block = client_control_block; + if (socket != nullptr) { + while (not socket->tx_packet_buffer.empty()) { + socket->send(); + } + if (socket->state == CLOSING) { + socket->close(); + } else if (socket->state == INACTIVE) { + tcp_connect(socket->connection_control_block, &socket->remote_ip.address, + socket->remote_port, connect_callback); + } + return ERR_OK; + } else { + tcp_abort(client_control_block); + return ERR_ABRT; + } +} + +err_t Socket::send_callback(void *arg, struct tcp_pcb *client_control_block, + uint16_t length) { + Socket *socket = (Socket *)arg; + socket->socket_control_block = client_control_block; + if (not socket->tx_packet_buffer.empty()) { + socket->send(); + } else if (socket->state == CLOSING) { + socket->close(); + } + return ERR_OK; +} + +void Socket::error_callback(void *arg, err_t error) { + Socket *socket = (Socket *)arg; + socket->close(); + ErrorHandler("Client socket error: %d. Socket closed, remote ip: %s", error, + socket->remote_ip.string_address.c_str()); +} + +void Socket::connection_error_callback(void *arg, err_t error) { + if (error == ERR_RST) { + Socket *socket = (Socket *)arg; + + socket->pending_connection_reset = true; + return; + } else if (error == ERR_ABRT) { + return; + } + ErrorHandler("Connection socket error: %d. Couldn t start client socket ", + error); +} + +err_t Socket::connection_poll_callback( + void *arg, struct tcp_pcb *connection_control_block) { + Socket *socket = (Socket *)arg; + if (socket->pending_connection_reset) { + socket->reset(); + socket->pending_connection_reset = false; + return ERR_ABRT; + } else if (socket->connection_control_block->state == SYN_SENT) { + socket->pending_connection_reset = true; + } + return ERR_OK; +} + +void Socket::config_keepalive(tcp_pcb *control_block, Socket *socket) { + control_block->so_options |= SOF_KEEPALIVE; + control_block->keep_idle = + socket->keepalive_config.inactivity_time_until_keepalive_ms; + control_block->keep_intvl = socket->keepalive_config.space_between_tries_ms; + control_block->keep_cnt = socket->keepalive_config.tries_until_disconnection; +} + +#endif diff --git a/Src/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.cpp b/Src/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.cpp new file mode 100644 index 00000000..006e7995 --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.cpp @@ -0,0 +1,96 @@ +/* + * DatagramSocket.cpp + * + * Created on: 2 nov. 2022 + * Author: stefa + */ + +#include "HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.hpp" +#include "ErrorHandler/ErrorHandler.hpp" + +#ifdef HAL_ETH_MODULE_ENABLED + +DatagramSocket::DatagramSocket() = default; + +DatagramSocket::DatagramSocket(DatagramSocket &&other) + : udp_control_block(move(other.udp_control_block)), + local_ip(move(other.local_ip)), local_port(move(other.local_port)), + remote_ip(move(other.remote_ip)), remote_port(move(remote_port)) {} + +DatagramSocket::DatagramSocket(IPV4 local_ip, uint32_t local_port, + IPV4 remote_ip, uint32_t remote_port) + : local_ip(local_ip), local_port(local_port), remote_ip(remote_ip), + remote_port(remote_port) { + if (not Ethernet::is_running) { + ErrorHandler("Cannot declare UDP socket before Ethernet::start()"); + return; + } + udp_control_block = udp_new(); + err_t error = udp_bind(udp_control_block, &local_ip.address, local_port); + + if (error == ERR_OK) { + udp_recv(udp_control_block, receive_callback, nullptr); + udp_connect(udp_control_block, &remote_ip.address, remote_port); + is_disconnected = false; + Ethernet::update(); + } else { + udp_remove(udp_control_block); + is_disconnected = true; + ErrorHandler("Error binding UDP socket"); + } +} + +DatagramSocket::DatagramSocket(EthernetNode local_node, + EthernetNode remote_node) + : DatagramSocket(local_node.ip, local_node.port, remote_node.ip, + remote_node.port) {} + +DatagramSocket::~DatagramSocket() { + if (not is_disconnected) + close(); +} + +void DatagramSocket::operator=(DatagramSocket &&other) { + udp_control_block = move(other.udp_control_block); + local_ip = move(other.local_ip); + local_port = move(other.local_port); + remote_ip = other.remote_ip; + remote_port = other.remote_port; + other.is_disconnected = true; +} + +void DatagramSocket::reconnect() { + udp_disconnect(udp_control_block); + is_disconnected = true; + err_t error = udp_bind(udp_control_block, &local_ip.address, local_port); + + if (error == ERR_OK) { + udp_recv(udp_control_block, receive_callback, nullptr); + udp_connect(udp_control_block, &remote_ip.address, remote_port); + is_disconnected = false; + Ethernet::update(); + } else { + udp_remove(udp_control_block); + is_disconnected = true; + ErrorHandler("Error binding UDP socket"); + } +} + +void DatagramSocket::close() { + udp_disconnect(udp_control_block); + udp_remove(udp_control_block); + is_disconnected = true; +} + +void DatagramSocket::receive_callback(void *args, + struct udp_pcb *udp_control_block, + struct pbuf *packet_buffer, + const ip_addr_t *remote_address, + u16_t port) { + uint8_t *received_data = (uint8_t *)packet_buffer->payload; + Packet::parse_data(received_data); + + pbuf_free(packet_buffer); +} + +#endif diff --git a/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c b/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c new file mode 100644 index 00000000..5ef59a5d --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c @@ -0,0 +1,38 @@ +#include "HALAL/Services/Communication/Ethernet/PHY/phy_driver.h" +#include "stm32h7xx_hal.h" + +#ifdef USE_PHY_KSZ8041 + +extern ETH_HandleTypeDef heth; +#define PHY_ADDR 1 + +static uint32_t phy_read(uint32_t reg) { + uint32_t val; + HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, reg, &val); + return val; +} + +static phy_link_state_t ksz8041_get_link_state(void) { + static uint8_t link_latched = 0; + + uint32_t bmsr; + HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, 1, &bmsr); + HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, 1, &bmsr); + + if (!(bmsr & (1 << 2))) { + link_latched = 0; + return PHY_LINK_DOWN; + } + + if (!link_latched) { + link_latched = 1; + return PHY_100_FULL; + } + + return PHY_100_FULL; +} + +const phy_driver_t phy_ksz8041 = {.init = NULL, + .get_link_state = ksz8041_get_link_state}; + +#endif \ No newline at end of file diff --git a/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c b/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c new file mode 100644 index 00000000..3a5af58f --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c @@ -0,0 +1,57 @@ +#include "HALAL/Services/Communication/Ethernet/PHY/phy_driver.h" + +#ifdef USE_PHY_LAN8742 + +#include "lan8742.h" +#include "stm32h7xx_hal.h" + +/* Bus IO provided by ethernetif.c */ +extern int32_t ETH_PHY_IO_Init(void); +extern int32_t ETH_PHY_IO_DeInit(void); +extern int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, + uint32_t RegVal); +extern int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, + uint32_t *pRegVal); +extern int32_t ETH_PHY_IO_GetTick(void); + +static lan8742_Object_t lan; + +static lan8742_IOCtx_t ctx = { + .Init = ETH_PHY_IO_Init, + .DeInit = ETH_PHY_IO_DeInit, + .WriteReg = ETH_PHY_IO_WriteReg, + .ReadReg = ETH_PHY_IO_ReadReg, + .GetTick = ETH_PHY_IO_GetTick, +}; + +static void lan_init(void) { + /* Explicit PHY address (robust) */ + lan.DevAddr = LAN8742_PHY_ADDRESS; + + LAN8742_RegisterBusIO(&lan, &ctx); + LAN8742_Init(&lan); +} + +static phy_link_state_t lan_get_link_state(void) { + int32_t st = LAN8742_GetLinkState(&lan); + + switch (st) { + case LAN8742_STATUS_100MBITS_FULLDUPLEX: + return PHY_100_FULL; + case LAN8742_STATUS_100MBITS_HALFDUPLEX: + return PHY_100_HALF; + case LAN8742_STATUS_10MBITS_FULLDUPLEX: + return PHY_10_FULL; + case LAN8742_STATUS_10MBITS_HALFDUPLEX: + return PHY_10_HALF; + default: + return PHY_LINK_DOWN; + } +} + +const phy_driver_t phy_lan8742 = { + .init = lan_init, + .get_link_state = lan_get_link_state, +}; + +#endif /* USE_PHY_LAN8742 */ \ No newline at end of file diff --git a/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c b/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c new file mode 100644 index 00000000..2d7822e9 --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c @@ -0,0 +1,13 @@ +#include "HALAL/Services/Communication/Ethernet/PHY/phy_driver.h" + +#if defined(USE_PHY_KSZ8041) +extern const phy_driver_t phy_ksz8041; +const phy_driver_t *phy_driver = &phy_ksz8041; + +#elif defined(USE_PHY_LAN8742) +extern const phy_driver_t phy_lan8742; +const phy_driver_t *phy_driver = &phy_lan8742; + +#else +#error "No PHY selected" +#endif \ No newline at end of file diff --git a/Src/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.cpp b/Src/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.cpp deleted file mode 100644 index d2751d35..00000000 --- a/Src/HALAL/Services/Communication/Ethernet/TCP/ServerSocket.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/* - * ServerSocket.cpp - * - * Created on: Nov 23, 2022 - * Author: stefa - */ -#ifdef STLIB_ETH -#include "HALAL/Services/Communication/Ethernet/TCP/ServerSocket.hpp" -#include "lwip/priv/tcp_priv.h" -#include "ErrorHandler/ErrorHandler.hpp" -#ifdef HAL_ETH_MODULE_ENABLED - -uint8_t ServerSocket::priority = 1; -unordered_map ServerSocket::listening_sockets = {}; - -ServerSocket::ServerSocket() = default; - -ServerSocket::ServerSocket(IPV4 local_ip, uint32_t local_port) : local_ip(local_ip),local_port(local_port){ - if(not Ethernet::is_running) { - ErrorHandler("Cannot declare UDP socket before Ethernet::start()"); - return; - } - tx_packet_buffer = {}; - rx_packet_buffer = {}; - state = INACTIVE; - server_control_block = tcp_new(); - tcp_nagle_disable(server_control_block); - ip_set_option(server_control_block, SOF_REUSEADDR); - err_t error = tcp_bind(server_control_block, &local_ip.address, local_port); - - if(error == ERR_OK){ - server_control_block = tcp_listen(server_control_block); - state = LISTENING; - listening_sockets[local_port] = this; - tcp_accept(server_control_block, accept_callback); - }else{ - memp_free(MEMP_TCP_PCB, server_control_block); - ErrorHandler("Cannot bind server socket, error %d",(int16_t)error); - } - OrderProtocol::sockets.push_back(this); -} - - -ServerSocket::ServerSocket(IPV4 local_ip, uint32_t local_port, uint32_t inactivity_time_until_keepalive_ms, uint32_t space_between_tries_ms, uint32_t tries_until_disconnection): ServerSocket(local_ip, local_port){ - keepalive_config.inactivity_time_until_keepalive_ms = inactivity_time_until_keepalive_ms; - keepalive_config.space_between_tries_ms = space_between_tries_ms; - keepalive_config.tries_until_disconnection = tries_until_disconnection; -} - - -ServerSocket::ServerSocket(ServerSocket&& other) : local_ip(move(other.local_ip)), local_port(move(other.local_port)) -, state(other.state),server_control_block(move(other.server_control_block)) { - listening_sockets[local_port] = this; - tx_packet_buffer = {}; - rx_packet_buffer = {}; -} - -void ServerSocket::operator=(ServerSocket&& other){ - local_ip = move(other.local_ip); - local_port = move(other.local_port); - server_control_block = move(other.server_control_block); - state = other.state; - listening_sockets[local_port] = this; - tx_packet_buffer = {}; - rx_packet_buffer = {}; - if(not (std::find(OrderProtocol::sockets.begin(), OrderProtocol::sockets.end(), this) != OrderProtocol::sockets.end())) - OrderProtocol::sockets.push_back(this); -} - -ServerSocket::~ServerSocket(){ - //el destructor no destruye - auto it = std::find(OrderProtocol::sockets.begin(), OrderProtocol::sockets.end(), this); - if(it == OrderProtocol::sockets.end()) return; - else OrderProtocol::sockets.erase(it); - tcp_abort(client_control_block); - tcp_abort(server_control_block); - while(!tx_packet_buffer.empty()){ - free(tx_packet_buffer.front()); - tx_packet_buffer.pop(); - } - while(!rx_packet_buffer.empty()){ - free(rx_packet_buffer.front()); - rx_packet_buffer.pop(); - } - -} - -ServerSocket::ServerSocket(EthernetNode local_node) : ServerSocket(local_node.ip,local_node.port){}; - -void ServerSocket::close(){ - // Clean all callbacks - tcp_arg(client_control_block, nullptr); - tcp_sent(client_control_block, nullptr); - tcp_recv(client_control_block, nullptr); - tcp_err(client_control_block, nullptr); - tcp_poll(client_control_block, nullptr, 0); - - tcp_close(client_control_block); - while(!tx_packet_buffer.empty()){ - pbuf_free(tx_packet_buffer.front()); - tx_packet_buffer.pop(); - } - while(!rx_packet_buffer.empty()){ - pbuf_free(rx_packet_buffer.front()); - rx_packet_buffer.pop(); - } - - tcp_pcb_remove(&tcp_active_pcbs, client_control_block); - tcp_free(client_control_block); - - listening_sockets[local_port] = this; - state = CLOSED; - - priority--; - -} - -void ServerSocket::process_data(){ - while(!rx_packet_buffer.empty()){ - struct pbuf* packet = rx_packet_buffer.front(); - rx_packet_buffer.pop(); - uint8_t* new_data = (uint8_t*)(packet->payload); - tcp_recved(client_control_block, packet->tot_len); - uint16_t id = Packet::get_id(new_data); - if (Order::orders.contains(id)) { - Order::orders[id]->store_ip_order(remote_ip.string_address); - Order::process_data(this, new_data); - } - pbuf_free(packet); - } -} - -bool ServerSocket::add_order_to_queue(Order& order){ - if(state == ACCEPTED){ - return false; //yet to decide if add_order_to_queue should send the order when used after the connection is accepted or just return false - } - struct memp* next_memory_pointer_in_packet_buffer_pool = (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; - if(next_memory_pointer_in_packet_buffer_pool == nullptr){ - memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], next_memory_pointer_in_packet_buffer_pool); - return false; - } - - uint8_t* order_buffer = order.build(); - - struct pbuf* packet = pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); - pbuf_take(packet, order_buffer, order.get_size()); - tx_packet_buffer.push(packet); - return true; -} - -void ServerSocket::send(){ - pbuf* temporal_packet_buffer; - err_t error = ERR_OK; - while(error == ERR_OK && !tx_packet_buffer.empty() && tx_packet_buffer.front()->len <= tcp_sndbuf(client_control_block)){ - temporal_packet_buffer = tx_packet_buffer.front(); - error = tcp_write(client_control_block, temporal_packet_buffer->payload, temporal_packet_buffer->len, TCP_WRITE_FLAG_COPY); - if(error == ERR_OK){ - tx_packet_buffer.pop(); - tcp_output(client_control_block); - memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION],temporal_packet_buffer); - }else{ - ErrorHandler("Cannot write to socket, error: %d", error); - } - } -} - -bool ServerSocket::is_connected(){ - return state == ServerSocket::ServerState::ACCEPTED; -} - -err_t ServerSocket::accept_callback(void* arg, struct tcp_pcb* incomming_control_block, err_t error){ - if(listening_sockets.contains(incomming_control_block->local_port)){ - ServerSocket* server_socket = listening_sockets[incomming_control_block->local_port]; - - server_socket->state = ACCEPTED; - server_socket->client_control_block = incomming_control_block; - server_socket->remote_ip = IPV4(incomming_control_block->remote_ip); - server_socket->rx_packet_buffer = {}; - - tcp_setprio(incomming_control_block, priority); - tcp_nagle_disable(incomming_control_block); - ip_set_option(incomming_control_block, SOF_REUSEADDR); - - tcp_arg(incomming_control_block, server_socket); - tcp_recv(incomming_control_block, receive_callback); - tcp_sent(incomming_control_block, send_callback); - tcp_err(incomming_control_block, error_callback); - tcp_poll(incomming_control_block, poll_callback , 0); - config_keepalive(incomming_control_block, server_socket); - - - tcp_close(server_socket->server_control_block); - priority++; - - return ERR_OK; - }else - return ERROR; -} - -err_t ServerSocket::receive_callback(void* arg, struct tcp_pcb* client_control_block, struct pbuf* packet_buffer, err_t error){ - ServerSocket* server_socket = (ServerSocket*) arg; - server_socket->client_control_block = client_control_block; - - if(packet_buffer == nullptr){ //FIN has been received - server_socket->state = CLOSING; - return ERR_OK; - } - - if(error != ERR_OK){ //Check if packet is valid - if(packet_buffer != nullptr){ - pbuf_free(packet_buffer); - } - return error; - } - else if(server_socket->state == ACCEPTED){ - server_socket->rx_packet_buffer.push(packet_buffer); - server_socket->process_data(); - return ERR_OK; - } - - else if(server_socket->state == CLOSING){ //Socket is already closed - while(not server_socket->rx_packet_buffer.empty()){ - pbuf_free(server_socket->rx_packet_buffer.front()); - server_socket->rx_packet_buffer.pop(); - } - server_socket->rx_packet_buffer = {}; - pbuf_free(packet_buffer); - return ERR_OK; - } - return ERR_OK; -} - -void ServerSocket::error_callback(void *arg, err_t error){ - ServerSocket* server_socket = (ServerSocket*) arg; - server_socket->close(); - ErrorHandler("Socket error: %d. Socket closed", error); -} - -err_t ServerSocket::poll_callback(void *arg, struct tcp_pcb *client_control_block){ - ServerSocket* server_socket = (ServerSocket*)arg; - server_socket->client_control_block = client_control_block; - - - if(server_socket == nullptr){ //Polling non existing pcb, fatal error - tcp_abort(client_control_block); - return ERR_ABRT; - } - - while(not server_socket->tx_packet_buffer.empty()){ //TX FIFO is not empty - server_socket->send(); - } - - while(not server_socket->rx_packet_buffer.empty()){ //RX FIFO is not empty - server_socket->process_data(); - } - - if(server_socket->state == CLOSING){ //pcb has been polled to close - server_socket->close(); - } - - return ERR_OK; -} - -err_t ServerSocket::send_callback(void *arg, struct tcp_pcb *client_control_block, u16_t len){ - ServerSocket* server_socket = (ServerSocket*)arg; - server_socket->client_control_block = client_control_block; - if(!server_socket->tx_packet_buffer.empty()){ - server_socket->send(); - } - else if(server_socket->state == CLOSING){ - server_socket->close(); - } - return ERR_OK; -} - -void ServerSocket::config_keepalive(tcp_pcb* control_block, ServerSocket* server_socket){ - control_block->so_options |= SOF_KEEPALIVE; - control_block->keep_idle = server_socket->keepalive_config.inactivity_time_until_keepalive_ms; - control_block->keep_intvl = server_socket->keepalive_config.space_between_tries_ms; - control_block->keep_cnt = server_socket->keepalive_config.tries_until_disconnection; -} - - -#endif //HAL_ETH_MODULE_ENABLED -#endif //STLIB_ETH diff --git a/Src/HALAL/Services/Communication/Ethernet/TCP/Socket.cpp b/Src/HALAL/Services/Communication/Ethernet/TCP/Socket.cpp deleted file mode 100644 index b8ef803c..00000000 --- a/Src/HALAL/Services/Communication/Ethernet/TCP/Socket.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Socket.cpp - * - * Created on: Nov 23, 2022 - * Author: stefa - */ -#include "HALAL/Services/Communication/Ethernet/TCP/Socket.hpp" -#include "ErrorHandler/ErrorHandler.hpp" -#ifdef HAL_ETH_MODULE_ENABLED - -unordered_map Socket::connecting_sockets = {}; - - -Socket::Socket() = default; - -Socket::Socket(Socket&& other):connection_control_block(move(other.connection_control_block)),remote_port(move(remote_port)), - state(other.state){ - EthernetNode remote_node(other.remote_ip, other.remote_port); - connecting_sockets[remote_node] = this; -} - -void Socket::operator=(Socket&& other){ - connection_control_block = move(other.connection_control_block); - remote_port = move(other.remote_port); - state = other.state; - EthernetNode remote_node(other.remote_ip, other.remote_port); - connecting_sockets[remote_node] = this; - if(std::find(OrderProtocol::sockets.begin(), OrderProtocol::sockets.end(), this) == OrderProtocol::sockets.end()) - OrderProtocol::sockets.push_back(this); -} - -Socket::~Socket(){ - auto it = std::find(OrderProtocol::sockets.begin(), OrderProtocol::sockets.end(), this); - if(it == OrderProtocol::sockets.end()) return; - else OrderProtocol::sockets.erase(it); -} - -Socket::Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, uint32_t remote_port,bool use_keep_alive): - local_ip(local_ip), local_port(local_port),remote_ip(remote_ip), remote_port(remote_port),use_keep_alives{use_keep_alive} -{ - if(not Ethernet::is_running) { - ErrorHandler("Cannot declare TCP socket before Ethernet::start()"); - return; - } - state = INACTIVE; - tx_packet_buffer = {}; - rx_packet_buffer = {}; - EthernetNode remote_node(remote_ip, remote_port); - - connection_control_block = tcp_new(); - tcp_bind(connection_control_block, &local_ip.address, local_port); - tcp_nagle_disable(connection_control_block); - tcp_arg(connection_control_block, this); - tcp_poll(connection_control_block,connection_poll_callback,1); - tcp_err(connection_control_block, connection_error_callback); - - connecting_sockets[remote_node] = this; - tcp_connect(connection_control_block, &remote_ip.address , remote_port, connect_callback); - OrderProtocol::sockets.push_back(this); -} - -Socket::Socket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, uint32_t remote_port, uint32_t inactivity_time_until_keepalive_ms, uint32_t space_between_tries_ms, uint32_t tries_until_disconnection): Socket(local_ip, local_port, remote_ip, remote_port){ - keepalive_config.inactivity_time_until_keepalive_ms = inactivity_time_until_keepalive_ms; - keepalive_config.space_between_tries_ms = space_between_tries_ms; - keepalive_config.tries_until_disconnection = tries_until_disconnection; -} - -Socket::Socket(EthernetNode local_node, EthernetNode remote_node):Socket(local_node.ip, local_node.port, remote_node.ip, remote_node.port){} - -void Socket::close(){ - tcp_arg(socket_control_block, nullptr); - tcp_sent(socket_control_block, nullptr); - tcp_recv(socket_control_block, nullptr); - tcp_err(socket_control_block, nullptr); - tcp_poll(socket_control_block, nullptr, 0); - - while(!tx_packet_buffer.empty()){ - pbuf_free(tx_packet_buffer.front()); - tx_packet_buffer.pop(); - } - while(!rx_packet_buffer.empty()){ - pbuf_free(rx_packet_buffer.front()); - rx_packet_buffer.pop(); - } - - tcp_close(socket_control_block); - state = INACTIVE; -} - -void Socket::reconnect(){ - EthernetNode remote_node(remote_ip, remote_port); - if(!connecting_sockets.contains(remote_node)){ - connecting_sockets[remote_node] = this; - } - tcp_connect(connection_control_block, &remote_ip.address , remote_port, connect_callback); -} - -void Socket::reset(){ - EthernetNode remote_node(remote_ip, remote_port); - if(!connecting_sockets.contains(remote_node)){ - connecting_sockets[remote_node] = this; - } - state = INACTIVE; - tcp_abort(connection_control_block); - connection_control_block = tcp_new(); - - tcp_bind(connection_control_block, &local_ip.address, local_port); - tcp_nagle_disable(connection_control_block); - tcp_arg(connection_control_block, this); - tcp_poll(connection_control_block,connection_poll_callback,1); - tcp_err(connection_control_block, connection_error_callback); - - tcp_connect(connection_control_block, &remote_ip.address , remote_port, connect_callback); - -} - - -void Socket::send(){ - pbuf* temporal_packet_buffer; - err_t error = ERR_OK; - while(error == ERR_OK && !tx_packet_buffer.empty() && tx_packet_buffer.front()->len <= tcp_sndbuf(socket_control_block)){ - temporal_packet_buffer = tx_packet_buffer.front(); - error = tcp_write(socket_control_block, temporal_packet_buffer->payload, temporal_packet_buffer->len, TCP_WRITE_FLAG_COPY); - if(error == ERR_OK){ - tx_packet_buffer.pop(); - tcp_output(socket_control_block); - memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION],temporal_packet_buffer); - }else{ - if(error == ERR_MEM){ - close(); - ErrorHandler("Too many unacked messages on client socket, disconnecting..."); - }else{ - ErrorHandler("Cannot write to client socket. Error code: %d",error); - } - } - } -} - -void Socket::process_data(){ - while(!rx_packet_buffer.empty()){ - struct pbuf* packet = rx_packet_buffer.front(); - rx_packet_buffer.pop(); - uint8_t* new_data = (uint8_t*)(packet->payload); - tcp_recved(socket_control_block, packet->tot_len); - uint16_t id = Packet::get_id(new_data); - if (Order:: orders.contains(id)) { - Order::orders[id]->store_ip_order(remote_ip.string_address); - Order::process_data(this, new_data); - } - - pbuf_free(packet); - } -} - -bool Socket::add_order_to_queue(Order& order){ - if(state == Socket::SocketState::CONNECTED){ - return false; - } - struct memp* next_memory_pointer_in_packet_buffer_pool = (*(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION]->tab))->next; - if(next_memory_pointer_in_packet_buffer_pool == nullptr){ - memp_free_pool(memp_pools[PBUF_POOL_MEMORY_DESC_POSITION], next_memory_pointer_in_packet_buffer_pool); - return false; - } - - uint8_t* order_buffer = order.build(); - - struct pbuf* packet = pbuf_alloc(PBUF_TRANSPORT, order.get_size(), PBUF_POOL); - pbuf_take(packet, order_buffer, order.get_size()); - Socket::tx_packet_buffer.push(packet); - return true; -} - -bool Socket::is_connected(){ - return state == Socket::SocketState::CONNECTED; -} - -err_t Socket::connect_callback(void* arg, struct tcp_pcb* client_control_block, err_t error){ - IPV4 remote_ip; - remote_ip.address = client_control_block->remote_ip; - EthernetNode remote_node(remote_ip,client_control_block->remote_port); - - if(connecting_sockets.contains(remote_node)){ - Socket* socket = connecting_sockets[remote_node]; - connecting_sockets.erase(remote_node); - - socket->socket_control_block = client_control_block; - socket->state = CONNECTED; - - tcp_nagle_disable(client_control_block); - tcp_arg(client_control_block, socket); - tcp_recv(client_control_block, receive_callback); - tcp_poll(client_control_block, poll_callback,0); - tcp_sent(client_control_block, send_callback); - tcp_err(client_control_block, error_callback); - if(socket->use_keep_alives) - config_keepalive(client_control_block, socket); - - return ERR_OK; - }else return ERROR; -} - -err_t Socket::receive_callback(void* arg, struct tcp_pcb* client_control_block, struct pbuf* packet_buffer, err_t error){ - Socket* socket = (Socket*)arg; - socket->socket_control_block = client_control_block; - if(packet_buffer == nullptr){ //FIN is received - socket->state = CLOSING; - return ERR_OK; - } - if(error != ERR_OK){ - if(packet_buffer != nullptr){ - pbuf_free(packet_buffer); - } - return error; - }else if(socket->state == CONNECTED){ - socket->rx_packet_buffer.push(packet_buffer); - tcp_recved(client_control_block, packet_buffer->tot_len); - socket->process_data(); - pbuf_free(packet_buffer); - return ERR_OK; - }else{ - tcp_recved(client_control_block, packet_buffer->tot_len); - socket->tx_packet_buffer = {}; - pbuf_free(packet_buffer); - return ERR_OK; - } -} - -err_t Socket::poll_callback(void* arg, struct tcp_pcb* client_control_block){ - Socket* socket = (Socket*)arg; - socket->socket_control_block = client_control_block; - if(socket != nullptr){ - while(not socket->tx_packet_buffer.empty()){ - socket->send(); - } - if(socket->state == CLOSING){ - socket->close(); - }else if(socket->state == INACTIVE){ - tcp_connect(socket->connection_control_block, &socket->remote_ip.address , socket->remote_port, connect_callback); - } - return ERR_OK; - }else{ - tcp_abort(client_control_block); - return ERR_ABRT; - } -} - -err_t Socket::send_callback(void* arg, struct tcp_pcb* client_control_block, uint16_t length){ - Socket* socket = (Socket*)arg; - socket->socket_control_block = client_control_block; - if(not socket->tx_packet_buffer.empty()){ - socket->send(); - }else if(socket->state == CLOSING){ - socket->close(); - } - return ERR_OK; -} - -void Socket::error_callback(void *arg, err_t error){ - Socket* socket = (Socket*) arg; - socket->close(); - ErrorHandler("Client socket error: %d. Socket closed, remote ip: %s",error,socket->remote_ip.string_address.c_str()); -} - -void Socket::connection_error_callback(void *arg, err_t error){ - if(error == ERR_RST){ - Socket* socket = (Socket*) arg; - - socket->pending_connection_reset = true; - return; - }else if(error == ERR_ABRT){ - return; - } - ErrorHandler("Connection socket error: %d. Couldn t start client socket ", error); -} - -err_t Socket::connection_poll_callback(void *arg, struct tcp_pcb* connection_control_block){ - Socket* socket = (Socket*) arg; - if(socket->pending_connection_reset){ - socket->reset(); - socket->pending_connection_reset = false; - return ERR_ABRT; - } - else if(socket->connection_control_block->state == SYN_SENT){ - socket->pending_connection_reset = true; - } - return ERR_OK; -} - -void Socket::config_keepalive(tcp_pcb* control_block, Socket* socket){ - control_block->so_options |= SOF_KEEPALIVE; - control_block->keep_idle = socket->keepalive_config.inactivity_time_until_keepalive_ms; - control_block->keep_intvl = socket->keepalive_config.space_between_tries_ms; - control_block->keep_cnt = socket->keepalive_config.tries_until_disconnection; -} - -#endif - diff --git a/Src/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.cpp b/Src/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.cpp deleted file mode 100644 index 431f42b1..00000000 --- a/Src/HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * DatagramSocket.cpp - * - * Created on: 2 nov. 2022 - * Author: stefa - */ - -#include "HALAL/Services/Communication/Ethernet/UDP/DatagramSocket.hpp" -#include "ErrorHandler/ErrorHandler.hpp" - -#ifdef HAL_ETH_MODULE_ENABLED - -DatagramSocket::DatagramSocket() = default; - -DatagramSocket::DatagramSocket(DatagramSocket&& other):udp_control_block(move(other.udp_control_block)), local_ip(move(other.local_ip)) , local_port(move(other.local_port)) ,remote_ip(move(other.remote_ip)), - remote_port(move(remote_port)) - {} - -DatagramSocket::DatagramSocket(IPV4 local_ip, uint32_t local_port, IPV4 remote_ip, uint32_t remote_port): local_ip(local_ip), local_port(local_port), remote_ip(remote_ip), remote_port(remote_port){ - if(not Ethernet::is_running) { - ErrorHandler("Cannot declare UDP socket before Ethernet::start()"); - return; - } - udp_control_block = udp_new(); - err_t error = udp_bind(udp_control_block, &local_ip.address, local_port); - - if(error == ERR_OK){ - udp_recv(udp_control_block, receive_callback, nullptr); - udp_connect(udp_control_block, &remote_ip.address, remote_port); - is_disconnected = false; - Ethernet::update(); - } - else{ - udp_remove(udp_control_block); - is_disconnected = true; - ErrorHandler("Error binding UDP socket"); - } - } - -DatagramSocket::DatagramSocket(EthernetNode local_node, EthernetNode remote_node): DatagramSocket(local_node.ip, local_node.port, remote_node.ip, remote_node.port){} - -DatagramSocket::~DatagramSocket(){ - if(not is_disconnected) - close(); -} - -void DatagramSocket::operator=(DatagramSocket&& other){ - udp_control_block = move(other.udp_control_block); - local_ip = move(other.local_ip); - local_port = move(other.local_port); - remote_ip = other.remote_ip; - remote_port = other.remote_port; - other.is_disconnected = true; -} - -void DatagramSocket::reconnect(){ - udp_disconnect(udp_control_block); - is_disconnected = true; - err_t error = udp_bind(udp_control_block, &local_ip.address, local_port); - - if(error == ERR_OK){ - udp_recv(udp_control_block, receive_callback, nullptr); - udp_connect(udp_control_block, &remote_ip.address, remote_port); - is_disconnected = false; - Ethernet::update(); - } - else{ - udp_remove(udp_control_block); - is_disconnected = true; - ErrorHandler("Error binding UDP socket"); - } -} - -void DatagramSocket::close(){ - udp_disconnect(udp_control_block); - udp_remove(udp_control_block); - is_disconnected = true; -} - -void DatagramSocket::receive_callback(void *args, struct udp_pcb *udp_control_block, struct pbuf *packet_buffer, const ip_addr_t *remote_address, u16_t port){ - uint8_t* received_data = (uint8_t*)packet_buffer->payload; - Packet::parse_data(received_data); - - pbuf_free(packet_buffer); -} - -#endif From 50e07dd710180dbc8309c5da37723899b945ddb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 00:12:23 +0100 Subject: [PATCH 08/19] Modified cmakelists to list manually and refactored includes through all the project --- CMakeLists.txt | 258 +++++++++++------- .../Communication/Ethernet/NewEthernet.hpp | 20 +- .../Control/Blocks/MovingAverage.hpp | 8 +- Inc/ST-LIB_HIGH/FlashStorer/FlashStorer.hpp | 5 +- Inc/ST-LIB_HIGH/Protections/Boundary.hpp | 5 +- Inc/ST-LIB_HIGH/Protections/Notification.hpp | 3 +- .../Protections/ProtectionManager.hpp | 6 +- .../Communication/Server/Server.hpp | 8 +- .../DigitalOutput/DigitalOutput.hpp | 4 +- Inc/ST-LIB_LOW/HalfBridge/HalfBridge.hpp | 5 +- Inc/ST-LIB_LOW/Math/Math.hpp | 5 +- Inc/ST-LIB_LOW/Sd/Sd.hpp | 12 +- Inc/ST-LIB_LOW/Sensors/Common/PT100.hpp | 10 +- .../Sensors/DigitalSensor/DigitalSensor.hpp | 6 +- .../Sensors/EncoderSensor/EncoderSensor.hpp | 7 +- .../Sensors/LinearSensor/LinearSensor.hpp | 7 +- .../Sensors/LookupSensor/LookupSensor.hpp | 3 +- Inc/ST-LIB_LOW/Sensors/NTC/NTC.hpp | 7 +- .../Sensors/PWMSensor/PWMSensor.hpp | 7 +- Inc/ST-LIB_LOW/Sensors/Sensor/Sensor.hpp | 11 +- .../SensorInterrupt/SensorInterrupt.hpp | 6 +- Inc/ST-LIB_LOW/StateMachine/StateMachine.hpp | 2 +- Inc/ST-LIB_LOW/StateMachine/StateOrder.hpp | 5 +- LWIP/Target/ethernetif.c | 28 +- .../Communication/Ethernet/PHY/ksz8041.c | 12 +- .../Protections/ProtectionManager.cpp | 2 + Src/ST-LIB_LOW/Clocks/Counter.cpp | 3 +- Src/ST-LIB_LOW/Clocks/Stopwatch.cpp | 3 +- .../DigitalOutput/DigitalOutput.cpp | 4 +- Src/ST-LIB_LOW/HalfBridge/HalfBridge.cpp | 2 + Src/ST-LIB_LOW/Math/Math.cpp | 5 +- .../Sensors/DigitalSensor/DigitalSensor.cpp | 3 +- .../Sensors/LookupSensor/LookupSensor.cpp | 2 + Src/ST-LIB_LOW/Sensors/Sensor/Sensor.cpp | 10 +- 34 files changed, 326 insertions(+), 158 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd82f13a..81e60dd4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,11 +16,17 @@ enable_testing() option(USE_ETHERNET "Enable ethernet peripheral" OFF) option(TARGET_NUCLEO "Targets the STM32H723 Nucleo development board" OFF) +set(LAN8742_PHY_ADDRESS 0 CACHE STRING "LAN8742 PHY address (strap-dependent)") +set(KSZ8041_PHY_ADDRESS 1 CACHE STRING "KSZ8041 PHY address (strap-dependent)") # ============================ # PHY selection (Ethernet) # ============================ +set(SELECTED_PHY "") +set(USE_PHY_LAN8742 OFF) +set(USE_PHY_KSZ8041 OFF) + if(USE_ETHERNET) if(TARGET_NUCLEO) @@ -34,6 +40,14 @@ if(USE_ETHERNET) set(SELECTED_PHY "${PHY_TYPE}") endif() + if(SELECTED_PHY STREQUAL "LAN8742") + set(USE_PHY_LAN8742 ON) + elseif(SELECTED_PHY STREQUAL "KSZ8041") + set(USE_PHY_KSZ8041 ON) + else() + message(FATAL_ERROR "Unknown PHY: ${SELECTED_PHY}") + endif() + message(STATUS "${PROJECT_NAME} PHY: ${SELECTED_PHY}") endif() @@ -154,78 +168,135 @@ if(CMAKE_CROSSCOMPILING) ) if(USE_ETHERNET) - set(LWIP_DIR ${STM32CUBEH7}/Middlewares/Third_Party/LwIP) - file(GLOB LWIP_SOURCES - ${LWIP_DIR}/src/core/*.c - ${LWIP_DIR}/src/core/ipv4/*.c - ${LWIP_DIR}/src/core/ipv6/*.c - ${LWIP_DIR}/src/api/*.c - ${LWIP_DIR}/src/netif/*.c - ${LWIP_DIR}/system/*.c + set(LWIP_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/api_lib.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/api_msg.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/err.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/if_api.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/netbuf.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/netdb.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/netifapi.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/sockets.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/tcpip.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/altcp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/altcp_alloc.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/altcp_tcp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/def.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/dns.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/inet_chksum.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/init.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ip.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/autoip.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/dhcp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/etharp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/icmp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/igmp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4_addr.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4_frag.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/dhcp6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ethip6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/icmp6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/inet6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ip6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ip6_addr.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ip6_frag.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/mld6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/nd6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/mem.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/memp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/netif.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/pbuf.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/raw.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/stats.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/sys.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/tcp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/tcp_in.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/tcp_out.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/timeouts.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/udp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/bridgeif.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/bridgeif_fdb.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/ethernet.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/lowpan6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/lowpan6_ble.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/lowpan6_common.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/slipif.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/zepif.c ) set(USER_LWIP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/LWIP/App/lwip.c ${CMAKE_CURRENT_LIST_DIR}/LWIP/Target/ethernetif.c ) - - # PHY-specific source (HALAL) - if(SELECTED_PHY STREQUAL "LAN8742") - set(PHY_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c - ) - elseif(SELECTED_PHY STREQUAL "KSZ8041") - set(PHY_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c - ) - else() - message(FATAL_ERROR "Unknown PHY: ${SELECTED_PHY}") - endif() - - list(APPEND LWIP_SOURCES - ${PHY_SOURCES} - ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c - ) - - file(GLOB_RECURSE USER_LWIP_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/LWIP/*.c - ) - endif() - - file(GLOB_RECURSE USER_LWIP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/LWIP/*.c) endif() # ============================ # HALAL: ETH / NO_ETH # ============================ -file(GLOB_RECURSE HALAL_C_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/*.c) -file(GLOB_RECURSE HALAL_CPP_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/*.cpp) - -set(HALAL_ETH_CORE_REGEX - ".*/HALAL/Services/Communication/Ethernet/[^/]+\\.(c|cpp)$" +set(HALAL_C_NO_ETH + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/HardFault/HardfaultTrace.c ) -set(HALAL_C_ETH_CORE ${HALAL_C_ALL}) -list(FILTER HALAL_C_ETH_CORE INCLUDE REGEX "${HALAL_ETH_CORE_REGEX}") - -set(HALAL_CPP_ETH_CORE ${HALAL_CPP_ALL}) -list(FILTER HALAL_CPP_ETH_CORE INCLUDE REGEX "${HALAL_ETH_CORE_REGEX}") - -set(HALAL_ETH_LWIP_REGEX - ".*/HALAL/Services/Communication/Ethernet/LWIP/.*" +set(HALAL_CPP_NO_ETH + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/HALAL.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/DMA/DMA.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/HALconfig/Halconfig.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/LowPowerTimer/LowPowerTimer.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/MDMA/MDMA.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/MPUManager/MPUManager.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/Packets/SPIOrder.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/PinModel/Pin.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/TimerDomain/TimerDomain.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/TimerPeripheral/TimerPeripheral.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/ADC/ADC.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/CORDIC/CORDIC.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/FDCAN/FDCAN.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/I2C/I2C.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/SPI/SPI.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/UART/UART.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/DigitalInputService/DigitalInputService.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/DigitalOutputService/DigitalOutputService.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/EXTI/EXTI.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Encoder/Encoder.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/FMAC/FMAC.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Flash/Flash.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Flash/FlashTests/Flash_Test.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/InfoWarning/InfoWarning.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/InputCapture/InputCapture.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/PWM/DualCenterPWM/DualCenterPWM.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/PWM/DualPWM/DualPWM.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/PWM/DualPhasedPWM/DualPhasedPWM.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/PWM/PWM/PWM.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/PWM/PhasedPWM/PhasedPWM.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Time/RTC.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Time/Scheduler.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Time/Time.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Watchdog/Watchdog.cpp ) -set(HALAL_C_ETH_LWIP ${HALAL_C_ALL}) -list(FILTER HALAL_C_ETH_LWIP INCLUDE REGEX "${HALAL_ETH_LWIP_REGEX}") - -set(HALAL_CPP_ETH_LWIP ${HALAL_CPP_ALL}) -list(FILTER HALAL_CPP_ETH_LWIP INCLUDE REGEX "${HALAL_ETH_LWIP_REGEX}") +set(HALAL_C_ETH_CORE) +set(HALAL_CPP_ETH_CORE + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/IPV4/IPV4.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/MAC/MAC.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/Packets/Packet.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/SNTP/SNTP.cpp +) -set(HALAL_C_ETH_PHY "") +set(HALAL_C_ETH_LWIP) +set(HALAL_CPP_ETH_LWIP + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/LWIP/Ethernet.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/OrderProtocol.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/LWIP/TCP/Socket.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/LWIP/UDP/DatagramSocket.cpp +) +set(HALAL_C_ETH_PHY) if(USE_ETHERNET) list(APPEND HALAL_C_ETH_PHY ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c @@ -234,6 +305,7 @@ if(USE_ETHERNET) if(USE_PHY_LAN8742) list(APPEND HALAL_C_ETH_PHY ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Drivers/BSP/Components/lan8742/lan8742.c ) endif() @@ -244,60 +316,58 @@ if(USE_ETHERNET) endif() endif() -set(HALAL_C_NO_ETH ${HALAL_C_ALL}) -list(FILTER HALAL_C_NO_ETH EXCLUDE REGEX - ".*/HALAL/Services/Communication/Ethernet/.*" -) - -set(HALAL_CPP_NO_ETH ${HALAL_CPP_ALL}) -list(FILTER HALAL_CPP_NO_ETH EXCLUDE REGEX - ".*/HALAL/Services/Communication/Ethernet/.*" -) - # ============================ # C++ Utilities # ============================ -file(GLOB_RECURSE CPP_UTILITIES_C ${CMAKE_CURRENT_LIST_DIR}/Src/C++Utilities/*.c) -file(GLOB_RECURSE CPP_UTILITIES_CPP ${CMAKE_CURRENT_LIST_DIR}/Src/C++Utilities/*.cpp) +set(CPP_UTILITIES_C) +set(CPP_UTILITIES_CPP) # ============================ # ST-LIB_LOW: ETH / NO_ETH # ============================ -file(GLOB_RECURSE STLIB_LOW_C_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/*.c) -file(GLOB_RECURSE STLIB_LOW_CPP_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/*.cpp) +set(STLIB_LOW_C_ETH) -set(STLIB_LOW_ETH_REGEX ".*/ST-LIB_LOW/(Communication/.*|StateMachine/(StateOrder|HeapStateOrder|StackStateOrder)\\.cpp)$") -set(STLIB_LOW_C_ETH ${STLIB_LOW_C_ALL}) -list(FILTER STLIB_LOW_C_ETH INCLUDE REGEX "${STLIB_LOW_ETH_REGEX}") - -set(STLIB_LOW_CPP_ETH ${STLIB_LOW_CPP_ALL}) -list(FILTER STLIB_LOW_CPP_ETH INCLUDE REGEX "${STLIB_LOW_ETH_REGEX}") - -set(STLIB_LOW_C_NO_ETH ${STLIB_LOW_C_ALL}) -list(FILTER STLIB_LOW_C_NO_ETH EXCLUDE REGEX "${STLIB_LOW_ETH_REGEX}") +set(STLIB_LOW_CPP_ETH + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Communication/Server/Server.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/StateMachine/StateOrder.cpp +) -set(STLIB_LOW_CPP_NO_ETH ${STLIB_LOW_CPP_ALL}) -list(FILTER STLIB_LOW_CPP_NO_ETH EXCLUDE REGEX "${STLIB_LOW_ETH_REGEX}") +set(STLIB_LOW_C_NO_ETH) + +set(STLIB_LOW_CPP_NO_ETH + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Clocks/Counter.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Clocks/Stopwatch.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/DigitalOutput/DigitalOutput.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/ErrorHandler/ErrorHandler.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/HalfBridge/HalfBridge.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Math/Math.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/ST-LIB_LOW.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sd/Sd.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/NTC/NTC.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/Sensor/Sensor.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_LOW/Sensors/SensorInterrupt/SensorInterrupt.cpp +) # ============================ # ST-LIB_HIGH # ============================ -file(GLOB_RECURSE STLIB_HIGH_C_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_HIGH/*.c) -file(GLOB_RECURSE STLIB_HIGH_CPP_ALL ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_HIGH/*.cpp) +set(STLIB_HIGH_C_ETH) -set(STLIB_HIGH_ETH_REGEX ".*/ST-LIB_HIGH/Protections/.*\\.cpp$") -set(STLIB_HIGH_C_ETH ${STLIB_HIGH_C_ALL}) -list(FILTER STLIB_HIGH_C_ETH INCLUDE REGEX "${STLIB_HIGH_ETH_REGEX}") - -set(STLIB_HIGH_CPP_ETH ${STLIB_HIGH_CPP_ALL}) -list(FILTER STLIB_HIGH_CPP_ETH INCLUDE REGEX "${STLIB_HIGH_ETH_REGEX}") +set(STLIB_HIGH_CPP_ETH + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_HIGH/Protections/Boundary.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_HIGH/Protections/ProtectionManager.cpp +) -set(STLIB_HIGH_C_NO_ETH ${STLIB_HIGH_C_ALL}) -list(FILTER STLIB_HIGH_C_NO_ETH EXCLUDE REGEX "${STLIB_HIGH_ETH_REGEX}") +set(STLIB_HIGH_C_NO_ETH) -set(STLIB_HIGH_CPP_NO_ETH ${STLIB_HIGH_CPP_ALL}) -list(FILTER STLIB_HIGH_CPP_NO_ETH EXCLUDE REGEX "${STLIB_HIGH_ETH_REGEX}") +set(STLIB_HIGH_CPP_NO_ETH + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_HIGH/FlashStorer/FlashStorer.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_HIGH/FlashStorer/FlashVariable.cpp + ${CMAKE_CURRENT_LIST_DIR}/Src/ST-LIB_HIGH/ST-LIB_HIGH.cpp +) # ============================ # Librería STLIB_LIBRARY @@ -312,8 +382,8 @@ add_library(${STLIB_LIBRARY} STATIC ${HALAL_C_NO_ETH} ${HALAL_CPP_NO_ETH} - ${HALAL_C_ETH_CORE} - ${HALAL_CPP_ETH_CORE} + $<$:${HALAL_C_ETH_CORE}> + $<$:${HALAL_CPP_ETH_CORE}> $<$:${HALAL_C_ETH_LWIP}> $<$:${HALAL_CPP_ETH_LWIP}> @@ -353,8 +423,10 @@ target_compile_definitions(${STLIB_LIBRARY} PUBLIC $<$:USE_HAL_DRIVER> $<$:STM32H723xx> - $<$,$>:USE_PHY_LAN8742> - $<$,$>:USE_PHY_KSZ8041> + $<$:USE_PHY_LAN8742> + $<$:USE_PHY_KSZ8041> + $<$:LAN8742_PHY_ADDRESS=${LAN8742_PHY_ADDRESS}> + $<$:KSZ8041_PHY_ADDRESS=${KSZ8041_PHY_ADDRESS}> $<$>:TESTING_ENV> diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index 29d64d31..def88bbe 100644 --- a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -22,6 +22,13 @@ extern uint8_t IP_ADDRESS[4], NETMASK_ADDRESS[4], GATEWAY_ADDRESS[4]; namespace ST_LIB { extern void compile_error(const char *msg); +#ifndef PHY_RESET_LOW_DELAY_MS +#define PHY_RESET_LOW_DELAY_MS 10 +#endif +#ifndef PHY_RESET_HIGH_DELAY_MS +#define PHY_RESET_HIGH_DELAY_MS 10 +#endif + struct EthernetDomain { struct EthernetPins { @@ -189,12 +196,12 @@ struct EthernetDomain { for (std::size_t i = 0; i < N; ++i) { const EthernetDomain::Config &e = cfgs[i]; - /* --- RESET PHY (KSZ8041) --- */ + /* --- RESET PHY --- */ // RESET_N pin low then high do_instances[e.phy_reset_id].turn_off(); // RESET_N = 0 - HAL_Delay(10); + HAL_Delay(PHY_RESET_LOW_DELAY_MS); do_instances[e.phy_reset_id].turn_on(); // RESET_N = 1 - HAL_Delay(10); + HAL_Delay(PHY_RESET_HIGH_DELAY_MS); /* --- CLOCKS ETH --- */ __HAL_RCC_ETH1MAC_CLK_ENABLE(); @@ -261,8 +268,9 @@ struct EthernetDomain { } struct Instance {}; template struct Init { - static void init(std::span cfgs) {} - }; + static void init(std::span cfgs, + std::span do_instances) {}; + } }; } // namespace ST_LIB -#endif // STLIB_ETH \ No newline at end of file +#endif // STLIB_ETH diff --git a/Inc/ST-LIB_HIGH/Control/Blocks/MovingAverage.hpp b/Inc/ST-LIB_HIGH/Control/Blocks/MovingAverage.hpp index 175c6184..b5be8a2a 100644 --- a/Inc/ST-LIB_HIGH/Control/Blocks/MovingAverage.hpp +++ b/Inc/ST-LIB_HIGH/Control/Blocks/MovingAverage.hpp @@ -1,8 +1,11 @@ #pragma once -#include "stdio.h" +#include +#include +#include + #include "../ControlSystem.hpp" -#include "HALAL/HALAL.hpp" +#include "HALAL/Models/Concepts/Concepts.hpp" template class MovingAverage : public ControlBlock { @@ -154,4 +157,3 @@ class IntegerMovingAverage : public ControlBlock { } } }; - diff --git a/Inc/ST-LIB_HIGH/FlashStorer/FlashStorer.hpp b/Inc/ST-LIB_HIGH/FlashStorer/FlashStorer.hpp index 67fae197..410f6d3c 100644 --- a/Inc/ST-LIB_HIGH/FlashStorer/FlashStorer.hpp +++ b/Inc/ST-LIB_HIGH/FlashStorer/FlashStorer.hpp @@ -1,9 +1,9 @@ #pragma once #include "C++Utilities/CppUtils.hpp" -#include "ErrorHandler/ErrorHandler.hpp" -#include "HALAL/HALAL.hpp" #include "FlashVariable.hpp" +#include "HALAL/Models/Concepts/Concepts.hpp" +#include "HALAL/Services/Flash/Flash.hpp" #define FLASH_STORER_MAX_SIZE ((uint32_t)(1028*64)) #define FLASH_STORER_START_ADDRESS (FLASH_STORER_MAX_ADDRESS - FLASH_STORER_MAX_SIZE) @@ -67,4 +67,3 @@ bool FlashStorer::add_variables(Type&... var){ return FlashStorer::total_size >= FLASH_STORER_MAX_SIZE; } - diff --git a/Inc/ST-LIB_HIGH/Protections/Boundary.hpp b/Inc/ST-LIB_HIGH/Protections/Boundary.hpp index 774709dc..d939f93e 100644 --- a/Inc/ST-LIB_HIGH/Protections/Boundary.hpp +++ b/Inc/ST-LIB_HIGH/Protections/Boundary.hpp @@ -1,8 +1,11 @@ #pragma once #define PROTECTIONTYPE_LENGTH 8 +#include "C++Utilities/CppUtils.hpp" #include "Control/Blocks/MeanCalculator.hpp" #include "ErrorHandler/ErrorHandler.hpp" -#include "HALAL/HALAL.hpp" +#include "HALAL/Models/Packets/Order.hpp" +#include "HALAL/Services/InfoWarning/InfoWarning.hpp" +#include "HALAL/Services/Time/RTC.hpp" using type_id_t = void (*)(); template diff --git a/Inc/ST-LIB_HIGH/Protections/Notification.hpp b/Inc/ST-LIB_HIGH/Protections/Notification.hpp index 45fc52b2..16472822 100644 --- a/Inc/ST-LIB_HIGH/Protections/Notification.hpp +++ b/Inc/ST-LIB_HIGH/Protections/Notification.hpp @@ -2,8 +2,8 @@ #include "C++Utilities/CppUtils.hpp" #include "ErrorHandler/ErrorHandler.hpp" +#include "HALAL/Models/Packets/Order.hpp" #include "Protection.hpp" -#include "HALAL/HALAL.hpp" class Notification : public Order{ private: @@ -99,4 +99,3 @@ class Notification : public Order{ return *(uint16_t*)(buffer + sizeof(id)); } }; - diff --git a/Inc/ST-LIB_HIGH/Protections/ProtectionManager.hpp b/Inc/ST-LIB_HIGH/Protections/ProtectionManager.hpp index 4beb1094..62564998 100644 --- a/Inc/ST-LIB_HIGH/Protections/ProtectionManager.hpp +++ b/Inc/ST-LIB_HIGH/Protections/ProtectionManager.hpp @@ -1,6 +1,10 @@ #pragma once -#include "HALAL/HALAL.hpp" +#include + +#include "C++Utilities/CppUtils.hpp" +#include "HALAL/Models/BoardID/BoardID.hpp" +#include "HALAL/Models/Packets/Order.hpp" #include "Notification.hpp" #include "Protection.hpp" #include "StateMachine/StateMachine.hpp" diff --git a/Inc/ST-LIB_LOW/Communication/Server/Server.hpp b/Inc/ST-LIB_LOW/Communication/Server/Server.hpp index 3c682524..dc78ab02 100644 --- a/Inc/ST-LIB_LOW/Communication/Server/Server.hpp +++ b/Inc/ST-LIB_LOW/Communication/Server/Server.hpp @@ -7,8 +7,14 @@ #pragma once #ifdef STLIB_ETH -#include "HALAL/HALAL.hpp" +#include +#include +#include + #include "ErrorHandler/ErrorHandler.hpp" +#include "HALAL/Models/IPV4/IPV4.hpp" +#include "HALAL/Models/Packets/Order.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/TCP/ServerSocket.hpp" #ifndef MAX_CONNECTIONS_TCP_SERVER #define MAX_CONNECTIONS_TCP_SERVER 10 diff --git a/Inc/ST-LIB_LOW/DigitalOutput/DigitalOutput.hpp b/Inc/ST-LIB_LOW/DigitalOutput/DigitalOutput.hpp index d3f707d4..8566d5cf 100644 --- a/Inc/ST-LIB_LOW/DigitalOutput/DigitalOutput.hpp +++ b/Inc/ST-LIB_LOW/DigitalOutput/DigitalOutput.hpp @@ -7,7 +7,9 @@ #pragma once -#include "HALAL/HALAL.hpp" +#include + +#include "HALAL/Models/PinModel/Pin.hpp" class DigitalOutput { public: diff --git a/Inc/ST-LIB_LOW/HalfBridge/HalfBridge.hpp b/Inc/ST-LIB_LOW/HalfBridge/HalfBridge.hpp index 8e8b4f88..3ddd6dfa 100644 --- a/Inc/ST-LIB_LOW/HalfBridge/HalfBridge.hpp +++ b/Inc/ST-LIB_LOW/HalfBridge/HalfBridge.hpp @@ -7,7 +7,10 @@ #pragma once -#include "HALAL/HALAL.hpp" +#include + +#include "HALAL/Models/PinModel/Pin.hpp" +#include "HALAL/Services/PWM/DualPhasedPWM/DualPhasedPWM.hpp" #include "ErrorHandler/ErrorHandler.hpp" class HalfBridge { diff --git a/Inc/ST-LIB_LOW/Math/Math.hpp b/Inc/ST-LIB_LOW/Math/Math.hpp index 552ebd7e..a895d088 100644 --- a/Inc/ST-LIB_LOW/Math/Math.hpp +++ b/Inc/ST-LIB_LOW/Math/Math.hpp @@ -6,7 +6,8 @@ */ #pragma once -#include "ST-LIB.hpp" +#include +#include #define TG_DECIMAL_BITS 16 #define SQ_DECIMAL_BITS 16 #define MAX_INT 2147483647 @@ -31,5 +32,5 @@ class Math{ static inline int32_t tg_to_unitary(int32_t tg_in); static inline int32_t unitary_to_tg(int32_t in); private: - static array pointers; + static std::array pointers; }; diff --git a/Inc/ST-LIB_LOW/Sd/Sd.hpp b/Inc/ST-LIB_LOW/Sd/Sd.hpp index 02441d6c..08f834bb 100644 --- a/Inc/ST-LIB_LOW/Sd/Sd.hpp +++ b/Inc/ST-LIB_LOW/Sd/Sd.hpp @@ -8,10 +8,18 @@ #ifndef SD_HPP #define SD_HPP +#include +#include +#include +#include +#include +#include + #include "stm32h7xx_hal.h" #include "ErrorHandler/ErrorHandler.hpp" -#include "HALAL/HALAL.hpp" +#include "HALAL/Models/Pin.hpp" +#include "HALAL/Models/MPU.hpp" #include "ST-LIB_LOW/DigitalInput2.hpp" using ST_LIB::DigitalInputDomain; @@ -443,4 +451,4 @@ static inline SdDomain::Instance* get_sd_instance(SD_HandleTypeDef *hsd) { } // namespace ST_LIB -#endif // SD_HPP \ No newline at end of file +#endif // SD_HPP diff --git a/Inc/ST-LIB_LOW/Sensors/Common/PT100.hpp b/Inc/ST-LIB_LOW/Sensors/Common/PT100.hpp index 209f6d3f..1a05075d 100644 --- a/Inc/ST-LIB_LOW/Sensors/Common/PT100.hpp +++ b/Inc/ST-LIB_LOW/Sensors/Common/PT100.hpp @@ -1,9 +1,11 @@ #pragma once -#include "HALAL/HALAL.hpp" -#include "Sensors/Sensor/Sensor.hpp" -#include "ErrorHandler/ErrorHandler.hpp" -#include "Control/ControlBlock.hpp" +#include +#include + #include "Control/Blocks/MovingAverage.hpp" +#include "HALAL/Models/PinModel/Pin.hpp" +#include "HALAL/Services/ADC/ADC.hpp" +#include "Sensors/Sensor/Sensor.hpp" template diff --git a/Inc/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.hpp b/Inc/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.hpp index 8689d52b..55ec634d 100644 --- a/Inc/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.hpp +++ b/Inc/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.hpp @@ -7,8 +7,9 @@ */ #pragma once -#include "HALAL/HALAL.hpp" -#include "ErrorHandler/ErrorHandler.hpp" +#include + +#include "HALAL/Models/PinModel/Pin.hpp" class DigitalSensor{ @@ -24,4 +25,3 @@ class DigitalSensor{ PinState *value; }; - diff --git a/Inc/ST-LIB_LOW/Sensors/EncoderSensor/EncoderSensor.hpp b/Inc/ST-LIB_LOW/Sensors/EncoderSensor/EncoderSensor.hpp index 6f65985d..53cdd84b 100644 --- a/Inc/ST-LIB_LOW/Sensors/EncoderSensor/EncoderSensor.hpp +++ b/Inc/ST-LIB_LOW/Sensors/EncoderSensor/EncoderSensor.hpp @@ -7,8 +7,13 @@ */ #pragma once +#include +#include + +#include "C++Utilities/CppUtils.hpp" #include "ErrorHandler/ErrorHandler.hpp" -#include "HALAL/HALAL.hpp" +#include "HALAL/Models/PinModel/Pin.hpp" +#include "HALAL/Services/Encoder/Encoder.hpp" template class EncoderSensor { diff --git a/Inc/ST-LIB_LOW/Sensors/LinearSensor/LinearSensor.hpp b/Inc/ST-LIB_LOW/Sensors/LinearSensor/LinearSensor.hpp index 3d312438..8923318d 100644 --- a/Inc/ST-LIB_LOW/Sensors/LinearSensor/LinearSensor.hpp +++ b/Inc/ST-LIB_LOW/Sensors/LinearSensor/LinearSensor.hpp @@ -6,8 +6,11 @@ */ #pragma once -#include "HALAL/HALAL.hpp" -#include "ErrorHandler/ErrorHandler.hpp" +#include +#include + +#include "HALAL/Models/PinModel/Pin.hpp" +#include "HALAL/Services/ADC/ADC.hpp" #include "Sensors/Sensor/Sensor.hpp" template diff --git a/Inc/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.hpp b/Inc/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.hpp index 5a508db7..1cc766d9 100644 --- a/Inc/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.hpp +++ b/Inc/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.hpp @@ -6,7 +6,8 @@ */ #pragma once -#include "HALAL/HALAL.hpp" +#include +#include "HALAL/Models/PinModel/Pin.hpp" #include "ErrorHandler/ErrorHandler.hpp" #include "C++Utilities/CppUtils.hpp" diff --git a/Inc/ST-LIB_LOW/Sensors/NTC/NTC.hpp b/Inc/ST-LIB_LOW/Sensors/NTC/NTC.hpp index 76e05361..3c139116 100644 --- a/Inc/ST-LIB_LOW/Sensors/NTC/NTC.hpp +++ b/Inc/ST-LIB_LOW/Sensors/NTC/NTC.hpp @@ -10,9 +10,11 @@ This NTC class is not generic. It is only for 10k Ohm, 1976Beta value NTCs. */ #pragma once -#include "HALAL/HALAL.hpp" +#include + +#include "HALAL/Models/PinModel/Pin.hpp" +#include "HALAL/Services/ADC/ADC.hpp" #include "Sensors/Sensor/Sensor.hpp" -#include "ErrorHandler/ErrorHandler.hpp" class NTC{ public: @@ -501,4 +503,3 @@ class NTC{ float* value; uint8_t id; }; - diff --git a/Inc/ST-LIB_LOW/Sensors/PWMSensor/PWMSensor.hpp b/Inc/ST-LIB_LOW/Sensors/PWMSensor/PWMSensor.hpp index d490a10e..4b929973 100644 --- a/Inc/ST-LIB_LOW/Sensors/PWMSensor/PWMSensor.hpp +++ b/Inc/ST-LIB_LOW/Sensors/PWMSensor/PWMSensor.hpp @@ -7,8 +7,11 @@ */ #pragma once -#include "ErrorHandler/ErrorHandler.hpp" -#include "HALAL/HALAL.hpp" +#include + +#include "HALAL/Models/PinModel/Pin.hpp" +#include "HALAL/Services/InputCapture/InputCapture.hpp" +#include "Sensors/Sensor/Sensor.hpp" template class PWMSensor { protected: diff --git a/Inc/ST-LIB_LOW/Sensors/Sensor/Sensor.hpp b/Inc/ST-LIB_LOW/Sensors/Sensor/Sensor.hpp index e6daef5e..5d843fa8 100644 --- a/Inc/ST-LIB_LOW/Sensors/Sensor/Sensor.hpp +++ b/Inc/ST-LIB_LOW/Sensors/Sensor/Sensor.hpp @@ -6,14 +6,13 @@ */ #pragma once -#include "C++Utilities/CppUtils.hpp" -#include "HALAL/HALAL.hpp" +#include +#include class Sensor{ public: static void start(); - static vector adc_id_list; - static vector EXTI_id_list; - static vector inputcapture_id_list; + static std::vector adc_id_list; + static std::vector EXTI_id_list; + static std::vector inputcapture_id_list; }; - diff --git a/Inc/ST-LIB_LOW/Sensors/SensorInterrupt/SensorInterrupt.hpp b/Inc/ST-LIB_LOW/Sensors/SensorInterrupt/SensorInterrupt.hpp index 2519cd09..20cbc70e 100644 --- a/Inc/ST-LIB_LOW/Sensors/SensorInterrupt/SensorInterrupt.hpp +++ b/Inc/ST-LIB_LOW/Sensors/SensorInterrupt/SensorInterrupt.hpp @@ -7,8 +7,10 @@ */ #pragma once -#include "HALAL/HALAL.hpp" -#include "ErrorHandler/ErrorHandler.hpp" +#include +#include + +#include "HALAL/Services/EXTI/EXTI.hpp" class SensorInterrupt{ public: diff --git a/Inc/ST-LIB_LOW/StateMachine/StateMachine.hpp b/Inc/ST-LIB_LOW/StateMachine/StateMachine.hpp index 790d02b5..9ae7b2a9 100644 --- a/Inc/ST-LIB_LOW/StateMachine/StateMachine.hpp +++ b/Inc/ST-LIB_LOW/StateMachine/StateMachine.hpp @@ -2,7 +2,7 @@ #include "C++Utilities/CppUtils.hpp" #include "C++Utilities/StaticVector.hpp" #include "ErrorHandler/ErrorHandler.hpp" -#include "HALAL/HALAL.hpp" +#include "HALAL/Services/Time/Scheduler.hpp" #include #include #include diff --git a/Inc/ST-LIB_LOW/StateMachine/StateOrder.hpp b/Inc/ST-LIB_LOW/StateMachine/StateOrder.hpp index 99d0a387..f7ad0a20 100644 --- a/Inc/ST-LIB_LOW/StateMachine/StateOrder.hpp +++ b/Inc/ST-LIB_LOW/StateMachine/StateOrder.hpp @@ -1,5 +1,7 @@ #pragma once -#include "HALAL/HALAL.hpp" +#include +#include "HALAL/Models/Packets/Order.hpp" +#include "HALAL/Models/Packets/OrderProtocol.hpp" #include "ErrorHandler/ErrorHandler.hpp" #include @@ -42,4 +44,3 @@ class StateOrder : public Order{ - diff --git a/LWIP/Target/ethernetif.c b/LWIP/Target/ethernetif.c index b8670841..2b558efc 100644 --- a/LWIP/Target/ethernetif.c +++ b/LWIP/Target/ethernetif.c @@ -258,4 +258,30 @@ void pbuf_free_custom(struct pbuf *p) { RxAllocStatus = RX_ALLOC_OK; } -u32_t sys_now(void) { return HAL_GetTick(); } \ No newline at end of file +u32_t sys_now(void) { return HAL_GetTick(); } + +/******************************************************************************* + * PHY IO (LAN8742) + ******************************************************************************/ +int32_t ETH_PHY_IO_Init(void) { + HAL_ETH_SetMDIOClockRange(&heth); + return 0; +} + +int32_t ETH_PHY_IO_DeInit(void) { return 0; } + +int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, + uint32_t *pRegVal) { + return (HAL_ETH_ReadPHYRegister(&heth, DevAddr, RegAddr, pRegVal) == HAL_OK) + ? 0 + : -1; +} + +int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, + uint32_t RegVal) { + return (HAL_ETH_WritePHYRegister(&heth, DevAddr, RegAddr, RegVal) == HAL_OK) + ? 0 + : -1; +} + +int32_t ETH_PHY_IO_GetTick(void) { return HAL_GetTick(); } diff --git a/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c b/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c index 5ef59a5d..3225f984 100644 --- a/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c +++ b/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c @@ -4,11 +4,13 @@ #ifdef USE_PHY_KSZ8041 extern ETH_HandleTypeDef heth; -#define PHY_ADDR 1 +#ifndef KSZ8041_PHY_ADDRESS +#define KSZ8041_PHY_ADDRESS 1 +#endif static uint32_t phy_read(uint32_t reg) { uint32_t val; - HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, reg, &val); + HAL_ETH_ReadPHYRegister(&heth, KSZ8041_PHY_ADDRESS, reg, &val); return val; } @@ -16,8 +18,8 @@ static phy_link_state_t ksz8041_get_link_state(void) { static uint8_t link_latched = 0; uint32_t bmsr; - HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, 1, &bmsr); - HAL_ETH_ReadPHYRegister(&heth, PHY_ADDR, 1, &bmsr); + HAL_ETH_ReadPHYRegister(&heth, KSZ8041_PHY_ADDRESS, 1, &bmsr); + HAL_ETH_ReadPHYRegister(&heth, KSZ8041_PHY_ADDRESS, 1, &bmsr); if (!(bmsr & (1 << 2))) { link_latched = 0; @@ -35,4 +37,4 @@ static phy_link_state_t ksz8041_get_link_state(void) { const phy_driver_t phy_ksz8041 = {.init = NULL, .get_link_state = ksz8041_get_link_state}; -#endif \ No newline at end of file +#endif diff --git a/Src/ST-LIB_HIGH/Protections/ProtectionManager.cpp b/Src/ST-LIB_HIGH/Protections/ProtectionManager.cpp index 3b4799be..0f93b137 100644 --- a/Src/ST-LIB_HIGH/Protections/ProtectionManager.cpp +++ b/Src/ST-LIB_HIGH/Protections/ProtectionManager.cpp @@ -1,5 +1,7 @@ #include "Protections/ProtectionManager.hpp" +#include "HALAL/Services/Communication/FDCAN/FDCAN.hpp" + #include "Protections/Notification.hpp" IStateMachine* ProtectionManager::general_state_machine = nullptr; diff --git a/Src/ST-LIB_LOW/Clocks/Counter.cpp b/Src/ST-LIB_LOW/Clocks/Counter.cpp index 48b7389b..2644c7c8 100644 --- a/Src/ST-LIB_LOW/Clocks/Counter.cpp +++ b/Src/ST-LIB_LOW/Clocks/Counter.cpp @@ -6,7 +6,8 @@ */ #include -#include + +#include "HALAL/Services/Time/Time.hpp" void Counter::update(){ this->freq = (this->counter + 0.0)/(this->update_period_ms / 1000.0); diff --git a/Src/ST-LIB_LOW/Clocks/Stopwatch.cpp b/Src/ST-LIB_LOW/Clocks/Stopwatch.cpp index a29505b5..c6fab13b 100644 --- a/Src/ST-LIB_LOW/Clocks/Stopwatch.cpp +++ b/Src/ST-LIB_LOW/Clocks/Stopwatch.cpp @@ -6,7 +6,8 @@ */ #include "Clocks/Stopwatch.hpp" -#include "HALAL/HALAL.hpp" + +#include "HALAL/Services/Time/Time.hpp" void Stopwatch::start(const string id){ diff --git a/Src/ST-LIB_LOW/DigitalOutput/DigitalOutput.cpp b/Src/ST-LIB_LOW/DigitalOutput/DigitalOutput.cpp index 0b2a7439..9348a360 100644 --- a/Src/ST-LIB_LOW/DigitalOutput/DigitalOutput.cpp +++ b/Src/ST-LIB_LOW/DigitalOutput/DigitalOutput.cpp @@ -7,6 +7,8 @@ #include "DigitalOutput/DigitalOutput.hpp" +#include "HALAL/Services/DigitalOutputService/DigitalOutputService.hpp" + DigitalOutput::DigitalOutput(Pin& pin) : pin(pin), id(DigitalOutputService::inscribe(pin)) {} @@ -22,4 +24,4 @@ void DigitalOutput::toggle() { DigitalOutputService::toggle(id); } bool DigitalOutput::lock_pin_state(PinState state) { return DigitalOutputService::lock_pin_state(id, state); -} \ No newline at end of file +} diff --git a/Src/ST-LIB_LOW/HalfBridge/HalfBridge.cpp b/Src/ST-LIB_LOW/HalfBridge/HalfBridge.cpp index 6bc67038..6e4cc03e 100644 --- a/Src/ST-LIB_LOW/HalfBridge/HalfBridge.cpp +++ b/Src/ST-LIB_LOW/HalfBridge/HalfBridge.cpp @@ -7,6 +7,8 @@ #include +#include "HALAL/Services/DigitalOutputService/DigitalOutputService.hpp" + HalfBridge::HalfBridge(Pin& positive_pwm_pin, Pin& positive_pwm_negated_pin, Pin& negative_pwm_pin, Pin& negative_pwm_negated_pin, Pin& enable_pin) : is_dual(true), positive_pwm{positive_pwm_pin, positive_pwm_negated_pin}, diff --git a/Src/ST-LIB_LOW/Math/Math.cpp b/Src/ST-LIB_LOW/Math/Math.cpp index 27d0e781..fb80fbc5 100644 --- a/Src/ST-LIB_LOW/Math/Math.cpp +++ b/Src/ST-LIB_LOW/Math/Math.cpp @@ -1,7 +1,9 @@ #include "ST-LIB_LOW/Math/Math.hpp" +#include "HALAL/Services/CORDIC/CORDIC.hpp" + #ifndef SIM_ON -array Math::pointers = {0}; +std::array Math::pointers = {0}; int32_t Math::sin(int32_t angle){ pointers[0] = angle; @@ -150,4 +152,3 @@ int32_t Math::unitary_to_tg(int32_t in){ } #endif //SIM_ON - diff --git a/Src/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.cpp b/Src/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.cpp index 27be3de5..8f5c2ad6 100644 --- a/Src/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.cpp +++ b/Src/ST-LIB_LOW/Sensors/DigitalSensor/DigitalSensor.cpp @@ -1,5 +1,6 @@ #include "Sensors/DigitalSensor/DigitalSensor.hpp" -#include "Sensors/Sensor/Sensor.hpp" + +#include "HALAL/Services/DigitalInputService/DigitalInputService.hpp" DigitalSensor::DigitalSensor(Pin &pin, PinState *value) : id(DigitalInput::inscribe(pin)), value(value){} diff --git a/Src/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.cpp b/Src/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.cpp index a88e21ce..29dbc733 100644 --- a/Src/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.cpp +++ b/Src/ST-LIB_LOW/Sensors/LookupSensor/LookupSensor.cpp @@ -1,4 +1,6 @@ #include "Sensors/LookupSensor/LookupSensor.hpp" + +#include "HALAL/Services/ADC/ADC.hpp" #include "Sensors/Sensor/Sensor.hpp" diff --git a/Src/ST-LIB_LOW/Sensors/Sensor/Sensor.cpp b/Src/ST-LIB_LOW/Sensors/Sensor/Sensor.cpp index 1a273e96..f337d380 100644 --- a/Src/ST-LIB_LOW/Sensors/Sensor/Sensor.cpp +++ b/Src/ST-LIB_LOW/Sensors/Sensor/Sensor.cpp @@ -1,8 +1,12 @@ #include "Sensors/Sensor/Sensor.hpp" -vector Sensor::adc_id_list{}; -vector Sensor::EXTI_id_list{}; -vector Sensor::inputcapture_id_list{}; +#include "HALAL/Services/ADC/ADC.hpp" +#include "HALAL/Services/EXTI/EXTI.hpp" +#include "HALAL/Services/InputCapture/InputCapture.hpp" + +std::vector Sensor::adc_id_list{}; +std::vector Sensor::EXTI_id_list{}; +std::vector Sensor::inputcapture_id_list{}; void Sensor::start(){ for(uint8_t adc_id : adc_id_list){ From 27a9e7df9e5758fe0dd71b0eb4915bcfa9ee309e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 00:19:19 +0100 Subject: [PATCH 09/19] Added new presets to gh checks --- .github/workflows/build.yml | 8 ++++---- .github/workflows/compile-checks.yml | 9 ++++++--- .github/workflows/tests.yml | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 974e7ff1..bdd4e5f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: preset: description: > CMake preset to build the project, run - `cmake --build --list-presets` to see options + `cmake --list-presets` to see options required: false type: string default: 'nucleo-debug' @@ -20,7 +20,7 @@ on: preset: description: > CMake preset to build the project, run - `cmake --build --list-presets` to see options + `cmake --list-presets` to see options required: false type: string default: 'nucleo-debug' @@ -43,7 +43,7 @@ jobs: submodules: false fetch-depth: 1 - - name: Init submodules\ + - name: Init submodules run: | git config --global --add safe.directory '*' ./tools/init-submodules.sh @@ -63,4 +63,4 @@ jobs: path: out/build/${{ inputs.preset }}/libst-lib.a retention-days: 7 compression-level: 0 - if-no-files-found: error \ No newline at end of file + if-no-files-found: error diff --git a/.github/workflows/compile-checks.yml b/.github/workflows/compile-checks.yml index 27dc9e4a..39d1c7a7 100644 --- a/.github/workflows/compile-checks.yml +++ b/.github/workflows/compile-checks.yml @@ -33,9 +33,12 @@ jobs: - board-debug - board-release - board-relwithdebinfo - - board-debug-eth - - board-release-eth - - board-relwithdebinfo-eth + - board-debug-eth-ksz8041 + - board-debug-eth-lan8742 + - board-release-eth-ksz8041 + - board-release-eth-lan8742 + - board-relwithdebinfo-eth-ksz8041 + - board-relwithdebinfo-eth-lan8742 # - simulator fail-fast: false uses: ./.github/workflows/build.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d3150e41..8f4bcfcf 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -24,7 +24,7 @@ jobs: - name: Build run: | - cmake --build out/build/simulator + cmake --build --preset simulator - name: Run tests (ctest) working-directory: out/build/simulator From 6c0018f89e6fd69f1f08994227507363bc5de5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 00:27:18 +0100 Subject: [PATCH 10/19] Improved tests --- .github/workflows/tests.yml | 39 +++++++++++++++++-- .../Communication/Ethernet/NewEthernet.hpp | 4 +- Tests/CMakeLists.txt | 6 ++- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8f4bcfcf..66712b32 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,9 +5,14 @@ on: pull_request: branches: [ development ] +concurrency: + group: tests-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: tests: runs-on: ubuntu-latest + timeout-minutes: 30 steps: - name: Checkout repository @@ -17,16 +22,42 @@ jobs: run: | sudo apt-get update sudo apt-get install -y cmake ninja-build build-essential + + - name: Cache simulator deps + uses: actions/cache@v4 + with: + path: out/build/simulator/_deps + key: simulator-deps-${{ runner.os }}-${{ hashFiles('CMakeLists.txt', 'Tests/CMakeLists.txt') }} + restore-keys: | + simulator-deps-${{ runner.os }}- - name: Configure (CMake) run: | - cmake --preset simulator + cmake -S . -B out/build/simulator -G Ninja -DCMAKE_BUILD_TYPE=Debug - name: Build run: | - cmake --build --preset simulator + cmake --build out/build/simulator - name: Run tests (ctest) - working-directory: out/build/simulator run: | - ctest --output-on-failure + ctest --test-dir out/build/simulator --output-on-failure --output-junit out/build/simulator/junit.xml + + - name: Test report + if: always() + uses: dorny/test-reporter@v1 + with: + name: Simulator Tests + path: out/build/simulator/junit.xml + reporter: java-junit + + - name: Upload test reports + if: always() + uses: actions/upload-artifact@v4 + with: + name: simulator-test-reports + path: | + out/build/simulator/junit.xml + out/build/simulator/Testing/Temporary/LastTest.log + retention-days: 7 + if-no-files-found: ignore diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index def88bbe..804a754d 100644 --- a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -3,9 +3,9 @@ #include "stm32h7xx_hal.h" #include "C++Utilities/CppUtils.hpp" +#include "DigitalOutput2.hpp" #ifdef STLIB_ETH -#include "DigitalOutput2.hpp" #include "HALAL/Models/MAC/MAC.hpp" #include "HALAL/Services/Communication/Ethernet/LWIP/EthernetHelper.hpp" #include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" @@ -270,7 +270,7 @@ struct EthernetDomain { template struct Init { static void init(std::span cfgs, std::span do_instances) {}; - } + }; }; } // namespace ST_LIB #endif // STLIB_ETH diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 628ec53c..f940d7ce 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -52,7 +52,9 @@ target_include_directories(${STLIB_TEST_EXECUTABLE} PRIVATE ) include(GoogleTest) -gtest_discover_tests(${STLIB_TEST_EXECUTABLE}) +gtest_discover_tests( + ${STLIB_TEST_EXECUTABLE} +) add_custom_command( TARGET ${STLIB_TEST_EXECUTABLE} @@ -60,4 +62,4 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_BINARY_DIR}/${STLIB_TEST_EXECUTABLE} ${CMAKE_SOURCE_DIR}/out/build/test.elf -) \ No newline at end of file +) From 560bd675daf2815d9940bbfe518a97d9f1e89771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 00:50:42 +0100 Subject: [PATCH 11/19] Fixed simulator build --- CMakeLists.txt | 16 +++++++++------- Inc/C++Utilities/CppImports.hpp | 14 +++++++------- Tests/Time/timer_wrapper_test.cpp | 4 ++-- tools/run_sim_tests.sh | 10 ++++++++-- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81e60dd4..dbccf0db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -278,6 +278,7 @@ set(HALAL_CPP_NO_ETH ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Watchdog/Watchdog.cpp ) + set(HALAL_C_ETH_CORE) set(HALAL_CPP_ETH_CORE ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Models/IPV4/IPV4.cpp @@ -379,15 +380,16 @@ add_library(${STLIB_LIBRARY} STATIC $<$,$>:${LWIP_SOURCES}> $<$,$>:${USER_LWIP_SOURCES}> - ${HALAL_C_NO_ETH} - ${HALAL_CPP_NO_ETH} + $<$:${HALAL_C_NO_ETH}> + $<$:${HALAL_CPP_NO_ETH}> + + $<$,$>:${HALAL_C_ETH_CORE}> + $<$,$>:${HALAL_CPP_ETH_CORE}> - $<$:${HALAL_C_ETH_CORE}> - $<$:${HALAL_CPP_ETH_CORE}> + $<$,$>:${HALAL_C_ETH_LWIP}> + $<$,$>:${HALAL_CPP_ETH_LWIP}> + $<$,$>:${HALAL_C_ETH_PHY}> - $<$:${HALAL_C_ETH_LWIP}> - $<$:${HALAL_CPP_ETH_LWIP}> - $<$:${HALAL_C_ETH_PHY}> $<$:${CPP_UTILITIES_C}> $<$:${CPP_UTILITIES_CPP}> diff --git a/Inc/C++Utilities/CppImports.hpp b/Inc/C++Utilities/CppImports.hpp index 1966065f..51d156e6 100644 --- a/Inc/C++Utilities/CppImports.hpp +++ b/Inc/C++Utilities/CppImports.hpp @@ -16,14 +16,14 @@ #include #include #include -#ifdef SIM_ON -#ifdef __APPLE__ -#include // macOS +#if defined(SIM_ON) || defined(TESTING_ENV) +# ifdef __APPLE__ +# include // macOS +# else +# include // Linux/Unix +# endif #else -#include // Linux/Unix -#endif -#else -#include +# include #endif #include #include diff --git a/Tests/Time/timer_wrapper_test.cpp b/Tests/Time/timer_wrapper_test.cpp index 47a657dc..0ef7059a 100644 --- a/Tests/Time/timer_wrapper_test.cpp +++ b/Tests/Time/timer_wrapper_test.cpp @@ -109,8 +109,8 @@ TEST_F(TimerWrapperTests, ConfigureTimer) { #define PERIOD 1000 tim1.set_prescaler(PRESCALER_VAL); tim1.configure16bit(callback, 0, PERIOD); - EXPECT_EQ(TIM1_BASE->PSC, PRESCALER_VAL); /* set prescaler */ - EXPECT_EQ(TIM1_BASE->ARR, PERIOD); /* set period */ + EXPECT_EQ(static_cast(TIM1_BASE->PSC), static_cast(PRESCALER_VAL)); /* set prescaler */ + EXPECT_EQ(static_cast(TIM1_BASE->ARR), static_cast(PERIOD)); /* set period */ EXPECT_EQ(TIM1_BASE->CR1 & TIM_CR1_CEN, TIM_CR1_CEN); /* set counter enable */ } diff --git a/tools/run_sim_tests.sh b/tools/run_sim_tests.sh index 87278a4b..3335702b 100755 --- a/tools/run_sim_tests.sh +++ b/tools/run_sim_tests.sh @@ -1,4 +1,10 @@ #!/bin/sh +set -eu -cd out/build/simulator/Tests -./st-lib-test +script_dir="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)" +repo_root="$(CDPATH= cd -- "${script_dir}/.." && pwd)" +build_dir="${repo_root}/out/build/simulator" + +cmake -S "${repo_root}" -B "${build_dir}" -G Ninja -DCMAKE_BUILD_TYPE=Debug +cmake --build "${build_dir}" +ctest --test-dir "${build_dir}" --output-on-failure From 3ad35b732adb48300bde89123d2994acf515689c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 00:53:52 +0100 Subject: [PATCH 12/19] Added new presets --- CMakePresets.json | 94 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index 3c341ea8..38087504 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -123,36 +123,75 @@ } }, { - "name": "board-debug-eth", - "displayName": "Board [DBG] [ETH]", + "name": "board-debug-eth-ksz8041", + "displayName": "Board [DBG] [ETH] [KSZ8041]", "inherits": [ "mcu" ], "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", - "USE_ETHERNET": "ON" + "USE_ETHERNET": "ON", + "PHY_TYPE": "KSZ8041" } }, { - "name": "board-release-eth", - "displayName": "Board [REL] [ETH]", + "name": "board-debug-eth-lan8742", + "displayName": "Board [DBG] [ETH] [LAN8742]", + "inherits": [ + "mcu" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "USE_ETHERNET": "ON", + "PHY_TYPE": "LAN8742" + } + }, + { + "name": "board-release-eth-ksz8041", + "displayName": "Board [REL] [ETH] [KSZ8041]", "inherits": [ "mcu" ], "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", - "USE_ETHERNET": "ON" + "USE_ETHERNET": "ON", + "PHY_TYPE": "KSZ8041" + } + }, + { + "name": "board-release-eth-lan8742", + "displayName": "Board [REL] [ETH] [LAN8742]", + "inherits": [ + "mcu" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "USE_ETHERNET": "ON", + "PHY_TYPE": "LAN8742" } }, { - "name": "board-relwithdebinfo-eth", - "displayName": "Board [RWD] [ETH]", + "name": "board-relwithdebinfo-eth-ksz8041", + "displayName": "Board [RWD] [ETH] [KSZ8041]", "inherits": [ "mcu" ], "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo", - "USE_ETHERNET": "ON" + "USE_ETHERNET": "ON", + "PHY_TYPE": "KSZ8041" + } + }, + { + "name": "board-relwithdebinfo-eth-lan8742", + "displayName": "Board [RWD] [ETH] [LAN8742]", + "inherits": [ + "mcu" + ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "USE_ETHERNET": "ON", + "PHY_TYPE": "LAN8742" } }, { @@ -169,67 +208,66 @@ "buildPresets": [ { "name": "nucleo-debug", - "displayName": "Nucleo [DBG]", "configurePreset": "nucleo-debug" }, { "name": "nucleo-release", - "displayName": "Nucleo [REL]", "configurePreset": "nucleo-release" }, { "name": "nucleo-relwithdebinfo", - "displayName": "Nucleo [RWD]", "configurePreset": "nucleo-relwithdebinfo" }, { "name": "nucleo-debug-eth", - "displayName": "Nucleo [DBG] [ETH]", "configurePreset": "nucleo-debug-eth" }, { "name": "nucleo-release-eth", - "displayName": "Nucleo [REL] [ETH]", "configurePreset": "nucleo-release-eth" }, { "name": "nucleo-relwithdebinfo-eth", - "displayName": "Nucleo [RWD] [ETH]", "configurePreset": "nucleo-relwithdebinfo-eth" }, { "name": "board-debug", - "displayName": "Board [DBG]", "configurePreset": "board-debug" }, { "name": "board-release", - "displayName": "Board [REL]", "configurePreset": "board-release" }, { "name": "board-relwithdebinfo", - "displayName": "Board [RWD]", "configurePreset": "board-relwithdebinfo" }, { - "name": "board-debug-eth", - "displayName": "Board [DBG] [ETH]", - "configurePreset": "board-debug-eth" + "name": "board-debug-eth-ksz8041", + "configurePreset": "board-debug-eth-ksz8041" + }, + { + "name": "board-debug-eth-lan8742", + "configurePreset": "board-debug-eth-lan8742" }, { - "name": "board-release-eth", - "displayName": "Board [REL] [ETH]", - "configurePreset": "board-release-eth" + "name": "board-release-eth-ksz8041", + "configurePreset": "board-release-eth-ksz8041" }, { - "name": "board-relwithdebinfo-eth", - "displayName": "Board [RWD] [ETH]", - "configurePreset": "board-relwithdebinfo-eth" + "name": "board-release-eth-lan8742", + "configurePreset": "board-release-eth-lan8742" + }, + { + "name": "board-relwithdebinfo-eth-ksz8041", + "configurePreset": "board-relwithdebinfo-eth-ksz8041" + }, + { + "name": "board-relwithdebinfo-eth-lan8742", + "configurePreset": "board-relwithdebinfo-eth-lan8742" }, { "name": "simulator", - "displayName": "Simulator", "configurePreset": "simulator" } ] From 9788a44c142df7b38114b3d55e8925ee27fbfd28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 00:57:01 +0100 Subject: [PATCH 13/19] Fixed JUnit --- .github/workflows/tests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 66712b32..22c78611 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,8 @@ jobs: - name: Run tests (ctest) run: | - ctest --test-dir out/build/simulator --output-on-failure --output-junit out/build/simulator/junit.xml + ctest --test-dir out/build/simulator --no-tests=error --output-on-failure --output-junit out/build/simulator/junit.xml + test -f out/build/simulator/junit.xml - name: Test report if: always() From 264737d2190f8d17885ff619cf25ec035e11503c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 00:59:41 +0100 Subject: [PATCH 14/19] Removed JUnit --- .github/workflows/tests.yml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 22c78611..2a97e014 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,16 +41,7 @@ jobs: - name: Run tests (ctest) run: | - ctest --test-dir out/build/simulator --no-tests=error --output-on-failure --output-junit out/build/simulator/junit.xml - test -f out/build/simulator/junit.xml - - - name: Test report - if: always() - uses: dorny/test-reporter@v1 - with: - name: Simulator Tests - path: out/build/simulator/junit.xml - reporter: java-junit + ctest --test-dir out/build/simulator --no-tests=error --output-on-failure - name: Upload test reports if: always() @@ -58,7 +49,6 @@ jobs: with: name: simulator-test-reports path: | - out/build/simulator/junit.xml out/build/simulator/Testing/Temporary/LastTest.log retention-days: 7 if-no-files-found: ignore From 126714d3ed22b656be51819c88621bea659bcf40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 01:03:29 +0100 Subject: [PATCH 15/19] Removed unnecesary loop --- .../Communication/Ethernet/NewEthernet.hpp | 130 +++++++++--------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index 804a754d..7efbc481 100644 --- a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -159,14 +159,14 @@ struct EthernetDomain { template static consteval array build(span config) { array cfgs{}; - for (std::size_t i = 0; i < N; ++i) { - const auto &e = config[i]; - cfgs[i].local_mac = e.local_mac; - cfgs[i].local_ip = e.local_ip; - cfgs[i].subnet_mask = e.subnet_mask; - cfgs[i].gateway = e.gateway; - cfgs[i].phy_reset_id = e.phy_reset_id; - } + static_assert(N == max_instances, + "EthernetDomain only supports a single instance"); + const auto &e = config[0]; + cfgs[0].local_mac = e.local_mac; + cfgs[0].local_ip = e.local_ip; + cfgs[0].subnet_mask = e.subnet_mask; + cfgs[0].gateway = e.gateway; + cfgs[0].phy_reset_id = e.phy_reset_id; return cfgs; } @@ -193,63 +193,63 @@ struct EthernetDomain { static void init(std::span cfgs, std::span do_instances) { - for (std::size_t i = 0; i < N; ++i) { - const EthernetDomain::Config &e = cfgs[i]; - - /* --- RESET PHY --- */ - // RESET_N pin low then high - do_instances[e.phy_reset_id].turn_off(); // RESET_N = 0 - HAL_Delay(PHY_RESET_LOW_DELAY_MS); - do_instances[e.phy_reset_id].turn_on(); // RESET_N = 1 - HAL_Delay(PHY_RESET_HIGH_DELAY_MS); - - /* --- CLOCKS ETH --- */ - __HAL_RCC_ETH1MAC_CLK_ENABLE(); - __HAL_RCC_ETH1TX_CLK_ENABLE(); - __HAL_RCC_ETH1RX_CLK_ENABLE(); - - /* --- NVIC --- */ - HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(ETH_IRQn); - - /* --- IP / MAC --- */ - MAC local_mac{e.local_mac}; - IPV4 local_ip{e.local_ip}; - IPV4 subnet_mask{e.subnet_mask}; - IPV4 gateway{e.gateway}; - - ipaddr = local_ip.address; - netmask = subnet_mask.address; - gw = gateway.address; - - IP_ADDRESS[0] = ipaddr.addr & 0xFF; - IP_ADDRESS[1] = (ipaddr.addr >> 8) & 0xFF; - IP_ADDRESS[2] = (ipaddr.addr >> 16) & 0xFF; - IP_ADDRESS[3] = (ipaddr.addr >> 24) & 0xFF; - - NETMASK_ADDRESS[0] = netmask.addr & 0xFF; - NETMASK_ADDRESS[1] = (netmask.addr >> 8) & 0xFF; - NETMASK_ADDRESS[2] = (netmask.addr >> 16) & 0xFF; - NETMASK_ADDRESS[3] = (netmask.addr >> 24) & 0xFF; - - GATEWAY_ADDRESS[0] = gw.addr & 0xFF; - GATEWAY_ADDRESS[1] = (gw.addr >> 8) & 0xFF; - GATEWAY_ADDRESS[2] = (gw.addr >> 16) & 0xFF; - GATEWAY_ADDRESS[3] = (gw.addr >> 24) & 0xFF; - - gnetif.hwaddr[0] = local_mac.address[0]; - gnetif.hwaddr[1] = local_mac.address[1]; - gnetif.hwaddr[2] = local_mac.address[2]; - gnetif.hwaddr[3] = local_mac.address[3]; - gnetif.hwaddr[4] = local_mac.address[4]; - gnetif.hwaddr[5] = local_mac.address[5]; - gnetif.hwaddr_len = 6; - - /* --- LwIP / ETH init --- */ - MX_LWIP_Init(); - - instances[i] = Instance{}; - } + static_assert(N == max_instances, + "EthernetDomain only supports a single instance"); + const EthernetDomain::Config &e = cfgs[0]; + + /* --- RESET PHY --- */ + // RESET_N pin low then high + do_instances[e.phy_reset_id].turn_off(); // RESET_N = 0 + HAL_Delay(PHY_RESET_LOW_DELAY_MS); + do_instances[e.phy_reset_id].turn_on(); // RESET_N = 1 + HAL_Delay(PHY_RESET_HIGH_DELAY_MS); + + /* --- CLOCKS ETH --- */ + __HAL_RCC_ETH1MAC_CLK_ENABLE(); + __HAL_RCC_ETH1TX_CLK_ENABLE(); + __HAL_RCC_ETH1RX_CLK_ENABLE(); + + /* --- NVIC --- */ + HAL_NVIC_SetPriority(ETH_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(ETH_IRQn); + + /* --- IP / MAC --- */ + MAC local_mac{e.local_mac}; + IPV4 local_ip{e.local_ip}; + IPV4 subnet_mask{e.subnet_mask}; + IPV4 gateway{e.gateway}; + + ipaddr = local_ip.address; + netmask = subnet_mask.address; + gw = gateway.address; + + IP_ADDRESS[0] = ipaddr.addr & 0xFF; + IP_ADDRESS[1] = (ipaddr.addr >> 8) & 0xFF; + IP_ADDRESS[2] = (ipaddr.addr >> 16) & 0xFF; + IP_ADDRESS[3] = (ipaddr.addr >> 24) & 0xFF; + + NETMASK_ADDRESS[0] = netmask.addr & 0xFF; + NETMASK_ADDRESS[1] = (netmask.addr >> 8) & 0xFF; + NETMASK_ADDRESS[2] = (netmask.addr >> 16) & 0xFF; + NETMASK_ADDRESS[3] = (netmask.addr >> 24) & 0xFF; + + GATEWAY_ADDRESS[0] = gw.addr & 0xFF; + GATEWAY_ADDRESS[1] = (gw.addr >> 8) & 0xFF; + GATEWAY_ADDRESS[2] = (gw.addr >> 16) & 0xFF; + GATEWAY_ADDRESS[3] = (gw.addr >> 24) & 0xFF; + + gnetif.hwaddr[0] = local_mac.address[0]; + gnetif.hwaddr[1] = local_mac.address[1]; + gnetif.hwaddr[2] = local_mac.address[2]; + gnetif.hwaddr[3] = local_mac.address[3]; + gnetif.hwaddr[4] = local_mac.address[4]; + gnetif.hwaddr[5] = local_mac.address[5]; + gnetif.hwaddr_len = 6; + + /* --- LwIP / ETH init --- */ + MX_LWIP_Init(); + + instances[0] = Instance{}; } }; }; From 45d260822da6ba123b121e64088725cf0de9c734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 12:20:17 +0100 Subject: [PATCH 16/19] improved compilation --- CMakeLists.txt | 90 ++++++++++++++++++++++-------------------- LWIP/Target/lwipopts.h | 9 +++++ 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dbccf0db..9b7c8725 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,9 +16,28 @@ enable_testing() option(USE_ETHERNET "Enable ethernet peripheral" OFF) option(TARGET_NUCLEO "Targets the STM32H723 Nucleo development board" OFF) +option(USE_CCACHE "Use ccache if available" ON) +option(STLIB_USE_PCH "Enable precompiled headers for ST-LIB" ON) +if(NOT DEFINED ENABLE_LTO) + if(CMAKE_CROSSCOMPILING) + set(ENABLE_LTO OFF) + else() + set(ENABLE_LTO ON) + endif() +endif() +set(ENABLE_LTO "${ENABLE_LTO}" CACHE BOOL "Enable link-time optimization (LTO)") set(LAN8742_PHY_ADDRESS 0 CACHE STRING "LAN8742 PHY address (strap-dependent)") set(KSZ8041_PHY_ADDRESS 1 CACHE STRING "KSZ8041 PHY address (strap-dependent)") +if(USE_CCACHE) + find_program(CCACHE_PROGRAM ccache) + if(CCACHE_PROGRAM) + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + set(CMAKE_ASM_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + endif() +endif() + # ============================ # PHY selection (Ethernet) # ============================ @@ -74,10 +93,12 @@ if(NOT CMAKE_CROSSCOMPILING) message(STATUS "Compiling for simulator") add_subdirectory(Tests) else() - execute_process( - COMMAND git submodule update --init --depth 1 Drivers/BSP/Components/lan8742 - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7 - ) + if(NOT EXISTS ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Drivers/BSP/Components/lan8742) + execute_process( + COMMAND git submodule update --init --depth 1 Drivers/BSP/Components/lan8742 + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7 + ) + endif() endif() # ============================ @@ -171,40 +192,10 @@ if(CMAKE_CROSSCOMPILING) set(LWIP_DIR ${STM32CUBEH7}/Middlewares/Third_Party/LwIP) set(LWIP_SOURCES - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/api_lib.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/api_msg.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/err.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/if_api.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/netbuf.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/netdb.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/netifapi.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/sockets.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/api/tcpip.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/altcp.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/altcp_alloc.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/altcp_tcp.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/def.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/dns.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/inet_chksum.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/init.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ip.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/autoip.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/dhcp.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/etharp.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/icmp.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/igmp.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4_addr.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4_frag.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/dhcp6.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ethip6.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/icmp6.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/inet6.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ip6.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ip6_addr.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/ip6_frag.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/mld6.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv6/nd6.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/inet_chksum.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/mem.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/memp.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/netif.c @@ -217,14 +208,12 @@ if(CMAKE_CROSSCOMPILING) ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/tcp_out.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/timeouts.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/udp.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/bridgeif.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/bridgeif_fdb.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/etharp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/icmp.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4_addr.c + ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/core/ipv4/ip4_frag.c ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/ethernet.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/lowpan6.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/lowpan6_ble.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/lowpan6_common.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/slipif.c - ${CMAKE_CURRENT_LIST_DIR}/STM32CubeH7/Middlewares/Third_Party/LwIP/src/netif/zepif.c ) set(USER_LWIP_SOURCES @@ -443,6 +432,8 @@ target_compile_options(${STLIB_LIBRARY} PRIVATE $<$:-mfloat-abi=hard> $<$:-mthumb> $<$:-specs=nosys.specs> + $<$:-g> + $<$:-g> $<$:-ffunction-sections> $<$:-fdata-sections> $<$:-fno-exceptions> @@ -498,6 +489,21 @@ target_include_directories(${STLIB_LIBRARY} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/Inc/ST-LIB_HIGH ) +if(ENABLE_LTO) + set_property(TARGET ${STLIB_LIBRARY} PROPERTY INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) + set_property(TARGET ${STLIB_LIBRARY} PROPERTY INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON) +endif() + +if(STLIB_USE_PCH) + if(COMMAND target_precompile_headers) + target_precompile_headers(${STLIB_LIBRARY} PRIVATE + $<$:${CMAKE_CURRENT_LIST_DIR}/Inc/C++Utilities/CppImports.hpp> + ) + else() + message(WARNING "STLIB_USE_PCH=ON but target_precompile_headers is not available in this CMake version") + endif() +endif() + if(PROJECT_IS_TOP_LEVEL) configure_file( diff --git a/LWIP/Target/lwipopts.h b/LWIP/Target/lwipopts.h index 29f2fd46..e319dd6a 100644 --- a/LWIP/Target/lwipopts.h +++ b/LWIP/Target/lwipopts.h @@ -105,6 +105,15 @@ #define CHECKSUM_CHECK_ICMP6 0 /*-----------------------------------------------------------------------------*/ /* USER CODE BEGIN 1 */ +#define LWIP_IPV6 0 +#define LWIP_DHCP 0 +#define LWIP_AUTOIP 0 +#define LWIP_DNS 0 +#define LWIP_IGMP 0 +#define LWIP_IPV6_MLD 0 +#define LWIP_IPV6_DHCP6 0 +#define LWIP_IPV6_REASS 0 +#define LWIP_IPV6_FRAG 0 /* USER CODE END 1 */ From d3c8915bd98db95f4d23c32bf7b67d4d04f8025d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 17:25:42 +0100 Subject: [PATCH 17/19] lan8742 working --- .github/workflows/compile-checks.yml | 6 +- CMakeLists.txt | 16 +- CMakePresets.json | 32 ++-- .../Communication/Ethernet/NewEthernet.hpp | 20 ++- LWIP/Target/ethernetif.c | 4 +- .../Communication/Ethernet/PHY/lan8700.c | 155 ++++++++++++++++++ .../Communication/Ethernet/PHY/lan8742.c | 52 +++++- .../Communication/Ethernet/PHY/phy_select.c | 6 +- 8 files changed, 263 insertions(+), 28 deletions(-) create mode 100644 Src/HALAL/Services/Communication/Ethernet/PHY/lan8700.c diff --git a/.github/workflows/compile-checks.yml b/.github/workflows/compile-checks.yml index 39d1c7a7..275f4771 100644 --- a/.github/workflows/compile-checks.yml +++ b/.github/workflows/compile-checks.yml @@ -34,11 +34,11 @@ jobs: - board-release - board-relwithdebinfo - board-debug-eth-ksz8041 - - board-debug-eth-lan8742 + - board-debug-eth-lan8700 - board-release-eth-ksz8041 - - board-release-eth-lan8742 + - board-release-eth-lan8700 - board-relwithdebinfo-eth-ksz8041 - - board-relwithdebinfo-eth-lan8742 + - board-relwithdebinfo-eth-lan8700 # - simulator fail-fast: false uses: ./.github/workflows/build.yml diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b7c8725..ee361c9c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,9 @@ if(NOT DEFINED ENABLE_LTO) endif() set(ENABLE_LTO "${ENABLE_LTO}" CACHE BOOL "Enable link-time optimization (LTO)") set(LAN8742_PHY_ADDRESS 0 CACHE STRING "LAN8742 PHY address (strap-dependent)") +set(LAN8700_PHY_ADDRESS 31 CACHE STRING "LAN8700 PHY address (strap-dependent)") set(KSZ8041_PHY_ADDRESS 1 CACHE STRING "KSZ8041 PHY address (strap-dependent)") +set(LAN8700_FORCE_100FD OFF CACHE BOOL "Force LAN8700 to 100Mbps Full Duplex (debug)") if(USE_CCACHE) find_program(CCACHE_PROGRAM ccache) @@ -44,6 +46,7 @@ endif() set(SELECTED_PHY "") set(USE_PHY_LAN8742 OFF) +set(USE_PHY_LAN8700 OFF) set(USE_PHY_KSZ8041 OFF) if(USE_ETHERNET) @@ -54,13 +57,15 @@ if(USE_ETHERNET) else() if(NOT DEFINED PHY_TYPE) message(FATAL_ERROR - "USE_ETHERNET=ON and TARGET_NUCLEO=OFF but PHY_TYPE not set (KSZ8041 or LAN8742)") + "USE_ETHERNET=ON and TARGET_NUCLEO=OFF but PHY_TYPE not set (KSZ8041, LAN8742, or LAN8700)") endif() set(SELECTED_PHY "${PHY_TYPE}") endif() if(SELECTED_PHY STREQUAL "LAN8742") set(USE_PHY_LAN8742 ON) + elseif(SELECTED_PHY STREQUAL "LAN8700") + set(USE_PHY_LAN8700 ON) elseif(SELECTED_PHY STREQUAL "KSZ8041") set(USE_PHY_KSZ8041 ON) else() @@ -299,6 +304,12 @@ if(USE_ETHERNET) ) endif() + if(USE_PHY_LAN8700) + list(APPEND HALAL_C_ETH_PHY + ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/lan8700.c + ) + endif() + if(USE_PHY_KSZ8041) list(APPEND HALAL_C_ETH_PHY ${CMAKE_CURRENT_LIST_DIR}/Src/HALAL/Services/Communication/Ethernet/PHY/ksz8041.c @@ -415,9 +426,12 @@ target_compile_definitions(${STLIB_LIBRARY} PUBLIC $<$:STM32H723xx> $<$:USE_PHY_LAN8742> + $<$:USE_PHY_LAN8700> $<$:USE_PHY_KSZ8041> $<$:LAN8742_PHY_ADDRESS=${LAN8742_PHY_ADDRESS}> + $<$:LAN8700_PHY_ADDRESS=${LAN8700_PHY_ADDRESS}> $<$:KSZ8041_PHY_ADDRESS=${KSZ8041_PHY_ADDRESS}> + $<$,$>:LAN8700_FORCE_100FD> $<$>:TESTING_ENV> diff --git a/CMakePresets.json b/CMakePresets.json index 38087504..f59704a4 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -135,15 +135,15 @@ } }, { - "name": "board-debug-eth-lan8742", - "displayName": "Board [DBG] [ETH] [LAN8742]", + "name": "board-debug-eth-lan8700", + "displayName": "Board [DBG] [ETH] [LAN8700]", "inherits": [ "mcu" ], "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "USE_ETHERNET": "ON", - "PHY_TYPE": "LAN8742" + "PHY_TYPE": "LAN8700" } }, { @@ -159,15 +159,15 @@ } }, { - "name": "board-release-eth-lan8742", - "displayName": "Board [REL] [ETH] [LAN8742]", + "name": "board-release-eth-lan8700", + "displayName": "Board [REL] [ETH] [LAN8700]", "inherits": [ "mcu" ], "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", "USE_ETHERNET": "ON", - "PHY_TYPE": "LAN8742" + "PHY_TYPE": "LAN8700" } }, { @@ -183,15 +183,15 @@ } }, { - "name": "board-relwithdebinfo-eth-lan8742", - "displayName": "Board [RWD] [ETH] [LAN8742]", + "name": "board-relwithdebinfo-eth-lan8700", + "displayName": "Board [RWD] [ETH] [LAN8700]", "inherits": [ "mcu" ], "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo", "USE_ETHERNET": "ON", - "PHY_TYPE": "LAN8742" + "PHY_TYPE": "LAN8700" } }, { @@ -247,28 +247,28 @@ "configurePreset": "board-debug-eth-ksz8041" }, { - "name": "board-debug-eth-lan8742", - "configurePreset": "board-debug-eth-lan8742" + "name": "board-debug-eth-lan8700", + "configurePreset": "board-debug-eth-lan8700" }, { "name": "board-release-eth-ksz8041", "configurePreset": "board-release-eth-ksz8041" }, { - "name": "board-release-eth-lan8742", - "configurePreset": "board-release-eth-lan8742" + "name": "board-release-eth-lan8700", + "configurePreset": "board-release-eth-lan8700" }, { "name": "board-relwithdebinfo-eth-ksz8041", "configurePreset": "board-relwithdebinfo-eth-ksz8041" }, { - "name": "board-relwithdebinfo-eth-lan8742", - "configurePreset": "board-relwithdebinfo-eth-lan8742" + "name": "board-relwithdebinfo-eth-lan8700", + "configurePreset": "board-relwithdebinfo-eth-lan8700" }, { "name": "simulator", "configurePreset": "simulator" } ] -} \ No newline at end of file +} diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index 7efbc481..ec937eb3 100644 --- a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -12,6 +12,7 @@ extern "C" { #include "ethernetif.h" #include "lwip.h" +#include "netif/etharp.h" } extern uint32_t EthernetLinkTimer; @@ -38,6 +39,7 @@ struct EthernetDomain { const GPIODomain::Pin &CRS_DV; const GPIODomain::Pin &RXD0; const GPIODomain::Pin &RXD1; + const GPIODomain::Pin &RXER; const GPIODomain::Pin &TXD1; const GPIODomain::Pin &TX_EN; const GPIODomain::Pin &TXD0; @@ -50,6 +52,7 @@ struct EthernetDomain { .CRS_DV = PA7, .RXD0 = PC4, .RXD1 = PC5, + .RXER = PG2, .TXD1 = PB13, .TX_EN = PG11, .TXD0 = PG13, @@ -60,6 +63,7 @@ struct EthernetDomain { .CRS_DV = PA7, .RXD0 = PC4, .RXD1 = PC5, + .RXER = PG2, .TXD1 = PB13, .TX_EN = PB11, .TXD0 = PB12, @@ -80,7 +84,7 @@ struct EthernetDomain { EthernetPins pins; Entry e; - std::array rmii_gpios; + std::array rmii_gpios; DigitalOutputDomain::DigitalOutput phy_reset; consteval Ethernet(EthernetPins pins, const char *local_mac, @@ -113,6 +117,10 @@ struct EthernetDomain { GPIODomain::Pull::None, GPIODomain::Speed::VeryHigh, GPIODomain::AlternateFunction::AF11), + GPIODomain::GPIO(pins.RXER, GPIODomain::OperationMode::ALT_PP, + GPIODomain::Pull::None, + GPIODomain::Speed::VeryHigh, + GPIODomain::AlternateFunction::AF11), GPIODomain::GPIO(pins.TXD1, GPIODomain::OperationMode::ALT_PP, GPIODomain::Pull::None, GPIODomain::Speed::VeryHigh, @@ -198,13 +206,21 @@ struct EthernetDomain { const EthernetDomain::Config &e = cfgs[0]; /* --- RESET PHY --- */ +#ifndef NUCLEO // RESET_N pin low then high do_instances[e.phy_reset_id].turn_off(); // RESET_N = 0 HAL_Delay(PHY_RESET_LOW_DELAY_MS); do_instances[e.phy_reset_id].turn_on(); // RESET_N = 1 HAL_Delay(PHY_RESET_HIGH_DELAY_MS); +#else + // Nucleo boards typically rely on the PHY's own reset circuitry. + HAL_Delay(PHY_RESET_HIGH_DELAY_MS); +#endif /* --- CLOCKS ETH --- */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RMII); + __HAL_RCC_ETH1MAC_CLK_ENABLE(); __HAL_RCC_ETH1TX_CLK_ENABLE(); __HAL_RCC_ETH1RX_CLK_ENABLE(); @@ -248,6 +264,8 @@ struct EthernetDomain { /* --- LwIP / ETH init --- */ MX_LWIP_Init(); + netif_set_up(&gnetif); + etharp_gratuitous(&gnetif); instances[0] = Instance{}; } diff --git a/LWIP/Target/ethernetif.c b/LWIP/Target/ethernetif.c index 2b558efc..44bebd23 100644 --- a/LWIP/Target/ethernetif.c +++ b/LWIP/Target/ethernetif.c @@ -172,7 +172,7 @@ void ethernet_link_check_state(struct netif *netif) { if (state == PHY_LINK_DOWN) { if (eth_link_up) { eth_link_up = 0; - HAL_ETH_Stop(&heth); + HAL_ETH_Stop_IT(&heth); netif_set_link_down(netif); netif_set_down(netif); } @@ -206,7 +206,7 @@ void ethernet_link_check_state(struct netif *netif) { } HAL_ETH_SetMACConfig(&heth, &macconf); - HAL_ETH_Start(&heth); + HAL_ETH_Start_IT(&heth); netif_set_link_up(netif); netif_set_up(netif); diff --git a/Src/HALAL/Services/Communication/Ethernet/PHY/lan8700.c b/Src/HALAL/Services/Communication/Ethernet/PHY/lan8700.c new file mode 100644 index 00000000..efef62ef --- /dev/null +++ b/Src/HALAL/Services/Communication/Ethernet/PHY/lan8700.c @@ -0,0 +1,155 @@ +#include "HALAL/Services/Communication/Ethernet/PHY/phy_driver.h" + +#ifdef USE_PHY_LAN8700 + +#include "stm32h7xx_hal.h" + +extern ETH_HandleTypeDef heth; + +#ifndef LAN8700_PHY_ADDRESS +#define LAN8700_PHY_ADDRESS 31 +#endif + +#define LAN8700_BCR 0x00U +#define LAN8700_BSR 0x01U +#define LAN8700_PHYID1 0x02U +#define LAN8700_PHYID2 0x03U +#define LAN8700_ANAR 0x04U +#define LAN8700_ANLPAR 0x05U +#define LAN8700_SMR 0x12U +#define LAN8700_PHYSCSR 0x1FU + +#define LAN8700_BCR_RESET 0x8000U +#define LAN8700_BCR_AUTONEG 0x1000U +#define LAN8700_BCR_RESTART_AUTONEG 0x0200U +#define LAN8700_BCR_POWER_DOWN 0x0800U +#define LAN8700_BCR_SPEED_SELECT 0x2000U +#define LAN8700_BCR_DUPLEX_MODE 0x0100U + +#define LAN8700_BSR_LINK_STATUS 0x0004U +#define LAN8700_BSR_AUTONEG_COMPLETE 0x0020U + +#define LAN8700_ANAR_100FD 0x0100U +#define LAN8700_ANAR_100HD 0x0080U +#define LAN8700_ANAR_10FD 0x0040U +#define LAN8700_ANAR_10HD 0x0020U + + +static uint32_t lan8700_active_addr = LAN8700_PHY_ADDRESS; + +static uint32_t lan8700_read(uint32_t reg) { + uint32_t val = 0; + HAL_ETH_ReadPHYRegister(&heth, lan8700_active_addr, reg, &val); + return val; +} + +static void lan8700_write(uint32_t reg, uint32_t val) { + HAL_ETH_WritePHYRegister(&heth, lan8700_active_addr, reg, val); +} + +static void lan8700_wait_reset_clear(void) { + uint32_t start = HAL_GetTick(); + while (HAL_GetTick() - start < 100U) { + if ((lan8700_read(LAN8700_BCR) & LAN8700_BCR_RESET) == 0U) { + break; + } + } +} + +static uint8_t lan8700_scan_address(void) { + uint32_t id1 = 0U; + uint32_t id2 = 0U; + for (uint32_t addr = 0; addr <= 31; ++addr) { + if (HAL_ETH_ReadPHYRegister(&heth, addr, LAN8700_PHYID1, &id1) != HAL_OK) { + continue; + } + if (HAL_ETH_ReadPHYRegister(&heth, addr, LAN8700_PHYID2, &id2) != HAL_OK) { + continue; + } + if ((id1 != 0x0000U) && (id1 != 0xFFFFU)) { + return (uint8_t)addr; + } + } + return 0xFF; +} + +static void lan8700_init(void) { + HAL_ETH_SetMDIOClockRange(&heth); + + /* Verify MDIO responds at configured address, otherwise auto-scan */ + uint32_t id1 = 0U; + if (HAL_ETH_ReadPHYRegister(&heth, lan8700_active_addr, LAN8700_PHYID1, + &id1) != HAL_OK || + (id1 == 0x0000U) || (id1 == 0xFFFFU)) { + uint8_t addr = lan8700_scan_address(); + if (addr == 0xFF) { + return; + } + lan8700_active_addr = addr; + } + + uint32_t bcr = lan8700_read(LAN8700_BCR); + if (bcr & LAN8700_BCR_POWER_DOWN) { + bcr &= ~LAN8700_BCR_POWER_DOWN; + lan8700_write(LAN8700_BCR, bcr); + } + + /* Soft reset to load strap defaults */ + lan8700_write(LAN8700_BCR, LAN8700_BCR_RESET); + lan8700_wait_reset_clear(); + + /* Start auto-negotiation (or force 100FD for debug) */ + bcr = lan8700_read(LAN8700_BCR); + bcr |= LAN8700_BCR_AUTONEG | LAN8700_BCR_RESTART_AUTONEG; + lan8700_write(LAN8700_BCR, bcr); +} + +static phy_link_state_t lan8700_get_link_state(void) { + uint32_t bsr = lan8700_read(LAN8700_BSR); + /* BSR is latch-low: read twice to clear latched bits */ + bsr = lan8700_read(LAN8700_BSR); + + if ((bsr & LAN8700_BSR_LINK_STATUS) == 0U) { + return PHY_LINK_DOWN; + } + + uint32_t bcr = lan8700_read(LAN8700_BCR); + if ((bcr & LAN8700_BCR_AUTONEG) == 0U) { + const uint32_t speed_100 = (bcr & LAN8700_BCR_SPEED_SELECT); + const uint32_t full = (bcr & LAN8700_BCR_DUPLEX_MODE); + if (speed_100) { + return full ? PHY_100_FULL : PHY_100_HALF; + } + return full ? PHY_10_FULL : PHY_10_HALF; + } + + if ((bsr & LAN8700_BSR_AUTONEG_COMPLETE) == 0U) { + return PHY_LINK_DOWN; + } + + uint32_t anar = lan8700_read(LAN8700_ANAR); + uint32_t anlpar = lan8700_read(LAN8700_ANLPAR); + uint32_t common = anar & anlpar; + + if (common & LAN8700_ANAR_100FD) { + return PHY_100_FULL; + } + if (common & LAN8700_ANAR_100HD) { + return PHY_100_HALF; + } + if (common & LAN8700_ANAR_10FD) { + return PHY_10_FULL; + } + if (common & LAN8700_ANAR_10HD) { + return PHY_10_HALF; + } + + return PHY_LINK_DOWN; +} + +const phy_driver_t phy_lan8700 = { + .init = lan8700_init, + .get_link_state = lan8700_get_link_state, +}; + +#endif /* USE_PHY_LAN8700 */ diff --git a/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c b/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c index 3a5af58f..40a6f045 100644 --- a/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c +++ b/Src/HALAL/Services/Communication/Ethernet/PHY/lan8742.c @@ -5,6 +5,8 @@ #include "lan8742.h" #include "stm32h7xx_hal.h" +extern ETH_HandleTypeDef heth; + /* Bus IO provided by ethernetif.c */ extern int32_t ETH_PHY_IO_Init(void); extern int32_t ETH_PHY_IO_DeInit(void); @@ -25,14 +27,56 @@ static lan8742_IOCtx_t ctx = { }; static void lan_init(void) { - /* Explicit PHY address (robust) */ - lan.DevAddr = LAN8742_PHY_ADDRESS; + uint32_t id1 = 0, id2 = 0; + HAL_ETH_SetMDIOClockRange(&heth); LAN8742_RegisterBusIO(&lan, &ctx); - LAN8742_Init(&lan); + + if (lan.IO.Init) { + lan.IO.Init(); + } + + lan.Is_Initialized = 0; + lan.DevAddr = LAN8742_PHY_ADDRESS; + + /* Prefer configured address; fall back to MDIO scan if not responsive */ + if (lan.IO.ReadReg(lan.DevAddr, LAN8742_PHYI1R, &id1) < 0 || + lan.IO.ReadReg(lan.DevAddr, LAN8742_PHYI2R, &id2) < 0 || + (id1 == 0x0000U) || (id1 == 0xFFFFU)) { + for (uint32_t addr = 0; addr <= 31; ++addr) { + if (lan.IO.ReadReg(addr, LAN8742_PHYI1R, &id1) < 0) { + continue; + } + if (lan.IO.ReadReg(addr, LAN8742_PHYI2R, &id2) < 0) { + continue; + } + if ((id1 != 0x0000U) && (id1 != 0xFFFFU)) { + lan.DevAddr = addr; + break; + } + } + } + + if ((id1 != 0x0000U) && (id1 != 0xFFFFU)) { + lan.Is_Initialized = 1; + } + + if (lan.Is_Initialized) { + LAN8742_DisablePowerDownMode(&lan); + LAN8742_StartAutoNego(&lan); + + uint32_t bcr = 0; + if (lan.IO.ReadReg(lan.DevAddr, LAN8742_BCR, &bcr) >= 0) { + bcr |= (LAN8742_BCR_AUTONEGO_EN | LAN8742_BCR_RESTART_AUTONEGO); + lan.IO.WriteReg(lan.DevAddr, LAN8742_BCR, bcr); + } + } } static phy_link_state_t lan_get_link_state(void) { + if (!lan.Is_Initialized) { + return PHY_LINK_DOWN; + } int32_t st = LAN8742_GetLinkState(&lan); switch (st) { @@ -54,4 +98,4 @@ const phy_driver_t phy_lan8742 = { .get_link_state = lan_get_link_state, }; -#endif /* USE_PHY_LAN8742 */ \ No newline at end of file +#endif /* USE_PHY_LAN8742 */ diff --git a/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c b/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c index 2d7822e9..435cf130 100644 --- a/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c +++ b/Src/HALAL/Services/Communication/Ethernet/PHY/phy_select.c @@ -8,6 +8,10 @@ const phy_driver_t *phy_driver = &phy_ksz8041; extern const phy_driver_t phy_lan8742; const phy_driver_t *phy_driver = &phy_lan8742; +#elif defined(USE_PHY_LAN8700) +extern const phy_driver_t phy_lan8700; +const phy_driver_t *phy_driver = &phy_lan8700; + #else #error "No PHY selected" -#endif \ No newline at end of file +#endif From 2367f646f1f230a83945ed7c7817a3528090b03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 18:08:51 +0100 Subject: [PATCH 18/19] added extern C protection --- LWIP/Target/ethernetif.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/LWIP/Target/ethernetif.h b/LWIP/Target/ethernetif.h index 364fcb75..18b2b8b0 100644 --- a/LWIP/Target/ethernetif.h +++ b/LWIP/Target/ethernetif.h @@ -24,6 +24,10 @@ #include "lwip/err.h" #include "lwip/netif.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Within 'USER CODE' section, code will be kept by default at each generation */ /* USER CODE BEGIN 0 */ @@ -42,4 +46,7 @@ u32_t sys_now(void); /* USER CODE BEGIN 1 */ void pbuf_free_custom(struct pbuf *p); /* USER CODE END 1 */ +#ifdef __cplusplus +} +#endif #endif From 77224aa709b0b77e54f5a2cf2ce55bc6f0deb9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20S=C3=A1ez?= Date: Fri, 6 Feb 2026 18:26:53 +0100 Subject: [PATCH 19/19] added bridge between NewEthernet and Sockets --- Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp index ec937eb3..053a8890 100644 --- a/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp +++ b/Inc/HALAL/Services/Communication/Ethernet/NewEthernet.hpp @@ -7,6 +7,7 @@ #ifdef STLIB_ETH #include "HALAL/Models/MAC/MAC.hpp" +#include "HALAL/Services/Communication/Ethernet/LWIP/Ethernet.hpp" #include "HALAL/Services/Communication/Ethernet/LWIP/EthernetHelper.hpp" #include "HALAL/Services/Communication/Ethernet/LWIP/EthernetNode.hpp" extern "C" { @@ -266,6 +267,8 @@ struct EthernetDomain { MX_LWIP_Init(); netif_set_up(&gnetif); etharp_gratuitous(&gnetif); + ::Ethernet::is_ready = true; + ::Ethernet::is_running = true; instances[0] = Instance{}; }