diff --git a/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/User/system_ch32v20x.c b/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/User/system_ch32v20x.c index 574b3a9ec..0b5283b76 100644 --- a/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/User/system_ch32v20x.c +++ b/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/User/system_ch32v20x.c @@ -29,8 +29,8 @@ //#define SYSCLK_FREQ_48MHz_HSI 48000000 //#define SYSCLK_FREQ_56MHz_HSI 56000000 //#define SYSCLK_FREQ_72MHz_HSI 72000000 -#define SYSCLK_FREQ_96MHz_HSI 96000000 -//#define SYSCLK_FREQ_120MHz_HSI 120000000 +// #define SYSCLK_FREQ_96MHz_HSI 96000000 +#define SYSCLK_FREQ_120MHz_HSI 120000000 //#define SYSCLK_FREQ_144MHz_HSI 144000000 /* Clock Definitions */ diff --git a/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/interrupt_switch.S b/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/interrupt_switch.S index e89fea31e..4d7b3cb3e 100644 --- a/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/interrupt_switch.S +++ b/Ubiquitous/XiZi_IIoT/arch/risc-v/ch32v208rbt6/interrupt_switch.S @@ -1,8 +1,8 @@ #include "cpuport.h" -.global SW_handler +.global SW_Handler .align 2 -SW_handler: +SW_Handler: /* save all from thread context */ #ifdef ARCH_RISCV_FPU addi sp, sp, -32 * FREGBYTES @@ -46,6 +46,7 @@ SW_handler: /* saved MPIE */ li t0, 0x80 STORE t0, 2 * REGBYTES(sp) + /* Temporarily disable HPE */ li t0, 0x20 diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c index 28d97aa1a..c8f27cb02 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.c @@ -31,17 +31,20 @@ #include "connect_uart.h" #include "core_riscv.h" #include "xsconfig.h" -#include +#include "board.h" #include #include #include +#include +#include "connect_ether.h" // core clock. extern uint32_t SystemCoreClock; static uint32_t _SysTick_Config(uint32_t ticks) { - NVIC_SetPriority(SysTicK_IRQn, 0xf0); + // SystemCoreClockUpdate(); + NVIC_SetPriority(SysTicK_IRQn, 1); NVIC_SetPriority(Software_IRQn, 0xf0); NVIC_EnableIRQ(SysTicK_IRQn); NVIC_EnableIRQ(Software_IRQn); @@ -52,7 +55,6 @@ static uint32_t _SysTick_Config(uint32_t ticks) SysTick->CTLR = 0xF; return 0; } - /** * This function will initial your board. */ @@ -64,13 +66,21 @@ void InitBoardHardware() /* initialize memory system */ InitBoardMemory(MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); InitHwUart(); - InstallConsole("uart1", "uart1_drv", "uart1_dev1"); - + InstallConsole("uart1", SERIAL_DRV_NAME_1, SERIAL_1_DEVICE_NAME_0); +#ifdef BSP_USING_ETH + // InitHwEth(); +#endif KPrintf("consle init completed.\n"); KPrintf("board initialization......\n"); // KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, gd32vf103_SRAM_SIZE); + KPrintf("memory address range: [0x%08x - 0x%08x] SRAM_SIZE: %d, ssize: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, SRAM_SIZE, __stack_size); /* initialize memory system */ - + x_ubase dynamic_buddy_start = ALIGN_MEN_UP((x_ubase)MEMORY_START_ADDRESS, MM_PAGE_SIZE); + x_ubase dynamic_buddy_end = ALIGN_MEN_DOWN((x_ubase)MEMORY_END_ADDRESS, MM_PAGE_SIZE); + KPrintf("dynamic buddy address range: [0x%08x - 0x%08x]\n", dynamic_buddy_start, dynamic_buddy_end); + // memory address range: [0x20001440 - 0xcb0843e0] + // dynamic buddy address range: [0x20002000 - 0xcb084000] + ShowMemory(); KPrintf("board init done.\n"); KPrintf("start okernel...\n"); } diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.h b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.h index 0e6b6f9c0..874d047fb 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.h +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/board.h @@ -36,13 +36,16 @@ Modification: #define ch32v20x_PIN_NUMBERS 48 /* board configuration */ -#define SRAM_SIZE 20 -#define SRAM_END (0x20000000 + SRAM_SIZE * 1024) +#define SRAM_SIZE 48 +#define EUSR_STACK_SIZE 2048 +// #define SRAM_END (0x20000000 + SRAM_SIZE * 0x400) +// #define SRAM_END (0x20008000) +#define SRAM_END (0x2000C000) extern int _ebss; extern int __stack_size; #define MEMORY_START_ADDRESS ((void *)&_ebss) -#define MEMORY_END_ADDRESS (SRAM_END-__stack_size) +#define MEMORY_END_ADDRESS (SRAM_END) void InitBoardHardware(void); diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/config.mk b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/config.mk index fd64cf9f0..0855c54f6 100755 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/config.mk @@ -1,7 +1,7 @@ export CFLAGS := -march=rv32imac -mabi=ilp32 -msmall-data-limit=8 -msave-restore -Os -g export AFLAGS := -march=rv32imac -mabi=ilp32 -x assembler-with-cpp -ggdb -export LFLAGS := -march=rv32imac -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiZi-ch32v307vct6.map,-cref,-u,_start -T $(BSP_ROOT)/link.ld +export LFLAGS := -march=rv32imac -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiZi-ch32v208vct6.map,-cref,-u,_start -T $(BSP_ROOT)/link.ld # export CFLAGS := -march=rv32imacxw -mabi=ilp32 -msmall-data-limit=8 -msave-restore -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common -g -std=gnu99 # export AFLAGS := -march=rv32imac -mabi=ilp32 -x assembler-with-cpp -ggdb @@ -15,6 +15,8 @@ export CROSS_COMPILE ?=/opt/riscv64-toolchain/bin/riscv64-unknown-elf- export DEFINES := -DHAVE_CCONFIG_H -DHAVE_SIGINFO +export LINK_WCH_NET := $(KERNEL_ROOT)/board/ch32v208rbt6/third_party_driver/ethernet/libwchnet.a + export ARCH = risc-v export MCU = CH32V208 diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/link.ld b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/link.ld index 4b3dfd6bd..112504256 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/link.ld +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/link.ld @@ -26,8 +26,8 @@ MEMORY FLASH-144K + RAM-48K FLASH-160K + RAM-32K */ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 144K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 48K } diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig index 21b27f1ea..aa3b10601 100755 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Kconfig @@ -6,5 +6,8 @@ menuconfig BSP_USING_UART if BSP_USING_UART source "$BSP_DIR/third_party_driver/uart/Kconfig" endif - + +menuconfig BSP_USING_ETH + bool "Using Ethernet" + default y \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile index 94cb5f1a3..2fd2d3af4 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Makefile @@ -4,5 +4,7 @@ SRC_DIR := Peripheral ifeq ($(CONFIG_BSP_USING_UART),y) SRC_DIR += uart endif - +ifeq ($(CONFIG_BSP_USING_ETH),y) + SRC_DIR += ethernet +endif include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Peripheral/inc/ch32v20x.h b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Peripheral/inc/ch32v20x.h index 621e488c7..30de07bd3 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Peripheral/inc/ch32v20x.h +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/Peripheral/inc/ch32v20x.h @@ -17,9 +17,9 @@ extern "C" { #endif #if !defined(CH32V20x_D8W) && !defined(CH32V20x_D8) && !defined(CH32V20x_D6) -#define CH32V20x_D6 /* CH32V203F6-CH32V203F8-CH32V203G6-CH32V203G8-CH32V203K6-CH32V203K8-CH32V203C6-CH32V203C8-CH32V203G8*/ +//#define CH32V20x_D6 /* CH32V203F6-CH32V203F8-CH32V203G6-CH32V203G8-CH32V203K6-CH32V203K8-CH32V203C6-CH32V203C8-CH32V203G8*/ //#define CH32V20x_D8 /* CH32V203RBT6 */ -//#define CH32V20x_D8W /* CH32V208 */ +#define CH32V20x_D8W /* CH32V208 */ #endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/Makefile new file mode 100755 index 000000000..17b175216 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := eth_driver.c connect_ether.c +SRC_DIR := test + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/connect_ether.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/connect_ether.c new file mode 100644 index 000000000..0ee5fd80a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/connect_ether.c @@ -0,0 +1,269 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : main.c + * Author : WCH + * Version : V1.0.0 + * Date : 2022/05/31 + * Description : Main program body. + ********************************************************************************* + * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. + * Attention: This software (modified or not) and binary are used for + * microcontroller manufactured by Nanjing Qinheng Microelectronics. + *******************************************************************************/ +/* + *@Note +TCP Client example, demonstrating that TCP Client connects +to the server and receives data and then sends it back. +For details on the selection of engineering chips, +please refer to the "CH32V30x Evaluation Board Manual" under the CH32V307EVT\EVT\PUB folder. + */ + +#include "connect_ether.h" +#include "ch32v20x_rcc.h" +#include "ch32v20x_tim.h" +#include "core_riscv.h" +#include "eth_driver.h" +#include "string.h" +#include "xs_base.h" + +extern uint32_t SystemCoreClock; +#define KEEPALIVE_ENABLE 1 // Enable keep alive function + +uint8_t MACAddr[6]; // MAC address +uint8_t IPAddr[4] = { 192, 168, 1, 10 }; // IP address +uint8_t GWIPAddr[4] = { 192, 168, 1, 1 }; // Gateway IP address +uint8_t IPMask[4] = { 255, 255, 255, 0 }; // subnet mask + +uint8_t MyBuf[RECE_BUF_LEN]; +uint8_t socket[WCHNET_MAX_SOCKET_NUM]; // Save the currently connected socket +uint8_t SocketRecvBuf[WCHNET_MAX_SOCKET_NUM][RECE_BUF_LEN]; // socket receive buffer + +/********************************************************************* + * @fn mStopIfError + * + * @brief check if error. + * + * @param iError - error constants. + * + * @return none + */ +void mStopIfError(uint8_t iError) +{ + if (iError == WCHNET_ERR_SUCCESS) + return; + KPrintf("Error: %02X\r\n", (uint16_t)iError); +} + +/********************************************************************* + * @fn TIM2_Init + * + * @brief Initializes TIM2. + * + * @return none + */ +void TIM2_Init(void) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = { 0 }; + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + + TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000; + TIM_TimeBaseStructure.TIM_Prescaler = WCHNETTIMERPERIOD * 1000 - 1; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); + TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); + + TIM_Cmd(TIM2, ENABLE); + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); + NVIC_EnableIRQ(TIM2_IRQn); +} + +/********************************************************************* + * @fn WCHNET_CreateTcpSocket + * + * @brief Create TCP Socket + * + * @return none + */ +void WCHNET_CreateTcpSocket(uint8_t* DESIP, uint16_t srcport, uint16_t desport, uint8_t* SocketId) +{ + uint8_t i; + SOCK_INF TmpSocketInf; + + memset((void*)&TmpSocketInf, 0, sizeof(SOCK_INF)); + memcpy((void*)TmpSocketInf.IPAddr, DESIP, 4); + TmpSocketInf.DesPort = desport; + TmpSocketInf.SourPort = srcport++; + TmpSocketInf.ProtoType = PROTO_TYPE_TCP; + TmpSocketInf.RecvBufLen = RECE_BUF_LEN; + i = WCHNET_SocketCreat(SocketId, &TmpSocketInf); + KPrintf("SocketId %d\r\n", *SocketId); + mStopIfError(i); + i = WCHNET_SocketConnect(*SocketId); // make a TCP connection + mStopIfError(i); +} + +/********************************************************************* + * @fn WCHNET_DataLoopback + * + * @brief Data loopback function. + * + * @param id - socket id. + * + * @return none + */ +void WCHNET_DataLoopback(uint8_t id) +{ + u32 len, totallen; + uint8_t *p = MyBuf, TransCnt = 255; + + len = WCHNET_SocketRecvLen(id, NULL); // query length + KPrintf("Receive Len = %d\r\n", len); + totallen = len; + WCHNET_SocketRecv(id, MyBuf, &len); // Read the data of the receive buffer into MyBuf + while (1) { + len = totallen; + WCHNET_SocketSend(id, p, &len); // Send the data + totallen -= len; // Subtract the sent length from the total length + p += len; // offset buffer pointer + if (!--TransCnt) + break; // Timeout exit + if (totallen) + continue; // If the data is not sent, continue to send + break; // After sending, exit + } +} + +/********************************************************************* + * @fn WCHNET_HandleSockInt + * + * @brief Socket Interrupt Handle + * + * @param socketid - socket id. + * intstat - interrupt status + * + * @return 0 or TIME_OUT + */ +int WCHNET_HandleSockInt(uint8_t socketid, uint8_t intstat) +{ + uint8_t i; + + if (intstat & SINT_STAT_RECV) // receive data + { + WCHNET_DataLoopback(socketid); // Data loopback + } + if (intstat & SINT_STAT_CONNECT) // connect successfully + { +#if KEEPALIVE_ENABLE + WCHNET_SocketSetKeepLive(socketid, ENABLE); +#endif + WCHNET_ModifyRecvBuf(socketid, (u32)SocketRecvBuf[socketid], RECE_BUF_LEN); + for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) { + if (socket[i] == 0xff) { // save connected socket id + socket[i] = socketid; + break; + } + } + KPrintf("TCP Connect Success\r\n"); + KPrintf("socket id: %d\r\n", socket[i]); + } + if (intstat & SINT_STAT_DISCONNECT) // disconnect + { + for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) { // delete disconnected socket id + if (socket[i] == socketid) { + socket[i] = 0xff; + break; + } + } + KPrintf("TCP Disconnect\r\n"); + } + if (intstat & SINT_STAT_TIM_OUT) // timeout disconnect + { + for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) { // delete disconnected socket id + if (socket[i] == socketid) { + socket[i] = 0xff; + break; + } + } + KPrintf("TCP Timeout\r\n"); + return TIME_OUT; + } + return 0; +} + +/********************************************************************* + * @fn WCHNET_HandleGlobalInt + * + * @brief Global Interrupt Handle + * + * @return 0 or SockInt + */ +int WCHNET_HandleGlobalInt(void) +{ + uint8_t intstat; + uint16_t i; + uint8_t socketint; + + intstat = WCHNET_GetGlobalInt(); // get global interrupt flag + if (intstat & GINT_STAT_UNREACH) // Unreachable interrupt + { + KPrintf("GINT_STAT_UNREACH\r\n"); + } + if (intstat & GINT_STAT_IP_CONFLI) // IP conflict + { + KPrintf("GINT_STAT_IP_CONFLI\r\n"); + } + if (intstat & GINT_STAT_PHY_CHANGE) // PHY status change + { + i = WCHNET_GetPHYStatus(); + if (i & PHY_Linked_Status) + KPrintf("PHY Link Success\r\n"); + } + if (intstat & GINT_STAT_SOCKET) { // socket related interrupt + for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) { + socketint = WCHNET_GetSocketInt(i); + if (socketint) { + return WCHNET_HandleSockInt(i, socketint); + } + } + } + return 0; +} + +uint8_t InitHwEth() +{ + uint8_t i = 0; + + KPrintf("net version:%x\n", WCHNET_GetVer()); + KPrintf("WCHNET_LIB_VER: %x\n", WCHNET_LIB_VER); + if (WCHNET_LIB_VER != WCHNET_GetVer()) { + KPrintf("version error.\n"); + } + + // WCHNET_GetMacAddr(MACAddr); // get the chip MAC address + KPrintf("mac addr:"); + for (i = 0; i < 6; i++) + KPrintf("%x ", MACAddr[i]); + KPrintf("\n"); + + // TIM2_Init(); + + i = ETH_LibInit(IPAddr, GWIPAddr, IPMask, MACAddr); // Ethernet library initialize + mStopIfError(i); + if (i == WCHNET_ERR_SUCCESS) + KPrintf("WCHNET_LibInit Success\r\n"); +#if KEEPALIVE_ENABLE // Configure keep alive parameters + { + struct _KEEP_CFG cfg; + + cfg.KLIdle = 20000; + cfg.KLIntvl = 15000; + cfg.KLCount = 9; + WCHNET_ConfigKeepLive(&cfg); + } +#endif + +// memset(socket, 0xff, WCHNET_MAX_SOCKET_NUM); + + return i; +} diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/eth_driver.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/eth_driver.c new file mode 100755 index 000000000..c6e95a9f7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/eth_driver.c @@ -0,0 +1,745 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : eth_driver.c +* Author : WCH +* Version : V1.3.0 +* Date : 2022/05/26 +* Description : eth program body. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "string.h" +#include "eth_driver.h" + + __attribute__((__aligned__(4))) ETH_DMADESCTypeDef DMARxDscrTab[ETH_RXBUFNB]; /* MAC receive descriptor, 4-byte aligned*/ + __attribute__((__aligned__(4))) ETH_DMADESCTypeDef DMATxDscrTab[ETH_TXBUFNB]; /* MAC send descriptor, 4-byte aligned */ + + __attribute__((__aligned__(4))) uint8_t MACRxBuf[ETH_RXBUFNB*ETH_RX_BUF_SZE]; /* MAC receive buffer, 4-byte aligned */ + __attribute__((__aligned__(4))) uint8_t MACTxBuf[ETH_TXBUFNB*ETH_TX_BUF_SZE]; /* MAC send buffer, 4-byte aligned */ + +__attribute__((__aligned__(4))) SOCK_INF SocketInf[WCHNET_MAX_SOCKET_NUM]; /* Socket information table, 4-byte alignment */ +const uint16_t MemNum[8] = {WCHNET_NUM_IPRAW, + WCHNET_NUM_UDP, + WCHNET_NUM_TCP, + WCHNET_NUM_TCP_LISTEN, + WCHNET_NUM_TCP_SEG, + WCHNET_NUM_IP_REASSDATA, + WCHNET_NUM_PBUF, + WCHNET_NUM_POOL_BUF + }; +const uint16_t MemSize[8] = {WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_IPRAW_PCB), + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_UDP_PCB), + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_PCB), + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_PCB_LISTEN), + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_SEG), + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_IP_REASSDATA), + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_PBUF), + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_PBUF) + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_POOL_BUF) + }; + __attribute__((__aligned__(4)))uint8_t Memp_Memory[WCHNET_MEMP_SIZE]; + __attribute__((__aligned__(4)))uint8_t Mem_Heap_Memory[WCHNET_RAM_HEAP_SIZE]; + __attribute__((__aligned__(4)))uint8_t Mem_ArpTable[WCHNET_RAM_ARP_TABLE_SIZE]; + +uint32_t volatile LocalTime; +ETH_DMADESCTypeDef *DMATxDescToSet; +ETH_DMADESCTypeDef *DMARxDescToGet; +ETH_DMADESCTypeDef *pDMARxSet; + +volatile uint8_t phyLinkReset; +volatile uint32_t phyLinkTime; +uint8_t phyPN = 0x01; +uint8_t phyStatus = 0; +uint8_t phySucCnt = 0; +uint8_t phyLinkCnt = 0; +uint8_t phyRetryCnt = 0; +uint8_t CRCErrPktCnt = 0; +uint8_t phyLinkStatus = 0; +uint8_t phyPNChangeCnt = 0; +uint8_t PhyPolarityDetect = 0; +/********************************************************************* + * @fn WCHNET_GetMacAddr + * + * @brief Get MAC address + * + * @return none. + */ +void WCHNET_GetMacAddr( uint8_t *p ) +{ + uint8_t i; + uint8_t *macaddr=(uint8_t *)(ROM_CFG_USERADR_ID+5); + + for(i=0;i<6;i++) + { + *p = *macaddr; + p++; + macaddr--; + } +} + +/********************************************************************* + * @fn WCHNET_TimeIsr + * + * @brief + * + * @return none. + */ +void WCHNET_TimeIsr( uint16_t timperiod ) +{ + LocalTime += timperiod; +} + +/********************************************************************* + * @fn WritePHYReg + * + * @brief MCU write PHY register. + * + * @param reg_add - PHY address, + * reg_val - value you want to write. + * + * @return none + */ +void WritePHYReg(uint8_t reg_add,uint16_t reg_val) +{ + R32_ETH_MIWR = (reg_add & RB_ETH_MIREGADR_MIRDL) | (1<<8) | (reg_val<<16); +} + +/********************************************************************* + * @fn ReadPHYReg + * + * @brief MCU read PHY register. + * + * @param reg_add - PHY address. + * + * @return value you want to get. + */ +uint16_t ReadPHYReg(uint8_t reg_add) +{ + R8_ETH_MIREGADR = reg_add; // write address + return R16_ETH_MIRD; // get data +} + +/********************************************************************* + * @fn WCHNET_LinkProcess + * + * @brief link process. + * + * @param none. + * + * @return none. + */ +void WCHNET_LinkProcess( void ) +{ + uint16_t phy_anlpar, phy_bmcr, phy_bmsr; + + phy_anlpar = ReadPHYReg(PHY_ANLPAR); + phy_bmsr = ReadPHYReg(PHY_BMSR); + + if(phy_anlpar&PHY_ANLPAR_SELECTOR_FIELD) + { + if( !(phyLinkStatus&PHY_LINK_WAIT_SUC) ) + { + if( (phyPN&0x0C) == PHY_PN_SWITCH_P ) + { + phySucCnt = 0; + phyLinkCnt = 0; + phyLinkStatus = PHY_LINK_WAIT_SUC; + } + else + { + if( !(phyLinkStatus&PHY_LINK_SUC_N) ) + { + phyRetryCnt = 0; + phyLinkStatus |= PHY_LINK_SUC_N; + phyPN &= ~PHY_PN_SWITCH_N; + phy_bmcr = ReadPHYReg(PHY_BMCR); + phy_bmcr |= 1<<9; + WritePHYReg(PHY_BMCR, phy_bmcr); + WritePHYReg(PHY_MDIX, phyPN); + } + else + { + phySucCnt = 0; + phyLinkCnt = 0; + phyLinkStatus = PHY_LINK_WAIT_SUC; + } + } + } + else{ + if((phySucCnt++ == 5) && ((phy_bmsr&PHY_AutoNego_Complete) == 0)) + { + phySucCnt = 0; + phyRetryCnt = 0; + phyPNChangeCnt = 0; + phyLinkStatus = PHY_LINK_INIT; + phy_bmcr = ReadPHYReg(PHY_BMCR); + phy_bmcr |= 1<<9; + WritePHYReg(PHY_BMCR, phy_bmcr); + if((phyPN&0x0C) == PHY_PN_SWITCH_P) + { + phyPN |= PHY_PN_SWITCH_N; + } + else { + phyPN &= ~PHY_PN_SWITCH_N; + } + WritePHYReg(PHY_MDIX, phyPN); + } + } + } + else + { + if(phy_bmsr & PHY_AutoNego_Complete) + { + phySucCnt = 0; + phyLinkCnt = 0; + phyLinkStatus = PHY_LINK_WAIT_SUC; + } + else { + if( phyLinkStatus == PHY_LINK_WAIT_SUC ) + { + if(phyLinkCnt++ == 10) + { + phyLinkCnt = 0; + phyRetryCnt = 0; + phyPNChangeCnt = 0; + phyLinkStatus = PHY_LINK_INIT; + } + } + else if(phyLinkStatus == PHY_LINK_INIT) + { + if(phyPNChangeCnt++ == 10) + { + phyPNChangeCnt = 0; + phyPN = ReadPHYReg(PHY_MDIX); + phyPN &= ~0x0c; + phyPN ^= 0x03; + WritePHYReg(PHY_MDIX, phyPN); + } + else{ + if((phyPN&0x0C) == PHY_PN_SWITCH_P) + { + phyPN |= PHY_PN_SWITCH_N; + } + else { + phyPN &= ~PHY_PN_SWITCH_N; + } + WritePHYReg(PHY_MDIX, phyPN); + } + } + else if(phyLinkStatus == PHY_LINK_SUC_N) + { + if((phyPN&0x0C) == PHY_PN_SWITCH_P) + { + phyPN |= PHY_PN_SWITCH_N; + phy_bmcr = ReadPHYReg(PHY_BMCR); + phy_bmcr |= 1<<9; + WritePHYReg(PHY_BMCR, phy_bmcr); + Delay_Us(10); + WritePHYReg(PHY_MDIX, phyPN); + } + else{ + if(phyRetryCnt++ == 15) + { + phyRetryCnt = 0; + phyPNChangeCnt = 0; + phyLinkStatus = PHY_LINK_INIT; + } + } + } + } + } +} + +/********************************************************************* + * @fn WCHNET_PhyPNProcess + * + * @brief Phy PN Polarity related processing + * + * @param none. + * + * @return none. + */ +void WCHNET_PhyPNProcess(void) +{ + uint32_t PhyVal; + + phyLinkTime = LocalTime; + if(CRCErrPktCnt >= 3) + { + PhyVal = ReadPHYReg(PHY_MDIX); + if((PhyVal >> 2) & 0x01) + PhyVal &= ~(3 << 2); //change PHY PN Polarity to normal + else + PhyVal |= 1 << 2; //change PHY PN Polarity to reverse + WritePHYReg(PHY_MDIX, PhyVal); + CRCErrPktCnt = 0; + } +} + +/********************************************************************* + * @fn WCHNET_HandlePhyNegotiation + * + * @brief Handle PHY Negotiation. + * + * @param none. + * + * @return none. + */ +void WCHNET_HandlePhyNegotiation(void) +{ + if(phyLinkReset) /* After the PHY link is disconnected, wait 500ms before turning on the PHY clock*/ + { + if( LocalTime - phyLinkTime >= 500 ) + { + phyLinkReset = 0; + EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN; + WritePHYReg(PHY_BMCR, PHY_Reset); + PHY_NEGOTIATION_PARAM_INIT(); + } + } + else + { + if( !phyStatus ) /* Handling PHY Negotiation Exceptions */ + { + if( LocalTime - phyLinkTime >= PHY_LINK_TASK_PERIOD ) /* 50ms cycle timing call */ + { + phyLinkTime = LocalTime; + WCHNET_LinkProcess( ); + } + } + else{ + if(PhyPolarityDetect) + { + if( LocalTime - phyLinkTime >= 2 * PHY_LINK_TASK_PERIOD ) + { + WCHNET_PhyPNProcess(); + } + } + } + } +} + +/********************************************************************* + * @fn WCHNET_MainTask + * + * @brief library main task function + * + * @return none. + */ +void WCHNET_MainTask(void) +{ + WCHNET_NetInput( ); /* Ethernet data input */ + WCHNET_PeriodicHandle( ); /* Protocol stack time-related task processing */ + WCHNET_HandlePhyNegotiation( ); +} + +/********************************************************************* + * @fn ETH_LedLinkSet + * + * @brief set eth link led,setbit 0 or 1,the link led turn on or turn off + * + * @return none + */ +void ETH_LedLinkSet( uint8_t mode ) +{ + if( mode == LED_OFF ) + { + GPIO_SetBits(GPIOC, GPIO_Pin_0); + } + else + { + GPIO_ResetBits(GPIOC, GPIO_Pin_0); + } +} + +/********************************************************************* + * @fn ETH_LedDataSet + * + * @brief set eth data led,setbit 0 or 1,the data led turn on or turn off + * + * @return none + */ +void ETH_LedDataSet( uint8_t mode ) +{ + if( mode == LED_OFF ) + { + GPIO_SetBits(GPIOC, GPIO_Pin_1); + } + else + { + GPIO_ResetBits(GPIOC, GPIO_Pin_1); + } +} + +/********************************************************************* + * @fn ETH_LedConfiguration + * + * @brief set eth data and link led pin + * + * @return none + */ +void ETH_LedConfiguration(void) +{ + GPIO_InitTypeDef GPIO={0}; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); + GPIO.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; + GPIO.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIOC,&GPIO); + ETH_LedDataSet(LED_OFF); + ETH_LedLinkSet(LED_OFF); +} + +/********************************************************************* + * @fn ETH_DMATxDescChainInit + * + * @brief Initializes the DMA Tx descriptors in chain mode. + * + * @param DMATxDescTab - Pointer on the first Tx desc list + * TxBuff - Pointer on the first TxBuffer list + * TxBuffCount - Number of the used Tx desc in the list + * + * @return none + */ +void ETH_DMATxDescChainInit(ETH_DMADESCTypeDef *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount) +{ + ETH_DMADESCTypeDef *DMATxDesc; + + DMATxDescToSet = DMATxDescTab; + DMATxDesc = DMATxDescTab; + DMATxDesc->Status = 0; + DMATxDesc->Buffer1Addr = (uint32_t)TxBuff; + DMATxDesc->Buffer2NextDescAddr = (uint32_t)DMATxDescTab; +} + +/********************************************************************* + * @fn ETH_DMARxDescChainInit + * + * @brief Initializes the DMA Rx descriptors in chain mode. + * + * @param DMARxDescTab - Pointer on the first Rx desc list. + * RxBuff - Pointer on the first RxBuffer list. + * RxBuffCount - Number of the used Rx desc in the list. + * + * @return none + */ +void ETH_DMARxDescChainInit(ETH_DMADESCTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount) +{ + uint8_t i = 0; + ETH_DMADESCTypeDef *DMARxDesc; + + DMARxDescToGet = DMARxDescTab; + for(i = 0; i < RxBuffCount; i++) + { + DMARxDesc = DMARxDescTab + i; + DMARxDesc->Status = ETH_DMARxDesc_OWN; + DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i * ETH_MAX_PACKET_SIZE]); + + if(i < (RxBuffCount - 1)) + { + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab + i + 1); + } + else + { + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab); + } + } +} + +/********************************************************************* + * @fn ETH_Start + * + * @brief Enables ENET MAC and DMA reception/transmission. + * + * @return none + */ +void ETH_Start(void) +{ + R16_ETH_ERXST = DMARxDescToGet->Buffer1Addr; + R8_ETH_ECON1 |= RB_ETH_ECON1_RXEN; //receive enable +} + +/********************************************************************* + * @fn ETH_SetClock + * + * @brief Set ETH Clock(60MHz). + * + * @return none + */ +void ETH_SetClock(void) +{ + /* ETH initialization */ + RCC_ETHDIVConfig(RCC_ETHCLK_Div2); // 120M/2 = 60MHz +} + +/********************************************************************* + * @fn ETH_Configuration + * + * @brief Ethernet configure. + * + * @return none + */ +void ETH_Configuration( uint8_t *macAddr ) +{ + ETH_SetClock( ); + R8_ETH_EIE = 0; + R8_ETH_EIE |= RB_ETH_EIE_INTIE | + RB_ETH_EIE_RXIE| + RB_ETH_EIE_LINKIE| + RB_ETH_EIE_TXIE | + RB_ETH_EIE_TXERIE| + RB_ETH_EIE_RXERIE; //Turn on all interrupts + + R8_ETH_EIE |= RB_ETH_EIE_R_EN50; //Turn on 50 ohm pull-up + + R8_ETH_EIR = 0xff; //clear interrupt flag + R8_ETH_ESTAT |= RB_ETH_ESTAT_INT | RB_ETH_ESTAT_BUFER; //clear state + + R8_ETH_ECON1 |= (RB_ETH_ECON1_TXRST|RB_ETH_ECON1_RXRST); //Transceiver module reset + R8_ETH_ECON1 &= ~(RB_ETH_ECON1_TXRST|RB_ETH_ECON1_RXRST); + + //Filter mode, received packet type + R8_ETH_ERXFCON = 0; + R8_ETH_MAADRL1 = macAddr[5]; // MAC assignment + R8_ETH_MAADRL2 = macAddr[4]; + R8_ETH_MAADRL3 = macAddr[3]; + R8_ETH_MAADRL4 = macAddr[2]; + R8_ETH_MAADRL5 = macAddr[1]; + R8_ETH_MAADRL6 = macAddr[0]; + + //Filter mode, limit packet type + R8_ETH_MACON1 |= RB_ETH_MACON1_MARXEN; //MAC receive enable + R8_ETH_MACON2 &= ~RB_ETH_MACON2_PADCFG; + R8_ETH_MACON2 |= PADCFG_AUTO_3; //All short packets are automatically padded to 60 bytes + R8_ETH_MACON2 |= RB_ETH_MACON2_TXCRCEN; //Hardware padded CRC + R8_ETH_MACON2 &= ~RB_ETH_MACON2_HFRMEN; //Jumbo frames are not received + R8_ETH_MACON2 |= RB_ETH_MACON2_FULDPX; + R16_ETH_MAMXFL = ETH_MAX_PACKET_SIZE; + R8_ETH_ECON2 &= ~(0x07 << 1); + R8_ETH_ECON2 |= 5 << 1; + + EXTEN->EXTEN_CTR |= EXTEN_ETH_10M_EN; +} + +/********************************************************************* + * @fn ETH_TxPktChainMode + * + * @brief Ethernet sends data frames in chain mode. + * + * @param len Send data length + * pBuff send buffer pointer + * + * @return Send status. + */ +uint32_t ETH_TxPktChainMode(uint16_t len, uint32_t *pBuff ) +{ + /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ + if( DMATxDescToSet->Status & ETH_DMATxDesc_OWN ) + { + /* Return ERROR: OWN bit set */ + return ETH_ERROR; + } + DMATxDescToSet->Status |= ETH_DMATxDesc_OWN; + R16_ETH_ETXLN = len; + R16_ETH_ETXST = (uint32_t)pBuff; + R8_ETH_ECON1 |= RB_ETH_ECON1_TXRTS; //start sending + /* Update the ETHERNET DMA global Tx descriptor with next Tx descriptor */ + /* Chained Mode */ + /* Selects the next DMA Tx descriptor list for next buffer to send */ + DMATxDescToSet = (ETH_DMADESCTypeDef*) (DMATxDescToSet->Buffer2NextDescAddr); + /* Return SUCCESS */ + return ETH_SUCCESS; +} + +/********************************************************************* + * @fn ETH_LinkUpCfg + * + * @brief When the PHY is connected, configure the relevant functions. + * + * @param regval BMSR register value + * + * @return none. + */ +void ETH_LinkUpCfg(uint16_t regval) +{ + WCHNET_PhyStatus( regval ); + /* Receive CRC error packets */ + R8_ETH_ERXFCON |= RB_ETH_ERXFCON_CRCEN; + CRCErrPktCnt = 0; + PhyPolarityDetect = 1; + phyLinkTime = LocalTime; + phyStatus = PHY_Linked_Status; + ETH_Start( ); +} + +/********************************************************************* + * @fn ETH_LinkDownCfg + * + * @brief When the PHY is disconnected, configure the relevant functions. + * + * @param regval BMSR register value + * + * @return none. + */ +void ETH_LinkDownCfg(uint16_t regval) +{ + WCHNET_PhyStatus( regval ); + EXTEN->EXTEN_CTR &= ~EXTEN_ETH_10M_EN; + phyLinkReset = 1; + phyLinkTime = LocalTime; +} + +/********************************************************************* + * @fn ETH_PHYLink + * + * @brief + * + * @return none + */ +void ETH_PHYLink( void ) +{ + u16 phy_bsr, phy_anlpar; + + phy_bsr = ReadPHYReg(PHY_BMSR); + phy_anlpar = ReadPHYReg(PHY_ANLPAR); + + if(phy_bsr & PHY_Linked_Status) //Valid link established + { + if(phy_bsr & PHY_AutoNego_Complete) //Auto-negotiation completed -- LinkUp + { + ETH_LinkUpCfg(phy_bsr); + } + else { + if(phy_anlpar == 0) //The auto-negotiation signal of the peer device is not obtained + { + WritePHYReg(PHY_BMCR, PHY_Reset); + PHY_NEGOTIATION_PARAM_INIT(); + } + else { + ETH_LinkDownCfg(phy_bsr); + } + } + } + else { //LinkDown + ETH_LinkDownCfg(phy_bsr); + } +} + +/********************************************************************* + * @fn WCHNET_ETHIsr + * + * @brief + * + * @return none + */ +void WCHNET_ETHIsr( void ) +{ + uint8_t eth_irq_flag, estat_regval; + + eth_irq_flag = R8_ETH_EIR; + if(eth_irq_flag&RB_ETH_EIR_RXIF) //Receive complete + { + R8_ETH_EIR = RB_ETH_EIR_RXIF; + /* Check if the descriptor is owned by the ETHERNET DMA */ + if( DMARxDescToGet->Status & ETH_DMARxDesc_OWN ) + { + estat_regval = R8_ETH_ESTAT; + if(estat_regval & \ + (RB_ETH_ESTAT_BUFER | RB_ETH_ESTAT_RXCRCER | RB_ETH_ESTAT_RXNIBBLE | RB_ETH_ESTAT_RXMORE)) + { + return; + } + if( ((ETH_DMADESCTypeDef*)(DMARxDescToGet->Buffer2NextDescAddr))->Status& ETH_DMARxDesc_OWN ) + { + DMARxDescToGet->Status &= ~ETH_DMARxDesc_OWN; + DMARxDescToGet->Status &= ~ETH_DMARxDesc_ES; + DMARxDescToGet->Status |= (ETH_DMARxDesc_FS|ETH_DMARxDesc_LS); + DMARxDescToGet->Status &= ~ETH_DMARxDesc_FL; + DMARxDescToGet->Status |= ((R16_ETH_ERXLN+4)<Buffer2NextDescAddr); + R16_ETH_ERXST = DMARxDescToGet->Buffer1Addr; + } + } + if(PhyPolarityDetect) + { + PhyPolarityDetect = 0; + /* Discard CRC error packet */ + R8_ETH_ERXFCON &= ~RB_ETH_ERXFCON_CRCEN; + } + } + if(eth_irq_flag&RB_ETH_EIR_TXIF) //send completed + { + DMATxDescToSet->Status &= ~ETH_DMATxDesc_OWN; + R8_ETH_EIR = RB_ETH_EIR_TXIF; + } + if(eth_irq_flag&RB_ETH_EIR_LINKIF) //Link change + { + ETH_PHYLink(); + R8_ETH_EIR = RB_ETH_EIR_LINKIF; + } + if(eth_irq_flag&RB_ETH_EIR_TXERIF) //send error + { + DMATxDescToSet->Status &= ~ETH_DMATxDesc_OWN; + R8_ETH_EIR = RB_ETH_EIR_TXERIF; + } + if(eth_irq_flag&RB_ETH_EIR_RXERIF) //receive error + { + if(PhyPolarityDetect) CRCErrPktCnt++; + R8_ETH_EIR = RB_ETH_EIR_RXERIF; + } +} + +/********************************************************************* + * @fn ETH_Init + * + * @brief Ethernet initialization. + * + * @return none + */ +void ETH_Init( uint8_t *macAddr ) +{ + ETH_LedConfiguration( ); + Delay_Ms(100); + ETH_Configuration( macAddr ); + ETH_DMATxDescChainInit(DMATxDscrTab, MACTxBuf, ETH_TXBUFNB); + ETH_DMARxDescChainInit(DMARxDscrTab, MACRxBuf, ETH_RXBUFNB); + pDMARxSet = DMARxDscrTab; + NVIC_EnableIRQ(ETH_IRQn); +} + +/********************************************************************* + * @fn ETH_LibInit + * + * @brief Ethernet library initialization program + * + * @return command status + */ +uint8_t ETH_LibInit( uint8_t *ip, uint8_t *gwip, uint8_t *mask, uint8_t *macaddr ) +{ + uint8_t s; + struct _WCH_CFG cfg; + + memset(&cfg,0,sizeof(cfg)); + cfg.TxBufSize = ETH_TX_BUF_SZE; + cfg.TCPMss = WCHNET_TCP_MSS; + cfg.HeapSize = WCHNET_MEM_HEAP_SIZE; + cfg.ARPTableNum = WCHNET_NUM_ARP_TABLE; + cfg.MiscConfig0 = WCHNET_MISC_CONFIG0; + cfg.MiscConfig1 = WCHNET_MISC_CONFIG1; + cfg.led_link = ETH_LedLinkSet; + cfg.led_data = ETH_LedDataSet; + cfg.net_send = ETH_TxPktChainMode; + cfg.CheckValid = WCHNET_CFG_VALID; + s = WCHNET_ConfigLIB(&cfg); + if(s){ + return (s); + } + s = WCHNET_Init(ip,gwip,mask,macaddr); + ETH_Init(macaddr); + return (s); +} + +/******************************** endfile @ eth_driver ******************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/libwchnet.a b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/libwchnet.a new file mode 100644 index 000000000..ccab70a97 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/libwchnet.a differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/Makefile b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/Makefile new file mode 100755 index 000000000..bf55d6f89 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := wch_tcp_test.c + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/wch_tcp_test.c b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/wch_tcp_test.c new file mode 100644 index 000000000..298c1b37e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/ethernet/test/wch_tcp_test.c @@ -0,0 +1,47 @@ +#include "connect_ether.h" +#include "eth_driver.h" +#include "shell.h" +#include "wchnet.h" +#include "xs_base.h" + +uint8_t DESIP[4] = { 192, 168, 1, 100 }; // destination IP address +uint16_t desport = 1000; // destination port +uint16_t srcport = 1000; // source port + +uint8_t SocketId; + +/********************************************************************* + * @fn TCP client + * + * + * @return none + */ +int Tcp_Client(void) +{ + uint8_t i; + for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) + WCHNET_CreateTcpSocket(DESIP, srcport, desport, &SocketId); // Create TCP Socket + + while (1) { + /*Ethernet library main task function, + * which needs to be called cyclically*/ + WCHNET_MainTask(); + /*Query the Ethernet global interrupt, + * if there is an interrupt, call the global interrupt handler*/ + if (WCHNET_QueryGlobalInt()) { + if (WCHNET_HandleGlobalInt() == TIME_OUT) { + WCHNET_CreateTcpSocket(DESIP, srcport, desport, &SocketId); + } + } + } +} + +int test_tcp_client(int argc, char* argv[]) +{ + KPrintf("TCPClient Test\r\n"); + Tcp_Client(); + return 0; +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + test_tcp_client, test_tcp_client, test tcp client); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/connect_ether.h b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/connect_ether.h new file mode 100644 index 000000000..074822c5d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/connect_ether.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +/** + * @file connect_ethernet.h + * @brief define rvstar uart function + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-08-01 + */ + +#ifndef CONNECT_ETH_H +#define CONNECT_ETH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t InitHwEth(); +void WCHNET_CreateTcpSocket(uint8_t* DESIP, uint16_t srcport, uint16_t desport, uint8_t* SocketId); +void WCHNET_CreateTcpSocketListen(uint16_t srcport, uint8_t* SocketId); + +int WCHNET_HandleGlobalInt(void); + +#define TIME_OUT -1 + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/eth_driver.h b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/eth_driver.h new file mode 100755 index 000000000..1739ee2bf --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/eth_driver.h @@ -0,0 +1,103 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : eth_driver.h +* Author : WCH +* Version : V1.3.0 +* Date : 2022/05/27 +* Description : This file contains the headers of the ETH Driver. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __ETH_DRIVER__ +#define __ETH_DRIVER__ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "debug.h" + +#define ROM_CFG_USERADR_ID 0x1FFFF7E8 + +#define PHY_LINK_TASK_PERIOD 50 + +#define PHY_ANLPAR_SELECTOR_FIELD 0x1F +#define PHY_ANLPAR_SELECTOR_VALUE 0x01 /* 5B'00001 */ + +#define PHY_LINK_INIT 0x00 +#define PHY_LINK_SUC_P (1<<0) +#define PHY_LINK_SUC_N (1<<1) +#define PHY_LINK_WAIT_SUC (1<<7) + +#define PHY_PN_SWITCH_P (0<<2) +#define PHY_PN_SWITCH_N (1<<2) +#define PHY_PN_SWITCH_AUTO (2<<2) + +#ifndef WCHNETTIMERPERIOD +#define WCHNETTIMERPERIOD 10 /* Timer period, in Ms. */ +#endif + +#define PHY_NEGOTIATION_PARAM_INIT() do{\ + phySucCnt = 0;\ + phyStatus = 0;\ + phyLinkCnt = 0;\ + phyRetryCnt = 0;\ + phyPNChangeCnt = 0;\ + phyLinkStatus = PHY_LINK_INIT;\ +}while(0) + +/* definition for Ethernet frame */ +#define ETH_MAX_PACKET_SIZE 1536 /* ETH_HEADER + VLAN_TAG + MAX_ETH_PAYLOAD + ETH_CRC */ +#define ETH_HEADER 14 /* 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */ +#define ETH_CRC 4 /* Ethernet CRC */ +#define ETH_EXTRA 2 /* Extra bytes in some cases */ +#define VLAN_TAG 4 /* optional 802.1q VLAN Tag */ +#define MIN_ETH_PAYLOAD 46 /* Minimum Ethernet payload size */ +#define MAX_ETH_PAYLOAD 1500 /* Maximum Ethernet payload size */ + +/* Bit or field definition of TDES0 register (DMA Tx descriptor status register)*/ +#define ETH_DMATxDesc_OWN ((uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */ + +/* Bit or field definition of RDES0 register (DMA Rx descriptor status register) */ +#define ETH_DMARxDesc_OWN ((uint32_t)0x80000000) /* OWN bit: descriptor is owned by DMA engine */ +#define ETH_DMARxDesc_FL ((uint32_t)0x3FFF0000) /* Receive descriptor frame length */ +#define ETH_DMARxDesc_ES ((uint32_t)0x00008000) /* Error summary: */ +#define ETH_DMARxDesc_FS ((uint32_t)0x00000200) /* First descriptor of the frame */ +#define ETH_DMARxDesc_LS ((uint32_t)0x00000100) /* Last descriptor of the frame */ + +#define ETH_DMARxDesc_FrameLengthShift 16 + +/* ETHERNET errors */ +#define ETH_ERROR ((uint32_t)0) +#define ETH_SUCCESS ((uint32_t)1) + +/* ETH structure definition */ +typedef struct +{ + uint32_t volatile Status; /* Status */ + uint32_t ControlBufferSize; /* Control and Buffer1, Buffer2 lengths */ + uint32_t Buffer1Addr; /* Buffer1 address pointer */ + uint32_t Buffer2NextDescAddr; /* Buffer2 or next descriptor address pointer */ +} ETH_DMADESCTypeDef; + +#include "wchnet.h" + +extern SOCK_INF SocketInf[ ]; + +void ETH_PHYLink( void ); +void WCHNET_ETHIsr( void ); +void WCHNET_MainTask( void ); +void ETH_LedConfiguration(void); +void ETH_Init( uint8_t *macAddr ); +void ETH_LedLinkSet( uint8_t mode ); +void ETH_LedDataSet( uint8_t mode ); +void WCHNET_TimeIsr( uint16_t timperiod ); +void ETH_Configuration( uint8_t *macAddr ); +uint8_t ETH_LibInit( uint8_t *ip, uint8_t *gwip, uint8_t *mask, uint8_t *macaddr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/libwchnet.a b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/libwchnet.a new file mode 100755 index 000000000..9eee4821c Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/libwchnet.a differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/net_config.h b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/net_config.h new file mode 100755 index 000000000..1c365d0d4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/net_config.h @@ -0,0 +1,167 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : net_config.h +* Author : WCH +* Version : V1.30 +* Date : 2022/06/02 +* Description : This file contains the configurations of +* Ethernet protocol stack library +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __NET_CONFIG_H__ +#define __NET_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/********************************************************************* + * socket configuration, IPRAW + UDP + TCP + TCP_LISTEN = number of sockets + */ +#define WCHNET_NUM_IPRAW 0 /* Number of IPRAW connections */ + +#define WCHNET_NUM_UDP 0 /* The number of UDP connections */ + +#define WCHNET_NUM_TCP 1 /* Number of TCP connections */ + +#define WCHNET_NUM_TCP_LISTEN 0 /* Number of TCP listening */ + +/* The number of sockets, the maximum is 31 */ +#define WCHNET_MAX_SOCKET_NUM (WCHNET_NUM_IPRAW+WCHNET_NUM_UDP+WCHNET_NUM_TCP+WCHNET_NUM_TCP_LISTEN) + +#define WCHNET_TCP_MSS 1460 /* Size of TCP MSS*/ + +#define WCHNET_NUM_POOL_BUF (WCHNET_NUM_TCP*2+2) /* The number of POOL BUFs, the number of receive queues */ + +/********************************************************************* + * MAC queue configuration + */ +#define ETH_TXBUFNB 1 /* The number of descriptors sent by the MAC */ + +#define ETH_RXBUFNB 4 /* Number of MAC received descriptors */ + +#ifndef ETH_MAX_PACKET_SIZE +#define ETH_RX_BUF_SZE 1520 /* MAC receive buffer length, an integer multiple of 4 */ +#define ETH_TX_BUF_SZE 1520 /* MAC send buffer length, an integer multiple of 4 */ +#else +#define ETH_RX_BUF_SZE ETH_MAX_PACKET_SIZE +#define ETH_TX_BUF_SZE ETH_MAX_PACKET_SIZE +#endif + +/********************************************************************* + * Functional configuration + */ +#define WCHNET_PING_ENABLE 1 /* PING is enabled, PING is enabled by default */ + +#define TCP_RETRY_COUNT 20 /* The number of TCP retransmissions, the default value is 20 */ + +#define TCP_RETRY_PERIOD 10 /* TCP retransmission period, the default value is 10, the unit is 50ms */ + +#define SOCKET_SEND_RETRY 0 /* Send failed retry configuration, 1: enable, 0: disable */ + +#define FINE_DHCP_PERIOD 8 /* Fine DHCP period, the default value is 8, the unit is 250ms */ + +#define CFG0_TCP_SEND_COPY 1 /* TCP send buffer copy, 1: copy, 0: not copy */ + +#define CFG0_TCP_RECV_COPY 1 /* TCP receive replication optimization, internal debugging use */ + +#define CFG0_TCP_OLD_DELETE 0 /* Delete oldest TCP connection, 1: enable, 0: disable */ + +#define CFG0_IP_REASS_PBUFS 0 /* Number of reassembled IP PBUFs */ + +#define CFG0_TCP_DEALY_ACK_DISABLE 1 /* 1: disable TCP delay ACK 0: enable TCP delay ACK */ + +/********************************************************************* + * Memory related configuration + */ +/* If you want to achieve a higher transmission speed, + * try to increase RECE_BUF_LEN to (WCHNET_TCP_MSS*4) + * and increase WCHNET_NUM_TCP_SEG to (WCHNET_NUM_TCP*4)*/ +#define RECE_BUF_LEN (WCHNET_TCP_MSS*2) /* socket receive buffer size */ + +#define WCHNET_NUM_PBUF WCHNET_NUM_POOL_BUF /* Number of PBUF structures */ + +#define WCHNET_NUM_TCP_SEG (WCHNET_NUM_TCP*2) /* The number of TCP segments used to send */ + +#define WCHNET_MEM_HEAP_SIZE (((WCHNET_TCP_MSS+0x10+54+8)*WCHNET_NUM_TCP_SEG)+ETH_TX_BUF_SZE+64+2*0x18) /* memory heap size */ + +#define WCHNET_NUM_ARP_TABLE 50 /* Number of ARP lists */ + +#define WCHNET_MEM_ALIGNMENT 4 /* 4 byte alignment */ + +#if CFG0_IP_REASS_PBUFS +#define WCHNET_NUM_IP_REASSDATA 2 /* Number of reassembled IP structures */ +/*1: When using the fragmentation function, + * ensure that the size of WCHNET_SIZE_POOL_BUF is large enough to store a single fragmented packet*/ +#define WCHNET_SIZE_POOL_BUF (((1500 + 14 + 4) + 3) & ~3) /* Buffer size for receiving a single packet */ +/*2: When creating a socket that can receive fragmented packets, + * ensure that "RecvBufLen" member of the "struct _SOCK_INF" structure + * (the parameter initialized when calling WCHNET_SocketCreat) is sufficient + * to receive a complete fragmented packet */ +#else +#define WCHNET_NUM_IP_REASSDATA 0 /* Number of reassembled IP structures */ +#define WCHNET_SIZE_POOL_BUF (((WCHNET_TCP_MSS + 40 + 14 + 4) + 3) & ~3) /* Buffer size for receiving a single packet */ +#endif + +/* Check receive buffer */ +#if(WCHNET_NUM_POOL_BUF * WCHNET_SIZE_POOL_BUF < ETH_RX_BUF_SZE) + #error "WCHNET_NUM_POOL_BUF or WCHNET_TCP_MSS Error" + #error "Please Increase WCHNET_NUM_POOL_BUF or WCHNET_TCP_MSS to make sure the receive buffer is sufficient" +#endif +/* Check the configuration of the SOCKET quantity */ +#if( WCHNET_NUM_TCP_LISTEN && !WCHNET_NUM_TCP ) + #error "WCHNET_NUM_TCP Error,Please Configure WCHNET_NUM_TCP >= 1" +#endif +/* Check byte alignment must be a multiple of 4 */ +#if((WCHNET_MEM_ALIGNMENT % 4) || (WCHNET_MEM_ALIGNMENT == 0)) + #error "WCHNET_MEM_ALIGNMENT Error,Please Configure WCHNET_MEM_ALIGNMENT = 4 * N, N >=1" +#endif +/* TCP maximum segment length */ +#if((WCHNET_TCP_MSS > 1460) || (WCHNET_TCP_MSS < 60)) + #error "WCHNET_TCP_MSS Error,Please Configure WCHNET_TCP_MSS >= 60 && WCHNET_TCP_MSS <= 1460" +#endif +/* Number of ARP cache tables */ +#if((WCHNET_NUM_ARP_TABLE > 0X7F) || (WCHNET_NUM_ARP_TABLE < 1)) + #error "WCHNET_NUM_ARP_TABLE Error,Please Configure WCHNET_NUM_ARP_TABLE >= 1 && WCHNET_NUM_ARP_TABLE <= 0X7F" +#endif +/* Check POOL BUF configuration */ +#if(WCHNET_NUM_POOL_BUF < 1) + #error "WCHNET_NUM_POOL_BUF Error,Please Configure WCHNET_NUM_POOL_BUF >= 1" +#endif +/* Check PBUF structure configuration */ +#if(WCHNET_NUM_PBUF < 1) + #error "WCHNET_NUM_PBUF Error,Please Configure WCHNET_NUM_PBUF >= 1" +#endif +/* Check IP Assignment Configuration */ +#if(CFG0_IP_REASS_PBUFS && ((WCHNET_NUM_IP_REASSDATA > 10) || (WCHNET_NUM_IP_REASSDATA < 1))) + #error "WCHNET_NUM_IP_REASSDATA Error,Please Configure WCHNET_NUM_IP_REASSDATA < 10 && WCHNET_NUM_IP_REASSDATA >= 1 " +#endif +/* Check the number of reassembled IP PBUFs */ +#if(CFG0_IP_REASS_PBUFS > WCHNET_NUM_POOL_BUF) + #error "WCHNET_NUM_POOL_BUF Error,Please Configure CFG0_IP_REASS_PBUFS < WCHNET_NUM_POOL_BUF" +#endif +/* Check Timer period, in Ms. */ +#if(WCHNETTIMERPERIOD > 50) + #error "WCHNETTIMERPERIOD Error,Please Configure WCHNETTIMERPERIOD < 50" +#endif + +/* Configuration value 0 */ +#define WCHNET_MISC_CONFIG0 (((CFG0_TCP_SEND_COPY) << 0) |\ + ((CFG0_TCP_RECV_COPY) << 1) |\ + ((CFG0_TCP_OLD_DELETE) << 2) |\ + ((CFG0_IP_REASS_PBUFS) << 3) |\ + ((CFG0_TCP_DEALY_ACK_DISABLE) << 8)) +/* Configuration value 1 */ +#define WCHNET_MISC_CONFIG1 (((WCHNET_MAX_SOCKET_NUM)<<0)|\ + ((WCHNET_PING_ENABLE) << 13) |\ + ((TCP_RETRY_COUNT) << 14) |\ + ((TCP_RETRY_PERIOD) << 19) |\ + ((SOCKET_SEND_RETRY) << 25) |\ + ((FINE_DHCP_PERIOD) << 27)) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/wchnet.h b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/wchnet.h new file mode 100644 index 000000000..4d52a19da --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch32v208rbt6/third_party_driver/include/wchnet.h @@ -0,0 +1,591 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : wchnet.h + * Author : WCH + * Version : V1.80 + * Date : 2023/05/12 + * Description : This file contains the headers of + * the Ethernet protocol stack library. + ********************************************************************************* + * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. + * Attention: This software (modified or not) and binary are used for + * microcontroller manufactured by Nanjing Qinheng Microelectronics. + *******************************************************************************/ +#ifndef __WCHNET_H__ +#define __WCHNET_H__ + +#include "stdint.h" +#ifndef NET_LIB +#include "net_config.h" +#endif +#ifdef __cplusplus +extern "C" { +#endif + +#define WCHNET_LIB_VER 0x18 // the library version number +#define WCHNET_CFG_VALID 0x12345678 // Configuration value valid flag + +/* LED state @LED_STAT */ +#define LED_ON 0 +#define LED_OFF 1 + +/* PHY state @PHY_STAT */ +#define PHY_LINK_SUCCESS (1 << 2) // PHY connection success +#define PHY_AUTO_SUCCESS (1 << 5) // PHY auto negotiation completed + +/* Library initialization state @CFG_INIT_STAT */ +#define INIT_OK 0x00 +#define INIT_ERR_RX_BUF_SIZE 0x01 +#define INIT_ERR_TCP_MSS 0x02 +#define INIT_ERR_HEAP_SIZE 0x03 +#define INIT_ERR_ARP_TABLE_NEM 0x04 +#define INIT_ERR_MISC_CONFIG0 0x05 +#define INIT_ERR_MISC_CONFIG1 0x06 +#define INIT_ERR_FUNC_SEND 0x09 +#define INIT_ERR_CHECK_VALID 0xFF + +/* Socket protocol type */ +#define PROTO_TYPE_IP_RAW 0 // IP layer raw data +#define PROTO_TYPE_UDP 2 // UDP protocol +#define PROTO_TYPE_TCP 3 // TCP protocol + +/* interrupt status */ +/* The following are the states + * that GLOB_INT will generate */ +#define GINT_STAT_UNREACH (1 << 0) // unreachable interrupt +#define GINT_STAT_IP_CONFLI (1 << 1) // IP conflict interrupt +#define GINT_STAT_PHY_CHANGE (1 << 2) // PHY state change interrupt +#define GINT_STAT_SOCKET (1 << 4) // socket related interrupt + +/* The following are the states + * that Sn_INT will generate*/ +#define SINT_STAT_RECV (1 << 2) // the socket receives data or the receive buffer is not empty +#define SINT_STAT_CONNECT (1 << 3) // connect successfully,generated in TCP mode +#define SINT_STAT_DISCONNECT (1 << 4) // disconnect,generated in TCP mode +#define SINT_STAT_TIM_OUT (1 << 6) // timeout disconnect,generated in TCP mode + +/* Definitions for error constants. @ERR_T */ +#define ERR_T +#define WCHNET_ERR_SUCCESS 0x00 // No error, everything OK +#define WCHNET_ERR_BUSY 0x10 // busy +#define WCHNET_ERR_MEM 0x11 // Out of memory error +#define WCHNET_ERR_BUF 0x12 // Buffer error +#define WCHNET_ERR_TIMEOUT 0x13 // Timeout +#define WCHNET_ERR_RTE 0x14 // Routing problem +#define WCHNET_ERR_ABRT 0x15 // Connection aborted +#define WCHNET_ERR_RST 0x16 // Connection reset +#define WCHNET_ERR_CLSD 0x17 // Connection closed +#define WCHNET_ERR_CONN 0x18 // Not connected +#define WCHNET_ERR_VAL 0x19 // Illegal value +#define WCHNET_ERR_ARG 0x1a // Illegal argument +#define WCHNET_ERR_USE 0x1b // Address in use +#define WCHNET_ERR_IF 0x1c // Low-level netif error +#define WCHNET_ERR_ISCONN 0x1d // Already connected +#define WCHNET_ERR_INPROGRESS 0x1e // Operation in progress +#define WCHNET_ERR_SOCKET_MEM 0X20 // Socket information error +#define WCHNET_ERR_UNSUPPORT_PROTO 0X21 // unsupported protocol type +#define WCHNET_RET_ABORT 0x5F // command process fail +#define WCHNET_ERR_UNKNOW 0xFA // unknow + +/* unreachable condition related codes */ +#define UNREACH_CODE_HOST 0 // host unreachable +#define UNREACH_CODE_NET 1 // network unreachable +#define UNREACH_CODE_PROTOCOL 2 // protocol unreachable +#define UNREACH_CODE_PROT 3 // port unreachable +/*For other values, please refer to the RFC792 document*/ + +/* TCP disconnect related codes */ +#define TCP_CLOSE_NORMAL 0 // normal disconnect,a four-way handshake +#define TCP_CLOSE_RST 1 // reset the connection and close +#define TCP_CLOSE_ABANDON 2 // drop connection, and no termination message is sent + +/* socket state code */ +#define SOCK_STAT_CLOSED 0X00 // socket close +#define SOCK_STAT_OPEN 0X05 // socket open + +/* TCP state code */ +#define TCP_CLOSED 0 // TCP close +#define TCP_LISTEN 1 // TCP listening +#define TCP_SYN_SENT 2 // SYN send, connect request +#define TCP_SYN_RCVD 3 // SYN received, connection request received +#define TCP_ESTABLISHED 4 // TCP connection establishment +#define TCP_FIN_WAIT_1 5 // WAIT_1 state +#define TCP_FIN_WAIT_2 6 // WAIT_2 state +#define TCP_CLOSE_WAIT 7 // wait to close +#define TCP_CLOSING 8 // closing +#define TCP_LAST_ACK 9 // LAST_ACK +#define TCP_TIME_WAIT 10 // 2MSL wait + +/* The following values are fixed and cannot be changed */ +#define WCHNET_MEM_ALIGN_SIZE(size) (((size) + WCHNET_MEM_ALIGNMENT - 1) & ~(WCHNET_MEM_ALIGNMENT - 1)) +#define WCHNET_SIZE_IPRAW_PCB 0x1C // IPRAW PCB size +#define WCHNET_SIZE_UDP_PCB 0x20 // UDP PCB size +#define WCHNET_SIZE_TCP_PCB 0xB4 // TCP PCB size +#define WCHNET_SIZE_TCP_PCB_LISTEN 0x24 // TCP LISTEN PCB size +#define WCHNET_SIZE_IP_REASSDATA 0x20 // IP reassembled Management +#define WCHNET_SIZE_PBUF 0x10 // Packet Buf +#define WCHNET_SIZE_TCP_SEG 0x14 // TCP SEG structure +#define WCHNET_SIZE_MEM 0x08 // sizeof(struct mem) +#define WCHNET_SIZE_ARP_TABLE 0x18 // sizeof ARP table + +#define WCHNET_MEMP_SIZE ((WCHNET_MEM_ALIGNMENT - 1) + (WCHNET_NUM_IPRAW * WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_IPRAW_PCB)) + (WCHNET_NUM_UDP * WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_UDP_PCB)) + (WCHNET_NUM_TCP * WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_PCB)) + (WCHNET_NUM_TCP_LISTEN * WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_PCB_LISTEN)) + (WCHNET_NUM_TCP_SEG * WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_TCP_SEG)) + (WCHNET_NUM_IP_REASSDATA * WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_IP_REASSDATA)) + (WCHNET_NUM_PBUF * WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_PBUF)) + (WCHNET_NUM_POOL_BUF * (WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_PBUF) + WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_POOL_BUF)))) + +#define HEAP_MEM_ALIGN_SIZE (WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_MEM)) +#define WCHNET_RAM_HEAP_SIZE (WCHNET_MEM_ALIGN_SIZE(WCHNET_MEM_HEAP_SIZE) + HEAP_MEM_ALIGN_SIZE) +#define WCHNET_RAM_ARP_TABLE_SIZE (WCHNET_MEM_ALIGN_SIZE(WCHNET_SIZE_ARP_TABLE) * WCHNET_NUM_ARP_TABLE) + +typedef struct +{ + uint32_t length; + uint32_t buffer; +} ETHFrameType; + +/* LED callback type */ +typedef void (*led_callback)(uint8_t setbit); + +/* net send callback type */ +typedef uint32_t (*eth_tx_set)(uint16_t len, uint32_t* pBuff); + +/* net receive callback type */ +typedef uint32_t (*eth_rx_set)(ETHFrameType* pkt); + +/* DNS callback type */ +typedef void (*dns_callback)(const char* name, uint8_t* ipaddr, void* callback_arg); + +/* DHCP callback type */ +typedef uint8_t (*dhcp_callback)(uint8_t status, void*); + +/* socket receive callback type */ +struct _SOCK_INF; +typedef void (*pSockRecv)(struct _SOCK_INF*, uint32_t, uint16_t, uint8_t*, uint32_t); + +/* Socket information struct */ +typedef struct _SOCK_INF { + uint32_t IntStatus; // interrupt state + uint32_t SockIndex; // Socket index value + uint32_t RecvStartPoint; // Start pointer of the receive buffer + uint32_t RecvBufLen; // Receive buffer length + uint32_t RecvCurPoint; // current pointer to receive buffer + uint32_t RecvReadPoint; // The read pointer of the receive buffer + uint32_t RecvRemLen; // The length of the remaining data in the receive buffer + uint32_t ProtoType; // protocol type + uint32_t SockStatus; // Low byte Socket state, the next low byte is TCP state, only meaningful in TCP mode + uint32_t DesPort; // destination port + uint32_t SourPort; // Source port, protocol type in IPRAW mode + uint8_t IPAddr[4]; // Socket destination IP address + void* Resv1; // Reserved, for internal use, for saving individual PCBs + void* Resv2; // Reserved, used internally, used by TCP Server + pSockRecv AppCallBack; // receive callback function +} SOCK_INF; + +struct _WCH_CFG { + uint32_t TxBufSize; // MAC send buffer size, reserved for use + uint32_t TCPMss; // TCP MSS size + uint32_t HeapSize; // heap memory size + uint32_t ARPTableNum; // Number of ARP lists + uint32_t MiscConfig0; // Miscellaneous Configuration 0 + /* Bit 0 TCP send buffer copy 1: copy, 0: not copy */ + /* Bit 1 TCP receive replication optimization, used for internal debugging */ + /* bit 2 delete oldest TCP connection 1: enable, 0: disable */ + /* Bits 3-7 Number of PBUFs of IP segments */ + /* Bit 8 TCP Delay ACK disable */ + uint32_t MiscConfig1; // Miscellaneous Configuration 1 + /* Bits 0-7 Number of Sockets*/ + /* Bits 8-12 Reserved */ + /* Bit 13 PING enable, 1: On 0: Off */ + /* Bits 14-18 TCP retransmission times */ + /* Bits 19-23 TCP retransmission period, in 50 milliseconds */ + /* bit 25 send failed retry, 1: enable, 0: disable */ + /* bit 26 Select whether to perform IPv4 checksum check on + * the TCP/UDP/ICMP header of the received frame payload by hardware, + * and calculate and insert the checksum of the IP header and payload of the sent frame by hardware.*/ + /* Bits 27-31 period (in 250 milliseconds) of Fine DHCP periodic process */ + led_callback led_link; // PHY Link Status Indicator + led_callback led_data; // Ethernet communication indicator + eth_tx_set net_send; // Ethernet send + eth_rx_set net_recv; // Ethernet receive + uint32_t CheckValid; // Configuration value valid flag, fixed value @WCHNET_CFG_VALID +}; + +struct _NET_SYS { + uint8_t IPAddr[4]; // IP address + uint8_t GWIPAddr[4]; // Gateway IP address + uint8_t MASKAddr[4]; // subnet mask + uint8_t MacAddr[8]; // MAC address + uint8_t UnreachIPAddr[4]; // Unreachable IP address + uint32_t RetranCount; // number of retries,default is 10 times + uint32_t RetranPeriod; // Retry period, unit MS, default 500MS + uint32_t PHYStat; // PHY state code + uint32_t NetStat; // The status of the Ethernet, including whether it is open, etc. + uint32_t MackFilt; // MAC filtering, the default is to receive broadcasts, receive local MAC + uint32_t GlobIntStatus; // global interrupt + uint32_t UnreachCode; // unreachable code + uint32_t UnreachProto; // unreachable protocol + uint32_t UnreachPort; // unreachable port + uint32_t SendFlag; + uint32_t Flags; +}; + +/* KEEP LIVE configuration structure */ +struct _KEEP_CFG { + uint32_t KLIdle; // KEEPLIVE idle time, in ms + uint32_t KLIntvl; // KEEPLIVE period, in ms + uint32_t KLCount; // KEEPLIVE times +}; + +/** + * @brief Library initialization . + * + * @param ip - IP address pointer + * @param gwip - Gateway address pointer + * @param mask - Subnet mask pointer + * @param macaddr - MAC address pointer + * + * @return @ERR_T + */ +uint8_t WCHNET_Init(const uint8_t* ip, const uint8_t* gwip, const uint8_t* mask, const uint8_t* macaddr); + +/** + * @brief get library version + * + * @param None + * + * @return library version + */ +uint8_t WCHNET_GetVer(void); + +/** + * @brief Get MAC address. + * + * @param(in) macaddr - MAC address + * + * @param(out) MAC address + * + * @return None + */ +void WCHNET_GetMacAddr(uint8_t* macaddr); + +/** + * @brief Library parameter configuration. + * + * @param cfg - Configuration parameter @_WCH_CFG + * + * @return Library configuration initialization state @CFG_INIT_STAT + */ +uint8_t WCHNET_ConfigLIB(struct _WCH_CFG* cfg); + +/** + * @brief Handle periodic tasks in the protocol stack + * + * @param None + * + * @return None + */ +void WCHNET_PeriodicHandle(void); + +/** + * @brief Ethernet data input. Always called in the main program, + * or called after the reception interrupt is detected. + * + * @param + * + * @return None + */ +void WCHNET_NetInput(void); + +/** + * @brief Ethernet interrupt service function. Called after + * Ethernet interrupt is generated. + * + * @param None + * + * @return None + */ +void WCHNET_ETHIsr(void); + +/** + * @brief Get PHY status + * + * @param None + * + * @return PHY status @PHY_STAT + */ +uint8_t WCHNET_GetPHYStatus(void); + +/** + * @brief Query global interrupt status. + * + * @param None + * + * @return GLOB_INT + */ +uint8_t WCHNET_QueryGlobalInt(void); + +/** + * @brief Read global interrupt and clear it. + * + * @param None + * + * @return GLOB_INT + */ +uint8_t WCHNET_GetGlobalInt(void); + +/** + * @brief create socket + * + * @param(in) *socketid - socket variable pointer + * @param socinf - Configuration parameters for creating sockets @SOCK_INF + * + * @param(out) *socketid - socket value + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketCreat(uint8_t* socketid, SOCK_INF* socinf); + +/** + * @brief Socket sends data. + * + * @param socketid - socket id value + * @param *buf - the first address of send buffer + * @param(in) *len - pointer to the length of the data expected to be sent + * + * @param(out) *len - pointer to the length of the data sent actually + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketSend(uint8_t socketid, uint8_t* buf, uint32_t* len); + +/** + * @brief Socket receives data. + * + * @param socketid - socket id value + * @param *buf - the first address of receive buffer + * @param(in) *len - pointer to the length of the data expected to be read + * + * @param(out) *buf - the first address of data buffer + * @param(out) *len - pointer to the length of the data read actually + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketRecv(uint8_t socketid, uint8_t* buf, uint32_t* len); + +/** + * @brief Get socket interrupt, and clear socket interrupt. + * + * @param socketid - socket id value + * + * @return Sn_INT + */ +uint8_t WCHNET_GetSocketInt(uint8_t socketid); + +/** + * @brief Get the length of the data received by socket. + * + * @param socketid - socket id value + * @param(in) *bufaddr - the first address of receive buffer + * + * @param(out) *bufaddr - the first address of data buffer + * + * @return the length of the data + */ +uint32_t WCHNET_SocketRecvLen(uint8_t socketid, uint32_t* bufaddr); + +/** + * @brief TCP connect. Used in TCP Client mode. + * + * @param socketid - socket id value + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketConnect(uint8_t socketid); + +/** + * @brief TCP listen. Used in TCP SERVER mode. + * + * @param socketid - socket id value + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketListen(uint8_t socketid); + +/** + * @brief Close socket. + * + * @param socketid - socket id value + * @param mode - the way of disconnection.Used in TCP connection. + * @TCP disconnect related codes + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketClose(uint8_t socketid, uint8_t mode); + +/** + * @brief Modify socket receive buffer. + * + * @param socketid - socket id value + * @param bufaddr - Address of the receive buffer + * @param bufsize - Size of the receive buffer + * + * @return None + */ +void WCHNET_ModifyRecvBuf(uint8_t socketid, uint32_t bufaddr, uint32_t bufsize); + +/** + * @brief UDP send, specify the target IP and target port + * + * @param socketid - socket id value + * @param *buf - Address of the sent data + * @param(in) *slen - Address of the sent length + * @param *sip - destination IP address + * @param port - destination port + * + * @param(out) *slen - actual length sent + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketUdpSendTo(uint8_t socketid, uint8_t* buf, uint32_t* slen, uint8_t* sip, uint16_t port); + +/** + * @brief Convert ASCII address to network address. + * + * @param *cp - ASCII address to be converted, such as "192.168.1.2" + * @param(in) *addr - First address of the memory stored in the converted network address + * @param(out) *addr - Converted network address, such as 0xC0A80102 + * @return 0 - Success. Others - Failure. + */ +uint8_t WCHNET_Aton(const char* cp, uint8_t* addr); + +/** + * @brief Convert network address to ASCII address. + * + * @param *ipaddr - socket id value + * + * @return Converted ASCII address + */ +uint8_t* WCHNET_Ntoa(uint8_t* ipaddr); + +/** + * @brief Set socket TTL. + * + * @param socketid - socket id value + * @param ttl - TTL value + * + * @return @ERR_T + */ +uint8_t WCHNET_SetSocketTTL(uint8_t socketid, uint8_t ttl); + +/** + * @brief Start TCP retry sending immediately. + * + * @param socketid - TTL value + * + * @return None + */ +void WCHNET_RetrySendUnack(uint8_t socketid); + +/** + * @brief Query the packets that are not sent successfully. + * + * @param socketid - TTL value + * @param(in) *addrlist - pointer to the address of the address list + * @param lislen - Length of the list + * + * @param(out) *addrlist - Address list of the data packets that are not sent successfully + * + * @return Number of unsent and unacknowledged segments + */ +uint8_t WCHNET_QueryUnack(uint8_t socketid, uint32_t* addrlist, uint16_t lislen); + +/** + * @brief Start DHCP. + * + * @param dhcp - Application layer callback function + * + * @return @ERR_T + */ +uint8_t WCHNET_DHCPStart(dhcp_callback dhcp); + +/** + * @brief Stop DHCP. + * + * @param None + * + * @return @ERR_T + */ +uint8_t WCHNET_DHCPStop(void); + +/** + * @brief Configure DHCP host name. + * + * @param *name - First address of DHCP host name + * + * @return 0 - Success. Others - Failure. + */ +uint8_t WCHNET_DHCPSetHostname(char* name); + +/** + * @brief Initialize the resolver: set up the UDP pcb and configure the default server + * + * @param *dnsip - the IP address of dns server + * @param port - the port number of dns server + * + * @return None + */ +void WCHNET_InitDNS(uint8_t* dnsip, uint16_t port); + +/** + * @brief Stop DNS. + * + * @param None + * + * @return None + */ +void WCHNET_DNSStop(void); + +/** + * Resolve a hostname (string) into an IP address. + * + * @param hostname - the hostname that is to be queried + * @param addr - pointer to a struct ip_addr where to store the address if it is already + * cached in the dns_table (only valid if ERR_OK is returned!) + * @param found - a callback function to be called on success, failure or timeout (only if + * ERR_INPROGRESS is returned!) + * @param arg - argument to pass to the callback function + * + * @return @ERR_T + * WCHNET_ERR_SUCCESS if hostname is a valid IP address string or the host name is already in the local names table. + * ERR_INPROGRESS enqueue a request to be sent to the DNS server for resolution if no errors are present. + */ +uint8_t WCHNET_HostNameGetIp(const char* hostname, uint8_t* addr, dns_callback found, void* arg); + +/** + * @brief Configure KEEP LIVE parameter. + * + * @param *cfg - KEEPLIVE configuration parameter + * + * @return None + */ +void WCHNET_ConfigKeepLive(struct _KEEP_CFG* cfg); + +/** + * @brief Configure socket KEEP LIVE enable. + * + * @param socketid - socket id value + * @param enable - 1: Enabled. 0: Disabled. + * + * @return @ERR_T + */ +uint8_t WCHNET_SocketSetKeepLive(uint8_t socketid, uint8_t enable); + +/** + * @brief Configure PHY state + * + * @param phy_stat - PHY state + * + * @return None + */ +void WCHNET_PhyStatus(uint32_t phy_stat); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Ubiquitous/XiZi_IIoT/kernel/memory/byte_manage.c b/Ubiquitous/XiZi_IIoT/kernel/memory/byte_manage.c index a802815c7..326e78d64 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/memory/byte_manage.c +++ b/Ubiquitous/XiZi_IIoT/kernel/memory/byte_manage.c @@ -656,6 +656,10 @@ void *x_malloc(x_size_t size) /* parameter detection */ if ((size == 0) || (size > ByteManager.dynamic_buddy_manager.dynamic_buddy_end - ByteManager.dynamic_buddy_manager.dynamic_buddy_start - ByteManager.dynamic_buddy_manager.active_memory)) { FREE_LIST_UNLOCK(lock); + KPrintf("require size:%d\n", size); + KPrintf("dynamic_buddy_end:%d\n", ByteManager.dynamic_buddy_manager.dynamic_buddy_end); + KPrintf("dynamic_buddy_start:%d\n", ByteManager.dynamic_buddy_manager.dynamic_buddy_start); + KPrintf("active_memory:%d\n", ByteManager.dynamic_buddy_manager.active_memory); return NONE; } #endif diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/init.c b/Ubiquitous/XiZi_IIoT/kernel/thread/init.c index 7c5b8cf02..190d6b856 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/init.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/init.c @@ -178,9 +178,9 @@ void EnvInitKTask(void *parameter) #else CreateMainTask(); extern long ShowTask(void); -ShowTask(); +// ShowTask(); extern void ShowMemory(void); -ShowMemory(); +// ShowMemory(); #endif #endif }