diff --git a/Drivers/EthDrv/eth_drv_lwip.c b/Drivers/EthDrv/eth_drv_lwip.c index 7cd170b..eca51ed 100644 --- a/Drivers/EthDrv/eth_drv_lwip.c +++ b/Drivers/EthDrv/eth_drv_lwip.c @@ -13,6 +13,7 @@ #include "lwip/netif.h" #include "lwip/snmp.h" +#include "lwip/tcpip.h" #include "mac_drv.h" #include "phy_drv/phy_common.h" @@ -36,7 +37,7 @@ // --------- Ethernet buffers ---------- // ------------------------------------- -#define ETH_BUFFER_SIZE (1536UL) +#define ETH_BUFFER_SIZE (1528UL) #define ETH_RX_BUF_SIZE (ETH_BUFFER_SIZE) #define ETH_TX_BUF_SIZE (ETH_BUFFER_SIZE) @@ -92,7 +93,7 @@ static void fetch_link_properties() { static void phy_thread(void *arg) { while (true) { - fetch_link_properties(); + tcpip_callback(fetch_link_properties, NULL); osDelay(500); } return; @@ -148,7 +149,7 @@ static void low_level_init(struct netif *netif) { netif->hwaddr_len = ETHARP_HWADDR_LEN; /* set MAC hardware address */ - memcpy(netif->hwaddr, &opts.mac, ETHARP_HWADDR_LEN); + memcpy(netif->hwaddr, opts.mac, ETHARP_HWADDR_LEN); /* maximum transfer unit */ netif->mtu = 1500; @@ -208,15 +209,15 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) { /* check if timestamping is demanded */ uint8_t opts = ETHHW_TXOPT_NONE; - bool tsEn = (p->tx_cb != NULL); + // bool tsEn = (p->tx_cb != NULL); ETHHW_OptArg_TxTsCap optArg; memset(&optArg, 0, sizeof(ETHHW_OptArg_TxTsCap)); - if (tsEn) { - opts = ETHHW_TXOPT_CAPTURE_TS; - optArg.txTsCbPtr = (uint32_t)(p->tx_cb); - optArg.tag = (uint32_t)p->tag; - } + // if (tsEn) { + // opts = ETHHW_TXOPT_CAPTURE_TS; + // optArg.txTsCbPtr = (uint32_t)(p->tx_cb); + // optArg.tag = (uint32_t)p->tag; + // } /* Pass the data to the MAC */ ETHHW_Transmit(ETH, concat_buf, concat_buf_level, opts, &optArg); @@ -277,8 +278,8 @@ int ETHHW_ReadCallback(ETHHW_EventDesc *evt) { } /* Copy the timestamp into the first pbuf */ - p->time_s = evt->data.rx.ts_s; - p->time_ns = evt->data.rx.ts_ns; + // p->time_s = evt->data.rx.ts_s; + // p->time_ns = evt->data.rx.ts_ns; MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); if (((u8_t *)p->payload)[0] & 1) { @@ -384,8 +385,8 @@ err_t ethernetif_init(struct netif *netif) { netif_set_up(netif); /* refresh and fetch PHY and link status */ - phy_refresh_link_status(); - fetch_link_properties(); + // phy_refresh_link_status(); + // fetch_link_properties(); return ERR_OK; } diff --git a/Drivers/EthDrv/mac_drv.c b/Drivers/EthDrv/mac_drv.c index 8ac2dc9..961a584 100644 --- a/Drivers/EthDrv/mac_drv.c +++ b/Drivers/EthDrv/mac_drv.c @@ -32,7 +32,7 @@ static void ETHHW_InitClocks() { RMII_MII_CRS_DV -------------------> PA7 RMII_MII_RXD0 ---------------------> PC4 RMII_MII_RXD1 ---------------------> PC5 - RMII_MII_RXER ---------------------> PB10) + (RMII_MII_RXER ---------------------> PB10) RMII_MII_TX_EN --------------------> PB11 RMII_MII_TXD0 ---------------------> PB12 RMII_MII_TXD1 ---------------------> PB13 @@ -116,10 +116,8 @@ static void ETHHW_InitPeripheral(ETH_TypeDef *eth, ETHHW_InitOpts *init) { WRITE_REG(eth->MACCR, mode | ETH_MACCR_IPC); /* ---- MTL initialization ---- */ - WRITE_REG(eth->MTLTQOMR, (0b111 << 16) | ETH_MTLTQOMR_TSF | - (0b10 << 2)); // transmit store and forward ON - // and enable transmit queue - WRITE_REG(eth->MTLRQOMR, ETH_MTLRQOMR_RSF); // receive store and forward ON + WRITE_REG(eth->MTLTQOMR, (0b111 << 16) | ETH_MTLTQOMR_TSF | (0b10 << 2)); // transmit store and forward ON and enable transmit queue + WRITE_REG(eth->MTLRQOMR, ETH_MTLRQOMR_RSF); // receive store and forward ON /* ---- DMA configuration ---- */ @@ -213,8 +211,7 @@ __weak int ETHHW_ReadCallback(ETHHW_EventDesc *evt) { return ETHHW_RET_RX_PROCESSED; } -ETHHW_DescFull *ETHHW_AdvanceDesc(ETHHW_DescFull *start, uint16_t n, - ETHHW_DescFull *bd, int delta) { +ETHHW_DescFull *ETHHW_AdvanceDesc(ETHHW_DescFull *start, uint16_t n, ETHHW_DescFull *bd, int delta) { int16_t index = (((uint32_t)(bd)) - ((uint32_t)(start))) / sizeof(ETHHW_DescFull); // int16_t startIndex = index; index = ((int)index + delta) % n; @@ -334,7 +331,7 @@ static void ETHHW_PrintRingBufStatus(ETH_TypeDef *eth, // process incoming packet void ETHHW_ProcessRx(ETH_TypeDef *eth) { - //ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_RX); + // ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_RX); ETHHW_DescFull *ring = (ETHHW_DescFull *)eth->DMACRDLAR; uint16_t ringLen = eth->DMACRDRLR + 1; @@ -525,7 +522,7 @@ void ETHHW_Transmit(ETH_TypeDef *eth, const uint8_t *buf, uint16_t len, uint8_t // ----------------- -void ETHHW_SetLinkProperties(ETH_TypeDef * eth, bool fastEthernet, bool fullDuplex) { +void ETHHW_SetLinkProperties(ETH_TypeDef *eth, bool fastEthernet, bool fullDuplex) { // fetch register content uint32_t reg = eth->MACCR; @@ -731,7 +728,7 @@ void ETHHW_SetPTPAddend(ETH_TypeDef *eth, uint32_t addend) { } } -uint32_t ETHHW_GetPTPAddend(ETH_TypeDef * eth) { +uint32_t ETHHW_GetPTPAddend(ETH_TypeDef *eth) { return eth->MACTSAR; } @@ -785,7 +782,8 @@ uint8_t ETHHW_GetAuxTimestampCnt(ETH_TypeDef *eth) { void ETHHW_StartPTPPPSPulseTrain(ETH_TypeDef *eth, uint32_t high_len, uint32_t period) { ETHHW_StopPTPPPSPulseTrain(eth); - while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {}; + while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) { + }; // delayed start of pulse train with (at least) 1s to ensure, // target timestamps point always in the future on return from this function @@ -812,7 +810,8 @@ void ETHHW_StopPTPPPSPulseTrain(ETH_TypeDef *eth) { if (!(eth->MACPPSCR & ETH_PTP_PPS_OUTPUT_MODE_SELECT)) { eth->MACPPSCR |= ETH_PTP_PPS_OUTPUT_MODE_SELECT; // switch to pulse-train mode } else { - while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {}; + while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) { + }; } eth->MACPPSCR |= ETH_PTP_PPS_PULSE_TRAIN_STOP_IMM; diff --git a/Inc/stm32h7xx_hal_conf.h b/Inc/stm32h7xx_hal_conf.h index 287f2ad..337559f 100644 --- a/Inc/stm32h7xx_hal_conf.h +++ b/Inc/stm32h7xx_hal_conf.h @@ -222,7 +222,7 @@ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ /* ########################### Ethernet Configuration ######################### */ -#define ETH_TX_DESC_CNT 8 /* number of Ethernet Tx DMA descriptors */ +#define ETH_TX_DESC_CNT 24 /* number of Ethernet Tx DMA descriptors */ #define ETH_RX_DESC_CNT 24 /* number of Ethernet Rx DMA descriptors */ #define UNIQUE_DEV_ID_BASE ((const uint8_t *)0x1FF1E800) diff --git a/Middlewares/Inc/FreeRTOSConfig.h b/Middlewares/Inc/FreeRTOSConfig.h index 1343d4d..185129e 100644 --- a/Middlewares/Inc/FreeRTOSConfig.h +++ b/Middlewares/Inc/FreeRTOSConfig.h @@ -47,7 +47,7 @@ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 1 -#define configCPU_CLOCK_HZ ( 550000000 ) +#define configCPU_CLOCK_HZ ( 400000000 ) #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configMAX_PRIORITIES ( 56 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 ) diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt index 36d5276..54c8ba6 100644 --- a/Modules/CMakeLists.txt +++ b/Modules/CMakeLists.txt @@ -56,4 +56,5 @@ target_link_libraries(${CMAKE_PROJECT_NAME} # flexptp # etherlib embfmt - lwipcore) + lwipcore + lwipallapps) diff --git a/Src/CMakeLists.txt b/Src/CMakeLists.txt index e306585..6931e85 100644 --- a/Src/CMakeLists.txt +++ b/Src/CMakeLists.txt @@ -6,6 +6,8 @@ target_sources( sysmem.c system_stm32h7xx.c + board_support.c + board_support.h cmds.c cmds.h ) @@ -18,4 +20,6 @@ target_include_directories( add_subdirectory(standard_output) add_subdirectory(cliutils) -add_subdirectory(ethernet) \ No newline at end of file +add_subdirectory(ethernet) + +add_subdirectory(user) \ No newline at end of file diff --git a/Src/board_support.c b/Src/board_support.c new file mode 100644 index 0000000..cdc0fb8 --- /dev/null +++ b/Src/board_support.c @@ -0,0 +1,73 @@ +#include "board_support.h" + +#include + +void leds_init() { + __HAL_RCC_GPIOC_CLK_ENABLE(); + + GPIO_InitTypeDef init; + init.Mode = GPIO_MODE_OUTPUT_PP; + init.Pin = GPIO_PIN_2 | GPIO_PIN_3; + init.Pull = GPIO_NOPULL; + init.Alternate = 0; + init.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(GPIOC, &init); + + HAL_GPIO_WritePin(GPIOC, init.Pin, GPIO_PIN_SET); +} + +void leds_write(uint8_t idx, bool state) { + GPIO_TypeDef *gpio; + uint16_t pin; + + switch (idx) { + case LEDS_USER1_GREEN: + gpio = GPIOC; + pin = GPIO_PIN_3; + break; + case LEDS_USER2_RED: + gpio = GPIOC; + pin = GPIO_PIN_2; + break; + default: + break; + } + + HAL_GPIO_WritePin(gpio, pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET); +} + +static EXTI_HandleTypeDef hEXTI13; + +void btn_init() { + // pin initialization + __HAL_RCC_GPIOC_CLK_ENABLE(); + + GPIO_InitTypeDef init; + init.Mode = GPIO_MODE_INPUT; + init.Pin = GPIO_PIN_13; + init.Pull = GPIO_NOPULL; + init.Alternate = 0; + init.Speed = GPIO_SPEED_LOW; + HAL_GPIO_Init(GPIOC, &init); + + // EXTI13 initialization + EXTI_ConfigTypeDef extiConf; + extiConf.Line = EXTI_LINE_13; + extiConf.GPIOSel = EXTI_GPIOC; + extiConf.Trigger = EXTI_TRIGGER_RISING; + extiConf.Mode = EXTI_MODE_INTERRUPT; + HAL_EXTI_SetConfigLine(&hEXTI13, &extiConf); + + // enable interrupt source + HAL_NVIC_SetPriority(EXTI15_10_IRQn, 12, 0); // some medium-low priority + HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); +} + +__weak void btn_cb() { + return; +} + +void EXTI15_10_IRQHandler() { + HAL_EXTI_ClearPending(&hEXTI13, EXTI_TRIGGER_RISING); // clear interrupt + btn_cb(); +} \ No newline at end of file diff --git a/Src/board_support.h b/Src/board_support.h new file mode 100644 index 0000000..bbbc410 --- /dev/null +++ b/Src/board_support.h @@ -0,0 +1,15 @@ +#ifndef SRC_BOARD_SUPPORT +#define SRC_BOARD_SUPPORT + +#include +#include + +#define LEDS_USER1_GREEN (0) +#define LEDS_USER2_RED (1) + +void leds_init(); +void leds_write(uint8_t idx, bool state); + +void btn_init(); + +#endif /* SRC_BOARD_SUPPORT */ diff --git a/Src/ethernet/ethernet_lwip.c b/Src/ethernet/ethernet_lwip.c index fe4018f..a9689a6 100644 --- a/Src/ethernet/ethernet_lwip.c +++ b/Src/ethernet/ethernet_lwip.c @@ -80,7 +80,7 @@ void init_ethernet() { osTimerStart(checkDhcpTmr, 1000); } -err_t hook_unknown_ethertype(struct pbuf *pbuf, struct netif *netif) { +__attribute__((weak)) err_t hook_unknown_ethertype(struct pbuf *pbuf, struct netif *netif) { pbuf_free(pbuf); return ERR_OK; diff --git a/Src/lwipopts.h b/Src/lwipopts.h index 5acd59f..3f05ced 100644 --- a/Src/lwipopts.h +++ b/Src/lwipopts.h @@ -31,9 +31,6 @@ ****************************************************************************** */ -#ifndef SRC_LWIPOPTS -#define SRC_LWIPOPTS - #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ @@ -51,7 +48,7 @@ /* MEM_SIZE: the size of the heap memory. If the application will send a lot of data that needs to be copied, this should be set high. */ -#define MEM_SIZE (12*1024) // (10*1024) +#define MEM_SIZE (16*1024) // (10*1024) #define LWIP_DECLARE_MEMORY_POSTFIX __attribute__((section(".lwIPHeapSection"))) @@ -75,15 +72,15 @@ a lot of data that needs to be copied, this should be set high. */ timeouts. */ #define MEMP_NUM_SYS_TIMEOUT 10 -#define LWIP_PBUF_CUSTOM_DATA \ - /** Ingress/egress timestamp seconds part */ \ - u32_t time_s; \ - /** Ingress/egress timestamp nanoseconds part */ \ - u32_t time_ns; \ - /** Transmit callback pointer */ \ - void (*tx_cb)(uint32_t, uint32_t, uint32_t); \ - /** Custom tag */ \ - void * tag; +// #define LWIP_PBUF_CUSTOM_DATA \ +// /** Ingress/egress timestamp seconds part */ \ +// u32_t time_s; \ +// /** Ingress/egress timestamp nanoseconds part */ \ +// u32_t time_ns; \ +// /** Transmit callback pointer */ \ +// void (*tx_cb)(uint32_t, uint32_t, uint32_t); \ +// /** Custom tag */ \ +// void * tag; @@ -134,7 +131,7 @@ a lot of data that needs to be copied, this should be set high. */ /* ---------- DHCP options ---------- */ #define LWIP_DHCP 1 - +#define LWIP_DHCP_CHECK_LINK_UP 1 /* ---------- UDP options ---------- */ #define LWIP_UDP 1 @@ -146,6 +143,9 @@ a lot of data that needs to be copied, this should be set high. */ //#define LWIP_HTTPD_CGI_SSI 1 #define LWIP_HTTPD_SSI 1 #define LWIP_HTTPD_CUSTOM_FILES 1 +#define LWIP_HTTPD_DYNAMIC_HEADERS 1 +#define LWIP_HTTPD_EXAMPLE_GENERATEDFILES 1 +#define LWIP_HTTPD_FILE_EXTENSION 1 #define HTTPD_USE_MEM_POOL 0 #define MEMP_NUM_PARALLEL_HTTPD_CONNS 8 #define LWIP_HTTPD_SSI_MULTIPART 0 @@ -222,7 +222,7 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums /** * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) */ -#define LWIP_NETCONN 1 +#define LWIP_NETCONN 0 /* ------------------------------------ @@ -241,7 +241,7 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums */ /** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the * file system (to prevent changing the file included in CVS) */ -#define HTTPD_USE_CUSTOM_FSDATA 1 +#define HTTPD_USE_CUSTOM_FSDATA 0 /* @@ -251,7 +251,7 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums */ #define TCPIP_THREAD_NAME "TCP/IP" -#define TCPIP_THREAD_STACKSIZE 2048 +#define TCPIP_THREAD_STACKSIZE 3072 #define TCPIP_MBOX_SIZE 6 #define DEFAULT_UDP_RECVMBOX_SIZE 6 #define DEFAULT_TCP_RECVMBOX_SIZE 6 @@ -273,5 +273,3 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - -#endif /* SRC_LWIPOPTS */ diff --git a/Src/main.c b/Src/main.c index d3258d4..8f72203 100644 --- a/Src/main.c +++ b/Src/main.c @@ -8,6 +8,7 @@ #include "FreeRTOSConfig.h" +#include "board_support.h" #include "cliutils/cli.h" #include "cmds.h" #include "ethernet/ethernet_lwip.h" @@ -17,6 +18,8 @@ #include +#include "user/user.h" + void init_pll() { RCC_OscInitTypeDef osc; RCC_ClkInitTypeDef clk; @@ -39,7 +42,7 @@ void init_pll() { osc.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // Wide-range VCO osc.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; // input frequency between 8MHz and 16MHz osc.PLL.PLLM = 2; // 25MHz -> 12.5MHz - osc.PLL.PLLN = 44; // 12.5MHz -> 550MHz + osc.PLL.PLLN = 32; // 12.5MHz -> 550MHz (44) osc.PLL.PLLP = 1; // 550MHz -> 550MHz osc.PLL.PLLQ = 5; // 550MHz -> 110MHz osc.PLL.PLLR = 5; // 550MHz -> 110MHz @@ -59,7 +62,7 @@ void init_pll() { clk.APB3CLKDivider = RCC_APB3_DIV2; clk.APB4CLKDivider = RCC_APB4_DIV2; - HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_3); // set a FLASH latency supporting maximum speed + HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_4); // set a FLASH latency supporting maximum speed // --------------------- } @@ -94,21 +97,10 @@ void print_welcome_message() { MSG(ANSI_COLOR_BGREEN "Greetings!" ANSI_COLOR_BYELLOW " Starting up... \n" ANSI_COLOR_RESET); } -static void init_led() { - __HAL_RCC_GPIOB_CLK_ENABLE(); - - GPIO_InitTypeDef init; - init.Mode = GPIO_MODE_OUTPUT_PP; - init.Pin = GPIO_PIN_14; - init.Pull = GPIO_NOPULL; - init.Alternate = 0; - init.Speed = GPIO_SPEED_HIGH; - HAL_GPIO_Init(GPIOB, &init); -} - void task_startup(void *arg) { - // initialize on-board LED(s) - init_led(); + // initialize on-board LEDs and buttons + leds_init(); + btn_init(); // initialize the CLI cli_init(); @@ -116,10 +108,6 @@ void task_startup(void *arg) { // print greetings print_welcome_message(); -// #ifdef DEBUG -// osDelay(2000); -// #endif - // initialize Ethernet init_ethernet(); @@ -128,6 +116,10 @@ void task_startup(void *arg) { // ------------- + user_init(); + + // ------------- + for (;;) { osDelay(1000); } @@ -144,6 +136,10 @@ void init_randomizer() { srand(LL_RNG_ReadRandData32(RNG)); } +void init_mpu() { + HAL_MPU_Disable(); +} + int main(void) { // initialize FPU and several system blocks SystemInit(); @@ -154,9 +150,12 @@ int main(void) { // initialize oscillator and clocking init_osc_and_clk(); - // make random a bit more undeterministic + // make random a bit more less deterministic init_randomizer(); + // initialize MPU + init_mpu(); + // initialize standard output serial_io_init(); @@ -179,10 +178,6 @@ int main(void) { } } -// void SysTick_Handler() { -// HAL_IncTick(); -// } - // ------------------------ uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((section(".FreeRTOSHeapSection"))); diff --git a/Src/user/CMakeLists.txt b/Src/user/CMakeLists.txt new file mode 100644 index 0000000..e2ca308 --- /dev/null +++ b/Src/user/CMakeLists.txt @@ -0,0 +1,4 @@ +target_sources(${CMAKE_PROJECT_NAME} PUBLIC + user.h + user.c +) \ No newline at end of file diff --git a/Src/user/user.c b/Src/user/user.c new file mode 100644 index 0000000..6ad2edb --- /dev/null +++ b/Src/user/user.c @@ -0,0 +1,397 @@ +#include "user.h" +#include "embfmt/embformat.h" +#include "lwip/apps/fs.h" +#include "lwip/apps/httpd.h" +#include "lwip/igmp.h" +#include "lwip/tcp.h" +#include "lwip/udp.h" +#include "netif/ethernet.h" +#include "standard_output/standard_output.h" +#include + +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +// ----------------------------------- + +#define RECV_BUF_LEN (511) +static char recv_buf[RECV_BUF_LEN + 1]; +static char *msg = "Üdvözlet a H735-ös kártyáról!"; + +// ----------- Custom EtherType client + +// TODO: 0x9000 fölött kb. bármit lehet választani + +#define CUSTOM_RX_ETHERTYPE (0x88F7) + +err_t hook_unknown_ethertype(struct pbuf *pbuf, struct netif *netif) { + // aquire ethertype + uint16_t etherType = 0; + memcpy(ðerType, ((uint8_t *)pbuf->payload) + 12, 2); + etherType = ntohs(etherType); + + uint8_t *shwa = ((uint8_t *)pbuf->payload) + 6; // get source hardware address + uint16_t len = pbuf->len - 14; // get payload length + uint8_t *payload = ((uint8_t *)pbuf->payload) + 14; // actual payload + + // check for match + if (etherType == CUSTOM_RX_ETHERTYPE) { + // copy payload + uint16_t copy_len = MIN(RECV_BUF_LEN, len); + recv_buf[copy_len] = '\0'; + memcpy(recv_buf, payload, copy_len); + + // print it + MSG("[%02X:%02X:%02X:%02X:%02X:%02X] %u\n%s\n", shwa[0], shwa[1], shwa[2], shwa[3], shwa[4], shwa[5], len, recv_buf); + } + + pbuf_free(pbuf); + + return ERR_OK; +} + +#define CUSTOM_TX_ETHERTYPE (0x9101) +static struct eth_addr dest_hwa = {.addr = {0x00, 0x1b, 0x21, 0x91, 0x9E, 0x64}}; + +void send_frame() { + uint16_t len = strlen(msg); + struct pbuf *p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM); + if (p == NULL) { + MSG("Nem sikerült pbuf-ot foglalni az Ethernet-keret küldéséhez!\n"); + return; + } + + memcpy(p->payload, msg, len); + if (ethernet_output(netif_default, p, (struct eth_addr *)netif_default->hwaddr, &dest_hwa, CUSTOM_TX_ETHERTYPE) != ERR_OK) { + MSG("Sikertelen volt az Ethernet-keret küldése!\n"); + return; + } + + pbuf_free(p); +} + +// ----------- UDP client ------------ + +static struct udp_pcb *udpc; +static ip4_addr_t dest_addr; +static uint16_t dest_port; + +void udp_client_init() { + // create new PCB + udpc = udp_new(); + if (udpc == NULL) { + MSG("Hiba az UDP-kliens létrehozásánál!\n"); + } + + // set destination IP address and port + IP4_ADDR(&dest_addr, 10, 42, 0, 1); + dest_port = 4000; + + // TODO: connect? +} + +void udp_client_send() { + uint16_t len = strlen(msg); + + // allocate pbuf and fill with contents + struct pbuf *buf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (buf == NULL) { + MSG("Nem lehetett újabb pbuf-ot foglalni!\n"); + return; + } + memcpy(buf->payload, msg, len); + + // send UDP datagram to defined destination + if (udp_sendto(udpc, buf, &dest_addr, dest_port) != ERR_OK) { + MSG("Nem sikerült elküldeni az UDP datagramot!\n"); + } + + // decrease reference count of the buf + pbuf_free(buf); +} + +// ----------------------------------- + +static struct udp_pcb *udps; +static uint16_t server_port; + +static void udp_server_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { + uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); + recv_buf[copy_len] = '\0'; + memcpy(recv_buf, p->payload, copy_len); + MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(addr), port, p->len, recv_buf); + pbuf_free(p); +} + +void udp_server_init() { + // create new PCB + udps = udp_new(); + if (udps == NULL) { + MSG("Hiba az UDP-szerver létrehozásánál!\n"); + } + + // set server port + server_port = 3000; + + // bind it to a local address + if (udp_bind(udps, IP4_ADDR_ANY, server_port) != ERR_OK) { + MSG("Nem sikerült az UDP-szervert felcsatolni a %u portra!\n", server_port); + udp_remove(udps); + } + + // register receive callback + udp_recv(udps, udp_server_recv, NULL); +} + +// ----------------------------------- + +static struct udp_pcb *udpmc; +static uint16_t mc_port; +static ip4_addr_t mc_group; + +static void udp_mcast_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { + uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); + recv_buf[copy_len] = '\0'; + memcpy(recv_buf, p->payload, copy_len); + MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(addr), port, p->len, recv_buf); + pbuf_free(p); +} + +void udp_mcast_init() { + // create new PCB + udpmc = udp_new(); + if (udps == NULL) { + MSG("Hiba a multicast UDP szolgáltatás létrehozásánál!\n"); + } + + // set multicast group's address and port + IP4_ADDR(&mc_group, 224, 0, 2, 5); + mc_port = 2000; + + // join the relevant multicast group + igmp_joingroup(&netif_default->ip_addr, &mc_group); + + // bind it to a local address + if (udp_bind(udpmc, &mc_group, mc_port) != ERR_OK) { + MSG("Nem sikerült az UDP-szervert felcsatolni a %u portra!\n", mc_port); + goto cleanup; + } + + // connect to the IGMP group + if (udp_connect(udpmc, &mc_group, mc_port) != ERR_OK) { + MSG("Nem sikerült az UDP multicast szolgáltatást becsatlakoztatni a multicast-csoportba!\n"); + goto cleanup; + } + + // register receive callback + udp_recv(udpmc, udp_mcast_recv, NULL); + + return; + +// --- +cleanup: + udp_remove(udpmc); + return; +} + +void udp_mcast_send() { + uint16_t len = strlen(msg); + + // allocate pbuf and fill with contents + struct pbuf *buf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); + if (buf == NULL) { + MSG("Nem lehetett újabb pbuf-ot foglalni!\n"); + return; + } + memcpy(buf->payload, msg, len); + + // send UDP datagram to defined destination + if (udp_send(udpmc, buf) != ERR_OK) { + MSG("Nem sikerült elküldeni az UDP datagramot!\n"); + } + + // decrease reference count of the buf + pbuf_free(buf); +} + +// ----------------------------------- + +static struct tcp_pcb *tcps; +static uint16_t tcps_port; +static ip_addr_t tcps_addr; + +static err_t tcp_server_conn_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { + if (p != NULL) { + uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); + recv_buf[copy_len] = '\0'; + memcpy(recv_buf, p->payload, copy_len); + MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port, p->len, recv_buf); + pbuf_free(p); + tcp_recved(tpcb, copy_len); + } else { + MSG("A kliens lekapcsolódott %s:%u\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); + } + return ERR_OK; +} + +static void tcp_server_conn_err(void *arg, err_t err) { + MSG("TCP-kapcsolat hiba! (%u)\n", err); +} + +static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { + tcp_recv(newpcb, tcp_server_conn_recv); + tcp_err(newpcb, tcp_server_conn_err); + MSG("Bejövő TCP-kapcsolat érkezett %s:%u!\n", ipaddr_ntoa(&newpcb->remote_ip), newpcb->remote_port); + + return ERR_OK; +} + +static void tcp_server_error(void *arg, err_t err) { + MSG("TCP-szerver hiba! (%u)\n", err); +} + +void tcp_server_init() { + // create new TCP service + tcps = tcp_new(); + if (tcps == NULL) { + MSG("Nem sikerült létrehozni a TCP szerver szolgáltatást!\n"); + return; + } + + // set port + tcps_port = 6000; + IP4_ADDR(&tcps_addr, 10, 42, 0, 137); + + // bind to local port + if (tcp_bind(tcps, &tcps_addr, tcps_port) != ERR_OK) { + MSG("Nem sikerült a TCP-szervert a %u portra csatolni!\n", tcps_port); + goto cleanup; + } + + // enable server functions + tcps = tcp_listen(tcps); + + // assign error handling function + tcp_err(tcps, tcp_server_error); + + // register accept callback + tcp_accept(tcps, tcp_server_accept); + + return; + +// ----- +cleanup: + tcp_close(tcps); + return; +} + +static struct tcp_pcb *tcpc; +static ip4_addr_t tcpc_remote_addr; +static uint16_t tcpc_remote_port; + +static void tcp_client_error(void *arg, err_t err) { + MSG("TCP-kliens hiba! (%u)\n", err); +} + +static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { + if (p != NULL) { + uint16_t copy_len = MIN(RECV_BUF_LEN, p->len); + recv_buf[copy_len] = '\0'; + memcpy(recv_buf, p->payload, copy_len); + MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port, p->len, recv_buf); + pbuf_free(p); + tcp_recved(tpcb, copy_len); + } else { + MSG("A szerver bontotta a kapcsolatot %s:%u\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); + } + return ERR_OK; +} + +static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) { + MSG("Sikeresen fölkapcsolódtunk a TCP-szerverre: %s:%u!\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port); + + tcp_write(tcpc, msg, strlen(msg), 0); + + tcp_close(tcpc); + + return ERR_OK; +} + +void tcp_client_init() { + // create new TCP service + tcpc = tcp_new(); + if (tcpc == NULL) { + MSG("Nem sikerült létrehozni a TCP szerver szolgáltatást!\n"); + return; + } + + // set remote address and port + IP4_ADDR(&tcpc_remote_addr, 10, 42, 0, 1); + tcpc_remote_port = 9000; + + // assign error handling function + tcp_err(tcpc, tcp_client_error); + + // assign reception callback + tcp_recv(tcpc, tcp_client_recv); + + // connect to remote host + tcp_connect(tcpc, &tcpc_remote_addr, tcpc_remote_port, tcp_client_connected); +} + +// ----------------------------------- + +#define GENDATA_LEN (31) +static char generated_data[GENDATA_LEN + 1]; + +int fs_open_custom(struct fs_file *file, const char *name) { + /* this example only provides one file */ + if (!strcmp(name, "/generated.html")) { + /* generate a random number */ + uint32_t random = rand(); + embfmt(generated_data, GENDATA_LEN, "%u is random!", random); + + /* initialize fs_file correctly */ + memset(file, 0, sizeof(struct fs_file)); + uint32_t len = strlen(generated_data); + file->pextension = mem_malloc(len); + if (file->pextension != NULL) { + /* instead of doing memcpy, you would generate e.g. a JSON here */ + memcpy(file->pextension, generated_data, len); + file->data = (const char *)file->pextension; + file->len = len; /* don't send the trailing 0 */ + file->index = file->len; + /* allow persisting connections */ + file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT; + return 1; + } + } + return 0; +} + +void fs_close_custom(struct fs_file *file) { + if (file && file->pextension) { + mem_free(file->pextension); + file->pextension = NULL; + } +} + +// ----------------------------------- + +void btn_cb() { + MSG("Küldés!\n"); + + //udp_client_send(); + // send_frame(); + // udp_mcast_send(); + tcp_client_init(); +} + +void user_init() { + udp_client_init(); + // udp_server_init(); + // udp_mcast_init(); + tcp_server_init(); + + httpd_init(); +} \ No newline at end of file diff --git a/Src/user/user.h b/Src/user/user.h new file mode 100644 index 0000000..b96d3a6 --- /dev/null +++ b/Src/user/user.h @@ -0,0 +1,6 @@ +#ifndef USER_USER +#define USER_USER + +void user_init(); + +#endif /* USER_USER */ diff --git a/stm32h735igkx_FLASH.ld b/stm32h735igkx_FLASH.ld index be6eab4..14958f7 100644 --- a/stm32h735igkx_FLASH.ld +++ b/stm32h735igkx_FLASH.ld @@ -176,12 +176,12 @@ SECTIONS .FreeRTOS_sec (NOLOAD) : { *(.FreeRTOSHeapSection) - } >ITCMRAM + } >RAM_D1 .lwIP_sec (NOLOAD) : { *(.lwIPHeapSection) - } > DTCMRAM + } >RAM_D1 /* Remove information from the standard libraries */ /DISCARD/ :