diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c index 1f37845f3..69ec0d706 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -14,47 +14,50 @@ */ /** -* @file board.c -* @brief support kd233-board init configure and start-up -* @version 1.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file board.c + * @brief support kd233-board init configure and start-up + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: board.c Description: support edu-riscv64-board init configure and driver/task/... init Others: https://canaan-creative.com/developer -History: +History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab -Modification: +Modification: 1. support edu-riscv64-board InitBoardHardware 2. support edu-riscv64-board Kd233Start 3. support edu-riscv64-board shell cmd, include reboot, shutdown *************************************************/ -#include +#include "board.h" + #include #include -#include "board.h" -#include "tick.h" +#include + +#include "connect_gpio.h" +#include "connect_hwtimer.h" +#include "connect_rtc.h" +#include "connect_soft_spi.h" #include "connect_uart.h" +#include "connect_w5500.h" +#include "connect_wdt.h" +#include "dmac.h" #include "encoding.h" #include "fpioa.h" -#include "dmac.h" -#include "connect_gpio.h" -#include "connect_soft_spi.h" -#include "connect_rtc.h" -#include "connect_hwtimer.h" -#include "connect_wdt.h" +#include "tick.h" // #if defined(FS_VFS) // #include // #endif -#define CPU0 (0) -#define CPU1 (1) +#define CPU0 (0) +#define CPU1 (1) extern x_base cpu2_boot_flag; extern void entry(void); extern void SecondaryCpuCStart(void); @@ -65,6 +68,7 @@ extern int HwCh376Init(void); extern int HwLcdInit(void); extern int HwSpiInit(void); extern int HwSoftSPIInit(void); +extern int HwWiznetInit(void); #include #ifdef MOUNT_USB @@ -72,199 +76,203 @@ extern int HwSoftSPIInit(void); * @description: Mount USB * @return 0 */ -int MountUsb(void) -{ - if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0) - KPrintf("usb mount to '/'\n"); - else - KPrintf("usb mount to '/' failed!\n"); - - return 0; +int MountUsb(void) { + if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, + FSTYPE_CH376, "/") == 0) + KPrintf("usb mount to '/'\n"); + else + KPrintf("usb mount to '/' failed!\n"); + + return 0; } #endif -#if defined(FS_VFS) && defined (MOUNT_SDCARD) +#if defined(FS_VFS) && defined(MOUNT_SDCARD) #include #include -extern SpiSdDeviceType SpiSdInit(struct Bus *bus, const char *dev_name, const char *drv_name, const char *sd_name); +extern SpiSdDeviceType SpiSdInit(struct Bus *bus, const char *dev_name, + const char *drv_name, const char *sd_name); /** * @description: Mount SD card * @return 0 */ -int MountSDCard(void) -{ - struct Bus *spi_bus; - spi_bus = BusFind(SOFT_SPI_BUS_NAME); - if (NONE == SpiSdInit(spi_bus, SOFT_SPI_DEVICE_NAME, SOFT_SPI_DRV_NAME, SPI_SD_NAME)) { - KPrintf("MountSDCard SpiSdInit error!\n"); - return -1; - } - if (EOK != MountFilesystem(SOFT_SPI_BUS_NAME, SPI_SD_NAME, SOFT_SPI_DRV_NAME, FSTYPE_FATFS, "/")) { - return -1; - } +int MountSDCard(void) { + struct Bus *spi_bus; + spi_bus = BusFind(SOFT_SPI_BUS_NAME); + if (NONE == SpiSdInit(spi_bus, SOFT_SPI_DEVICE_NAME, SOFT_SPI_DRV_NAME, + SPI_SD_NAME)) { + KPrintf("MountSDCard SpiSdInit error!\n"); + return -1; + } + if (EOK != MountFilesystem(SOFT_SPI_BUS_NAME, SPI_SD_NAME, SOFT_SPI_DRV_NAME, + FSTYPE_FATFS, "/")) { + return -1; + } - KPrintf("SPI SD card fatfs mounted\n"); - return 0; + KPrintf("SPI SD card fatfs mounted\n"); + return 0; } #endif +void InitBss(void) { + unsigned int *dst; - -void InitBss(void) -{ - unsigned int *dst; - - dst = &__bss_start; - while (dst < &__bss_end){ - *dst++ = 0; - } + dst = &__bss_start; + while (dst < &__bss_end) { + *dst++ = 0; + } } -void Kd233Start(uint32_t mhartid) -{ - switch(mhartid) { - case CPU0: - InitBss(); +void Kd233Start(uint32_t mhartid) { + switch (mhartid) { + case CPU0: + InitBss(); - /*kernel start entry*/ - entry(); - break; - case CPU1: - while(0x2018050420191010 != cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core + /*kernel start entry*/ + entry(); + break; + case CPU1: + while (0x2018050420191010 != + cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core #ifndef ARCH_SMP - asm volatile("wfi"); + asm volatile("wfi"); #endif - } + } #ifdef ARCH_SMP - SecondaryCpuCStart(); + SecondaryCpuCStart(); #endif - break; + break; - default: - break; - } + default: + break; + } } -int Freq(void) -{ - uint64 value = 0; +int Freq(void) { + uint64 value = 0; - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); - KPrintf("PLL0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); - KPrintf("PLL1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); - KPrintf("PLL2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); - KPrintf("CPU : %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); - KPrintf("APB0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); - KPrintf("APB1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); - KPrintf("APB2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); - KPrintf("HCLK: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); + KPrintf("PLL0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); + KPrintf("PLL1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); + KPrintf("PLL2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + KPrintf("CPU : %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + KPrintf("APB0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + KPrintf("APB1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); + KPrintf("APB2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); + KPrintf("HCLK: %d\n", value); - value = clint_get_time(); - KPrintf("mtime: %d\n", value); + value = clint_get_time(); + KPrintf("mtime: %d\n", value); - return 0; + return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Freq, Freq, show frequency information ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Freq, Freq, show frequency information); #ifdef ARCH_SMP extern int EnableHwclintIpi(void); #endif -struct InitSequenceDesc _board_init[] = -{ +struct InitSequenceDesc _board_init[] = { #ifdef BSP_USING_GPIO - { "hw_pin", HwGpioInit }, - { "io_config", IoConfigInit }, + {"hw_pin", HwGpioInit}, + {"io_config", IoConfigInit}, #endif #ifdef BSP_USING_I2C - { "hw_i2c", HwI2cInit }, + {"hw_i2c", HwI2cInit}, #endif #ifdef BSP_USING_RTC - { "hw_rtc", HwRtcInit }, + {"hw_rtc", HwRtcInit}, #endif #ifdef BSP_USING_SPI - { "hw_spi", HwSpiInit }, + {"hw_spi", HwSpiInit}, #endif #ifdef BSP_USING_LCD - { "hw_lcd", HwLcdInit }, + {"hw_lcd", HwLcdInit}, #endif #ifdef BSP_USING_USB - { "hw_usb", HwCh376Init}, + {"hw_usb", HwCh376Init}, #endif #ifdef BSP_USING_TOUCH - {"touch", HwTouchInit }, + {"touch", HwTouchInit}, #endif #ifdef BSP_USING_SOFT_SPI - {"soft_spi", HwSoftSPIInit }, + {"soft_spi", HwSoftSPIInit}, #endif #ifdef BSP_USING_HWTIMER - {"hw_timer", HwTimerInit }, + {"hw_timer", HwTimerInit}, #endif #ifdef BSP_USING_WDT - {"hw_wdt", HwWdtInit }, + {"hw_wdt", HwWdtInit}, #endif - { " NONE ",NONE }, +#ifdef BSP_USING_W5500 + {"w5500", HwWiznetInit}, +#endif + {" NONE ", NONE}, }; +void InitBoardHardware(void) { + int i = 0; + int ret = 0; -void InitBoardHardware(void) -{ - int i = 0; - int ret = 0; - - SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); - SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); + SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); + SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); #ifdef BSP_USING_GPIO - /* Init FPIOA */ - FpioaInit(); + /* Init FPIOA */ + FpioaInit(); #endif #ifdef BSP_USING_DMA - /* Dmac init */ - DmacInit(); + /* Dmac init */ + DmacInit(); #endif - /* initalize interrupt */ - InitHwinterrupt(); -#ifdef BSP_USING_UART - HwUartInit(); + /* initalize interrupt */ + InitHwinterrupt(); +#ifdef BSP_USING_UART + HwUartInit(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); #ifdef KERNEL_CONSOLE - /* set console device */ - InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); - KPrintf("\nconsole init completed.\n"); - KPrintf("board initialization......\n"); + /* set console device */ + InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, + KERNEL_CONSOLE_DEVICE_NAME); + KPrintf("\nconsole init completed.\n"); + KPrintf("board initialization......\n"); #endif /* KERNEL_CONSOLE */ - InitHwTick(); + InitHwTick(); #ifdef ARCH_SMP - EnableHwclintIpi(); + EnableHwclintIpi(); #endif #ifdef KERNEL_COMPONENTS_INIT - for(i = 0; _board_init[i].fn != NONE; i++) { - ret = _board_init[i].fn(); - KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed"); - } + for (i = 0; _board_init[i].fn != NONE; i++) { + ret = _board_init[i].fn(); + KPrintf("initialize %s %s\n", _board_init[i].fn_name, + ret == 0 ? "success" : "failed"); + } #endif - KPrintf("board init done.\n"); - KPrintf("start kernel...\n"); + KPrintf("board init done.\n"); + KPrintf("start kernel...\n"); } -void HwCpuReset(void) -{ - sysctl->soft_reset.soft_reset = 1; - while(RET_TRUE); +void HwCpuReset(void) { + sysctl->soft_reset.soft_reset = 1; + while (RET_TRUE) + ; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Reboot, HwCpuReset, reset machine ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Reboot, HwCpuReset, reset machine); diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig index 11ecca978..46ac183a1 100755 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig @@ -112,3 +112,11 @@ menuconfig BSP_USING_WDT if BSP_USING_WDT source "$BSP_DIR/third_party_driver/watchdog/Kconfig" endif + +menuconfig BSP_USING_WIZCHIP + bool "Using w5500 as network device" + default n + select RESOURCES_WIZCHIP + if BSP_USING_WIZCHIP + source "$BSP_DIR/third_party_driver/ethernet/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile index b8f466166..6ad13cc12 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile @@ -56,5 +56,8 @@ ifeq ($(CONFIG_BSP_USING_WDT),y) SRC_DIR += watchdog endif +ifeq ($(CONFIG_BSP_USING_WIZCHIP),y) + SRC_DIR += ethernet +endif include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig new file mode 100644 index 000000000..baf59367c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig @@ -0,0 +1,15 @@ +# Kconfig file + +config BSP_USING_W5500 +bool "Using w5500 " +default y + +# if BSP_USING_W5500 + config BSP_WIZ_RST_PIN + int + default 13 + + config BSP_WIZ_INT_PIN + int + default 14 +# endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile new file mode 100644 index 000000000..1ea20caac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md new file mode 100644 index 000000000..947404f4a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md @@ -0,0 +1,25 @@ +## w5500 测试文档 + +通过board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c 可以找到内写的3个,包含ping, tcp server test, tcp client test; + + - ping 测试,测试结果包括: + - pc ping w5500 + - w5500 ping baidu.com (DNS实现暂未实现,因此使用baidu.com的ip地址进行寻址) + + + + + +- tcp server 测试:在xizi中调用wiz_server_op,指定port,之后可以在pc中向该端口发送数据 + - wiz_server 将额外启动一个线程执行server工作,server将向client返回client发来的消息 + + + + + +- client 测试:通过wiz_client_op可以向pc中打开的tcp server发送消息 + - 由于wiz_client_test函数参数接收问题,测试使用的ip地址暂时使用硬编码实现 + + + + \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c new file mode 100644 index 000000000..22803ee9e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -0,0 +1,505 @@ + +#include "connect_w5500.h" + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" +#include "socket.h" +#include "w5500.h" + +#define SPI_LORA_FREQUENCY 10000000 + +// spi operations +extern void spi_enter_cris(void); +extern void spi_exit_cris(void); +extern void spi_select_cs(void); +extern void spi_deselete_cs(void); + +// global configurations for w5500 tcp connection +const uint32_t socket_tcp = 0; +const uint32_t g_wiznet_buf_size = 2048; + +static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, + .ip = {192, 168, 31, 13}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 31, 1}, + .dns = {0, 0, 0, 0}, + .dhcp = NETINFO_STATIC}; + +int network_init() { + wiz_NetInfo check_wiz_netinfo; + check_wiz_netinfo.dhcp = NETINFO_STATIC; + ctlnetwork(CN_SET_NETINFO, (void *)&g_wiz_netinfo); + ctlnetwork(CN_GET_NETINFO, (void *)&check_wiz_netinfo); + + if (memcmp(&g_wiz_netinfo, &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { + KPrintf( + "mac: %d; ip: %d; gw: %d; sn: %d; dns: %d; dhcp: %d;\n", + memcmp(&g_wiz_netinfo.mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), + memcmp(&g_wiz_netinfo.ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); + KPrintf("WIZCHIP set network information fail.\n"); + return ERROR; + } + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", g_wiz_netinfo.mac[0], + g_wiz_netinfo.mac[1], g_wiz_netinfo.mac[2], g_wiz_netinfo.mac[3], + g_wiz_netinfo.mac[4], g_wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", g_wiz_netinfo.ip[0], g_wiz_netinfo.ip[1], + g_wiz_netinfo.ip[2], g_wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", g_wiz_netinfo.gw[0], g_wiz_netinfo.gw[1], + g_wiz_netinfo.gw[2], g_wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", g_wiz_netinfo.sn[0], g_wiz_netinfo.sn[1], + g_wiz_netinfo.sn[2], g_wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", g_wiz_netinfo.dns[0], g_wiz_netinfo.dns[1], + g_wiz_netinfo.dns[2], g_wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); + + return EOK; +} + +/****************** spi init ******************/ +static struct Bus *w5500_spi_bus; +int w5500_spi_init() { + x_err_t ret = EOK; + + w5500_spi_bus = BusFind(SPI_BUS_NAME_1); + w5500_spi_bus->owner_haldev = + BusFindDevice(w5500_spi_bus, SPI_1_DEVICE_NAME_0); + w5500_spi_bus->owner_driver = BusFindDriver(w5500_spi_bus, SPI_1_DRV_NAME); + + w5500_spi_bus->match(w5500_spi_bus->owner_driver, + w5500_spi_bus->owner_haldev); + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + spi_master_param.spi_maxfrequency = SPI_LORA_FREQUENCY; + spi_master_param.spi_data_endian = 0; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", + w5500_spi_bus->owner_driver, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", w5500_spi_bus->owner_driver); + return ERROR; + } + + return EOK; +} + +void spi_write_byte(uint8_t tx_data) { + struct BusBlockWriteParam write_param; + write_param.buffer = &tx_data; + write_param.size = 1; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +uint8_t spi_read_byte(void) { + uint8_t result = 0; + struct BusBlockReadParam read_param; + read_param.buffer = &result; + read_param.size = 1; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); + return result; +} +void spi_write_burst(uint8_t *tx_buf, uint16_t len) { + struct BusBlockWriteParam write_param; + write_param.buffer = tx_buf; + write_param.size = len; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +void spi_read_burst(uint8_t *rx_buf, uint16_t len) { + struct BusBlockReadParam read_param; + read_param.buffer = rx_buf; + read_param.size = len; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); +} + +/****************** chip init ******************/ + +void wiz_reset() { + gpiohs_set_drive_mode(WIZ_RST_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_LOW); + MdelayKTask(20); + + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_HIGH); + MdelayKTask(20); +} + +void wiz_spi_handler_reg() { + // spi ops registration +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_) || \ + (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_) + /* register SPI device CS select callback function */ + gpiohs_set_drive_mode(SPI1_CS0_PIN, GPIO_DM_OUTPUT); + reg_wizchip_cs_cbfunc(spi_select_cs, spi_deselete_cs); +#else +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_ +#error "Unknown _WIZCHIP_IO_MODE_" +#else + reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); +#endif +#endif + + reg_wizchip_spi_cbfunc(spi_read_byte, spi_write_byte); + reg_wizchip_cris_cbfunc(spi_enter_cris, spi_exit_cris); + reg_wizchip_spiburst_cbfunc(spi_read_burst, spi_write_burst); +} + +int wiz_chip_cfg_init() { + uint8_t mem_size[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; + + /* reset WIZnet chip internal PHY, configures PHY mode. */ + if (ctlwizchip(CW_INIT_WIZCHIP, (void *)mem_size) == -1) { + KPrintf("WIZCHIP initialize failed."); + return ERROR; + } + + struct wiz_NetTimeout_t net_timeout; + net_timeout.retry_cnt = 5; + net_timeout.time_100us = 20000; + ctlnetwork(CN_SET_TIMEOUT, (void *)&net_timeout); + + return EOK; +} + +/****************** interrupt handle ******************/ +void wiz_irq_handler() {} + +int wiz_interrupt_init() { + int32_t ret = -ERROR; + + struct Bus *pin_bus = PinBusInitGet(); + + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void *)&pin_param; + + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.mode = GPIO_CFG_INPUT_PULLUP; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("config pin_param %d input failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_REGISTER; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_FALLING; + pin_param.irq_set.hdr = wiz_irq_handler; + pin_param.irq_set.args = NONE; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + // 4. enable interuption + pin_param.cmd = GPIO_IRQ_ENABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("enable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + return EOK; + + return EOK; +} + +int HwWiznetInit(void) { + wiz_reset(); + + if (EOK != w5500_spi_init()) { + return ERROR; + } + + wiz_spi_handler_reg(); + + if (EOK != wiz_chip_cfg_init()) { + return ERROR; + } + + network_init(); + + return EOK; +} + +/****************** basic functions ********************/ + +enum TCP_OPTION { + SEND_DATA = 0, + RECV_DATA, +}; + +uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint8_t dst_ip[4], uint16_t dst_port, + enum TCP_OPTION opt) { + // assert(buf_size <= g_wiznet_buf_size); + int32_t ret; + switch (getSn_SR(socket_tcp)) { + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(socket_tcp); + break; + case SOCK_CLOSED: + wiz_socket(socket_tcp, Sn_MR_TCP, 5000, 0x00); + break; + case SOCK_INIT: + KPrintf("[SOCKET CLIENT] sock init.\n"); + wiz_sock_connect(socket_tcp, dst_ip, dst_port); + break; + case SOCK_ESTABLISHED: + if (getSn_IR(socket_tcp) & Sn_IR_CON) { + printf("[SOCKET CLIENT] %d:Connected\r\n", socket_tcp); + setSn_IR(socket_tcp, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + if (ret <= 0) return ret; + } + } + break; + default: + break; + } +} + +void wiz_client_op_test(char *addr, uint16_t port, char *msg) { + /* argv[1]: ip + * argv[2]: port + * argv[3]: msg + */ + uint8_t client_sock = 2; + uint8_t ip[4] = {192, 168, 31, 127}; + uint32_t tmp_ip[4]; + KPrintf("wiz client to %s", addr); + sscanf(addr, "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + for (int i = 0; i < 4; ++i) { + ip[i] = (uint8_t)tmp_ip[i]; + } + uint8_t buf[g_wiznet_buf_size]; + KPrintf("wiz_server, send to %d.%d.%d.%d %d\n", // tip info + ip[0], ip[1], ip[2], ip[3], port); + sscanf(msg, "%s", buf); + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, SEND_DATA); + MdelayKTask(10); + memset(buf, 0, g_wiznet_buf_size); + // waiting for a responding. + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, RECV_DATA); + KPrintf("received msg: %s\n", buf); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(3), + wiz_client_op, wiz_client_op_test, + wiz_sock_recv or wiz_sock_send data as tcp client); + +int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint16_t port, enum TCP_OPTION opt) { + int32_t ret = 0; + uint16_t size = 0, sentsize = 0; + switch (getSn_SR(sn)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("%d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + return ret; + } + } + break; + case SOCK_CLOSE_WAIT: + printf("%d:CloseWait\r\n", sn); + if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; + printf("%d:Closed\r\n", sn); + break; + case SOCK_INIT: + printf("%d:Listen, port [%d]\r\n", sn, port); + if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: + printf("%d:LBTStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; + printf("%d:Opened\r\n", sn); + break; + default: + break; + } + return 0; +} + +void wiz_server(void *param) { + uint16_t port = *(uint16_t *)param; + KPrintf("wiz server, listen port: %d\n", port); + uint8_t buf[g_wiznet_buf_size]; + memset(buf, 0, g_wiznet_buf_size); + int ret = 0; + while (1) { + ret = wiz_server_op(0, buf, g_wiznet_buf_size, port, RECV_DATA); + if (ret > 0) { + wiz_server_op(0, buf, g_wiznet_buf_size, port, SEND_DATA); + }; + } +} + +void wiz_server_test(uint16_t port) { + /* argv[1]: port + */ + int32 wiz_server_id = + KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); + x_err_t flag = StartupKTask(wiz_server_id); + if (flag != EOK) { + KPrintf("StartupKTask wiz_server_id failed .\n"); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(1), + wiz_server_op, wiz_server_test, + wiz_sock_recv or wiz_sock_send data as tcp server); + +int32_t loopback_udps(uint8_t sn, uint8_t *buf, uint16_t port) { + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + // uint8_t packinfo = 0; + switch (getSn_SR(sn)) { + case SOCK_UDP: + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > g_wiznet_buf_size) size = g_wiznet_buf_size; + ret = wiz_sock_recvfrom(sn, buf, size, destip, (uint16_t *)&destport); + if (ret <= 0) { + printf("%d: wiz_sock_recvfrom error. %ld\r\n", sn, ret); + return ret; + } + size = (uint16_t)ret; + sentsize = 0; + while (sentsize != size) { + ret = wiz_sock_sendto(sn, buf + sentsize, size - sentsize, destip, + destport); + if (ret < 0) { + printf("%d: wiz_sock_sendto error. %ld\r\n", sn, ret); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: + printf("%d:LBUStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_UDP, port, 0x00)) != sn) return ret; + printf("%d:Opened, port [%d]\r\n", sn, port); + break; + default: + break; + } + return 1; +} + +void ifconfig() { + wiz_NetInfo wiz_netinfo; + ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], + wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], + wiz_netinfo.mac[4], wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], + wiz_netinfo.ip[2], wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], + wiz_netinfo.gw[2], wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], + wiz_netinfo.sn[2], wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], + wiz_netinfo.dns[2], wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + ifconfig, ifconfig, printf w5500 configurations); + +void char_arr_assign(uint8_t **dst, uint32_t *src, uint32_t len) { + for (int i = 0; i < len; ++i) { + (*dst)[i] = (uint8_t)(src[i]); + } +} + +void config_w5500_network(char *mac, char *ip, char *sn, char *gw, char *dns) { + wiz_NetInfo wiz_netinfo; + uint32_t tmp_arr[4]; + // config netinfo + sscanf(mac, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.mac, tmp_arr, 4); + sscanf(ip, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.ip, tmp_arr, 4); + sscanf(sn, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.sn, tmp_arr, 4); + sscanf(gw, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.gw, tmp_arr, 4); + sscanf(dns, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.dns, tmp_arr, 4); + // set new netinfo + ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); + ifconfig(); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(5), + config_w5500_network, config_w5500_network, + set w5500 configurations); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png new file mode 100644 index 000000000..7df09b0d9 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png new file mode 100644 index 000000000..167d455b8 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png new file mode 100644 index 000000000..c79f4bb85 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png new file mode 100644 index 000000000..e453995a6 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png new file mode 100644 index 000000000..63f2d5f57 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png new file mode 100644 index 000000000..7643c9bf3 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c new file mode 100755 index 000000000..820e0631c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c @@ -0,0 +1,912 @@ + +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* +//! addr parameter is not aligned by 4byte address. Copy 4 byte addr +//! value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status +//! (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +#include "wizchip_conf.h" + +// M20150401 : Typing Error +//#define SOCK_ANY_PORT_NUM 0xC000; +#define SOCK_ANY_PORT_NUM 0xC000 + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; + +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = { + 0, + 0, +}; + +// M20150601 : For extern decleation +// static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +// + +#if _WIZCHIP_ == 5200 +static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 +uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = { + 0, +}; // set by wiz_recv_data() +#endif + +#define CHECK_SOCKNUM() \ + do { \ + if (sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + } while (0); + +#define CHECK_SOCKMODE(mode) \ + do { \ + if ((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + } while (0); + +#define CHECK_SOCKINIT() \ + do { \ + if ((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + } while (0); + +#define CHECK_SOCKDATA() \ + do { \ + if (len == 0) return SOCKERR_DATALEN; \ + } while (0); + +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) { + CHECK_SOCKNUM(); + switch (protocol) { + case Sn_MR_TCP: { + // M20150601 : Fixed the warning - taddr will never be NULL + /* + uint8_t taddr[4]; + getSIPR(taddr); + */ + uint32_t taddr; + getSIPR((uint8_t *)&taddr); + if (taddr == 0) return SOCKERR_SOCKINIT; + break; + } + case Sn_MR_UDP: + case Sn_MR_MACRAW: + case Sn_MR_IPRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + // M20150601 : For SF_TCP_ALIGN & W5300 + // if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; + if ((flag & 0x04) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if (flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if (flag != 0) { + switch (protocol) { + case Sn_MR_TCP: + // M20150601 : For SF_TCP_ALIGN & W5300 +#if _WIZCHIP_ == 5300 + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK | SF_TCP_ALIGN)) == 0) + return SOCKERR_SOCKFLAG; +#else + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK)) == 0) + return SOCKERR_SOCKFLAG; +#endif + + break; + case Sn_MR_UDP: + if (flag & SF_IGMP_VER2) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#if _WIZCHIP_ == 5500 + if (flag & SF_UNI_BLOCK) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#endif + break; + default: + break; + } + } + wiz_sock_close(sn); +// M20150601 +#if _WIZCHIP_ == 5300 + setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | + (((uint16_t)(flag & 0x02)) << 7)); +#else + setSn_MR(sn, (protocol | (flag & 0xF0))); +#endif + if (!port) { + port = sock_any_port++; + if (sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn, port); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn)) + ; + // A20150401 : For release the previous sock_io_mode + sock_io_mode &= ~(1 << sn); + // + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + // M20150601 : repalce 0 with PACK_COMPLETED + // sock_pack_info[sn] = 0; + sock_pack_info[sn] = PACK_COMPLETED; + // + while (getSn_SR(sn) == SOCK_CLOSED) + ; + return (int8_t)sn; +} + +int8_t wiz_sock_close(uint8_t sn) { + CHECK_SOCKNUM(); +// A20160426 : Applied the erratum 1 of W5300 +#if (_WIZCHIP_ == 5300) + // M20160503 : Wrong socket parameter. s -> sn + // if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != + // getSn_TxMAX(s)) ) + if (((getSn_MR(sn) & 0x0F) == Sn_MR_TCP) && + (getSn_TX_FSR(sn) != getSn_TxMAX(sn))) { + uint8_t destip[4] = {0, 0, 0, 1}; + // TODO + // You can wait for completing to sending data; + // wait about 1 second; + // if you have completed to send data, skip the code of erratum 1 + // ex> wait_1s(); + // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue; + // + // M20160503 : The socket() of close() calls close() itself again. It + // occures a infinite loop - close()->socket()->close()->socket()-> ~ + // socket(s,Sn_MR_UDP,0x3000,0); + // sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown + // destination(0.0.0.1). + setSn_MR(sn, Sn_MR_UDP); + setSn_PORTR(sn, 0x3000); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn) != 0) + ; + while (getSn_SR(sn) != SOCK_UDP) + ; + wiz_sock_sendto( + sn, destip, 1, destip, + 0x3000); // send the dummy data to an unknown destination(0.0.0.1). + }; +#endif + setSn_CR(sn, Sn_CR_CLOSE); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + // A20150401 : Release the sock_io_mode of socket n. + sock_io_mode &= ~(1 << sn); + // + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while (getSn_SR(sn) != SOCK_CLOSED) + ; + return SOCK_OK; +} + +int8_t wiz_sock_listen(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + setSn_CR(sn, Sn_CR_LISTEN); + while (getSn_CR(sn)) + ; + while (getSn_SR(sn) != SOCK_LISTEN) { + wiz_sock_close(sn); + return SOCKERR_SOCKCLOSED; + } + return SOCK_OK; +} + +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return + // SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; + } + // + + if (port == 0) return SOCKERR_PORTZERO; + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + setSn_CR(sn, Sn_CR_CONNECT); + while (getSn_CR(sn)) + ; + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_ESTABLISHED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } + } + + return SOCK_OK; +} + +int8_t wiz_sock_disconnect(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_CR(sn, Sn_CR_DISCON); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending &= ~(1 << sn); + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_CLOSED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } + } + return SOCK_OK; +} + +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t freesize = 0; + + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) + return SOCKERR_SOCKSTATUS; + if (sock_is_sending & (1 << sn)) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); +// M20150401 : Typing Error +//#if _WZICHIP_ == 5200 +#if _WIZCHIP_ == 5200 + if (getSn_TX_RD(sn) != sock_next_rd[sn]) { + setSn_CR(sn, Sn_CR_SEND); + while (getSn_CR(sn)) + ; + return SOCK_BUSY; + } +#endif + sock_is_sending &= ~(1 << sn); + } else if (tmp & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } else + return SOCK_BUSY; + } + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + } + wiz_send_data(sn, buf, len); +#if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; +#endif + +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending |= (1 << sn); + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t recvsize = 0; +// A20150601 : For integarating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t head[2]; + uint16_t mr; +#endif + // + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if (recvsize < len) len = recvsize; + +// A20150601 : For Integrating with W5300 +#if _WIZCHIP_ == 5300 + // sock_pack_info[sn] = PACK_COMPLETED; // for clear + if (sock_remained_size[sn] == 0) { +#endif + // + while (1) { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) { + if (tmp == SOCK_CLOSE_WAIT) { + if (recvsize != 0) + break; + else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } else { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if ((sock_io_mode & (1 << sn)) && (recvsize == 0)) return SOCK_BUSY; + if (recvsize != 0) break; + }; +#if _WIZCHIP_ == 5300 + } +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 + if ((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) { + mr = getMR(); + if ((getSn_MR(sn) & Sn_MR_ALIGN) == 0) { + wiz_recv_data(sn, head, 2); + if (mr & MR_FS) + recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); + else + recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); + sock_pack_info[sn] = PACK_FIRST; + } + sock_remained_size[sn] = recvsize; + } + if (len > sock_remained_size[sn]) len = sock_remained_size[sn]; + recvsize = len; + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf = sock_remained_byte[sn]; + buf++; + sock_pack_info[sn] &= ~(PACK_FIFOBYTE); + recvsize -= 1; + sock_remained_size[sn] -= 1; + } + if (recvsize != 0) { + wiz_recv_data(sn, buf, recvsize); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + } + sock_remained_size[sn] -= recvsize; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; + if (recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; + } else + sock_pack_info[sn] = PACK_COMPLETED; + if (getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; + // len = recvsize; +#else + if (recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; +#endif + + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port) { + uint8_t tmp = 0; + uint16_t freesize = 0; + uint32_t taddr; + + CHECK_SOCKNUM(); + switch (getSn_MR(sn) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + // break; + // #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + break; + // #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + //{ + // uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + //} + // + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if ((taddr == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_IPINVALID; + if ((port == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); + //#if ( _WIZCHIP_ < 5200 ) + if ((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) + return SOCKERR_SOCKSTATUS; + //#else + // if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + //#endif + + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + getSIPR((uint8_t *)&taddr); + if (taddr == 0) { + getSUBR((uint8_t *)&taddr); + setSUBR((uint8_t *)"\x00\x00\x00\x00"); + } else + taddr = 0; +#endif + +// A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + // + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + while (1) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + // M:20131104 + // else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if (tmp & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); +// M20150409 : Fixed the lost of sign bits by type casting. +// len = (uint16_t)SOCKERR_TIMEOUT; +// break; +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + return SOCKERR_TIMEOUT; + } + //////////// + } +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port) { +// M20150601 : For W5300 +#if _WIZCHIP_ == 5300 + uint16_t mr; + uint16_t mr1; +#else + uint8_t mr; +#endif + // + uint8_t head[8]; + uint16_t pack_len = 0; + + CHECK_SOCKNUM(); + // CHECK_SOCKMODE(Sn_MR_UDP); +// A20150601 +#if _WIZCHIP_ == 5300 + mr1 = getMR(); +#endif + + switch ((mr = getSn_MR(sn)) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_IPRAW: + case Sn_MR_MACRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if (sock_remained_size[sn] == 0) { + while (1) { + pack_len = getSn_RX_RSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (pack_len == 0)) return SOCK_BUSY; + if (pack_len != 0) break; + }; + } + // D20150601 : Move it to bottom + // sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) { + case Sn_MR_UDP: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 8); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + // A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + if (mr1 & MR_FS) { + addr[0] = head[1]; + addr[1] = head[0]; + addr[2] = head[3]; + addr[3] = head[2]; + *port = head[5]; + *port = (*port << 8) + head[4]; + sock_remained_size[sn] = head[7]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; + } else { +#endif + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; +#if _WIZCHIP_ == 5300 + } +#endif + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + // A20150601 : For W5300 + len = pack_len; +#if _WIZCHIP_ == 5300 + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf++ = sock_remained_byte[sn]; + pack_len -= 1; + sock_remained_size[sn] -= 1; + sock_pack_info[sn] &= ~PACK_FIFOBYTE; + } +#endif + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + case Sn_MR_MACRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 2); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2; +#if _WIZCHIP_ == W5300 + if (sock_remained_size[sn] & 0x01) + sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; + else + sock_remained_size[sn] -= 4; +#endif + if (sock_remained_size[sn] > 1514) { + wiz_sock_close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); + break; + //#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 6); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + // M20150401 : For Typing Error + // sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + //#endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn, Sn_CR_RECV); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_remained_size[sn] -= pack_len; + // M20150601 : + // if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; +#if _WIZCHIP_ == 5300 + if (pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; +#endif + } else + sock_pack_info[sn] = PACK_COMPLETED; +#if _WIZCHIP_ == 5300 + pack_len = len; +#endif + // + // M20150409 : Explicit Type Casting + // return pack_len; + return (int32_t)pack_len; +} + +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg) { + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch (cstype) { + case CS_SET_IOMODE: + tmp = *((uint8_t *)arg); + if (tmp == SOCK_IO_NONBLOCK) + sock_io_mode |= (1 << sn); + else if (tmp == SOCK_IO_BLOCK) + sock_io_mode &= ~(1 << sn); + else + return SOCKERR_ARG; + break; + case CS_GET_IOMODE: + // M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t *)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t *)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t *)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t *)arg) = getSn_IR(sn); + break; +#if _WIZCHIP_ != 5100 + case CS_SET_INTMASK: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTMASK: + *((uint8_t *)arg) = getSn_IMR(sn); + break; +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + // M20131220 : Remove warning + // uint8_t tmp; + CHECK_SOCKNUM(); + switch (sotype) { + case SO_TTL: + setSn_TTL(sn, *(uint8_t *)arg); + break; + case SO_TOS: + setSn_TOS(sn, *(uint8_t *)arg); + break; + case SO_MSS: + setSn_MSSR(sn, *(uint16_t *)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t *)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ > 5200 + if (getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; +#endif + setSn_CR(sn, Sn_CR_SEND_KEEP); + while (getSn_CR(sn) != 0) { + // M20131220 + // if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn, *(uint8_t *)arg); + break; +#endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + CHECK_SOCKNUM(); + switch (sotype) { + case SO_FLAG: + *(uint8_t *)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t *)arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t *)arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint16_t *)arg = getSn_MSSR(sn); + break; + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + *(uint16_t *)arg = getSn_DPORT(sn); + break; +#if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t *)arg = getSn_KPALVTR(sn); + break; +#endif + case SO_SENDBUF: + *(uint16_t *)arg = getSn_TX_FSR(sn); + break; + case SO_RECVBUF: + *(uint16_t *)arg = getSn_RX_RSR(sn); + break; + case SO_STATUS: + *(uint8_t *)arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if (getSn_MR(sn) & Sn_MR_TCP) + *(uint16_t *)arg = getSn_RX_RSR(sn); + else + *(uint16_t *)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + // CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ != 5300 + if ((getSn_MR(sn) == Sn_MR_TCP)) return SOCKERR_SOCKMODE; +#endif + *(uint8_t *)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c new file mode 100644 index 000000000..7dbba1b46 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c @@ -0,0 +1,35 @@ + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" + +// #define SPI1_CS_GPIONUM 24 + +static x_base g_w5500_spi_lock; +/** + * @brief 进入临界区 + * @retval None + */ +void spi_enter_cris(void) { g_w5500_spi_lock = DisableLocalInterrupt(); } +/** + * @brief 退出临界区 + * @retval None + */ +void spi_exit_cris(void) { EnableLocalInterrupt(g_w5500_spi_lock); } + +/** + * @brief 片选信号输出低电平 + * @retval None + */ +void spi_select_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_LOW); } +/** + * @brief 片选信号输出高电平 + * @retval None + */ +void spi_deselete_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_HIGH); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c new file mode 100755 index 000000000..e98739488 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c @@ -0,0 +1,255 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to +//! M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case +//! _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include +#include "w5500.h" + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +#if (_WIZCHIP_ == 5500) +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) { + uint8_t ret; + uint8_t spi_data[3]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + // if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte + // operation + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint16_t getSn_TX_FSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + } + } while (val != val1); + return val; +} + +uint16_t getSn_RX_RSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + } + } while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_TX_WR(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel, wizdata, len); + + ptr += len; + setSn_TX_WR(sn, ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_RX_RD(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) { + uint16_t ptr = 0; + + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn, ptr); +} + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c new file mode 100644 index 000000000..c424ed177 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c @@ -0,0 +1,250 @@ + +#include "wiz_ping.h" + +#include +#include +#include +#include +#include + +#define Sn_PROTO(ch) (0x001408 + (ch << 5)) + +#define PING_BIND_PORT 3000 + +PINGMSGR PingRequest = {0}; +PINGMSGR PingReply = {0}; + +static uint16_t ping_RandomID = 0x1234; +static uint16_t ping_RandomSeqNum = 0x4321; +uint8_t ping_reply_received = 0; +uint8_t ping_req = 0; +uint8_t ping_rep = 0; +uint8_t ping_cnt = 0; +uint8_t ping_rep_buf[150] = {0}; + +// ping状态机 +#define PING_STA_FREE 0 +#define PING_STA_OPEN 1 +#define PING_STA_SEND 2 +#define PING_STA_WAIT 3 +#define PING_STA_CLOSE 4 + +uint8_t ping_sta = PING_STA_FREE; + +//当前ping的设备的序号 +uint8_t ping_socket = 0; + +#define bswap_16(A) ((((uint16)(A)&0xff00) >> 8) | (((uint16)(A)&0x00ff) << 8)) + +uint16_t htons(uint16_t n) { + union { + int i; + char c; + } u = {1}; + return u.c ? bswap_16(n) : n; +} + +uint16_t checksum(uint8_t *src, uint32_t len) { + uint16_t sum, tsum, i, j; + uint32_t lsum; + + j = len >> 1; + lsum = 0; + + for (i = 0; i < j; i++) { + tsum = src[i * 2]; + tsum = tsum << 8; + tsum += src[i * 2 + 1]; + lsum += tsum; + } + + if (len % 2) { + tsum = src[i * 2]; + lsum += (tsum << 8); + } + + sum = lsum; + sum = ~(sum + (lsum >> 16)); + return (uint16_t)sum; +} + +/** + *@brief 设定次数ping外网IP函数 + *@param sn- socket number + *@param addr- 外网IP地址 + *@param pCount- ping的次数 + *@return ping成功次数 + */ +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr) { + uint16_t rlen, cnt, i; + + ping_reply_received = 0; + ping_req = 0; + ping_rep = 0; + KPrintf("Ping:%d.%d.%d.%d\r\n", (addr[0]), (addr[1]), (addr[2]), (addr[3])); + + for (i = 0; i < pCount + 1; i++) /*循环ping pCount次*/ + { + switch (getSn_SR(sn)) /*获取socket状态*/ + { + case SOCK_CLOSED: /*socket关闭状态*/ + { + wiz_sock_close(sn); + /* Create Socket */ + IINCHIP_WRITE(Sn_PROTO(sn), IPPROTO_ICMP); /*设置ICMP 协议*/ + if (wiz_socket(sn, Sn_MR_IPRAW, PING_BIND_PORT, 0) != + 0) /*判断ip raw模式socket是否开启*/ + { + } + /* Check socket register */ + while (getSn_SR(sn) != SOCK_IPRAW) { + MdelayKTask(50); + }; + break; + } + case SOCK_IPRAW: /*ip raw模式*/ + { + cnt = 0; + ping_request(sn, addr); /*发送Ping请求*/ + ping_req++; + while (1) { + if ((rlen = getSn_RX_RSR(sn)) > 0) { + rlen = ping_reply(sn, addr, rlen); /*获取回复信息*/ + ping_rep++; + if (ping_reply_received) { + break; + } + } + if ((cnt > 300)) { + cnt = 0; + break; + } else { + cnt++; + MdelayKTask(10); + } + } + break; + } + default: + break; + } + if (ping_req >= pCount) { + wiz_sock_close(sn); + } + } + return ping_rep; +} + +/** + *@brief ping请求函数 + *@param sn- socket number + *@param addr- P地址 + *@return 无 + */ +uint8_t ping_request(uint8_t sn, uint8_t *addr) { + uint8_t *buffer; + uint16_t i, temp_len = 0; + ping_reply_received = 0; /*ping 回复初始化标志位*/ + PingRequest.Type = PING_REQUEST; /*Ping-Request*/ + PingRequest.Code = CODE_ZERO; /*总是 '0'*/ + PingRequest.ID = htons(ping_RandomID++); /*设置ping响应ID为随机的整型变量*/ + PingRequest.SeqNum = + htons(ping_RandomSeqNum++); /*设置ping响应的序列号为随机整形变量*/ + for (i = 0; i < PING_BUF_LEN; i++) { + PingRequest.Data[i] = (i) % 8; /*ping相应的数在'0'~'8‘*/ + } + PingRequest.CheckSum = 0; + /* 计算响应次数*/ + PingRequest.CheckSum = + htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest))); + + /*发送ping响应到目的方 */ + if (wiz_sock_sendto(sn, (uint8_t *)&PingRequest, sizeof(PingRequest), addr, + PING_BIND_PORT) == 0) { + KPrintf("Fail to send ping-reply packet\r\n"); + } else { + KPrintf("ping send\n"); + } + return 0; +} + +/** + *@brief 解析Ping回复 + *@param sn- socket number + *@param addr- Ping地址 + *@return 无 + */ +uint8_t ping_reply(uint8_t sn, uint8_t *addr, uint16_t rlen) { + uint16_t tmp_checksum; + uint16_t len; + uint16_t i; + + uint16_t port = PING_BIND_PORT; + PINGMSGR PingReply; + + memset(ping_rep_buf, 0, sizeof(ping_rep_buf)); + len = wiz_sock_recvfrom(sn, ping_rep_buf, rlen, addr, + &port); /*从目的端接收数据*/ + + if (ping_rep_buf[0] == PING_REPLY) { + PingReply.Type = ping_rep_buf[0]; + PingReply.Code = ping_rep_buf[1]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = ~checksum(ping_rep_buf, len); /*检查ping回复的次数*/ + if (tmp_checksum != 0xffff) { + KPrintf("tmp_checksum = %x\r\n", tmp_checksum); + } else { + KPrintf("Reply from %3d.%3d.%3d.%3d ID=%x Byte=%d\r\n\r\n", (addr[0]), + (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), (rlen + 6)); + ping_reply_received = 1; /*当退出ping回复循环时,设置ping回复标志为1*/ + } + } else if (ping_rep_buf[0] == PING_REQUEST) { + PingReply.Code = ping_rep_buf[1]; + PingReply.Type = ping_rep_buf[2]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = PingReply.CheckSum; /*检查ping回复次数*/ + PingReply.CheckSum = 0; + if (tmp_checksum != PingReply.CheckSum) { + KPrintf(" \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), + htons(PingReply.CheckSum)); + } else { + } + KPrintf( + " Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n", + (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), + (PingReply.SeqNum), (rlen + 6)); + ping_reply_received = 1; /* 当退出ping回复循环时,设置ping回复标志为1 + */ + } else { + KPrintf(" Unkonwn msg. \n"); + } + return 0; +} + +void wiz_ping_test(int argc, char *argv[]) { + uint32_t tmp_ip[4]; + uint8_t target_ip[4]; + if (argc >= 2) { + KPrintf("This is a Ping test: %s\n", argv[1]); + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], + &tmp_ip[3]); + target_ip[0] = (uint8_t)tmp_ip[0]; + target_ip[1] = (uint8_t)tmp_ip[1]; + target_ip[2] = (uint8_t)tmp_ip[2]; + target_ip[3] = (uint8_t)tmp_ip[3]; + ping_count(ping_socket, 5, target_ip); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + ping, wiz_ping_test, ping to given addr); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h new file mode 100644 index 000000000..3ead801b8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h @@ -0,0 +1,35 @@ +#ifndef _WIZ_PING_H_ +#define _WIZ_PING_H_ + +#include "socket.h" +#include "w5500.h" + +#define PING_BUF_LEN 32 +#define PING_REQUEST 8 +#define PING_REPLY 0 +#define CODE_ZERO 0 + +#define SOCKET_ERROR 1 +#define TIMEOUT_ERROR 2 +#define SUCCESS 3 +#define REPLY_ERROR 4 + +typedef struct pingmsg { + uint8_t Type; // 0 - Ping Reply, 8 - Ping Request + uint8_t Code; // Always 0 + uint16_t CheckSum; // Check sum + uint16_t ID; // Identification + uint16_t SeqNum; // Sequence Number + int8_t Data[PING_BUF_LEN]; // Ping Data : 1452 = IP RAW MTU - + // sizeof(Type+Code+CheckSum+ID+SeqNum) +} PINGMSGR; + +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr); + +uint8_t ping_request(uint8_t s, uint8_t *addr); + +uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen); + +void Ethernet_ping_service_deal(uint8_t sn); + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c new file mode 100755 index 000000000..1407c852f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c @@ -0,0 +1,862 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readdata() & +//! wizchip_bus_writedata() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting +//! it into uint8_t* For remove the warning when pointer type size is +//! not 32bit. If ptrdiff_t doesn't support in your complier, You +//! should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +// A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" + +///////////// +// M20150401 : Remove ; in the default callback function such as +// wizchip_cris_enter(), wizchip_cs_select() and etc. +///////////// + +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_enter(void) {}; +void wizchip_cris_enter(void) {} + +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_exit(void) {}; +void wizchip_cris_exit(void) {} + +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_select(void) {}; +void wizchip_cs_select(void) {} + +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_deselect(void) {}; +void wizchip_cs_deselect(void) {} + +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t +// *)((ptrdiff_t) AddrSel)); } +iodata_t wizchip_bus_readdata(uint32_t AddrSel) { + return *((volatile iodata_t *)((ptrdiff_t)AddrSel)); +} + +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile +// uint8_t*)((ptrdiff_t)AddrSel)) = wb; } +void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { + *((volatile iodata_t *)((ptrdiff_t)AddrSel)) = wb; +} + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// uint8_t wizchip_spi_readbyte(void) {return 0;}; +uint8_t wizchip_spi_readbyte(void) { return 0; } + +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writebyte(uint8_t wb) {}; +void wizchip_spi_writebyte(uint8_t wb) {} + +/** + * @brief Default function to burst read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_readburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @brief Default function to burst write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_writeburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @\ref _WIZCHIP instance + */ +// +// M20150401 : For a compiler didnot support a member of structure +// Replace the assignment of struct members with the assingment of +// array +// +/* +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; +*/ +_WIZCHIP WIZCHIP = {_WIZCHIP_IO_MODE_, + _WIZCHIP_ID_, + {wizchip_cris_enter, wizchip_cris_exit}, + {wizchip_cs_select, wizchip_cs_deselect}, + { + {// M20150601 : Rename the function + // wizchip_bus_readbyte, + // wizchip_bus_writebyte + wizchip_bus_readdata, wizchip_bus_writedata}, + + }}; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)) { + if (!cris_en || !cris_ex) { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } else { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)) { + if (!cs_sel || !cs_desel) { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } else { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +// M20150515 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)) +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)) + ; + // M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if (!bus_rb || !bus_wb) { + WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata; + WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata; + } else { + WIZCHIP.IF.BUS._read_data = bus_rb; + WIZCHIP.IF.BUS._write_data = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +// 20140626 Eric Added for SPI burst operations +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rb; + WIZCHIP.IF.SPI._write_burst = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg) { +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + uint8_t tmp = 0; +#endif + uint8_t *ptmp[2] = {0, 0}; + switch (cwtype) { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if (arg != 0) { + ptmp[0] = (uint8_t *)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind *)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind *)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind *)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind *)arg) = wizchip_getinterruptmask(); + break; +// M20150601 : This can be supported by W5200, W5500 +//#if _WIZCHIP_ > W5100 +#if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t *)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t *)arg = getINTLEVEL(); + break; +#endif + case CW_GET_ID: + ((uint8_t *)arg)[0] = WIZCHIP.id[0]; + ((uint8_t *)arg)[1] = WIZCHIP.id[1]; + ((uint8_t *)arg)[2] = WIZCHIP.id[2]; + ((uint8_t *)arg)[3] = WIZCHIP.id[3]; + ((uint8_t *)arg)[4] = WIZCHIP.id[4]; + ((uint8_t *)arg)[5] = WIZCHIP.id[5]; + ((uint8_t *)arg)[6] = 0; + break; +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t *)arg); +#endif +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; +#endif + default: + return -1; + } + return 0; +} + +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg) { + + switch (cntype) { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo *)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo *)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type *)arg); + case CN_GET_NETMODE: + *(netmode_type *)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout *)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout *)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) { + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; +// A20150601 +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + uint16_t mr = (uint16_t)getMR(); + setMR(mr | MR_IND); +#endif + // + getSHAR(mac); + getGAR(gw); + getSUBR(sn); + getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay +// A2015051 : For indirect bus mode +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + setMR(mr | MR_IND); +#endif + // + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize) { + int8_t i; +#if _WIZCHIP_ < W5200 + int8_t j; +#endif + int8_t tmp = 0; + wizchip_sw_reset(); + if (txsize) { + tmp = 0; +// M20150601 : For integrating with W5300 +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (txsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += txsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += txsize[i]; + +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 + j = 0; + while ((txsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_TXBUF_SIZE(i, j); +#else + setSn_TXBUF_SIZE(i, txsize[i]); +#endif + } + +#endif + } + + if (rxsize) { + tmp = 0; +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (rxsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += rxsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += rxsize[i]; +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // add condition for w5100 + j = 0; + while ((rxsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_RXBUF_SIZE(i, j); +#else + setSn_RXBUF_SIZE(i, rxsize[i]); +#endif + } +#endif + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) { + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + ir |= (1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ <= W5100S + ir |= sir; + setIR(ir); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIR(((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF))); +#else + setIR(ir); + // M20200227 : For clear + // setSIR(sir); + for (ir = 0; ir < 8; ir++) { + if (sir & (0x01 << ir)) + setSn_IR(ir, 0xff); + } + +#endif +} + +intr_kind wizchip_getinterrupt(void) { + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ <= W5100S + ir = getIR(); + sir = ir & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIR(); + ir = (uint8_t)(ret >> 8); + sir = (uint8_t)ret; +#else + ir = getIR(); + sir = getSIR(); +#endif + +// M20150601 : For Integrating with W5300 +//#if _WIZCHIP_ < W5500 +#if _WIZCHIP_ < W5200 + ir &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) { + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + simr &= 0x0F; + imr |= simr; + setIMR(imr); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIMR(((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF))); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) { + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ < W5200 + imr = getIMR(); + simr = imr & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIMR(); + imr = (uint8_t)(ret >> 8); + simr = (uint8_t)ret; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) { + int8_t tmp = PHY_LINK_OFF; +#if _WIZCHIP_ == W5100S + if (getPHYSR() & PHYSR_LNK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5500 + if (getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > W5100 + +int8_t wizphy_getphypmode(void) { + int8_t tmp = 0; +#if _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#elif _WIZCHIP_ == 5500 + if ((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#else + tmp = -1; +#endif + return tmp; +} +#endif + +#if _WIZCHIP_ == W5100S +void wizphy_reset(void) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + tmp |= BMCR_RESET; + wiz_mdio_write(PHYMDIO_BMCR, tmp); + while (wiz_mdio_read(PHYMDIO_BMCR) & BMCR_RESET) { + } +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= BMCR_AUTONEGO; + else { + tmp &= ~BMCR_AUTONEGO; + if (phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DUP; + } else { + tmp &= ~BMCR_DUP; + } + if (phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPEED; + } else { + tmp &= ~BMCR_SPEED; + } + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + phyconf->by = PHY_CONFBY_SW; + if (tmp & BMCR_AUTONEGO) { + phyconf->mode = PHY_MODE_AUTONEGO; + } else { + phyconf->mode = PHY_MODE_MANUAL; + if (tmp & BMCR_DUP) + phyconf->duplex = PHY_DUPLEX_FULL; + else + phyconf->duplex = PHY_DUPLEX_HALF; + if (tmp & BMCR_SPEED) + phyconf->speed = PHY_SPEED_100; + else + phyconf->speed = PHY_SPEED_10; + } +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + if (tmp & BMCR_PWDN) + return 0; + } else { + if ((tmp & BMCR_PWDN) != BMCR_PWDN) + return 0; + } + return -1; +} + +#endif +#if _WIZCHIP_ == W5500 +void wizphy_reset(void) { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + if (phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else { + if (phyconf->duplex == PHY_DUPLEX_FULL) { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } else { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf *phyconf) { + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = + (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if ((tmp & PHYCFGR_OPMD) == 0) + return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if (pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if (pmode == PHY_POWER_DOWN) { + if (tmp & PHYCFGR_OPMDC_PDOWN) + return 0; + } else { + if (tmp & PHYCFGR_OPMDC_ALLA) + return 0; + } + return -1; +} +#endif + +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo) { + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo) { + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0] = _DNS_[0]; + pnetinfo->dns[1] = _DNS_[1]; + pnetinfo->dns[2] = _DNS_[2]; + pnetinfo->dns[3] = _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) { + uint8_t tmp = 0; +#if _WIZCHIP_ != W5500 + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) + return -1; +#else + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) + return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) { return (netmode_type)getMR(); } + +void wizchip_settimeout(wiz_NetTimeout *nettime) { + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout *nettime) { + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h new file mode 100644 index 000000000..43359e8f4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h @@ -0,0 +1,38 @@ +/* + * 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_w5500.h + * @brief define aiit-riscv64-board spi function and struct + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-10-16 + */ + +#ifndef _CONNECT_W5500_H_ +#define _CONNECT_W5500_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static struct Bus *spi_bus; + +int HwWiznetInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h index f48e34c0d..37a74cc29 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h @@ -9,19 +9,19 @@ */ /** -* @file drv_io_config.h -* @brief define edu-riscv64-board io configure -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2022-10-17 -*/ + * @file drv_io_config.h + * @brief define edu-riscv64-board io configure + * @version 2.0 + * @author AIIT XUOS Lab + * @date 2022-10-17 + */ /************************************************* File name: drv_io_config.h Description: define edu-riscv64-board io configure Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.h for references https://github.com/RT-Thread/rt-thread/tree/v4.0.2 -History: +History: 1. Date: 2022-10-17 Author: AIIT XUOS Lab Modification: add edu-riscv64-board io configure define @@ -30,10 +30,65 @@ Modification: add edu-riscv64-board io configure define #ifndef __DRV_IO_CONFIG_H__ #define __DRV_IO_CONFIG_H__ -enum HS_GPIO_CONFIG -{ +<<<<<<< HEAD enum HS_GPIO_CONFIG { #ifdef BSP_USING_LCD - LCD_DC_PIN = 0, /* LCD DC PIN */ + LCD_DC_PIN = 0, /* LCD DC PIN */ +#endif +#ifdef BSP_SPI1_USING_SS0 + SPI1_CS0_PIN, +#endif +#ifdef BSP_SPI1_USING_SS1 + SPI1_CS1_PIN, +#endif +#ifdef BSP_SPI1_USING_SS2 + SPI1_CS2_PIN, +#endif +#ifdef BSP_SPI1_USING_SS3 + SPI1_CS3_PIN, +#endif +#ifdef BSP_USING_W5500 + WIZ_RST_PIN, WIZ_INT_PIN, +#endif + GPIO_ALLOC_START /* index of gpio driver start */ +} +; + +#ifdef BSP_USING_CH438 +#define FPIOA_CH438_ALE 12 +#define FPIOA_CH438_NWR 13 +#define FPIOA_CH438_NRD 14 +#define FPIOA_CH438_D0 15 +#define FPIOA_CH438_D1 16 +#define FPIOA_CH438_D2 17 +#define FPIOA_CH438_D3 18 +#define FPIOA_CH438_D4 19 +#define FPIOA_CH438_D5 20 +#define FPIOA_CH438_D6 21 +#define FPIOA_CH438_D7 22 +#define FPIOA_CH438_INT 23 + +#define BSP_CH438_ALE_PIN 24 +#define BSP_CH438_NWR_PIN 25 +#define BSP_CH438_NRD_PIN 26 +#define BSP_CH438_D0_PIN 27 +#define BSP_CH438_D1_PIN 28 +#define BSP_CH438_D2_PIN 29 +#define BSP_CH438_D3_PIN 30 +#define BSP_CH438_D4_PIN 31 +#define BSP_CH438_D5_PIN 32 +#define BSP_CH438_D6_PIN 33 +#define BSP_CH438_D7_PIN 34 +#define BSP_CH438_INT_PIN 35 +#endif + +#ifdef BSP_USING_SOFT_SPI +#define FPIOA_SOFT_SPI_SCK 26 +#define FPIOA_SOFT_SPI_MIOS 25 +#define FPIOA_SOFT_SPI_MSOI 27 +#define FPIOA_SOFT_SPI_NCS 28 +======= enum HS_GPIO_CONFIG { +#ifdef BSP_USING_LCD + LCD_DC_PIN = 0, /* LCD DC PIN */ #endif #ifdef BSP_SPI1_USING_SS0 SPI1_CS0_PIN, @@ -48,41 +103,43 @@ enum HS_GPIO_CONFIG SPI1_CS3_PIN, #endif GPIO_ALLOC_START /* index of gpio driver start */ -}; +} +; #ifdef BSP_USING_CH438 -#define FPIOA_CH438_ALE 12 -#define FPIOA_CH438_NWR 13 -#define FPIOA_CH438_NRD 14 -#define FPIOA_CH438_D0 15 -#define FPIOA_CH438_D1 16 -#define FPIOA_CH438_D2 17 -#define FPIOA_CH438_D3 18 -#define FPIOA_CH438_D4 19 -#define FPIOA_CH438_D5 20 -#define FPIOA_CH438_D6 21 -#define FPIOA_CH438_D7 22 -#define FPIOA_CH438_INT 23 +#define FPIOA_CH438_ALE 12 +#define FPIOA_CH438_NWR 13 +#define FPIOA_CH438_NRD 14 +#define FPIOA_CH438_D0 15 +#define FPIOA_CH438_D1 16 +#define FPIOA_CH438_D2 17 +#define FPIOA_CH438_D3 18 +#define FPIOA_CH438_D4 19 +#define FPIOA_CH438_D5 20 +#define FPIOA_CH438_D6 21 +#define FPIOA_CH438_D7 22 +#define FPIOA_CH438_INT 23 -#define BSP_CH438_ALE_PIN 24 -#define BSP_CH438_NWR_PIN 25 -#define BSP_CH438_NRD_PIN 26 -#define BSP_CH438_D0_PIN 27 -#define BSP_CH438_D1_PIN 28 -#define BSP_CH438_D2_PIN 29 -#define BSP_CH438_D3_PIN 30 -#define BSP_CH438_D4_PIN 31 -#define BSP_CH438_D5_PIN 32 -#define BSP_CH438_D6_PIN 33 -#define BSP_CH438_D7_PIN 34 -#define BSP_CH438_INT_PIN 35 +#define BSP_CH438_ALE_PIN 24 +#define BSP_CH438_NWR_PIN 25 +#define BSP_CH438_NRD_PIN 26 +#define BSP_CH438_D0_PIN 27 +#define BSP_CH438_D1_PIN 28 +#define BSP_CH438_D2_PIN 29 +#define BSP_CH438_D3_PIN 30 +#define BSP_CH438_D4_PIN 31 +#define BSP_CH438_D5_PIN 32 +#define BSP_CH438_D6_PIN 33 +#define BSP_CH438_D7_PIN 34 +#define BSP_CH438_INT_PIN 35 #endif #ifdef BSP_USING_SOFT_SPI -#define FPIOA_SOFT_SPI_SCK 26 -#define FPIOA_SOFT_SPI_MIOS 25 -#define FPIOA_SOFT_SPI_MSOI 27 -#define FPIOA_SOFT_SPI_NCS 28 +#define FPIOA_SOFT_SPI_SCK 26 +#define FPIOA_SOFT_SPI_MIOS 25 +#define FPIOA_SOFT_SPI_MSOI 27 +#define FPIOA_SOFT_SPI_NCS 28 +>>>>>>> upstream/prepare_for_master #define BSP_SOFT_SPI_SCK_PIN 26 #define BSP_SOFT_SPI_MIOS_PIN 25 @@ -108,6 +165,7 @@ enum HS_GPIO_CONFIG #define BSP_485_DIR_PIN 24 #endif -extern int IoConfigInit(void); + extern int + IoConfigInit(void); #endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h new file mode 100755 index 000000000..91e1a7bd9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h @@ -0,0 +1,585 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has + * much similar name and interface. But there is a little bit of difference. + * @details + * Comparison between WIZnet and Berkeley SOCKET APIs + * + * + * + * + * + * + * + * + * + * + * + * + * + *
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating + * a SOCKET but also binding a local port number, and listen() of WIZnet is not + * only listening to connection request from client but also accepting the + * connection request. \n When you program "TCP SERVER" with Berkeley SOCKET + * API, you can use only one listen port. When the listen SOCKET accepts a + * connection request from a client, it keeps listening. After accepting the + * connection request, a new SOCKET is created and the new SOCKET is used in + * communication with the client. \n Following figure shows network flow diagram + * by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as + * many as 8 listen SOCKET with same port number. \n Because there's no accept() + * in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request + * from a client, it is changed in order to communicate with the client. And the + * changed SOCKET is not listening any more and is dedicated for communicating + * with the client. \n If there're many listen SOCKET with same listen port + * number and a client requests a connection, the SOCKET which has the smallest + * SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY \ + 0 ///< Socket is busy on processing the operation. Valid only Non-block IO + ///< Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT \ + (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address + ///< when Sn_MR_TCP +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE \ + (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS \ + (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN \ + (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER \ + (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN \ + (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN \ + (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, + ///< multicast and own packet +#define SF_IGMP_VER2 \ + (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP + ///< version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE \ + (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 +#define SF_BROAD_BLOCK \ + (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast + ///< packet. Valid only in W5500 +#define SF_MULTI_BLOCK \ + (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in + ///< W5500 +#define SF_IPv6_BLOCK \ + (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in + ///< W5500 +#define SF_UNI_BLOCK \ + (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only + ///< in W5500 +#endif + +// A201505 : For W5300 +#if _WIZCHIP_ == 5300 +#define SF_TCP_ALIGN \ + 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN +#endif + +#define SF_IO_NONBLOCK \ + 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST \ + 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When + ///< W5300, This flag can be applied) +#define PACK_REMAINED \ + 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. + ///< (When W5300, This flag can be applied) +#define PACK_COMPLETED \ + 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + ///< (When W5300, This flag can be applied) +// A20150601 : For Integrating with W5300 +#define PACK_FIFOBYTE \ + 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR. +// + +#ifndef AF_WIZ +#define AF_WIZ 46 +#endif + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref + * SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n Valid + * flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref + * SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as + * TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t wiz_sock_close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is + * established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t wiz_sock_listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and + * port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediately. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request + * connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned + * immediately\n + */ +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as + parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. + \n + * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t wiz_sock_disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data + * greater than socket buffer size. \n In block io mode, It doesn't return until + * data send is completed - socket buffer size is greater than data. \n In + * non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is + * not enough. \n + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in + * the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data + * greater than socket buffer size. \n In block io mode, it doesn't return until + * data reception is completed - data is filled as len in socket buffer. + * \n In non-block io mode, it return @ref SOCK_BUSY immediately when len + * is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket + * \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port + * number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP + * address and port number passed as parameter.\n Even if the connectionless + * socket has been previously connected to a specific address, the address and + * port number parameters override the destination address for that particular + * datagram only. + * @note In block io mode, It doesn't return until data send is completed - + * socket buffer size is greater than len. In non-block io mode, It + * return @ref SOCK_BUSY immediately when socket buffer is not enough. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed + * \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to + * receive the data in other then TCP mode. \n This function is used to receive + * UDP and MAC_RAW mode, and handle the header as well. This function can divide + * to received the packet data. On the MACRAW SOCKET, the addr and port + * parameters are ignored. + * @note In block io mode, it doesn't return until data reception is + * completed - data is filled as len in socket buffer In non-block io + * mode, it return @ref SOCK_BUSY immediately when len is greater than + * data size in socket buffer. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet + * sized. When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. It is valid only when the first call recvfrom for + * receiving the packet. When it is valid, @ref packinfo[7] should be set as + * '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the + * packet. When it is valid, @ref packinfo[7] should be set as '1' after call + * @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for + * success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port); + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum { + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + // M20150410 : Remove the comma of last member + // SIK_ALL = 0x1F, ///< all interrupt + SIK_ALL = 0x1F ///< all interrupt +} sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum { + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref + ///< SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind +#if _WIZCHIP_ > 5100 + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, + ///< Not supported in W5100 + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref + ///< sockint_kind, Not supported in W5100 +#endif +} ctlsock_type; + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum { + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to + ///< flag in @ref socket(). + SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref + ///< setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref + ///< setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive + ///< packet in TCP mode, Not supported in W5100 +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP + ///< mode, Not supported in W5100, W5200 +#endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt + ///< TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in + ///< socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, + ///< @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in + ///< other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref + ///< PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in + ///< other then TCP mode. +} sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket + * buffer information. Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. + * \n + *
@b cstype @b data type@b + * value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE + * uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
+ * @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 + * ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n + * @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind + * @ref SIK_CONNECTED, etc.
+ * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref + * sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + *
@b sotype @b data type@b + * value
@ref SO_TTL uint8_t 0 ~ 255 + *
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ + * 65535
@ref SO_KEEPALIVESEND null + * null
@ref SO_KEEPALIVEAUTO uint8_t + * 0 ~ 255
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet + * \n + */ +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref + * sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + *
@b sotype @b data type@b + * value
@ref SO_FLAG uint8_t @ref + * SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t + * 0 ~ 255
@ref SO_MSS uint16_t + * 0 ~ 65535
@ref SO_DESTIP + * uint8_t[4]
@ref SO_DESTPORT + * uint16_t
@ref SO_KEEPALIVEAUTO + * uint8_t 0 ~ 255
@ref SO_SENDBUF + * uint16_t 0 ~ 65535
@ref SO_RECVBUF + * uint16_t 0 ~ 65535
@ref SO_STATUS + * uint8_t @ref SOCK_ESTABLISHED, etc..
@ref + * SO_REMAINSIZE uint16_t 0~ 65535
+ * @ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc... + *
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode + * and after call @ref recvfrom(). \n When SO_PACKINFO value is PACK_FIRST and + * the return value of recvfrom() is zero, This means the zero byte UDP data(UDP + * Header only) received. + */ +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif // _SOCKET_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h new file mode 100755 index 000000000..121baab06 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h @@ -0,0 +1,2321 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +// + +#ifndef _W5500_H_ +#define _W5500_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" +#include + + +/// @cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5500) +/// @endcond + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ \ + (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ \ + (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1 + 4 * N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2 + 4 * N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3 + 4 * N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) \ + (ADDR + (N << 8)) //< Increase offset address + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) \ + WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR, VAL) \ + WIZCHIP_WRITE(ADDR, VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR, BUF, LEN) \ + WIZCHIP_READ_BUF(ADDR, BUF, LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR, BUF, LEN) \ + WIZCHIP_WRITE(ADDR, BUF, LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref + * Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref + * Common_register_access_function and @ref Socket_register_access_function + */ + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), + * setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), + * setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), + * getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), + * setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), + * getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() getSn_MSSR(), + * setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), + * setSn_TXBUF_SIZE() \n getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data + * communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, + * Sn_RX_RD, Sn_RX_WR : Data communication + */ + +/** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or + * write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end +//-------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP +//----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + * + * + *
7 6 5 4 32 1 0
RST ReservedWOL PB PPPoE Reserved FARPReserved
+ * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be + * still until the bit will be written to by the host. If @ref IR is not equal + * to x00 INTn PIN is asserted to low until it is x00\n\n Each bit of @ref IR + * defined as follows. + * + * + * + *
7 6 5 43 2 1 0
CONFLICTUNREACH PPPoE MP ReservedReserved Reserved Reserved
+ * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ + * corresponds to each bit of @ref IR. When a bit of @ref _IMR_ is and the + * corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref _IMR_ is an interrupt will not be issued even if the + * corresponding bit of @ref IR is \n\n Each bit of @ref _IMR_ defined as the + * following. + * + * + * + *
7 6 5 43 2 1 0
IM_IR7IM_IR6 IM_IR5 IM_IR4 ReservedReserved Reserved Reserved
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is + * asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt + * will be issued. In other words, if a bit of @ref SIMR is an interrupt will + * be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref _RTR_ configures the retransmission timeout period. The unit of + * timeout period is 100us and the default of @ref _RTR_ is x07D0. And so the + * default timeout period is 200ms(100us X 2000). During the time configured by + * @ref _RTR_, W5500 waits for the peer response to the packet that is + * transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP + * command). If the peer does not respond within the @ref _RTR_ time, W5500 + * retransmits the packet or issues timeout. + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued + * (@ref Sn_IR_TIMEOUT = '1'). + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The + * unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP + * negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is + * acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during + * PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In + * addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, + * Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +//----------------------------- W5500 Socket Registers IOMAP +//----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + * + * + *
7 6 5 4 32 1 0
MULTI/MFENBCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3]Protocol[2] Protocol[1] Protocol[0]
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + * + * + *
Protocol[3] Protocol[2]Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0MACRAW
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) \ + (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, + * CONNECT, LISTEN, SEND, and RECEIVE.\n After W5500 accepts the command, the + * @ref Sn_CR register is automatically cleared to 0x00. Even though @ref Sn_CR + * is cleared to 0x00, the command is still being processed.\n To check whether + * the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server + * mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client + * mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP + * process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) \ + (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as + * establishment, termination, receiving data, timeout).\n When an interrupt + * occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes \n In order to clear the @ref Sn_IR bit, the host should + * write the bit to \n + * + * + * + *
7 6 5 43 2 1 0
ReservedReserved Reserved SEND_OK TIMEOUTRECV DISCON CON
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) \ + (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control + *packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the + *connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received + *the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) \ + (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before + * OPEN command is ordered. + */ +#define Sn_PORT(N) \ + (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n + * when using SEND_MAC command in UDP mode or it indicates that it is acquired + * in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) \ + (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP client + * mode, it configures an IP address of TCP serverbefore CONNECT command. In TCP + * server mode, it indicates an IP address of TCP clientafter successfully + * establishing connection. In UDP mode, it configures an IP address of peer to + * be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) \ + (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP + * clientmode, it configures the listen port number of TCP serverbefore CONNECT + * command. In TCP Servermode, it indicates the port number of TCP client after + * successfully establishing connection. In UDP mode, it configures the port + * number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) \ + (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) + * of Socket n. + */ +#define Sn_MSSR(N) \ + (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) + * of Socket n. It is set before OPEN command. + */ +#define Sn_TOS(N) \ + (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of + * Socket n. It is set before OPEN command. + */ +#define Sn_TTL(N) \ + (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from + * a peer. Although Socket n RX Buffer Block size is initially configured to + * 2Kbytes, user can re-configure its size using @ref Sn_RXBUF_SIZE. The total + * sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. When exceeded, the data + * reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. + * Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to + * a peer. Although Socket n TX Buffer Block size is initially configured to + * 2Kbytes, user can be re-configure its size using @ref Sn_TXBUF_SIZE. The + * total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. When exceeded, + * the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. + * It is initialized to the configured size by @ref Sn_TXBUF_SIZE. Data bigger + * than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the + * bigger data overwrites the previous saved data not yet sent. Therefore, check + * before saving the data to the Socket n TX Buffer, and if data is equal or + * smaller than its checked size, transmit the data with SEND/SEND_MAC command + * after saving the data in Socket n TX buffer. But, if data is bigger than its + * checked size, transmit the data after dividing into the checked size and + * saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) \ + (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP. After its initialization, it is auto-increased by SEND command. SEND + * command transmits the saved data from the current @ref Sn_TX_RD to the @ref + * Sn_TX_WR in the Socket n TX Buffer. After transmitting the saved data, the + * SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. If its + * increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and + * the carry bit occurs), then the carry bit is ignored and will automatically + * update with the lower 16bits value. + */ +#define Sn_TX_RD(N) \ + (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP.\n It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX + * buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased + * value as many as transmitting data size. If the increment value exceeds the + * maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), then the + * carry bit is ignored and will automatically update with the lower 16bits + * value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) \ + (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket + * n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as + * the difference between �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket + * n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) \ + (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read + * or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased + * value as many as the reading size. If the increment value exceeds the maximum + * value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) \ + (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is + * auto-increased by the data reception. If the increased value exceeds the + * maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), then + * the carry bit is ignored and will automatically update with the lower 16bits + * value. + */ +#define Sn_RX_WR(N) \ + (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is + * occurred and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref + * Sn_IR are and the n-th bit of @ref IR is Host is interrupted by asserted INTn + * PIN to low. + */ +#define Sn_IMR(N) \ + (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) \ + (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP + * ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, and ignored in + * other modes. The time unit is 5s. KA packet is transmittable after @ref Sn_SR + * is changed to SOCK_ESTABLISHED and after the data is transmitted or received + * to/from a peer at least once. In case of '@ref Sn_KPALVTR > 0', W5500 + * automatically transmits KA packet after time-period for checking the TCP + * connection (Auto-keepalive-process). In case of '@ref Sn_KPALVTR = 0', + * Auto-keep-alive-process will not operate, and KA packet can be transmitted by + * SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) \ + (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + +//(WIZCHIP_SREG_BLOCK(N) << 3)) + +//----------------------------- W5500 Register values +//----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will + * be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been + * normally processed, the Interrupt PIN (INTn) asserts to low. When using WOL + * mode, the UDP Socket should be opened with any source port number. (Refer to + * Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes + * synchronization stream (xFFFFFFFFFFFF and 16 times Target MAC address stream + * in UDP payload. The options such like password are ignored. You can use any + * UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP + * address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this + * bit is set as When this bit is Destination Information such as IP address + * and Port number may be checked with the corresponding @ref UIPR & @ref + * UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, + * this bit is set. + */ +#define IR_MP 0x10 + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1 << 7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1 << 6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7 << 3) +#define PHYCFGR_OPMDC_PDOWN (6 << 3) +#define PHYCFGR_OPMDC_NA (5 << 3) +#define PHYCFGR_OPMDC_100FA (4 << 3) +#define PHYCFGR_OPMDC_100F (3 << 3) +#define PHYCFGR_OPMDC_100H (2 << 3) +#define PHYCFGR_OPMDC_10F (1 << 3) +#define PHYCFGR_OPMDC_10H (0 << 3) +#define PHYCFGR_DPX_FULL (1 << 2) +#define PHYCFGR_DPX_HALF (0 << 2) +#define PHYCFGR_SPD_100 (1 << 1) +#define PHYCFGR_SPD_10 (0 << 1) +#define PHYCFGR_LNK_ON (1 << 0) +#define PHYCFGR_LNK_OFF (0 << 0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively + * configured with the multicast group IP address & port number before Socket n + * is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = + * 010.\m In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data + * packet is received from a peer.\n When this bit is It sends the ACK packet + * after waiting for the timeout time configured by @ref _RTR_. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and + * MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to + * itself. When this bit is W5500 can receive all packets on Ethernet. If user + * wants to implement Hybrid TCP/IP stack, it is recommended that this bit is + * set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to + * receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive + * the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol + * selected in Sn_MR(P3:P0). The table below shows the value of @ref Sn_SR + * corresponding to @ref Sn_MR.\n + * + * + * + * + *
\b Sn_MR (P[3:0])\b Sn_SR
Sn_MR_CLOSE + * (000)
Sn_MR_TCP (001) SOCK_INIT (0x13)
Sn_MR_UDP (010) SOCK_UDP (0x22)
S0_MR_MACRAW (100) SOCK_MACRAW (0x02)
+ */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP). + * In this mode, Socket n operates as a TCP serverand waits for + * connection-request (SYN packet) from any TCP client The @ref Sn_SR changes + * the state from \ref SOCK_INIT to \ref SOCKET_LISTEN. When a TCP + * clientconnection request is successfully established, the @ref Sn_SR changes + * from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes But when a + * TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status + * of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP + * serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref + * SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n The connect-request fails in + * the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware + * address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these + * cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as + * TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON + * command processes the disconnect-process (b>Active closeor Passive + * close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the + * peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet + * is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to + * @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref + * Sn_TX_FSR), Socket n, TX Write Pointer Register(@ref Sn_TX_WR), and Socket n + * TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired + * by the automatic ARP-process(Address Resolution Protocol).\n But SEND_MAC + * transmits data without the automatic ARP-process.\n In this case, the + * destination hardware address is acquired from @ref Sn_DHAR configured by + * host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive + * packet.\n If the peer can not respond to the keep-alive packet during timeout + * time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX + * Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n For more + * details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket + * n RX Write Pointer Register (@ref Sn_RX_WR), and Socket n RX Read Pointer + * Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful + * and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed + * to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN + * command is ordered.\n After @ref SOCK_INIT, user can use LISTEN /CONNECT + * command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and + * waiting for connection-request (SYN packet) from a peer TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is + * successfully accepted.\n Otherwise it will change to @ref SOCK_CLOSED after + * TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred. + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) + * to a peer.\n It is temporarily shown when @ref Sn_SR is changed from @ref + * SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n If + * connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it + * changes to @ref SOCK_ESTABLISHED.\n Otherwise, it changes to @ref SOCK_CLOSED + * after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request + * packet (SYN packet) from a peer.\n If socket n sends the response (SYN/ACK + * packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n If + * not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') + * is occurred. + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the + * SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or when the + * CONNECT command is successful.\n During @ref SOCK_ESTABLISHED, DATA packet + * can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) + * from the connected peer.\n This is half-closing status, and data can be + * transferred.\n For full-closing, DISCON command is used. But For + * just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) + * to the disconnect-request (FIN packet) by passive-close.\n It changes to @ref + * SOCK_CLOSED when Socket n received the response successfully, or when + * timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = + * '010').\n It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref + * Sn_CR_OPEN command is ordered.\n Unlike TCP mode, data can be transfered + * without the connection-process. + */ +#define SOCK_UDP 0x22 + +#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = + * 100and is valid only in Socket 0.\n It changes to SOCK_MACRAW when + * S0_MR(P[3:0] = 100and OPEN command is ordered.\n Like UDP mode socket, MACRAW + * mode Socket 0 can transfer a MAC packet (Ethernet frame) without the + * connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt.\n In OS environment, You can replace it to critical section api + * supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt. \n In OS environment, You can replace it to critical section api + * supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ(uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) WIZCHIP_WRITE(MR, mr) + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be + * allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) WIZCHIP_WRITE_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be + * allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) WIZCHIP_READ_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should + * be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) WIZCHIP_WRITE_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should + * be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be + * allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be + * allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be + * allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be + * allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) \ + { \ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL, 1), (uint8_t)intlevel); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +// M20150401 : Type explict declaration +/* +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) +*/ +#define getINTLEVEL() \ + (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) \ + { \ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_, 1), (uint8_t)rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +// M20150401 : Type explict declaration +/* +#define getRTR() \ + ((WIZCHIP_READ(_RTR_) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) +*/ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() WIZCHIP_READ(_RCR_) + +//================================================== test done +//=========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHAR address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) \ + { \ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID, 1), (uint8_t)psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +// uint16_t getPSID(void); +// M20150401 : Type explict declaration +/* +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) +*/ +#define getPSID() \ + (((uint16_t)WIZCHIP_READ(PSID) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) \ + { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU, 1), (uint8_t)pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +// M20150401 : Type explict declaration +/* +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) +*/ +#define getPMRU() \ + (((uint16_t)WIZCHIP_READ(PMRU) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It + * should be allocated 4 bytes. + */ +// M20150401 : Size Error of UIPR (6 -> 4) +/* +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) +*/ +#define getUIPR(uipr) WIZCHIP_READ_BUF(UIPR, uipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +// M20150401 : Type explict declaration +/* +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) +*/ +#define getUPORTR() \ + (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) WIZCHIP_WRITE(Sn_MR(sn), mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) \ + { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1), (uint8_t)port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) +*/ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP + * address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP + * address. It should be allocated 4 bytes. + * @sa setSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) \ + { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t)(dport >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1), (uint8_t)dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) +*/ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) \ + { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1), (uint8_t)mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) +*/ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn), rxbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) +*/ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) \ + { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1), (uint8_t)txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) +*/ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) \ + { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1), (uint8_t)rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) +*/ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) +*/ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) \ + { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1), (uint8_t)frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +// M20150401 : Type explict declaration +/* +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) +*/ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) +*/ +#define getSn_RxMAX(sn) (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10) + +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) +*/ +#define getSn_TxMAX(sn) (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of + * len(variable) bytes to internal TX memory and updates the Tx write + * pointer register. This function is being called by send() and sendto() + * function also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) + * bytes. This function is being called by recv() also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in + * internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif // _W5500_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h new file mode 100755 index 000000000..a58da3a19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h @@ -0,0 +1,704 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP + * I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, + * network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b + * W5500 or etc. \n\n ex> #define \_WIZCHIP_ W5500 + */ + +#define W5100 5100 +#define W5100S 5100 + 5 +#define W5200 5200 +#define W5300 5300 +#define W5500 5500 + +#ifndef _WIZCHIP_ +#define _WIZCHIP_ W5500 // W5100, W5100S, W5200, W5300, W5500 +#endif + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length \ \ \ + data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 2) /**< SPI interface mode for fixed length data mode*/ +#define _WIZCHIP_IO_MODE_SPI_5500_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 3) /**< SPI interface mode for fixed length data mode*/ + +#if (_WIZCHIP_ == W5100) +#define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100/w5100.h" + +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_ID_ "W5100S\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_5500_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100S/w5100s.h" +#elif (_WIZCHIP_ == W5200) +#define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ or @ref \ _WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "W5200/w5200.h" +#elif (_WIZCHIP_ == W5500) +#define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + * + * + */ +#ifndef _WIZCHIP_IO_MODE_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "w5500.h" +#elif (_WIZCHIP_ == W5300) +#define _WIZCHIP_ID_ "W5300\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#endif + +// A20150601 : Define the unit and bus width of IO DATA. +/** + * @brief Select the data width 8 or 16 bits. + * @todo you should select the bus width. Select one of 8 or 16. + */ +#ifndef _WIZCHIP_IO_BUS_WIDTH_ +#define _WIZCHIP_IO_BUS_WIDTH_ 16 // 8 +#endif +#if _WIZCHIP_IO_BUS_WIDTH_ == 8 +typedef uint8_t iodata_t; +#elif _WIZCHIP_IO_BUS_WIDTH_ == 16 +typedef uint16_t iodata_t; +#else +#error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16." +#endif +// +#include "W5300/w5300.h" +#else +#error \ + "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ +#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref + * \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). + * \n\n ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 + */ +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +// #define _WIZCHIP_IO_BASE_ 0x60000000 +//// for 5100S IND +#define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 +#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // for 5100S SPI +#endif + +#ifndef _WIZCHIP_IO_BASE_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000 +#endif + +// M20150401 : Typing Error +//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +#ifndef _WIZCHIP_IO_BASE_ +#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." +#endif +#endif + +#if _WIZCHIP_ >= W5200 +#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else +#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + +/******************************************************** + * WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. + *********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions + * W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP { + uint16_t if_mode; ///< host interface mode + uint8_t id[8]; ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b + ///< 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS { + void (*_enter)(void); ///< crtical section enter + void (*_exit)(void); ///< critial section exit + } CRIS; + /** + * The set of @ref \_WIZCHIP_ select control callback func. + */ + struct _CS { + void (*_select)(void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + } CS; + /** + * The set of interface IO callback func. + */ + union _IF { + /** + * For BUS interface IO + */ + // M20156501 : Modify the function name for integrating with W5300 + // struct + //{ + // uint8_t (*_read_byte) (uint32_t AddrSel); + // void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + //}BUS; + struct { + iodata_t (*_read_data)(uint32_t AddrSel); + void (*_write_data)(uint32_t AddrSel, iodata_t wb); + } BUS; + + /** + * For SPI interface IO + */ + struct { + uint8_t (*_read_byte)(void); + void (*_write_byte)(uint8_t wb); + void (*_read_burst)(uint8_t *pBuf, uint16_t len); + void (*_write_burst)(uint8_t *pBuf, uint16_t len); + } SPI; + // To be added + // + } IF; +} _WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum { + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 + ///< dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500 + CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation + ///< mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only + ///< W5500 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when + ///< PHYSTATUS.OPMD == 1. Valid Only W5500 + //#endif + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only + ///< W5100, W5200 + CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200 + //#endif +} ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum { + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +} ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum { +#if _WIZCHIP_ == W5500 + IK_WOL = + (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#elif _WIZCHIP_ == W5300 + IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU) +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != W5200 + IK_DEST_UNREACH = + (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > W5100S + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > W5100S + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt +#endif +} intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO \ + 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in + * W5500, and it indicates the real PHY status configured by HW or SW in all + * WIZCHIP. \n Valid only in W5500. + */ +typedef struct wiz_PhyConf_t { + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + // uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + // uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref + // PHY_LINK_ON or PHY_DUPLEX_OFF +} wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum { + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +} dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t { + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +} wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum { +#if _WIZCHIP_ == W5500 + NM_FORCEARP = (1 << 1), ///< Force to APP send whenever udp data is sent. + ///< Valid only in W5500 +#endif + NM_WAKEONLAN = (1 << 5), ///< Wake On Lan + NM_PINGBLOCK = (1 << 4), ///< Block ping-request + NM_PPPOE = (1 << 3), ///< PPPoE mode +} netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout + * configruation. + */ +typedef struct wiz_NetTimeout_t { + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +} wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such + *as \ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref + *WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT + *marco or register your functions. + *@note If you do not describe or register, default functions(@ref + *wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)); + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or + *register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +// M20150601 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)); +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte using SPI + *@param spi_wb : callback function to write byte using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to burst read using SPI + *@param spi_wb : callback function to burst write using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor + * PHY(Link,Speed,Half/Full/Auto), controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref + * ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref + * ctlnetwork_type in WIZCHIP \n 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg); + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of + * ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size + * 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size + * 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to + * uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +// todo +#if _WIZCHIP_ > W5100 +int8_t wizphy_getphylink( + void); ///< get the link status of phy in WIZCHIP. No use in W5100 +int8_t wizphy_getphypmode( + void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 + /** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_setphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphystat(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in + * W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ +int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** + * @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout *nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout *nettime); +#ifdef __cplusplus +} +#endif + +#endif // _WIZCHIP_CONF_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c index 42ee200ce..44d11dd3a 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c @@ -14,49 +14,54 @@ */ /** -* @file board.c -* @brief support kd233-board init configure and start-up -* @version 1.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file board.c + * @brief support kd233-board init configure and start-up + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: board.c -Description: support xidatong-riscv64-board init configure and driver/task/... init -Others: https://canaan-creative.com/developer -History: +Description: support xidatong-riscv64-board init configure and driver/task/... +init Others: https://canaan-creative.com/developer History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab -Modification: +Modification: 1. support xidatong-riscv64-board InitBoardHardware 2. support xidatong-riscv64-board Kd233Start 3. support xidatong-riscv64-board shell cmd, include reboot, shutdown *************************************************/ -#include +#include "board.h" + #include #include -#include "board.h" -#include "tick.h" +#include + +#include "connect_gpio.h" +#include "connect_spi.h" #include "connect_uart.h" +#include "connect_w5500.h" +#include "dmac.h" #include "encoding.h" #include "fpioa.h" -#include "dmac.h" -#include "connect_gpio.h" +#include "tick.h" #if defined(FS_VFS) #include #endif -#define CPU0 (0) -#define CPU1 (1) +#define CPU0 (0) +#define CPU1 (1) extern x_base cpu2_boot_flag; extern void entry(void); extern void SecondaryCpuCStart(void); extern int IoConfigInit(void); extern int HwI2cInit(void); extern int HwTouchInit(void); +extern int HwSpiInit(void); +extern int HwWiznetInit(void); extern int HwCh438Init(void); extern int HwCh376Init(void); extern int HwTimerInit(void); @@ -70,14 +75,14 @@ extern int HwWdtInit(void); * @description: Mount USB * @return 0 */ -int MountUsb(void) -{ - if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0) - KPrintf("usb mount to '/'\n"); - else - KPrintf("usb mount to '/' failed!\n"); - - return 0; +int MountUsb(void) { + if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, + FSTYPE_CH376, "/") == 0) + KPrintf("usb mount to '/'\n"); + else + KPrintf("usb mount to '/' failed!\n"); + + return 0; } #endif #ifdef MOUNT_SDCARD @@ -86,168 +91,183 @@ int MountUsb(void) * @return 0 */ -int MountSDCard(void) -{ - if (MountFilesystem(SDIO_BUS_NAME,SDIO_DEVICE_NAME ,SDIO_DRIVER_NAME , FSTYPE_CH376, "/") == 0) - KPrintf("sd card mount to '/'\n"); - else - KPrintf("sd card mount to '/' failed!\n"); - - return 0; +int MountSDCard(void) { + if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, + FSTYPE_CH376, "/") == 0) + KPrintf("sd card mount to '/'\n"); + else + KPrintf("sd card mount to '/' failed!\n"); + + return 0; +} + +if (EOK == MountFilesystem(SPI_BUS_NAME_1, SPI_SD_NAME, SPI_1_DRV_NAME, + FSTYPE_FATFS, "/")) + KPrintf("SPI SD card fatfs mounted\n"); + +return 0; } #endif #endif -void InitBss(void) -{ - unsigned int *dst; +void InitBss(void) { + unsigned int *dst; - dst = &__bss_start; - while (dst < &__bss_end){ - *dst++ = 0; - } + dst = &__bss_start; + while (dst < &__bss_end) { + *dst++ = 0; + } } -void Kd233Start(uint32_t mhartid) -{ - switch(mhartid) { - case CPU0: - InitBss(); +void Kd233Start(uint32_t mhartid) { + switch (mhartid) { + case CPU0: + InitBss(); - /*kernel start entry*/ - entry(); - break; - case CPU1: - while(0x2018050420191010 != cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core + /*kernel start entry*/ + entry(); + break; + case CPU1: + while (0x2018050420191010 != + cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core #ifndef ARCH_SMP - asm volatile("wfi"); + asm volatile("wfi"); #endif - } + } #ifdef ARCH_SMP - SecondaryCpuCStart(); + SecondaryCpuCStart(); #endif - break; + break; - default: - break; - } + default: + break; + } } -int Freq(void) -{ - uint64 value = 0; +int Freq(void) { + uint64 value = 0; - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); - KPrintf("PLL0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); - KPrintf("PLL1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); - KPrintf("PLL2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); - KPrintf("CPU : %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); - KPrintf("APB0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); - KPrintf("APB1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); - KPrintf("APB2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); - KPrintf("HCLK: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); + KPrintf("PLL0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); + KPrintf("PLL1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); + KPrintf("PLL2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + KPrintf("CPU : %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + KPrintf("APB0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + KPrintf("APB1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); + KPrintf("APB2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); + KPrintf("HCLK: %d\n", value); - value = clint_get_time(); - KPrintf("mtime: %d\n", value); + value = clint_get_time(); + KPrintf("mtime: %d\n", value); - return 0; + return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Freq, Freq, show frequency information ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Freq, Freq, show frequency information); #ifdef ARCH_SMP extern int EnableHwclintIpi(void); #endif -struct InitSequenceDesc _board_init[] = -{ +struct InitSequenceDesc _board_init[] = { #ifdef BSP_USING_GPIO - { "hw_pin", HwGpioInit }, - { "io_config", IoConfigInit }, + {"hw_pin", HwGpioInit}, + {"io_config", IoConfigInit}, #endif #ifdef BSP_USING_CH438 - { "hw_extuart", HwCh438Init }, + {"hw_extuart", HwCh438Init}, #endif #ifdef BSP_USING_I2C - { "hw_i2c", HwI2cInit }, + {"hw_i2c", HwI2cInit}, #endif #ifdef BSP_USING_RTC - { "hw_rtc", HwRtcInit }, + {"hw_rtc", HwRtcInit}, #endif #ifdef BSP_USING_HWTIMER - { "hw_timer" , HwTimerInit }, + {"hw_timer", HwTimerInit}, #endif #ifdef BSP_USING_WDT - { "hw_wdt", HwWdtInit }, + {"hw_wdt", HwWdtInit}, #endif #ifdef BSP_USING_SDIO - { "hw_sdio", HwCh376Init}, + {"hw_sdio", HwCh376Init}, #endif #ifdef BSP_USING_USB - { "hw_usb", HwCh376Init}, + {"hw_usb", HwCh376Init}, #endif #ifdef BSP_USING_TOUCH - {"touch", HwTouchInit }, + {"touch", HwTouchInit}, #endif - { " NONE ",NONE }, +#ifdef BSP_USING_SPI + {"spi", HwSpiInit}, +#endif +#ifdef BSP_USING_WIZCHIP + {"w5500", HwWiznetInit}, +#endif + {" NONE ", NONE}, }; -void InitBoardHardware(void) -{ - int i = 0; - int ret = 0; - - SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); - SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); +void InitBoardHardware(void) { + int i = 0; + int ret = 0; + + SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); + SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); #ifdef BSP_USING_GPIO - /* Init FPIOA */ - FpioaInit(); + /* Init FPIOA */ + FpioaInit(); #endif #ifdef BSP_USING_DMA - /* Dmac init */ - DmacInit(); + /* Dmac init */ + DmacInit(); #endif - /* initalize interrupt */ - InitHwinterrupt(); -#ifdef BSP_USING_UART - HwUartInit(); + /* initalize interrupt */ + InitHwinterrupt(); +#ifdef BSP_USING_UART + HwUartInit(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); #ifdef KERNEL_CONSOLE - /* set console device */ - InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); - KPrintf("\nconsole init completed.\n"); - KPrintf("board initialization......\n"); + /* set console device */ + InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, + KERNEL_CONSOLE_DEVICE_NAME); + KPrintf("\nconsole init completed.\n"); + KPrintf("board initialization......\n"); #endif /* KERNEL_CONSOLE */ - InitHwTick(); + InitHwTick(); #ifdef ARCH_SMP - EnableHwclintIpi(); + EnableHwclintIpi(); #endif #ifdef KERNEL_COMPONENTS_INIT - for(i = 0; _board_init[i].fn != NONE; i++) { - ret = _board_init[i].fn(); - KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed"); - } + for (i = 0; _board_init[i].fn != NONE; i++) { + ret = _board_init[i].fn(); + KPrintf("initialize %s %s\n", _board_init[i].fn_name, + ret == 0 ? "success" : "failed"); + } #endif - KPrintf("board init done.\n"); - KPrintf("start kernel...\n"); + KPrintf("board init done.\n"); + KPrintf("start kernel...\n"); } -void HwCpuReset(void) -{ - sysctl->soft_reset.soft_reset = 1; - while(RET_TRUE); +void HwCpuReset(void) { + sysctl->soft_reset.soft_reset = 1; + while (RET_TRUE) + ; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Reboot, HwCpuReset, reset machine ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Reboot, HwCpuReset, reset machine); diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig index 812afe099..59caa4164 100755 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig @@ -29,6 +29,22 @@ if BSP_USING_GPIO source "$BSP_DIR/third_party_driver/gpio/Kconfig" endif +menuconfig BSP_USING_SPI +bool "Using SPI device" +default n +select RESOURCES_SPI +if BSP_USING_SPI +source "$BSP_DIR/third_party_driver/spi/Kconfig" +endif + +menuconfig BSP_USING_WIZCHIP +bool "Using w5500 as network device" +default n +select RESOURCES_WIZCHIP +if BSP_USING_WIZCHIP +source "$BSP_DIR/third_party_driver/ethernet/Kconfig" +endif + menuconfig BSP_USING_I2C bool "Using I2C device" default n diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile index acb338501..bbd1cccd8 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile @@ -20,6 +20,14 @@ ifeq ($(CONFIG_BSP_USING_I2C),y) SRC_DIR += i2c endif +ifeq ($(CONFIG_BSP_USING_SPI),y) + SRC_DIR += spi +endif + +ifeq ($(CONFIG_BSP_USING_WIZCHIP),y) + SRC_DIR += ethernet +endif + ifeq ($(CONFIG_BSP_USING_TOUCH),y) SRC_DIR += touch endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Kconfig new file mode 100644 index 000000000..baf59367c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Kconfig @@ -0,0 +1,15 @@ +# Kconfig file + +config BSP_USING_W5500 +bool "Using w5500 " +default y + +# if BSP_USING_W5500 + config BSP_WIZ_RST_PIN + int + default 13 + + config BSP_WIZ_INT_PIN + int + default 14 +# endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Makefile new file mode 100644 index 000000000..1ea20caac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/ReadMe.md b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/ReadMe.md new file mode 100644 index 000000000..947404f4a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/ReadMe.md @@ -0,0 +1,25 @@ +## w5500 测试文档 + +通过board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c 可以找到内写的3个,包含ping, tcp server test, tcp client test; + + - ping 测试,测试结果包括: + - pc ping w5500 + - w5500 ping baidu.com (DNS实现暂未实现,因此使用baidu.com的ip地址进行寻址) + + + + + +- tcp server 测试:在xizi中调用wiz_server_op,指定port,之后可以在pc中向该端口发送数据 + - wiz_server 将额外启动一个线程执行server工作,server将向client返回client发来的消息 + + + + + +- client 测试:通过wiz_client_op可以向pc中打开的tcp server发送消息 + - 由于wiz_client_test函数参数接收问题,测试使用的ip地址暂时使用硬编码实现 + + + + \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c new file mode 100644 index 000000000..22803ee9e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -0,0 +1,505 @@ + +#include "connect_w5500.h" + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" +#include "socket.h" +#include "w5500.h" + +#define SPI_LORA_FREQUENCY 10000000 + +// spi operations +extern void spi_enter_cris(void); +extern void spi_exit_cris(void); +extern void spi_select_cs(void); +extern void spi_deselete_cs(void); + +// global configurations for w5500 tcp connection +const uint32_t socket_tcp = 0; +const uint32_t g_wiznet_buf_size = 2048; + +static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, + .ip = {192, 168, 31, 13}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 31, 1}, + .dns = {0, 0, 0, 0}, + .dhcp = NETINFO_STATIC}; + +int network_init() { + wiz_NetInfo check_wiz_netinfo; + check_wiz_netinfo.dhcp = NETINFO_STATIC; + ctlnetwork(CN_SET_NETINFO, (void *)&g_wiz_netinfo); + ctlnetwork(CN_GET_NETINFO, (void *)&check_wiz_netinfo); + + if (memcmp(&g_wiz_netinfo, &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { + KPrintf( + "mac: %d; ip: %d; gw: %d; sn: %d; dns: %d; dhcp: %d;\n", + memcmp(&g_wiz_netinfo.mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), + memcmp(&g_wiz_netinfo.ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); + KPrintf("WIZCHIP set network information fail.\n"); + return ERROR; + } + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", g_wiz_netinfo.mac[0], + g_wiz_netinfo.mac[1], g_wiz_netinfo.mac[2], g_wiz_netinfo.mac[3], + g_wiz_netinfo.mac[4], g_wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", g_wiz_netinfo.ip[0], g_wiz_netinfo.ip[1], + g_wiz_netinfo.ip[2], g_wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", g_wiz_netinfo.gw[0], g_wiz_netinfo.gw[1], + g_wiz_netinfo.gw[2], g_wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", g_wiz_netinfo.sn[0], g_wiz_netinfo.sn[1], + g_wiz_netinfo.sn[2], g_wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", g_wiz_netinfo.dns[0], g_wiz_netinfo.dns[1], + g_wiz_netinfo.dns[2], g_wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); + + return EOK; +} + +/****************** spi init ******************/ +static struct Bus *w5500_spi_bus; +int w5500_spi_init() { + x_err_t ret = EOK; + + w5500_spi_bus = BusFind(SPI_BUS_NAME_1); + w5500_spi_bus->owner_haldev = + BusFindDevice(w5500_spi_bus, SPI_1_DEVICE_NAME_0); + w5500_spi_bus->owner_driver = BusFindDriver(w5500_spi_bus, SPI_1_DRV_NAME); + + w5500_spi_bus->match(w5500_spi_bus->owner_driver, + w5500_spi_bus->owner_haldev); + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + spi_master_param.spi_maxfrequency = SPI_LORA_FREQUENCY; + spi_master_param.spi_data_endian = 0; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", + w5500_spi_bus->owner_driver, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", w5500_spi_bus->owner_driver); + return ERROR; + } + + return EOK; +} + +void spi_write_byte(uint8_t tx_data) { + struct BusBlockWriteParam write_param; + write_param.buffer = &tx_data; + write_param.size = 1; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +uint8_t spi_read_byte(void) { + uint8_t result = 0; + struct BusBlockReadParam read_param; + read_param.buffer = &result; + read_param.size = 1; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); + return result; +} +void spi_write_burst(uint8_t *tx_buf, uint16_t len) { + struct BusBlockWriteParam write_param; + write_param.buffer = tx_buf; + write_param.size = len; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +void spi_read_burst(uint8_t *rx_buf, uint16_t len) { + struct BusBlockReadParam read_param; + read_param.buffer = rx_buf; + read_param.size = len; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); +} + +/****************** chip init ******************/ + +void wiz_reset() { + gpiohs_set_drive_mode(WIZ_RST_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_LOW); + MdelayKTask(20); + + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_HIGH); + MdelayKTask(20); +} + +void wiz_spi_handler_reg() { + // spi ops registration +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_) || \ + (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_) + /* register SPI device CS select callback function */ + gpiohs_set_drive_mode(SPI1_CS0_PIN, GPIO_DM_OUTPUT); + reg_wizchip_cs_cbfunc(spi_select_cs, spi_deselete_cs); +#else +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_ +#error "Unknown _WIZCHIP_IO_MODE_" +#else + reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); +#endif +#endif + + reg_wizchip_spi_cbfunc(spi_read_byte, spi_write_byte); + reg_wizchip_cris_cbfunc(spi_enter_cris, spi_exit_cris); + reg_wizchip_spiburst_cbfunc(spi_read_burst, spi_write_burst); +} + +int wiz_chip_cfg_init() { + uint8_t mem_size[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; + + /* reset WIZnet chip internal PHY, configures PHY mode. */ + if (ctlwizchip(CW_INIT_WIZCHIP, (void *)mem_size) == -1) { + KPrintf("WIZCHIP initialize failed."); + return ERROR; + } + + struct wiz_NetTimeout_t net_timeout; + net_timeout.retry_cnt = 5; + net_timeout.time_100us = 20000; + ctlnetwork(CN_SET_TIMEOUT, (void *)&net_timeout); + + return EOK; +} + +/****************** interrupt handle ******************/ +void wiz_irq_handler() {} + +int wiz_interrupt_init() { + int32_t ret = -ERROR; + + struct Bus *pin_bus = PinBusInitGet(); + + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void *)&pin_param; + + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.mode = GPIO_CFG_INPUT_PULLUP; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("config pin_param %d input failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_REGISTER; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_FALLING; + pin_param.irq_set.hdr = wiz_irq_handler; + pin_param.irq_set.args = NONE; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + // 4. enable interuption + pin_param.cmd = GPIO_IRQ_ENABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("enable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + return EOK; + + return EOK; +} + +int HwWiznetInit(void) { + wiz_reset(); + + if (EOK != w5500_spi_init()) { + return ERROR; + } + + wiz_spi_handler_reg(); + + if (EOK != wiz_chip_cfg_init()) { + return ERROR; + } + + network_init(); + + return EOK; +} + +/****************** basic functions ********************/ + +enum TCP_OPTION { + SEND_DATA = 0, + RECV_DATA, +}; + +uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint8_t dst_ip[4], uint16_t dst_port, + enum TCP_OPTION opt) { + // assert(buf_size <= g_wiznet_buf_size); + int32_t ret; + switch (getSn_SR(socket_tcp)) { + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(socket_tcp); + break; + case SOCK_CLOSED: + wiz_socket(socket_tcp, Sn_MR_TCP, 5000, 0x00); + break; + case SOCK_INIT: + KPrintf("[SOCKET CLIENT] sock init.\n"); + wiz_sock_connect(socket_tcp, dst_ip, dst_port); + break; + case SOCK_ESTABLISHED: + if (getSn_IR(socket_tcp) & Sn_IR_CON) { + printf("[SOCKET CLIENT] %d:Connected\r\n", socket_tcp); + setSn_IR(socket_tcp, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + if (ret <= 0) return ret; + } + } + break; + default: + break; + } +} + +void wiz_client_op_test(char *addr, uint16_t port, char *msg) { + /* argv[1]: ip + * argv[2]: port + * argv[3]: msg + */ + uint8_t client_sock = 2; + uint8_t ip[4] = {192, 168, 31, 127}; + uint32_t tmp_ip[4]; + KPrintf("wiz client to %s", addr); + sscanf(addr, "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + for (int i = 0; i < 4; ++i) { + ip[i] = (uint8_t)tmp_ip[i]; + } + uint8_t buf[g_wiznet_buf_size]; + KPrintf("wiz_server, send to %d.%d.%d.%d %d\n", // tip info + ip[0], ip[1], ip[2], ip[3], port); + sscanf(msg, "%s", buf); + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, SEND_DATA); + MdelayKTask(10); + memset(buf, 0, g_wiznet_buf_size); + // waiting for a responding. + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, RECV_DATA); + KPrintf("received msg: %s\n", buf); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(3), + wiz_client_op, wiz_client_op_test, + wiz_sock_recv or wiz_sock_send data as tcp client); + +int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint16_t port, enum TCP_OPTION opt) { + int32_t ret = 0; + uint16_t size = 0, sentsize = 0; + switch (getSn_SR(sn)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("%d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + return ret; + } + } + break; + case SOCK_CLOSE_WAIT: + printf("%d:CloseWait\r\n", sn); + if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; + printf("%d:Closed\r\n", sn); + break; + case SOCK_INIT: + printf("%d:Listen, port [%d]\r\n", sn, port); + if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: + printf("%d:LBTStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; + printf("%d:Opened\r\n", sn); + break; + default: + break; + } + return 0; +} + +void wiz_server(void *param) { + uint16_t port = *(uint16_t *)param; + KPrintf("wiz server, listen port: %d\n", port); + uint8_t buf[g_wiznet_buf_size]; + memset(buf, 0, g_wiznet_buf_size); + int ret = 0; + while (1) { + ret = wiz_server_op(0, buf, g_wiznet_buf_size, port, RECV_DATA); + if (ret > 0) { + wiz_server_op(0, buf, g_wiznet_buf_size, port, SEND_DATA); + }; + } +} + +void wiz_server_test(uint16_t port) { + /* argv[1]: port + */ + int32 wiz_server_id = + KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); + x_err_t flag = StartupKTask(wiz_server_id); + if (flag != EOK) { + KPrintf("StartupKTask wiz_server_id failed .\n"); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(1), + wiz_server_op, wiz_server_test, + wiz_sock_recv or wiz_sock_send data as tcp server); + +int32_t loopback_udps(uint8_t sn, uint8_t *buf, uint16_t port) { + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + // uint8_t packinfo = 0; + switch (getSn_SR(sn)) { + case SOCK_UDP: + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > g_wiznet_buf_size) size = g_wiznet_buf_size; + ret = wiz_sock_recvfrom(sn, buf, size, destip, (uint16_t *)&destport); + if (ret <= 0) { + printf("%d: wiz_sock_recvfrom error. %ld\r\n", sn, ret); + return ret; + } + size = (uint16_t)ret; + sentsize = 0; + while (sentsize != size) { + ret = wiz_sock_sendto(sn, buf + sentsize, size - sentsize, destip, + destport); + if (ret < 0) { + printf("%d: wiz_sock_sendto error. %ld\r\n", sn, ret); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: + printf("%d:LBUStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_UDP, port, 0x00)) != sn) return ret; + printf("%d:Opened, port [%d]\r\n", sn, port); + break; + default: + break; + } + return 1; +} + +void ifconfig() { + wiz_NetInfo wiz_netinfo; + ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], + wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], + wiz_netinfo.mac[4], wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], + wiz_netinfo.ip[2], wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], + wiz_netinfo.gw[2], wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], + wiz_netinfo.sn[2], wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], + wiz_netinfo.dns[2], wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + ifconfig, ifconfig, printf w5500 configurations); + +void char_arr_assign(uint8_t **dst, uint32_t *src, uint32_t len) { + for (int i = 0; i < len; ++i) { + (*dst)[i] = (uint8_t)(src[i]); + } +} + +void config_w5500_network(char *mac, char *ip, char *sn, char *gw, char *dns) { + wiz_NetInfo wiz_netinfo; + uint32_t tmp_arr[4]; + // config netinfo + sscanf(mac, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.mac, tmp_arr, 4); + sscanf(ip, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.ip, tmp_arr, 4); + sscanf(sn, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.sn, tmp_arr, 4); + sscanf(gw, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.gw, tmp_arr, 4); + sscanf(dns, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.dns, tmp_arr, 4); + // set new netinfo + ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); + ifconfig(); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(5), + config_w5500_network, config_w5500_network, + set w5500 configurations); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client0.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client0.png new file mode 100644 index 000000000..7df09b0d9 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client1.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client1.png new file mode 100644 index 000000000..167d455b8 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping baidu.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping baidu.png new file mode 100644 index 000000000..c79f4bb85 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping baidu.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping w5500.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping w5500.png new file mode 100644 index 000000000..e453995a6 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping w5500.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server0.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server0.png new file mode 100644 index 000000000..63f2d5f57 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server1.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server1.png new file mode 100644 index 000000000..7643c9bf3 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/socket.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/socket.c new file mode 100755 index 000000000..820e0631c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/socket.c @@ -0,0 +1,912 @@ + +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* +//! addr parameter is not aligned by 4byte address. Copy 4 byte addr +//! value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status +//! (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +#include "wizchip_conf.h" + +// M20150401 : Typing Error +//#define SOCK_ANY_PORT_NUM 0xC000; +#define SOCK_ANY_PORT_NUM 0xC000 + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; + +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = { + 0, + 0, +}; + +// M20150601 : For extern decleation +// static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +// + +#if _WIZCHIP_ == 5200 +static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 +uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = { + 0, +}; // set by wiz_recv_data() +#endif + +#define CHECK_SOCKNUM() \ + do { \ + if (sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + } while (0); + +#define CHECK_SOCKMODE(mode) \ + do { \ + if ((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + } while (0); + +#define CHECK_SOCKINIT() \ + do { \ + if ((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + } while (0); + +#define CHECK_SOCKDATA() \ + do { \ + if (len == 0) return SOCKERR_DATALEN; \ + } while (0); + +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) { + CHECK_SOCKNUM(); + switch (protocol) { + case Sn_MR_TCP: { + // M20150601 : Fixed the warning - taddr will never be NULL + /* + uint8_t taddr[4]; + getSIPR(taddr); + */ + uint32_t taddr; + getSIPR((uint8_t *)&taddr); + if (taddr == 0) return SOCKERR_SOCKINIT; + break; + } + case Sn_MR_UDP: + case Sn_MR_MACRAW: + case Sn_MR_IPRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + // M20150601 : For SF_TCP_ALIGN & W5300 + // if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; + if ((flag & 0x04) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if (flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if (flag != 0) { + switch (protocol) { + case Sn_MR_TCP: + // M20150601 : For SF_TCP_ALIGN & W5300 +#if _WIZCHIP_ == 5300 + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK | SF_TCP_ALIGN)) == 0) + return SOCKERR_SOCKFLAG; +#else + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK)) == 0) + return SOCKERR_SOCKFLAG; +#endif + + break; + case Sn_MR_UDP: + if (flag & SF_IGMP_VER2) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#if _WIZCHIP_ == 5500 + if (flag & SF_UNI_BLOCK) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#endif + break; + default: + break; + } + } + wiz_sock_close(sn); +// M20150601 +#if _WIZCHIP_ == 5300 + setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | + (((uint16_t)(flag & 0x02)) << 7)); +#else + setSn_MR(sn, (protocol | (flag & 0xF0))); +#endif + if (!port) { + port = sock_any_port++; + if (sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn, port); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn)) + ; + // A20150401 : For release the previous sock_io_mode + sock_io_mode &= ~(1 << sn); + // + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + // M20150601 : repalce 0 with PACK_COMPLETED + // sock_pack_info[sn] = 0; + sock_pack_info[sn] = PACK_COMPLETED; + // + while (getSn_SR(sn) == SOCK_CLOSED) + ; + return (int8_t)sn; +} + +int8_t wiz_sock_close(uint8_t sn) { + CHECK_SOCKNUM(); +// A20160426 : Applied the erratum 1 of W5300 +#if (_WIZCHIP_ == 5300) + // M20160503 : Wrong socket parameter. s -> sn + // if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != + // getSn_TxMAX(s)) ) + if (((getSn_MR(sn) & 0x0F) == Sn_MR_TCP) && + (getSn_TX_FSR(sn) != getSn_TxMAX(sn))) { + uint8_t destip[4] = {0, 0, 0, 1}; + // TODO + // You can wait for completing to sending data; + // wait about 1 second; + // if you have completed to send data, skip the code of erratum 1 + // ex> wait_1s(); + // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue; + // + // M20160503 : The socket() of close() calls close() itself again. It + // occures a infinite loop - close()->socket()->close()->socket()-> ~ + // socket(s,Sn_MR_UDP,0x3000,0); + // sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown + // destination(0.0.0.1). + setSn_MR(sn, Sn_MR_UDP); + setSn_PORTR(sn, 0x3000); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn) != 0) + ; + while (getSn_SR(sn) != SOCK_UDP) + ; + wiz_sock_sendto( + sn, destip, 1, destip, + 0x3000); // send the dummy data to an unknown destination(0.0.0.1). + }; +#endif + setSn_CR(sn, Sn_CR_CLOSE); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + // A20150401 : Release the sock_io_mode of socket n. + sock_io_mode &= ~(1 << sn); + // + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while (getSn_SR(sn) != SOCK_CLOSED) + ; + return SOCK_OK; +} + +int8_t wiz_sock_listen(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + setSn_CR(sn, Sn_CR_LISTEN); + while (getSn_CR(sn)) + ; + while (getSn_SR(sn) != SOCK_LISTEN) { + wiz_sock_close(sn); + return SOCKERR_SOCKCLOSED; + } + return SOCK_OK; +} + +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return + // SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; + } + // + + if (port == 0) return SOCKERR_PORTZERO; + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + setSn_CR(sn, Sn_CR_CONNECT); + while (getSn_CR(sn)) + ; + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_ESTABLISHED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } + } + + return SOCK_OK; +} + +int8_t wiz_sock_disconnect(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_CR(sn, Sn_CR_DISCON); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending &= ~(1 << sn); + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_CLOSED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } + } + return SOCK_OK; +} + +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t freesize = 0; + + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) + return SOCKERR_SOCKSTATUS; + if (sock_is_sending & (1 << sn)) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); +// M20150401 : Typing Error +//#if _WZICHIP_ == 5200 +#if _WIZCHIP_ == 5200 + if (getSn_TX_RD(sn) != sock_next_rd[sn]) { + setSn_CR(sn, Sn_CR_SEND); + while (getSn_CR(sn)) + ; + return SOCK_BUSY; + } +#endif + sock_is_sending &= ~(1 << sn); + } else if (tmp & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } else + return SOCK_BUSY; + } + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + } + wiz_send_data(sn, buf, len); +#if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; +#endif + +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending |= (1 << sn); + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t recvsize = 0; +// A20150601 : For integarating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t head[2]; + uint16_t mr; +#endif + // + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if (recvsize < len) len = recvsize; + +// A20150601 : For Integrating with W5300 +#if _WIZCHIP_ == 5300 + // sock_pack_info[sn] = PACK_COMPLETED; // for clear + if (sock_remained_size[sn] == 0) { +#endif + // + while (1) { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) { + if (tmp == SOCK_CLOSE_WAIT) { + if (recvsize != 0) + break; + else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } else { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if ((sock_io_mode & (1 << sn)) && (recvsize == 0)) return SOCK_BUSY; + if (recvsize != 0) break; + }; +#if _WIZCHIP_ == 5300 + } +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 + if ((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) { + mr = getMR(); + if ((getSn_MR(sn) & Sn_MR_ALIGN) == 0) { + wiz_recv_data(sn, head, 2); + if (mr & MR_FS) + recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); + else + recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); + sock_pack_info[sn] = PACK_FIRST; + } + sock_remained_size[sn] = recvsize; + } + if (len > sock_remained_size[sn]) len = sock_remained_size[sn]; + recvsize = len; + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf = sock_remained_byte[sn]; + buf++; + sock_pack_info[sn] &= ~(PACK_FIFOBYTE); + recvsize -= 1; + sock_remained_size[sn] -= 1; + } + if (recvsize != 0) { + wiz_recv_data(sn, buf, recvsize); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + } + sock_remained_size[sn] -= recvsize; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; + if (recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; + } else + sock_pack_info[sn] = PACK_COMPLETED; + if (getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; + // len = recvsize; +#else + if (recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; +#endif + + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port) { + uint8_t tmp = 0; + uint16_t freesize = 0; + uint32_t taddr; + + CHECK_SOCKNUM(); + switch (getSn_MR(sn) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + // break; + // #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + break; + // #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + //{ + // uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + //} + // + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if ((taddr == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_IPINVALID; + if ((port == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); + //#if ( _WIZCHIP_ < 5200 ) + if ((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) + return SOCKERR_SOCKSTATUS; + //#else + // if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + //#endif + + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + getSIPR((uint8_t *)&taddr); + if (taddr == 0) { + getSUBR((uint8_t *)&taddr); + setSUBR((uint8_t *)"\x00\x00\x00\x00"); + } else + taddr = 0; +#endif + +// A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + // + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + while (1) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + // M:20131104 + // else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if (tmp & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); +// M20150409 : Fixed the lost of sign bits by type casting. +// len = (uint16_t)SOCKERR_TIMEOUT; +// break; +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + return SOCKERR_TIMEOUT; + } + //////////// + } +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port) { +// M20150601 : For W5300 +#if _WIZCHIP_ == 5300 + uint16_t mr; + uint16_t mr1; +#else + uint8_t mr; +#endif + // + uint8_t head[8]; + uint16_t pack_len = 0; + + CHECK_SOCKNUM(); + // CHECK_SOCKMODE(Sn_MR_UDP); +// A20150601 +#if _WIZCHIP_ == 5300 + mr1 = getMR(); +#endif + + switch ((mr = getSn_MR(sn)) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_IPRAW: + case Sn_MR_MACRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if (sock_remained_size[sn] == 0) { + while (1) { + pack_len = getSn_RX_RSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (pack_len == 0)) return SOCK_BUSY; + if (pack_len != 0) break; + }; + } + // D20150601 : Move it to bottom + // sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) { + case Sn_MR_UDP: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 8); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + // A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + if (mr1 & MR_FS) { + addr[0] = head[1]; + addr[1] = head[0]; + addr[2] = head[3]; + addr[3] = head[2]; + *port = head[5]; + *port = (*port << 8) + head[4]; + sock_remained_size[sn] = head[7]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; + } else { +#endif + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; +#if _WIZCHIP_ == 5300 + } +#endif + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + // A20150601 : For W5300 + len = pack_len; +#if _WIZCHIP_ == 5300 + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf++ = sock_remained_byte[sn]; + pack_len -= 1; + sock_remained_size[sn] -= 1; + sock_pack_info[sn] &= ~PACK_FIFOBYTE; + } +#endif + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + case Sn_MR_MACRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 2); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2; +#if _WIZCHIP_ == W5300 + if (sock_remained_size[sn] & 0x01) + sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; + else + sock_remained_size[sn] -= 4; +#endif + if (sock_remained_size[sn] > 1514) { + wiz_sock_close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); + break; + //#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 6); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + // M20150401 : For Typing Error + // sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + //#endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn, Sn_CR_RECV); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_remained_size[sn] -= pack_len; + // M20150601 : + // if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; +#if _WIZCHIP_ == 5300 + if (pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; +#endif + } else + sock_pack_info[sn] = PACK_COMPLETED; +#if _WIZCHIP_ == 5300 + pack_len = len; +#endif + // + // M20150409 : Explicit Type Casting + // return pack_len; + return (int32_t)pack_len; +} + +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg) { + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch (cstype) { + case CS_SET_IOMODE: + tmp = *((uint8_t *)arg); + if (tmp == SOCK_IO_NONBLOCK) + sock_io_mode |= (1 << sn); + else if (tmp == SOCK_IO_BLOCK) + sock_io_mode &= ~(1 << sn); + else + return SOCKERR_ARG; + break; + case CS_GET_IOMODE: + // M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t *)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t *)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t *)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t *)arg) = getSn_IR(sn); + break; +#if _WIZCHIP_ != 5100 + case CS_SET_INTMASK: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTMASK: + *((uint8_t *)arg) = getSn_IMR(sn); + break; +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + // M20131220 : Remove warning + // uint8_t tmp; + CHECK_SOCKNUM(); + switch (sotype) { + case SO_TTL: + setSn_TTL(sn, *(uint8_t *)arg); + break; + case SO_TOS: + setSn_TOS(sn, *(uint8_t *)arg); + break; + case SO_MSS: + setSn_MSSR(sn, *(uint16_t *)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t *)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ > 5200 + if (getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; +#endif + setSn_CR(sn, Sn_CR_SEND_KEEP); + while (getSn_CR(sn) != 0) { + // M20131220 + // if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn, *(uint8_t *)arg); + break; +#endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + CHECK_SOCKNUM(); + switch (sotype) { + case SO_FLAG: + *(uint8_t *)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t *)arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t *)arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint16_t *)arg = getSn_MSSR(sn); + break; + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + *(uint16_t *)arg = getSn_DPORT(sn); + break; +#if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t *)arg = getSn_KPALVTR(sn); + break; +#endif + case SO_SENDBUF: + *(uint16_t *)arg = getSn_TX_FSR(sn); + break; + case SO_RECVBUF: + *(uint16_t *)arg = getSn_RX_RSR(sn); + break; + case SO_STATUS: + *(uint8_t *)arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if (getSn_MR(sn) & Sn_MR_TCP) + *(uint16_t *)arg = getSn_RX_RSR(sn); + else + *(uint16_t *)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + // CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ != 5300 + if ((getSn_MR(sn) == Sn_MR_TCP)) return SOCKERR_SOCKMODE; +#endif + *(uint8_t *)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/spi_interface.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/spi_interface.c new file mode 100644 index 000000000..7dbba1b46 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/spi_interface.c @@ -0,0 +1,35 @@ + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" + +// #define SPI1_CS_GPIONUM 24 + +static x_base g_w5500_spi_lock; +/** + * @brief 进入临界区 + * @retval None + */ +void spi_enter_cris(void) { g_w5500_spi_lock = DisableLocalInterrupt(); } +/** + * @brief 退出临界区 + * @retval None + */ +void spi_exit_cris(void) { EnableLocalInterrupt(g_w5500_spi_lock); } + +/** + * @brief 片选信号输出低电平 + * @retval None + */ +void spi_select_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_LOW); } +/** + * @brief 片选信号输出高电平 + * @retval None + */ +void spi_deselete_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_HIGH); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/w5500.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/w5500.c new file mode 100755 index 000000000..e98739488 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/w5500.c @@ -0,0 +1,255 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to +//! M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case +//! _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include +#include "w5500.h" + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +#if (_WIZCHIP_ == 5500) +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) { + uint8_t ret; + uint8_t spi_data[3]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + // if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte + // operation + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint16_t getSn_TX_FSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + } + } while (val != val1); + return val; +} + +uint16_t getSn_RX_RSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + } + } while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_TX_WR(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel, wizdata, len); + + ptr += len; + setSn_TX_WR(sn, ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_RX_RD(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) { + uint16_t ptr = 0; + + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn, ptr); +} + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.c new file mode 100644 index 000000000..c424ed177 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.c @@ -0,0 +1,250 @@ + +#include "wiz_ping.h" + +#include +#include +#include +#include +#include + +#define Sn_PROTO(ch) (0x001408 + (ch << 5)) + +#define PING_BIND_PORT 3000 + +PINGMSGR PingRequest = {0}; +PINGMSGR PingReply = {0}; + +static uint16_t ping_RandomID = 0x1234; +static uint16_t ping_RandomSeqNum = 0x4321; +uint8_t ping_reply_received = 0; +uint8_t ping_req = 0; +uint8_t ping_rep = 0; +uint8_t ping_cnt = 0; +uint8_t ping_rep_buf[150] = {0}; + +// ping状态机 +#define PING_STA_FREE 0 +#define PING_STA_OPEN 1 +#define PING_STA_SEND 2 +#define PING_STA_WAIT 3 +#define PING_STA_CLOSE 4 + +uint8_t ping_sta = PING_STA_FREE; + +//当前ping的设备的序号 +uint8_t ping_socket = 0; + +#define bswap_16(A) ((((uint16)(A)&0xff00) >> 8) | (((uint16)(A)&0x00ff) << 8)) + +uint16_t htons(uint16_t n) { + union { + int i; + char c; + } u = {1}; + return u.c ? bswap_16(n) : n; +} + +uint16_t checksum(uint8_t *src, uint32_t len) { + uint16_t sum, tsum, i, j; + uint32_t lsum; + + j = len >> 1; + lsum = 0; + + for (i = 0; i < j; i++) { + tsum = src[i * 2]; + tsum = tsum << 8; + tsum += src[i * 2 + 1]; + lsum += tsum; + } + + if (len % 2) { + tsum = src[i * 2]; + lsum += (tsum << 8); + } + + sum = lsum; + sum = ~(sum + (lsum >> 16)); + return (uint16_t)sum; +} + +/** + *@brief 设定次数ping外网IP函数 + *@param sn- socket number + *@param addr- 外网IP地址 + *@param pCount- ping的次数 + *@return ping成功次数 + */ +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr) { + uint16_t rlen, cnt, i; + + ping_reply_received = 0; + ping_req = 0; + ping_rep = 0; + KPrintf("Ping:%d.%d.%d.%d\r\n", (addr[0]), (addr[1]), (addr[2]), (addr[3])); + + for (i = 0; i < pCount + 1; i++) /*循环ping pCount次*/ + { + switch (getSn_SR(sn)) /*获取socket状态*/ + { + case SOCK_CLOSED: /*socket关闭状态*/ + { + wiz_sock_close(sn); + /* Create Socket */ + IINCHIP_WRITE(Sn_PROTO(sn), IPPROTO_ICMP); /*设置ICMP 协议*/ + if (wiz_socket(sn, Sn_MR_IPRAW, PING_BIND_PORT, 0) != + 0) /*判断ip raw模式socket是否开启*/ + { + } + /* Check socket register */ + while (getSn_SR(sn) != SOCK_IPRAW) { + MdelayKTask(50); + }; + break; + } + case SOCK_IPRAW: /*ip raw模式*/ + { + cnt = 0; + ping_request(sn, addr); /*发送Ping请求*/ + ping_req++; + while (1) { + if ((rlen = getSn_RX_RSR(sn)) > 0) { + rlen = ping_reply(sn, addr, rlen); /*获取回复信息*/ + ping_rep++; + if (ping_reply_received) { + break; + } + } + if ((cnt > 300)) { + cnt = 0; + break; + } else { + cnt++; + MdelayKTask(10); + } + } + break; + } + default: + break; + } + if (ping_req >= pCount) { + wiz_sock_close(sn); + } + } + return ping_rep; +} + +/** + *@brief ping请求函数 + *@param sn- socket number + *@param addr- P地址 + *@return 无 + */ +uint8_t ping_request(uint8_t sn, uint8_t *addr) { + uint8_t *buffer; + uint16_t i, temp_len = 0; + ping_reply_received = 0; /*ping 回复初始化标志位*/ + PingRequest.Type = PING_REQUEST; /*Ping-Request*/ + PingRequest.Code = CODE_ZERO; /*总是 '0'*/ + PingRequest.ID = htons(ping_RandomID++); /*设置ping响应ID为随机的整型变量*/ + PingRequest.SeqNum = + htons(ping_RandomSeqNum++); /*设置ping响应的序列号为随机整形变量*/ + for (i = 0; i < PING_BUF_LEN; i++) { + PingRequest.Data[i] = (i) % 8; /*ping相应的数在'0'~'8‘*/ + } + PingRequest.CheckSum = 0; + /* 计算响应次数*/ + PingRequest.CheckSum = + htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest))); + + /*发送ping响应到目的方 */ + if (wiz_sock_sendto(sn, (uint8_t *)&PingRequest, sizeof(PingRequest), addr, + PING_BIND_PORT) == 0) { + KPrintf("Fail to send ping-reply packet\r\n"); + } else { + KPrintf("ping send\n"); + } + return 0; +} + +/** + *@brief 解析Ping回复 + *@param sn- socket number + *@param addr- Ping地址 + *@return 无 + */ +uint8_t ping_reply(uint8_t sn, uint8_t *addr, uint16_t rlen) { + uint16_t tmp_checksum; + uint16_t len; + uint16_t i; + + uint16_t port = PING_BIND_PORT; + PINGMSGR PingReply; + + memset(ping_rep_buf, 0, sizeof(ping_rep_buf)); + len = wiz_sock_recvfrom(sn, ping_rep_buf, rlen, addr, + &port); /*从目的端接收数据*/ + + if (ping_rep_buf[0] == PING_REPLY) { + PingReply.Type = ping_rep_buf[0]; + PingReply.Code = ping_rep_buf[1]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = ~checksum(ping_rep_buf, len); /*检查ping回复的次数*/ + if (tmp_checksum != 0xffff) { + KPrintf("tmp_checksum = %x\r\n", tmp_checksum); + } else { + KPrintf("Reply from %3d.%3d.%3d.%3d ID=%x Byte=%d\r\n\r\n", (addr[0]), + (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), (rlen + 6)); + ping_reply_received = 1; /*当退出ping回复循环时,设置ping回复标志为1*/ + } + } else if (ping_rep_buf[0] == PING_REQUEST) { + PingReply.Code = ping_rep_buf[1]; + PingReply.Type = ping_rep_buf[2]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = PingReply.CheckSum; /*检查ping回复次数*/ + PingReply.CheckSum = 0; + if (tmp_checksum != PingReply.CheckSum) { + KPrintf(" \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), + htons(PingReply.CheckSum)); + } else { + } + KPrintf( + " Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n", + (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), + (PingReply.SeqNum), (rlen + 6)); + ping_reply_received = 1; /* 当退出ping回复循环时,设置ping回复标志为1 + */ + } else { + KPrintf(" Unkonwn msg. \n"); + } + return 0; +} + +void wiz_ping_test(int argc, char *argv[]) { + uint32_t tmp_ip[4]; + uint8_t target_ip[4]; + if (argc >= 2) { + KPrintf("This is a Ping test: %s\n", argv[1]); + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], + &tmp_ip[3]); + target_ip[0] = (uint8_t)tmp_ip[0]; + target_ip[1] = (uint8_t)tmp_ip[1]; + target_ip[2] = (uint8_t)tmp_ip[2]; + target_ip[3] = (uint8_t)tmp_ip[3]; + ping_count(ping_socket, 5, target_ip); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + ping, wiz_ping_test, ping to given addr); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.h new file mode 100644 index 000000000..3ead801b8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.h @@ -0,0 +1,35 @@ +#ifndef _WIZ_PING_H_ +#define _WIZ_PING_H_ + +#include "socket.h" +#include "w5500.h" + +#define PING_BUF_LEN 32 +#define PING_REQUEST 8 +#define PING_REPLY 0 +#define CODE_ZERO 0 + +#define SOCKET_ERROR 1 +#define TIMEOUT_ERROR 2 +#define SUCCESS 3 +#define REPLY_ERROR 4 + +typedef struct pingmsg { + uint8_t Type; // 0 - Ping Reply, 8 - Ping Request + uint8_t Code; // Always 0 + uint16_t CheckSum; // Check sum + uint16_t ID; // Identification + uint16_t SeqNum; // Sequence Number + int8_t Data[PING_BUF_LEN]; // Ping Data : 1452 = IP RAW MTU - + // sizeof(Type+Code+CheckSum+ID+SeqNum) +} PINGMSGR; + +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr); + +uint8_t ping_request(uint8_t s, uint8_t *addr); + +uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen); + +void Ethernet_ping_service_deal(uint8_t sn); + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wizchip_conf.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wizchip_conf.c new file mode 100755 index 000000000..1407c852f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wizchip_conf.c @@ -0,0 +1,862 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readdata() & +//! wizchip_bus_writedata() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting +//! it into uint8_t* For remove the warning when pointer type size is +//! not 32bit. If ptrdiff_t doesn't support in your complier, You +//! should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +// A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" + +///////////// +// M20150401 : Remove ; in the default callback function such as +// wizchip_cris_enter(), wizchip_cs_select() and etc. +///////////// + +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_enter(void) {}; +void wizchip_cris_enter(void) {} + +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_exit(void) {}; +void wizchip_cris_exit(void) {} + +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_select(void) {}; +void wizchip_cs_select(void) {} + +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_deselect(void) {}; +void wizchip_cs_deselect(void) {} + +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t +// *)((ptrdiff_t) AddrSel)); } +iodata_t wizchip_bus_readdata(uint32_t AddrSel) { + return *((volatile iodata_t *)((ptrdiff_t)AddrSel)); +} + +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile +// uint8_t*)((ptrdiff_t)AddrSel)) = wb; } +void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { + *((volatile iodata_t *)((ptrdiff_t)AddrSel)) = wb; +} + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// uint8_t wizchip_spi_readbyte(void) {return 0;}; +uint8_t wizchip_spi_readbyte(void) { return 0; } + +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writebyte(uint8_t wb) {}; +void wizchip_spi_writebyte(uint8_t wb) {} + +/** + * @brief Default function to burst read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_readburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @brief Default function to burst write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_writeburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @\ref _WIZCHIP instance + */ +// +// M20150401 : For a compiler didnot support a member of structure +// Replace the assignment of struct members with the assingment of +// array +// +/* +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; +*/ +_WIZCHIP WIZCHIP = {_WIZCHIP_IO_MODE_, + _WIZCHIP_ID_, + {wizchip_cris_enter, wizchip_cris_exit}, + {wizchip_cs_select, wizchip_cs_deselect}, + { + {// M20150601 : Rename the function + // wizchip_bus_readbyte, + // wizchip_bus_writebyte + wizchip_bus_readdata, wizchip_bus_writedata}, + + }}; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)) { + if (!cris_en || !cris_ex) { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } else { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)) { + if (!cs_sel || !cs_desel) { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } else { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +// M20150515 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)) +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)) + ; + // M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if (!bus_rb || !bus_wb) { + WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata; + WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata; + } else { + WIZCHIP.IF.BUS._read_data = bus_rb; + WIZCHIP.IF.BUS._write_data = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +// 20140626 Eric Added for SPI burst operations +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rb; + WIZCHIP.IF.SPI._write_burst = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg) { +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + uint8_t tmp = 0; +#endif + uint8_t *ptmp[2] = {0, 0}; + switch (cwtype) { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if (arg != 0) { + ptmp[0] = (uint8_t *)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind *)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind *)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind *)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind *)arg) = wizchip_getinterruptmask(); + break; +// M20150601 : This can be supported by W5200, W5500 +//#if _WIZCHIP_ > W5100 +#if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t *)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t *)arg = getINTLEVEL(); + break; +#endif + case CW_GET_ID: + ((uint8_t *)arg)[0] = WIZCHIP.id[0]; + ((uint8_t *)arg)[1] = WIZCHIP.id[1]; + ((uint8_t *)arg)[2] = WIZCHIP.id[2]; + ((uint8_t *)arg)[3] = WIZCHIP.id[3]; + ((uint8_t *)arg)[4] = WIZCHIP.id[4]; + ((uint8_t *)arg)[5] = WIZCHIP.id[5]; + ((uint8_t *)arg)[6] = 0; + break; +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t *)arg); +#endif +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; +#endif + default: + return -1; + } + return 0; +} + +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg) { + + switch (cntype) { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo *)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo *)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type *)arg); + case CN_GET_NETMODE: + *(netmode_type *)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout *)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout *)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) { + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; +// A20150601 +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + uint16_t mr = (uint16_t)getMR(); + setMR(mr | MR_IND); +#endif + // + getSHAR(mac); + getGAR(gw); + getSUBR(sn); + getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay +// A2015051 : For indirect bus mode +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + setMR(mr | MR_IND); +#endif + // + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize) { + int8_t i; +#if _WIZCHIP_ < W5200 + int8_t j; +#endif + int8_t tmp = 0; + wizchip_sw_reset(); + if (txsize) { + tmp = 0; +// M20150601 : For integrating with W5300 +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (txsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += txsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += txsize[i]; + +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 + j = 0; + while ((txsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_TXBUF_SIZE(i, j); +#else + setSn_TXBUF_SIZE(i, txsize[i]); +#endif + } + +#endif + } + + if (rxsize) { + tmp = 0; +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (rxsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += rxsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += rxsize[i]; +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // add condition for w5100 + j = 0; + while ((rxsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_RXBUF_SIZE(i, j); +#else + setSn_RXBUF_SIZE(i, rxsize[i]); +#endif + } +#endif + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) { + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + ir |= (1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ <= W5100S + ir |= sir; + setIR(ir); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIR(((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF))); +#else + setIR(ir); + // M20200227 : For clear + // setSIR(sir); + for (ir = 0; ir < 8; ir++) { + if (sir & (0x01 << ir)) + setSn_IR(ir, 0xff); + } + +#endif +} + +intr_kind wizchip_getinterrupt(void) { + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ <= W5100S + ir = getIR(); + sir = ir & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIR(); + ir = (uint8_t)(ret >> 8); + sir = (uint8_t)ret; +#else + ir = getIR(); + sir = getSIR(); +#endif + +// M20150601 : For Integrating with W5300 +//#if _WIZCHIP_ < W5500 +#if _WIZCHIP_ < W5200 + ir &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) { + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + simr &= 0x0F; + imr |= simr; + setIMR(imr); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIMR(((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF))); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) { + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ < W5200 + imr = getIMR(); + simr = imr & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIMR(); + imr = (uint8_t)(ret >> 8); + simr = (uint8_t)ret; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) { + int8_t tmp = PHY_LINK_OFF; +#if _WIZCHIP_ == W5100S + if (getPHYSR() & PHYSR_LNK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5500 + if (getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > W5100 + +int8_t wizphy_getphypmode(void) { + int8_t tmp = 0; +#if _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#elif _WIZCHIP_ == 5500 + if ((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#else + tmp = -1; +#endif + return tmp; +} +#endif + +#if _WIZCHIP_ == W5100S +void wizphy_reset(void) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + tmp |= BMCR_RESET; + wiz_mdio_write(PHYMDIO_BMCR, tmp); + while (wiz_mdio_read(PHYMDIO_BMCR) & BMCR_RESET) { + } +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= BMCR_AUTONEGO; + else { + tmp &= ~BMCR_AUTONEGO; + if (phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DUP; + } else { + tmp &= ~BMCR_DUP; + } + if (phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPEED; + } else { + tmp &= ~BMCR_SPEED; + } + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + phyconf->by = PHY_CONFBY_SW; + if (tmp & BMCR_AUTONEGO) { + phyconf->mode = PHY_MODE_AUTONEGO; + } else { + phyconf->mode = PHY_MODE_MANUAL; + if (tmp & BMCR_DUP) + phyconf->duplex = PHY_DUPLEX_FULL; + else + phyconf->duplex = PHY_DUPLEX_HALF; + if (tmp & BMCR_SPEED) + phyconf->speed = PHY_SPEED_100; + else + phyconf->speed = PHY_SPEED_10; + } +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + if (tmp & BMCR_PWDN) + return 0; + } else { + if ((tmp & BMCR_PWDN) != BMCR_PWDN) + return 0; + } + return -1; +} + +#endif +#if _WIZCHIP_ == W5500 +void wizphy_reset(void) { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + if (phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else { + if (phyconf->duplex == PHY_DUPLEX_FULL) { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } else { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf *phyconf) { + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = + (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if ((tmp & PHYCFGR_OPMD) == 0) + return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if (pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if (pmode == PHY_POWER_DOWN) { + if (tmp & PHYCFGR_OPMDC_PDOWN) + return 0; + } else { + if (tmp & PHYCFGR_OPMDC_ALLA) + return 0; + } + return -1; +} +#endif + +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo) { + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo) { + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0] = _DNS_[0]; + pnetinfo->dns[1] = _DNS_[1]; + pnetinfo->dns[2] = _DNS_[2]; + pnetinfo->dns[3] = _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) { + uint8_t tmp = 0; +#if _WIZCHIP_ != W5500 + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) + return -1; +#else + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) + return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) { return (netmode_type)getMR(); } + +void wizchip_settimeout(wiz_NetTimeout *nettime) { + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout *nettime) { + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c index 78793b8aa..3b344e47d 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c @@ -9,44 +9,49 @@ */ /** -* @file drv_io_config.c -* @brief support xidatong-riscv64-board io configure -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file drv_io_config.c + * @brief support xidatong-riscv64-board io configure + * @version 2.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: drv_io_config.c Description: support kd233-board io configure Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.c for references https://github.com/RT-Thread/rt-thread/tree/v4.0.2 -History: +History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab Modification: support kd233-board io configure *************************************************/ -#include -#include #include "drv_io_config.h" -#include + +#include +#include +#include #define HS_GPIO(n) (FUNC_GPIOHS0 + n) -#define IOCONFIG(pin,func) {pin, func, #func} +#define IOCONFIG(pin, func) \ + { pin, func, #func } -static struct io_config -{ - int io_num; - fpioa_function_t func; - const char * FuncName; -} io_config[] = -{ +static struct io_config { + int io_num; + fpioa_function_t func; + const char* FuncName; +} io_config[] = { #ifdef BSP_USING_LCD - IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0), - IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK), - IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(LCD_DC_PIN)), + IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0), + IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK), + IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(LCD_DC_PIN)), +#endif + +#ifdef BSP_USING_W5500 + IOCONFIG(BSP_WIZ_RST_PIN, HS_GPIO(WIZ_RST_PIN)), + IOCONFIG(BSP_WIZ_INT_PIN, HS_GPIO(WIZ_INT_PIN)), #endif #ifdef BSP_USING_SPI1 @@ -83,63 +88,59 @@ static struct io_config #endif #ifdef BSP_USING_CH438 - IOCONFIG(BSP_CH438_ALE_PIN, HS_GPIO(FPIOA_CH438_ALE)), - IOCONFIG(BSP_CH438_NWR_PIN, HS_GPIO(FPIOA_CH438_NWR)), - IOCONFIG(BSP_CH438_NRD_PIN, HS_GPIO(FPIOA_CH438_NRD)), - IOCONFIG(BSP_CH438_INT_PIN, HS_GPIO(FPIOA_CH438_INT)), - IOCONFIG(BSP_CH438_D0_PIN, HS_GPIO(FPIOA_CH438_D0)), - IOCONFIG(BSP_CH438_D1_PIN, HS_GPIO(FPIOA_CH438_D1)), - IOCONFIG(BSP_CH438_D2_PIN, HS_GPIO(FPIOA_CH438_D2)), - IOCONFIG(BSP_CH438_D3_PIN, HS_GPIO(FPIOA_CH438_D3)), - IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)), - IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)), - IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)), - IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)) + IOCONFIG(BSP_CH438_ALE_PIN, HS_GPIO(FPIOA_CH438_ALE)), + IOCONFIG(BSP_CH438_NWR_PIN, HS_GPIO(FPIOA_CH438_NWR)), + IOCONFIG(BSP_CH438_NRD_PIN, HS_GPIO(FPIOA_CH438_NRD)), + IOCONFIG(BSP_CH438_INT_PIN, HS_GPIO(FPIOA_CH438_INT)), + IOCONFIG(BSP_CH438_D0_PIN, HS_GPIO(FPIOA_CH438_D0)), + IOCONFIG(BSP_CH438_D1_PIN, HS_GPIO(FPIOA_CH438_D1)), + IOCONFIG(BSP_CH438_D2_PIN, HS_GPIO(FPIOA_CH438_D2)), + IOCONFIG(BSP_CH438_D3_PIN, HS_GPIO(FPIOA_CH438_D3)), + IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)), + IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)), + IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)), + IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)) #endif }; -static int PrintIoConfig() -{ - int i; - KPrintf("IO Configuration Table\n"); - KPrintf("┌───────┬────────────────────────┐\n"); - KPrintf("│Pin │Function │\n"); - KPrintf("├───────┼────────────────────────┤\n"); - for(i = 0; i < sizeof io_config / sizeof io_config[0]; i++) - { - KPrintf("│%-2d │%-24.24s│\n", io_config[i].io_num, io_config[i].FuncName); - } - KPrintf("└───────┴────────────────────────┘\n"); - return 0; +static int PrintIoConfig() { + int i; + KPrintf("IO Configuration Table\n"); + KPrintf("┌───────┬────────────────────────┐\n"); + KPrintf("│Pin │Function │\n"); + KPrintf("├───────┼────────────────────────┤\n"); + for (i = 0; i < sizeof io_config / sizeof io_config[0]; i++) { + KPrintf("│%-2d │%-24.24s│\n", io_config[i].io_num, + io_config[i].FuncName); + } + KPrintf("└───────┴────────────────────────┘\n"); + return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), - io,PrintIoConfig,print io config); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + io, PrintIoConfig, print io config); -int IoConfigInit(void) -{ - int count = sizeof(io_config) / sizeof(io_config[0]); - int i; - int ret = 0; +int IoConfigInit(void) { + int count = sizeof(io_config) / sizeof(io_config[0]); + int i; + int ret = 0; - sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); - sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); - sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); #ifdef BSP_USING_UART2 - // for IO-27/28 - sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33); + // for IO-27/28 + sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33); #endif -#if defined(BSP_USING_UART1) || defined(BSP_USING_UART3) - // for IO-20~23 - sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); +#if defined(BSP_USING_UART1) || defined(BSP_USING_UART3) + // for IO-20~23 + sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); #endif - for(i = 0; i < count; i++) - { - ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func); - if(ret != 0) - return ret; - } + for (i = 0; i < count; i++) { + ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func); + if (ret != 0) return ret; + } - return ret; + return ret; } - diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c index 9802b69f7..6e71be831 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c @@ -26,6 +26,7 @@ #include "utils.h" #include "fpioa.h" #include "sysctl.h" +#include #define GPIO_MAX_PINNO 8 volatile gpio_t* const gpio = (volatile gpio_t*)GPIO_BASE_ADDR; diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_spi.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_spi.h new file mode 100644 index 000000000..cd746d016 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_spi.h @@ -0,0 +1,36 @@ +/* +* 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_spi.h +* @brief define aiit-riscv64-board spi function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_SPI_H +#define CONNECT_SPI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwSpiInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_w5500.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_w5500.h new file mode 100644 index 000000000..43359e8f4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_w5500.h @@ -0,0 +1,38 @@ +/* + * 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_w5500.h + * @brief define aiit-riscv64-board spi function and struct + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-10-16 + */ + +#ifndef _CONNECT_W5500_H_ +#define _CONNECT_W5500_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static struct Bus *spi_bus; + +int HwWiznetInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h index 4e247e955..7b2dfadca 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h @@ -9,19 +9,19 @@ */ /** -* @file drv_io_config.h -* @brief define xidatong-riscv64-board io configure -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file drv_io_config.h + * @brief define xidatong-riscv64-board io configure + * @version 2.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: drv_io_config.h Description: define xidatong-riscv64-board io configure Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.h for references https://github.com/RT-Thread/rt-thread/tree/v4.0.2 -History: +History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab Modification: add xidatong-riscv64-board io configure define @@ -30,52 +30,57 @@ Modification: add xidatong-riscv64-board io configure define #ifndef __DRV_IO_CONFIG_H__ #define __DRV_IO_CONFIG_H__ -enum HS_GPIO_CONFIG -{ +#include + +enum HS_GPIO_CONFIG { #ifdef BSP_USING_LCD - LCD_DC_PIN = 0, /* LCD DC PIN */ + LCD_DC_PIN = 0, /* LCD DC PIN */ #endif #ifdef BSP_SPI1_USING_SS0 - SPI1_CS0_PIN, + SPI1_CS0_PIN, #endif #ifdef BSP_SPI1_USING_SS1 - SPI1_CS1_PIN, + SPI1_CS1_PIN, #endif #ifdef BSP_SPI1_USING_SS2 - SPI1_CS2_PIN, + SPI1_CS2_PIN, #endif #ifdef BSP_SPI1_USING_SS3 - SPI1_CS3_PIN, + SPI1_CS3_PIN, #endif - GPIO_ALLOC_START /* index of gpio driver start */ +#ifdef BSP_USING_W5500 + WIZ_RST_PIN, + WIZ_INT_PIN, +#endif + GPIO_ALLOC_START /* index of gpio driver start */ }; #ifdef BSP_USING_CH438 -#define FPIOA_CH438_ALE 12 -#define FPIOA_CH438_NWR 13 -#define FPIOA_CH438_NRD 14 -#define FPIOA_CH438_D0 15 -#define FPIOA_CH438_D1 16 -#define FPIOA_CH438_D2 17 -#define FPIOA_CH438_D3 18 -#define FPIOA_CH438_D4 19 -#define FPIOA_CH438_D5 20 -#define FPIOA_CH438_D6 21 -#define FPIOA_CH438_D7 22 -#define FPIOA_CH438_INT 23 +#define FPIOA_CH438_ALE 12 +#define FPIOA_CH438_NWR 13 +#define FPIOA_CH438_NRD 14 +#define FPIOA_CH438_D0 15 +#define FPIOA_CH438_D1 16 +#define FPIOA_CH438_D2 17 +#define FPIOA_CH438_D3 18 +#define FPIOA_CH438_D4 19 +#define FPIOA_CH438_D5 20 +#define FPIOA_CH438_D6 21 +#define FPIOA_CH438_D7 22 +#define FPIOA_CH438_INT 23 -#define BSP_CH438_ALE_PIN 24 -#define BSP_CH438_NWR_PIN 25 -#define BSP_CH438_NRD_PIN 26 -#define BSP_CH438_D0_PIN 27 -#define BSP_CH438_D1_PIN 28 -#define BSP_CH438_D2_PIN 29 -#define BSP_CH438_D3_PIN 30 -#define BSP_CH438_D4_PIN 31 -#define BSP_CH438_D5_PIN 32 -#define BSP_CH438_D6_PIN 33 -#define BSP_CH438_D7_PIN 34 -#define BSP_CH438_INT_PIN 35 +#define BSP_CH438_ALE_PIN 24 +#define BSP_CH438_NWR_PIN 25 +#define BSP_CH438_NRD_PIN 26 +#define BSP_CH438_D0_PIN 27 +#define BSP_CH438_D1_PIN 28 +#define BSP_CH438_D2_PIN 29 +#define BSP_CH438_D3_PIN 30 +#define BSP_CH438_D4_PIN 31 +#define BSP_CH438_D5_PIN 32 +#define BSP_CH438_D6_PIN 33 +#define BSP_CH438_D7_PIN 34 +#define BSP_CH438_INT_PIN 35 #endif extern int IoConfigInit(void); diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/hardware_spi.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/hardware_spi.h new file mode 100644 index 000000000..4d3fd3599 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/hardware_spi.h @@ -0,0 +1,494 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_spi.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __HARDWARE_SPI_H__ +#define __HARDWARE_SPI_H__ + +#include "dmac.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +typedef struct _spi +{ + /* SPI Control Register 0 (0x00)*/ + volatile uint32_t ctrlr0; + /* SPI Control Register 1 (0x04)*/ + volatile uint32_t ctrlr1; + /* SPI Enable Register (0x08)*/ + volatile uint32_t ssienr; + /* SPI Microwire Control Register (0x0c)*/ + volatile uint32_t mwcr; + /* SPI Slave Enable Register (0x10)*/ + volatile uint32_t ser; + /* SPI Baud Rate Select (0x14)*/ + volatile uint32_t baudr; + /* SPI Transmit FIFO Threshold Level (0x18)*/ + volatile uint32_t txftlr; + /* SPI Receive FIFO Threshold Level (0x1c)*/ + volatile uint32_t rxftlr; + /* SPI Transmit FIFO Level Register (0x20)*/ + volatile uint32_t txflr; + /* SPI Receive FIFO Level Register (0x24)*/ + volatile uint32_t rxflr; + /* SPI Status Register (0x28)*/ + volatile uint32_t sr; + /* SPI Interrupt Mask Register (0x2c)*/ + volatile uint32_t imr; + /* SPI Interrupt Status Register (0x30)*/ + volatile uint32_t isr; + /* SPI Raw Interrupt Status Register (0x34)*/ + volatile uint32_t risr; + /* SPI Transmit FIFO Overflow Interrupt Clear Register (0x38)*/ + volatile uint32_t txoicr; + /* SPI Receive FIFO Overflow Interrupt Clear Register (0x3c)*/ + volatile uint32_t rxoicr; + /* SPI Receive FIFO Underflow Interrupt Clear Register (0x40)*/ + volatile uint32_t rxuicr; + /* SPI Multi-Master Interrupt Clear Register (0x44)*/ + volatile uint32_t msticr; + /* SPI Interrupt Clear Register (0x48)*/ + volatile uint32_t icr; + /* SPI DMA Control Register (0x4c)*/ + volatile uint32_t dmacr; + /* SPI DMA Transmit Data Level (0x50)*/ + volatile uint32_t dmatdlr; + /* SPI DMA Receive Data Level (0x54)*/ + volatile uint32_t dmardlr; + /* SPI Identification Register (0x58)*/ + volatile uint32_t idr; + /* SPI DWC_ssi component version (0x5c)*/ + volatile uint32_t ssic_version_id; + /* SPI Data Register 0-36 (0x60 -- 0xec)*/ + volatile uint32_t dr[36]; + /* SPI RX Sample Delay Register (0xf0)*/ + volatile uint32_t rx_sample_delay; + /* SPI SPI Control Register (0xf4)*/ + volatile uint32_t spi_ctrlr0; + /* reserved (0xf8)*/ + volatile uint32_t resv; + /* SPI XIP Mode bits (0xfc)*/ + volatile uint32_t xip_mode_bits; + /* SPI XIP INCR transfer opcode (0x100)*/ + volatile uint32_t xip_incr_inst; + /* SPI XIP WRAP transfer opcode (0x104)*/ + volatile uint32_t xip_wrap_inst; + /* SPI XIP Control Register (0x108)*/ + volatile uint32_t xip_ctrl; + /* SPI XIP Slave Enable Register (0x10c)*/ + volatile uint32_t xip_ser; + /* SPI XIP Receive FIFO Overflow Interrupt Clear Register (0x110)*/ + volatile uint32_t xrxoicr; + /* SPI XIP time out register for continuous transfers (0x114)*/ + volatile uint32_t xip_cnt_time_out; + volatile uint32_t endian; +} __attribute__((packed, aligned(4))) spi_t; +/* clang-format on */ + +typedef enum _spi_device_num +{ + SPI_DEVICE_0, + SPI_DEVICE_1, + SPI_DEVICE_2, + SPI_DEVICE_3, + SPI_DEVICE_MAX, +} spi_device_num_t; + +typedef enum _spi_work_mode +{ + SPI_WORK_MODE_0, + SPI_WORK_MODE_1, + SPI_WORK_MODE_2, + SPI_WORK_MODE_3, +} spi_work_mode_t; + +typedef enum _spi_frame_format +{ + SPI_FF_STANDARD, + SPI_FF_DUAL, + SPI_FF_QUAD, + SPI_FF_OCTAL +} spi_frame_format_t; + +typedef enum _spi_instruction_address_trans_mode +{ + SPI_AITM_STANDARD, + SPI_AITM_ADDR_STANDARD, + SPI_AITM_AS_FRAME_FORMAT +} spi_instruction_address_trans_mode_t; + +typedef enum _spi_transfer_mode +{ + SPI_TMOD_TRANS_RECV, + SPI_TMOD_TRANS, + SPI_TMOD_RECV, + SPI_TMOD_EEROM +} spi_transfer_mode_t; + + +typedef enum _spi_transfer_width +{ + SPI_TRANS_CHAR = 0x1, + SPI_TRANS_SHORT = 0x2, + SPI_TRANS_INT = 0x4, +} spi_transfer_width_t; + +typedef enum _spi_chip_select +{ + SPI_CHIP_SELECT_0, + SPI_CHIP_SELECT_1, + SPI_CHIP_SELECT_2, + SPI_CHIP_SELECT_3, + SPI_CHIP_SELECT_MAX, +} spi_chip_select_t; + +typedef enum +{ + WRITE_CONFIG, + READ_CONFIG, + WRITE_DATA_BYTE, + READ_DATA_BYTE, + WRITE_DATA_BLOCK, + READ_DATA_BLOCK, +} spi_slave_command_e; + +typedef struct +{ + uint8_t cmd; + uint8_t err; + uint32_t addr; + uint32_t len; +} spi_slave_command_t; + +typedef enum +{ + IDLE, + COMMAND, + TRANSFER, +} spi_slave_status_e; + +typedef int (*spi_slave_receive_callback_t)(void *ctx); + +typedef struct _spi_slave_instance +{ + uint8_t int_pin; + uint8_t ready_pin; + dmac_channel_number_t dmac_channel; + uint8_t dfs; + uint8_t slv_oe; + uint8_t work_mode; + size_t data_bit_length; + volatile spi_slave_status_e status; + volatile spi_slave_command_t command; + volatile uint8_t *config_ptr; + uint32_t config_len; + spi_slave_receive_callback_t callback; +} spi_slave_instance_t; + +typedef struct _spi_data_t +{ + dmac_channel_number_t tx_channel; + dmac_channel_number_t rx_channel; + uint32_t *tx_buf; + size_t tx_len; + uint32_t *rx_buf; + size_t rx_len; + spi_transfer_mode_t TransferMode; + bool fill_mode; +} spi_data_t; + +extern volatile spi_t *const spi[4]; + +/** + * @brief Set spi configuration + * + * @param[in] spi_num Spi bus number + * @param[in] mode Spi mode + * @param[in] frame_format Spi frame format + * @param[in] data_bit_length Spi data bit length + * @param[in] endian 0:little-endian 1:big-endian + * + * @return Void + */ +void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format, + size_t data_bit_length, uint32_t endian); + +/** + * @brief Set multiline configuration + * + * @param[in] spi_num Spi bus number + * @param[in] instruction_length Instruction length + * @param[in] address_length Address length + * @param[in] wait_cycles Wait cycles + * @param[in] instruction_address_trans_mode Spi transfer mode + * + */ +void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length, + uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode); + +/** + * @brief Spi send data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi receive data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special receive data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special send data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi send data by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint8_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi receive data by dma + * + * @param[in] w_channel_num Dmac write channel number + * @param[in] r_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special send data by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint32_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi special receive data by dma + * + * @param[in] dma_send_channel_num Dmac write channel number + * @param[in] dma_receive_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi fill dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buff Spi command buffer point + * @param[in] tx_len Spi command length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint32_t *tx_buff, size_t tx_len); + +/** + * @brief Spi normal send by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * @param[in] stw Spi transfer width + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width); + +/** + * @brief Spi normal send by dma + * + * @param[in] spi_num Spi bus number + * @param[in] spi_clk Spi clock rate + * + * @return The real spi clock rate + */ +uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk); + +/** + * @brief Spi full duplex send receive data by dma + * + * @param[in] dma_send_channel_num Dmac write channel number + * @param[in] dma_receive_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buf Spi send buffer + * @param[in] tx_len Spi send buffer length + * @param[in] rx_buf Spi receive buffer + * @param[in] rx_len Spi receive buffer length + * + */ +void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len); + +/** + * @brief Set spi slave configuration + * + * @param[in] int_pin SPI master starts sending data interrupt. + * @param[in] ready_pin SPI slave ready. + * @param[in] dmac_channel Dmac channel number for block. + * @param[in] data_bit_length Spi data bit length + * @param[in] data SPI slave device data buffer. + * @param[in] len The length of SPI slave device data buffer. + * @param[in] callback Callback of spi slave. + * + * @return Void + */ +void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback); + +/** + * @brief Spi handle transfer data operations + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] data Spi transfer data information + * @param[in] cb Spi DMA callback + * + */ +void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb); + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_SPI_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/socket.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/socket.h new file mode 100755 index 000000000..91e1a7bd9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/socket.h @@ -0,0 +1,585 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has + * much similar name and interface. But there is a little bit of difference. + * @details + * Comparison between WIZnet and Berkeley SOCKET APIs + * + * + * + * + * + * + * + * + * + * + * + * + * + *
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating + * a SOCKET but also binding a local port number, and listen() of WIZnet is not + * only listening to connection request from client but also accepting the + * connection request. \n When you program "TCP SERVER" with Berkeley SOCKET + * API, you can use only one listen port. When the listen SOCKET accepts a + * connection request from a client, it keeps listening. After accepting the + * connection request, a new SOCKET is created and the new SOCKET is used in + * communication with the client. \n Following figure shows network flow diagram + * by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as + * many as 8 listen SOCKET with same port number. \n Because there's no accept() + * in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request + * from a client, it is changed in order to communicate with the client. And the + * changed SOCKET is not listening any more and is dedicated for communicating + * with the client. \n If there're many listen SOCKET with same listen port + * number and a client requests a connection, the SOCKET which has the smallest + * SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY \ + 0 ///< Socket is busy on processing the operation. Valid only Non-block IO + ///< Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT \ + (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address + ///< when Sn_MR_TCP +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE \ + (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS \ + (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN \ + (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER \ + (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN \ + (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN \ + (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, + ///< multicast and own packet +#define SF_IGMP_VER2 \ + (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP + ///< version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE \ + (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 +#define SF_BROAD_BLOCK \ + (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast + ///< packet. Valid only in W5500 +#define SF_MULTI_BLOCK \ + (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in + ///< W5500 +#define SF_IPv6_BLOCK \ + (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in + ///< W5500 +#define SF_UNI_BLOCK \ + (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only + ///< in W5500 +#endif + +// A201505 : For W5300 +#if _WIZCHIP_ == 5300 +#define SF_TCP_ALIGN \ + 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN +#endif + +#define SF_IO_NONBLOCK \ + 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST \ + 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When + ///< W5300, This flag can be applied) +#define PACK_REMAINED \ + 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. + ///< (When W5300, This flag can be applied) +#define PACK_COMPLETED \ + 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + ///< (When W5300, This flag can be applied) +// A20150601 : For Integrating with W5300 +#define PACK_FIFOBYTE \ + 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR. +// + +#ifndef AF_WIZ +#define AF_WIZ 46 +#endif + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref + * SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n Valid + * flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref + * SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as + * TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t wiz_sock_close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is + * established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t wiz_sock_listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and + * port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediately. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request + * connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned + * immediately\n + */ +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as + parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. + \n + * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t wiz_sock_disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data + * greater than socket buffer size. \n In block io mode, It doesn't return until + * data send is completed - socket buffer size is greater than data. \n In + * non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is + * not enough. \n + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in + * the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data + * greater than socket buffer size. \n In block io mode, it doesn't return until + * data reception is completed - data is filled as len in socket buffer. + * \n In non-block io mode, it return @ref SOCK_BUSY immediately when len + * is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket + * \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port + * number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP + * address and port number passed as parameter.\n Even if the connectionless + * socket has been previously connected to a specific address, the address and + * port number parameters override the destination address for that particular + * datagram only. + * @note In block io mode, It doesn't return until data send is completed - + * socket buffer size is greater than len. In non-block io mode, It + * return @ref SOCK_BUSY immediately when socket buffer is not enough. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed + * \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to + * receive the data in other then TCP mode. \n This function is used to receive + * UDP and MAC_RAW mode, and handle the header as well. This function can divide + * to received the packet data. On the MACRAW SOCKET, the addr and port + * parameters are ignored. + * @note In block io mode, it doesn't return until data reception is + * completed - data is filled as len in socket buffer In non-block io + * mode, it return @ref SOCK_BUSY immediately when len is greater than + * data size in socket buffer. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet + * sized. When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. It is valid only when the first call recvfrom for + * receiving the packet. When it is valid, @ref packinfo[7] should be set as + * '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the + * packet. When it is valid, @ref packinfo[7] should be set as '1' after call + * @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for + * success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port); + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum { + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + // M20150410 : Remove the comma of last member + // SIK_ALL = 0x1F, ///< all interrupt + SIK_ALL = 0x1F ///< all interrupt +} sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum { + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref + ///< SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind +#if _WIZCHIP_ > 5100 + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, + ///< Not supported in W5100 + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref + ///< sockint_kind, Not supported in W5100 +#endif +} ctlsock_type; + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum { + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to + ///< flag in @ref socket(). + SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref + ///< setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref + ///< setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive + ///< packet in TCP mode, Not supported in W5100 +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP + ///< mode, Not supported in W5100, W5200 +#endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt + ///< TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in + ///< socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, + ///< @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in + ///< other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref + ///< PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in + ///< other then TCP mode. +} sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket + * buffer information. Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. + * \n + *
@b cstype @b data type@b + * value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE + * uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
+ * @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 + * ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n + * @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind + * @ref SIK_CONNECTED, etc.
+ * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref + * sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + *
@b sotype @b data type@b + * value
@ref SO_TTL uint8_t 0 ~ 255 + *
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ + * 65535
@ref SO_KEEPALIVESEND null + * null
@ref SO_KEEPALIVEAUTO uint8_t + * 0 ~ 255
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet + * \n + */ +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref + * sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + *
@b sotype @b data type@b + * value
@ref SO_FLAG uint8_t @ref + * SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t + * 0 ~ 255
@ref SO_MSS uint16_t + * 0 ~ 65535
@ref SO_DESTIP + * uint8_t[4]
@ref SO_DESTPORT + * uint16_t
@ref SO_KEEPALIVEAUTO + * uint8_t 0 ~ 255
@ref SO_SENDBUF + * uint16_t 0 ~ 65535
@ref SO_RECVBUF + * uint16_t 0 ~ 65535
@ref SO_STATUS + * uint8_t @ref SOCK_ESTABLISHED, etc..
@ref + * SO_REMAINSIZE uint16_t 0~ 65535
+ * @ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc... + *
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode + * and after call @ref recvfrom(). \n When SO_PACKINFO value is PACK_FIRST and + * the return value of recvfrom() is zero, This means the zero byte UDP data(UDP + * Header only) received. + */ +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif // _SOCKET_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/w5500.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/w5500.h new file mode 100755 index 000000000..121baab06 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/w5500.h @@ -0,0 +1,2321 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +// + +#ifndef _W5500_H_ +#define _W5500_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" +#include + + +/// @cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5500) +/// @endcond + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ \ + (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ \ + (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1 + 4 * N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2 + 4 * N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3 + 4 * N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) \ + (ADDR + (N << 8)) //< Increase offset address + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) \ + WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR, VAL) \ + WIZCHIP_WRITE(ADDR, VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR, BUF, LEN) \ + WIZCHIP_READ_BUF(ADDR, BUF, LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR, BUF, LEN) \ + WIZCHIP_WRITE(ADDR, BUF, LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref + * Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref + * Common_register_access_function and @ref Socket_register_access_function + */ + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), + * setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), + * setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), + * getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), + * setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), + * getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() getSn_MSSR(), + * setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), + * setSn_TXBUF_SIZE() \n getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data + * communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, + * Sn_RX_RD, Sn_RX_WR : Data communication + */ + +/** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or + * write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end +//-------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP +//----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + * + * + *
7 6 5 4 32 1 0
RST ReservedWOL PB PPPoE Reserved FARPReserved
+ * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be + * still until the bit will be written to by the host. If @ref IR is not equal + * to x00 INTn PIN is asserted to low until it is x00\n\n Each bit of @ref IR + * defined as follows. + * + * + * + *
7 6 5 43 2 1 0
CONFLICTUNREACH PPPoE MP ReservedReserved Reserved Reserved
+ * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ + * corresponds to each bit of @ref IR. When a bit of @ref _IMR_ is and the + * corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref _IMR_ is an interrupt will not be issued even if the + * corresponding bit of @ref IR is \n\n Each bit of @ref _IMR_ defined as the + * following. + * + * + * + *
7 6 5 43 2 1 0
IM_IR7IM_IR6 IM_IR5 IM_IR4 ReservedReserved Reserved Reserved
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is + * asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt + * will be issued. In other words, if a bit of @ref SIMR is an interrupt will + * be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref _RTR_ configures the retransmission timeout period. The unit of + * timeout period is 100us and the default of @ref _RTR_ is x07D0. And so the + * default timeout period is 200ms(100us X 2000). During the time configured by + * @ref _RTR_, W5500 waits for the peer response to the packet that is + * transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP + * command). If the peer does not respond within the @ref _RTR_ time, W5500 + * retransmits the packet or issues timeout. + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued + * (@ref Sn_IR_TIMEOUT = '1'). + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The + * unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP + * negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is + * acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during + * PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In + * addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, + * Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +//----------------------------- W5500 Socket Registers IOMAP +//----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + * + * + *
7 6 5 4 32 1 0
MULTI/MFENBCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3]Protocol[2] Protocol[1] Protocol[0]
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + * + * + *
Protocol[3] Protocol[2]Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0MACRAW
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) \ + (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, + * CONNECT, LISTEN, SEND, and RECEIVE.\n After W5500 accepts the command, the + * @ref Sn_CR register is automatically cleared to 0x00. Even though @ref Sn_CR + * is cleared to 0x00, the command is still being processed.\n To check whether + * the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server + * mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client + * mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP + * process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) \ + (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as + * establishment, termination, receiving data, timeout).\n When an interrupt + * occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes \n In order to clear the @ref Sn_IR bit, the host should + * write the bit to \n + * + * + * + *
7 6 5 43 2 1 0
ReservedReserved Reserved SEND_OK TIMEOUTRECV DISCON CON
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) \ + (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control + *packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the + *connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received + *the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) \ + (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before + * OPEN command is ordered. + */ +#define Sn_PORT(N) \ + (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n + * when using SEND_MAC command in UDP mode or it indicates that it is acquired + * in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) \ + (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP client + * mode, it configures an IP address of TCP serverbefore CONNECT command. In TCP + * server mode, it indicates an IP address of TCP clientafter successfully + * establishing connection. In UDP mode, it configures an IP address of peer to + * be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) \ + (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP + * clientmode, it configures the listen port number of TCP serverbefore CONNECT + * command. In TCP Servermode, it indicates the port number of TCP client after + * successfully establishing connection. In UDP mode, it configures the port + * number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) \ + (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) + * of Socket n. + */ +#define Sn_MSSR(N) \ + (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) + * of Socket n. It is set before OPEN command. + */ +#define Sn_TOS(N) \ + (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of + * Socket n. It is set before OPEN command. + */ +#define Sn_TTL(N) \ + (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from + * a peer. Although Socket n RX Buffer Block size is initially configured to + * 2Kbytes, user can re-configure its size using @ref Sn_RXBUF_SIZE. The total + * sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. When exceeded, the data + * reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. + * Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to + * a peer. Although Socket n TX Buffer Block size is initially configured to + * 2Kbytes, user can be re-configure its size using @ref Sn_TXBUF_SIZE. The + * total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. When exceeded, + * the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. + * It is initialized to the configured size by @ref Sn_TXBUF_SIZE. Data bigger + * than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the + * bigger data overwrites the previous saved data not yet sent. Therefore, check + * before saving the data to the Socket n TX Buffer, and if data is equal or + * smaller than its checked size, transmit the data with SEND/SEND_MAC command + * after saving the data in Socket n TX buffer. But, if data is bigger than its + * checked size, transmit the data after dividing into the checked size and + * saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) \ + (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP. After its initialization, it is auto-increased by SEND command. SEND + * command transmits the saved data from the current @ref Sn_TX_RD to the @ref + * Sn_TX_WR in the Socket n TX Buffer. After transmitting the saved data, the + * SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. If its + * increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and + * the carry bit occurs), then the carry bit is ignored and will automatically + * update with the lower 16bits value. + */ +#define Sn_TX_RD(N) \ + (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP.\n It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX + * buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased + * value as many as transmitting data size. If the increment value exceeds the + * maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), then the + * carry bit is ignored and will automatically update with the lower 16bits + * value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) \ + (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket + * n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as + * the difference between �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket + * n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) \ + (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read + * or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased + * value as many as the reading size. If the increment value exceeds the maximum + * value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) \ + (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is + * auto-increased by the data reception. If the increased value exceeds the + * maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), then + * the carry bit is ignored and will automatically update with the lower 16bits + * value. + */ +#define Sn_RX_WR(N) \ + (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is + * occurred and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref + * Sn_IR are and the n-th bit of @ref IR is Host is interrupted by asserted INTn + * PIN to low. + */ +#define Sn_IMR(N) \ + (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) \ + (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP + * ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, and ignored in + * other modes. The time unit is 5s. KA packet is transmittable after @ref Sn_SR + * is changed to SOCK_ESTABLISHED and after the data is transmitted or received + * to/from a peer at least once. In case of '@ref Sn_KPALVTR > 0', W5500 + * automatically transmits KA packet after time-period for checking the TCP + * connection (Auto-keepalive-process). In case of '@ref Sn_KPALVTR = 0', + * Auto-keep-alive-process will not operate, and KA packet can be transmitted by + * SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) \ + (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + +//(WIZCHIP_SREG_BLOCK(N) << 3)) + +//----------------------------- W5500 Register values +//----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will + * be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been + * normally processed, the Interrupt PIN (INTn) asserts to low. When using WOL + * mode, the UDP Socket should be opened with any source port number. (Refer to + * Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes + * synchronization stream (xFFFFFFFFFFFF and 16 times Target MAC address stream + * in UDP payload. The options such like password are ignored. You can use any + * UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP + * address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this + * bit is set as When this bit is Destination Information such as IP address + * and Port number may be checked with the corresponding @ref UIPR & @ref + * UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, + * this bit is set. + */ +#define IR_MP 0x10 + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1 << 7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1 << 6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7 << 3) +#define PHYCFGR_OPMDC_PDOWN (6 << 3) +#define PHYCFGR_OPMDC_NA (5 << 3) +#define PHYCFGR_OPMDC_100FA (4 << 3) +#define PHYCFGR_OPMDC_100F (3 << 3) +#define PHYCFGR_OPMDC_100H (2 << 3) +#define PHYCFGR_OPMDC_10F (1 << 3) +#define PHYCFGR_OPMDC_10H (0 << 3) +#define PHYCFGR_DPX_FULL (1 << 2) +#define PHYCFGR_DPX_HALF (0 << 2) +#define PHYCFGR_SPD_100 (1 << 1) +#define PHYCFGR_SPD_10 (0 << 1) +#define PHYCFGR_LNK_ON (1 << 0) +#define PHYCFGR_LNK_OFF (0 << 0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively + * configured with the multicast group IP address & port number before Socket n + * is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = + * 010.\m In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data + * packet is received from a peer.\n When this bit is It sends the ACK packet + * after waiting for the timeout time configured by @ref _RTR_. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and + * MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to + * itself. When this bit is W5500 can receive all packets on Ethernet. If user + * wants to implement Hybrid TCP/IP stack, it is recommended that this bit is + * set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to + * receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive + * the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol + * selected in Sn_MR(P3:P0). The table below shows the value of @ref Sn_SR + * corresponding to @ref Sn_MR.\n + * + * + * + * + *
\b Sn_MR (P[3:0])\b Sn_SR
Sn_MR_CLOSE + * (000)
Sn_MR_TCP (001) SOCK_INIT (0x13)
Sn_MR_UDP (010) SOCK_UDP (0x22)
S0_MR_MACRAW (100) SOCK_MACRAW (0x02)
+ */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP). + * In this mode, Socket n operates as a TCP serverand waits for + * connection-request (SYN packet) from any TCP client The @ref Sn_SR changes + * the state from \ref SOCK_INIT to \ref SOCKET_LISTEN. When a TCP + * clientconnection request is successfully established, the @ref Sn_SR changes + * from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes But when a + * TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status + * of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP + * serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref + * SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n The connect-request fails in + * the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware + * address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these + * cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as + * TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON + * command processes the disconnect-process (b>Active closeor Passive + * close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the + * peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet + * is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to + * @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref + * Sn_TX_FSR), Socket n, TX Write Pointer Register(@ref Sn_TX_WR), and Socket n + * TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired + * by the automatic ARP-process(Address Resolution Protocol).\n But SEND_MAC + * transmits data without the automatic ARP-process.\n In this case, the + * destination hardware address is acquired from @ref Sn_DHAR configured by + * host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive + * packet.\n If the peer can not respond to the keep-alive packet during timeout + * time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX + * Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n For more + * details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket + * n RX Write Pointer Register (@ref Sn_RX_WR), and Socket n RX Read Pointer + * Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful + * and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed + * to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN + * command is ordered.\n After @ref SOCK_INIT, user can use LISTEN /CONNECT + * command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and + * waiting for connection-request (SYN packet) from a peer TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is + * successfully accepted.\n Otherwise it will change to @ref SOCK_CLOSED after + * TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred. + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) + * to a peer.\n It is temporarily shown when @ref Sn_SR is changed from @ref + * SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n If + * connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it + * changes to @ref SOCK_ESTABLISHED.\n Otherwise, it changes to @ref SOCK_CLOSED + * after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request + * packet (SYN packet) from a peer.\n If socket n sends the response (SYN/ACK + * packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n If + * not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') + * is occurred. + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the + * SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or when the + * CONNECT command is successful.\n During @ref SOCK_ESTABLISHED, DATA packet + * can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) + * from the connected peer.\n This is half-closing status, and data can be + * transferred.\n For full-closing, DISCON command is used. But For + * just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) + * to the disconnect-request (FIN packet) by passive-close.\n It changes to @ref + * SOCK_CLOSED when Socket n received the response successfully, or when + * timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = + * '010').\n It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref + * Sn_CR_OPEN command is ordered.\n Unlike TCP mode, data can be transfered + * without the connection-process. + */ +#define SOCK_UDP 0x22 + +#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = + * 100and is valid only in Socket 0.\n It changes to SOCK_MACRAW when + * S0_MR(P[3:0] = 100and OPEN command is ordered.\n Like UDP mode socket, MACRAW + * mode Socket 0 can transfer a MAC packet (Ethernet frame) without the + * connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt.\n In OS environment, You can replace it to critical section api + * supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt. \n In OS environment, You can replace it to critical section api + * supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ(uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) WIZCHIP_WRITE(MR, mr) + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be + * allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) WIZCHIP_WRITE_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be + * allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) WIZCHIP_READ_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should + * be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) WIZCHIP_WRITE_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should + * be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be + * allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be + * allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be + * allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be + * allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) \ + { \ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL, 1), (uint8_t)intlevel); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +// M20150401 : Type explict declaration +/* +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) +*/ +#define getINTLEVEL() \ + (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) \ + { \ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_, 1), (uint8_t)rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +// M20150401 : Type explict declaration +/* +#define getRTR() \ + ((WIZCHIP_READ(_RTR_) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) +*/ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() WIZCHIP_READ(_RCR_) + +//================================================== test done +//=========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHAR address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) \ + { \ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID, 1), (uint8_t)psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +// uint16_t getPSID(void); +// M20150401 : Type explict declaration +/* +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) +*/ +#define getPSID() \ + (((uint16_t)WIZCHIP_READ(PSID) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) \ + { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU, 1), (uint8_t)pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +// M20150401 : Type explict declaration +/* +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) +*/ +#define getPMRU() \ + (((uint16_t)WIZCHIP_READ(PMRU) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It + * should be allocated 4 bytes. + */ +// M20150401 : Size Error of UIPR (6 -> 4) +/* +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) +*/ +#define getUIPR(uipr) WIZCHIP_READ_BUF(UIPR, uipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +// M20150401 : Type explict declaration +/* +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) +*/ +#define getUPORTR() \ + (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) WIZCHIP_WRITE(Sn_MR(sn), mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) \ + { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1), (uint8_t)port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) +*/ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP + * address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP + * address. It should be allocated 4 bytes. + * @sa setSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) \ + { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t)(dport >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1), (uint8_t)dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) +*/ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) \ + { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1), (uint8_t)mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) +*/ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn), rxbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) +*/ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) \ + { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1), (uint8_t)txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) +*/ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) \ + { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1), (uint8_t)rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) +*/ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) +*/ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) \ + { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1), (uint8_t)frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +// M20150401 : Type explict declaration +/* +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) +*/ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) +*/ +#define getSn_RxMAX(sn) (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10) + +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) +*/ +#define getSn_TxMAX(sn) (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of + * len(variable) bytes to internal TX memory and updates the Tx write + * pointer register. This function is being called by send() and sendto() + * function also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) + * bytes. This function is being called by recv() also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in + * internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif // _W5500_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/wizchip_conf.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/wizchip_conf.h new file mode 100755 index 000000000..a58da3a19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/wizchip_conf.h @@ -0,0 +1,704 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP + * I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, + * network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b + * W5500 or etc. \n\n ex> #define \_WIZCHIP_ W5500 + */ + +#define W5100 5100 +#define W5100S 5100 + 5 +#define W5200 5200 +#define W5300 5300 +#define W5500 5500 + +#ifndef _WIZCHIP_ +#define _WIZCHIP_ W5500 // W5100, W5100S, W5200, W5300, W5500 +#endif + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length \ \ \ + data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 2) /**< SPI interface mode for fixed length data mode*/ +#define _WIZCHIP_IO_MODE_SPI_5500_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 3) /**< SPI interface mode for fixed length data mode*/ + +#if (_WIZCHIP_ == W5100) +#define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100/w5100.h" + +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_ID_ "W5100S\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_5500_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100S/w5100s.h" +#elif (_WIZCHIP_ == W5200) +#define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ or @ref \ _WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "W5200/w5200.h" +#elif (_WIZCHIP_ == W5500) +#define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + * + * + */ +#ifndef _WIZCHIP_IO_MODE_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "w5500.h" +#elif (_WIZCHIP_ == W5300) +#define _WIZCHIP_ID_ "W5300\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#endif + +// A20150601 : Define the unit and bus width of IO DATA. +/** + * @brief Select the data width 8 or 16 bits. + * @todo you should select the bus width. Select one of 8 or 16. + */ +#ifndef _WIZCHIP_IO_BUS_WIDTH_ +#define _WIZCHIP_IO_BUS_WIDTH_ 16 // 8 +#endif +#if _WIZCHIP_IO_BUS_WIDTH_ == 8 +typedef uint8_t iodata_t; +#elif _WIZCHIP_IO_BUS_WIDTH_ == 16 +typedef uint16_t iodata_t; +#else +#error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16." +#endif +// +#include "W5300/w5300.h" +#else +#error \ + "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ +#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref + * \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). + * \n\n ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 + */ +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +// #define _WIZCHIP_IO_BASE_ 0x60000000 +//// for 5100S IND +#define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 +#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // for 5100S SPI +#endif + +#ifndef _WIZCHIP_IO_BASE_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000 +#endif + +// M20150401 : Typing Error +//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +#ifndef _WIZCHIP_IO_BASE_ +#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." +#endif +#endif + +#if _WIZCHIP_ >= W5200 +#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else +#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + +/******************************************************** + * WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. + *********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions + * W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP { + uint16_t if_mode; ///< host interface mode + uint8_t id[8]; ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b + ///< 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS { + void (*_enter)(void); ///< crtical section enter + void (*_exit)(void); ///< critial section exit + } CRIS; + /** + * The set of @ref \_WIZCHIP_ select control callback func. + */ + struct _CS { + void (*_select)(void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + } CS; + /** + * The set of interface IO callback func. + */ + union _IF { + /** + * For BUS interface IO + */ + // M20156501 : Modify the function name for integrating with W5300 + // struct + //{ + // uint8_t (*_read_byte) (uint32_t AddrSel); + // void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + //}BUS; + struct { + iodata_t (*_read_data)(uint32_t AddrSel); + void (*_write_data)(uint32_t AddrSel, iodata_t wb); + } BUS; + + /** + * For SPI interface IO + */ + struct { + uint8_t (*_read_byte)(void); + void (*_write_byte)(uint8_t wb); + void (*_read_burst)(uint8_t *pBuf, uint16_t len); + void (*_write_burst)(uint8_t *pBuf, uint16_t len); + } SPI; + // To be added + // + } IF; +} _WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum { + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 + ///< dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500 + CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation + ///< mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only + ///< W5500 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when + ///< PHYSTATUS.OPMD == 1. Valid Only W5500 + //#endif + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only + ///< W5100, W5200 + CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200 + //#endif +} ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum { + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +} ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum { +#if _WIZCHIP_ == W5500 + IK_WOL = + (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#elif _WIZCHIP_ == W5300 + IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU) +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != W5200 + IK_DEST_UNREACH = + (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > W5100S + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > W5100S + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt +#endif +} intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO \ + 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in + * W5500, and it indicates the real PHY status configured by HW or SW in all + * WIZCHIP. \n Valid only in W5500. + */ +typedef struct wiz_PhyConf_t { + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + // uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + // uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref + // PHY_LINK_ON or PHY_DUPLEX_OFF +} wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum { + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +} dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t { + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +} wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum { +#if _WIZCHIP_ == W5500 + NM_FORCEARP = (1 << 1), ///< Force to APP send whenever udp data is sent. + ///< Valid only in W5500 +#endif + NM_WAKEONLAN = (1 << 5), ///< Wake On Lan + NM_PINGBLOCK = (1 << 4), ///< Block ping-request + NM_PPPOE = (1 << 3), ///< PPPoE mode +} netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout + * configruation. + */ +typedef struct wiz_NetTimeout_t { + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +} wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such + *as \ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref + *WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT + *marco or register your functions. + *@note If you do not describe or register, default functions(@ref + *wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)); + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or + *register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +// M20150601 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)); +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte using SPI + *@param spi_wb : callback function to write byte using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to burst read using SPI + *@param spi_wb : callback function to burst write using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor + * PHY(Link,Speed,Half/Full/Auto), controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref + * ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref + * ctlnetwork_type in WIZCHIP \n 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg); + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of + * ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size + * 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size + * 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to + * uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +// todo +#if _WIZCHIP_ > W5100 +int8_t wizphy_getphylink( + void); ///< get the link status of phy in WIZCHIP. No use in W5100 +int8_t wizphy_getphypmode( + void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 + /** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_setphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphystat(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in + * W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ +int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** + * @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout *nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout *nettime); +#ifdef __cplusplus +} +#endif + +#endif // _WIZCHIP_CONF_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Kconfig new file mode 100644 index 000000000..9eb26b6a3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Kconfig @@ -0,0 +1,66 @@ +config BSP_USING_SPI1 +bool "Using spi1 " +default y + + +if BSP_USING_SPI1 + config SPI_BUS_NAME_1 + string "spi bus 1 name" + default "spi1" + config SPI_1_DRV_NAME + string "spi bus 1 driver name" + default "spi1_drv" + config BSP_SPI1_CLK_PIN + int "spi1 clk pin number" + default 9 + config BSP_SPI1_D0_PIN + int "spi1 d0 pin number" + default 11 + config BSP_SPI1_D1_PIN + int "spi1 d1 pin number" + default 10 + menuconfig BSP_SPI1_USING_SS0 + bool "SPI1 Enable SS0" + default y + if BSP_SPI1_USING_SS0 + config SPI_1_DEVICE_NAME_0 + string "spi bus 1 device 0 name" + default "spi1_dev0" + config BSP_SPI1_SS0_PIN + int "spi1 ss0 pin number" + default 12 + menuconfig BSP_SPI1_USING_SS1 + bool "SPI1 Enable SS1" + default n + endif + if BSP_SPI1_USING_SS1 + config SPI_1_DEVICE_NAME_1 + string "spi bus 1 device 1 name" + default "spi1_dev1" + config BSP_SPI1_SS1_PIN + int "spi1 ss1 pin number" + default 13 + endif + menuconfig BSP_SPI1_USING_SS2 + bool "SPI1 Enable SS2" + default n + if BSP_SPI1_USING_SS2 + config SPI_1_DEVICE_NAME_2 + string "spi bus 1 device 2 name" + default "spi1_dev2" + config BSP_SPI1_SS2_PIN + int "spi1 ss2 pin number" + default 26 + endif + menuconfig BSP_SPI1_USING_SS3 + bool "SPI1 Enable SS3" + default n + if BSP_SPI1_USING_SS3 + config SPI_1_DEVICE_NAME_3 + string "spi bus 1 device 3 name" + default "spi1_dev3" + config BSP_SPI1_SS3_PIN + int "spi1 ss3 pin number" + default 27 + endif +endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Makefile new file mode 100644 index 000000000..945c415a4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_spi.c hardware_spi.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/connect_spi.c new file mode 100644 index 000000000..4191b4e6b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/connect_spi.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2020 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-18 ZYH first version + */ + +/** + * @file connect_spi.c + * @brief support aiit-riscv64-board spi function and register to bus framework + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2021-04-25 + */ + +/************************************************* +File name: connect_spi.c +Description: support aiit-riscv64-board spi configure and spi bus register +function Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_spi.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. support aiit-riscv64-board spi configure, write and read +2. support aiit-riscv64-board spi bus device and driver register +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BSP_SPI1_USING_SS0 +#define SPI_DEVICE_SLAVE_ID_0 0 +#endif + +#ifdef BSP_SPI1_USING_SS1 +#define SPI_DEVICE_SLAVE_ID_1 1 +#endif + +#ifdef BSP_SPI1_USING_SS2 +#define SPI_DEVICE_SLAVE_ID_2 2 +#endif + +#ifdef BSP_SPI1_USING_SS3 +#define SPI_DEVICE_SLAVE_ID_3 3 +#endif + +static volatile spi_t *const spi_instance[4] = { + (volatile spi_t *)SPI0_BASE_ADDR, (volatile spi_t *)SPI1_BASE_ADDR, + (volatile spi_t *)SPI_SLAVE_BASE_ADDR, (volatile spi_t *)SPI3_BASE_ADDR}; + +void __spi_set_tmod(uint8_t spi_num, uint32_t tmod) { + CHECK(spi_num < SPI_DEVICE_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + uint8_t tmod_offset = 0; + switch (spi_num) { + case 0: + case 1: + case 2: + tmod_offset = 8; + break; + case 3: + default: + tmod_offset = 10; + break; + } + set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset); +} + +/*Init the spi sdk intetface */ +static uint32 SpiSdkInit(struct SpiDriver *spi_drv) { + NULL_PARAM_CHECK(spi_drv); + uint8 cs_gpio_pin, cs_select_id; + uint32 max_frequency; + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + + cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + cs_select_id = dev_param->spi_slave_param->spi_cs_select_id; + + gpiohs_set_drive_mode(cs_select_id, + GPIO_DM_OUTPUT); // Set the cs pin as output + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); // set the cs gpio high + + spi_init(dev_param->spi_dma_param->spi_master_id, + dev_param->spi_master_param->spi_work_mode & SPI_MODE_3, + dev_param->spi_master_param->spi_frame_format, + dev_param->spi_master_param->spi_data_bit_width, + dev_param->spi_master_param->spi_data_endian); + + max_frequency = + (dev_param->spi_master_param->spi_maxfrequency < SPI_MAX_CLOCK) + ? dev_param->spi_master_param->spi_maxfrequency + : SPI_MAX_CLOCK; + + uint32 real_freq = + spi_set_clk_rate(dev_param->spi_dma_param->spi_master_id, max_frequency); + + return EOK; +} + +static uint32 SpiSdkCfg(struct SpiDriver *spi_drv, + struct SpiMasterParam *spi_param) { + NULL_PARAM_CHECK(spi_drv); + NULL_PARAM_CHECK(spi_param); + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + + dev_param->spi_master_param = spi_param; + dev_param->spi_master_param->spi_work_mode = + dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK; + dev_param->spi_master_param->spi_frame_format = SPI_FF_STANDARD; + + return EOK; +} + +/*Configure the spi device param, make sure struct + * (configure_info->private_data) = (SpiMasterParam)*/ +static uint32 SpiDrvConfigure(void *drv, + struct BusConfigureInfo *configure_info) { + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct SpiDriver *spi_drv = (struct SpiDriver *)drv; + struct SpiMasterParam *spi_param; + + switch (configure_info->configure_cmd) { + case OPE_INT: + ret = SpiSdkInit(spi_drv); + break; + case OPE_CFG: + spi_param = (struct SpiMasterParam *)configure_info->private_data; + ret = SpiSdkCfg(spi_drv, spi_param); + break; + default: + break; + } + + return ret; +} + +static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, + struct SpiDataStandard *spi_datacfg) { + DEBUG_PRINT + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 device_id = dev_param->spi_slave_param->spi_slave_id; + uint8 device_master_id = dev_param->spi_dma_param->spi_master_id; + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + + while (NONE != spi_datacfg) { + uint32_t *tx_buff = NONE; + int i; + x_ubase dummy = 0xFFFFFFFFU; + + __spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV); + + if (spi_datacfg->spi_chip_select) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + if (spi_datacfg->length) { + DEBUG_PRINT + spi_instance[device_master_id]->dmacr = 0x3; + spi_instance[device_master_id]->ssienr = 0x01; + + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, + SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2); + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, + SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id * 2); + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, + (void *)(&spi_instance[device_master_id]->dr[0]), + &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, + spi_datacfg->length); + + if (!spi_datacfg->tx_buff) { + dmac_set_single_mode( + dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, + (void *)(&spi_instance[device_master_id]->dr[0]), + DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, + DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } else { + tx_buff = x_malloc(spi_datacfg->length * 4); + if (!tx_buff) { + goto transfer_done; + } + for (i = 0; i < spi_datacfg->length; i++) { + tx_buff[i] = ((uint8_t *)spi_datacfg->tx_buff)[i]; + } + dmac_set_single_mode( + dev_param->spi_dma_param->spi_dmac_txchannel, tx_buff, + (void *)(&spi_instance[device_master_id]->dr[0]), + DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, + DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } + + spi_instance[device_master_id]->ser = + 1U << dev_param->spi_slave_param->spi_cs_select_id; + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel); + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel); + spi_instance[device_master_id]->ser = 0x00; + spi_instance[device_master_id]->ssienr = 0x00; + + transfer_done: + if (tx_buff) { + x_free(tx_buff); + } + } + + if (spi_datacfg->spi_cs_release) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_datacfg = spi_datacfg->next; + } + + DEBUG_PRINT + return EOK; +} + +static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, + struct SpiDataStandard *spi_datacfg) { + DEBUG_PRINT + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint32 spi_read_length = 0; + ; + uint8 device_id = dev_param->spi_slave_param->spi_slave_id; + uint8 device_master_id = dev_param->spi_dma_param->spi_master_id; + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + + DEBUG_PRINT + while (NONE != spi_datacfg) { + uint32_t *rx_buff = NONE; + int i; + x_ubase dummy = 0xFFFFFFFFU; + + __spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV); + + if (spi_datacfg->spi_chip_select) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + if (spi_datacfg->length) { + spi_instance[device_master_id]->dmacr = 0x3; + spi_instance[device_master_id]->ssienr = 0x01; + + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, + SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2); + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, + SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id * 2); + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, + (void *)(&spi_instance[device_master_id]->dr[0]), + DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, + DMAC_TRANS_WIDTH_32, spi_datacfg->length); + + if (!spi_datacfg->rx_buff) { + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, + (void *)(&spi_instance[device_master_id]->dr[0]), + &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, + spi_datacfg->length); + } else { + rx_buff = x_calloc(spi_datacfg->length * 4, 1); + if (!rx_buff) { + goto transfer_done; + } + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, + (void *)(&spi_instance[device_master_id]->dr[0]), + rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, + spi_datacfg->length); + } + + spi_instance[device_master_id]->ser = + 1U << dev_param->spi_slave_param->spi_cs_select_id; + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel); + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel); + spi_instance[device_master_id]->ser = 0x00; + spi_instance[device_master_id]->ssienr = 0x00; + + DEBUG_PRINT + if (spi_datacfg->rx_buff) { + for (i = 0; i < spi_datacfg->length; i++) { + ((uint8_t *)spi_datacfg->rx_buff)[i] = (uint8_t)rx_buff[i]; + } + } + + transfer_done: + if (rx_buff) { + x_free(rx_buff); + } + } + + if (spi_datacfg->spi_cs_release) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_read_length += spi_datacfg->length; + spi_datacfg = spi_datacfg->next; + } + + DEBUG_PRINT + return spi_read_length; +} + +/*manage the spi device operations*/ +static const struct SpiDevDone spi_dev_done = { + .dev_open = NONE, + .dev_close = NONE, + .dev_write = SpiWriteData, + .dev_read = SpiReadData, +}; + +static int BoardSpiBusInit(struct SpiBus *spi_bus, + struct SpiDriver *spi_driver) { + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, SPI_1_DRV_NAME); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the spi driver to the spi bus*/ + ret = SpiDriverAttachToBus(SPI_1_DRV_NAME, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the spi device to the spi bus*/ +static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) { + x_err_t ret = EOK; + +#ifdef BSP_SPI1_USING_SS0 + static struct SpiHardwareDevice spi_device0; + memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam0; + memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam0.spi_slave_id = SPI_DEVICE_SLAVE_ID_0; + spi_slaveparam0.spi_cs_gpio_pin = SPI1_CS0_PIN; + spi_slaveparam0.spi_cs_select_id = SPI_CHIP_SELECT_0; + + spi_device0.spi_param.spi_dma_param = spi_initparam; + spi_device0.spi_param.spi_slave_param = &spi_slaveparam0; + + spi_device0.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), + SPI_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_0, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS1 + static struct SpiHardwareDevice spi_device1; + memset(&spi_device1, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam1; + memset(&spi_slaveparam1, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam1.spi_slave_id = SPI_DEVICE_SLAVE_ID_1; + spi_slaveparam1.spi_cs_gpio_pin = SPI1_CS1_PIN; + spi_slaveparam1.spi_cs_select_id = SPI_CHIP_SELECT_1; + + spi_device1.spi_param.spi_dma_param = spi_initparam; + spi_device1.spi_param.spi_slave_param = &spi_slaveparam1; + + spi_device1.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device1, (void *)(&spi_device1.spi_param), + SPI_1_DEVICE_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_1, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_1, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_1, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS2 + static struct SpiHardwareDevice spi_device2; + memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice)); + + spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2; + spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN; + spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2; + + spi_device2.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device2, (void *)(&spi_device2.spi_param), + SPI_1_DEVICE_NAME_2); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_2, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_2, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_2, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS3 + static struct SpiHardwareDevice spi_device3; + memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice)); + + spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3; + spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN; + spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3; + + spi_device3.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device3, (void *)(&spi_device3.spi_param), + SPI_1_DEVICE_NAME_3); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_3, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_3, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_3, ret); + return ERROR; + } +#endif + return ret; +} + +/*RISC-V 64 BOARD SPI INIT*/ +int HwSpiInit(void) { + x_err_t ret = EOK; + static struct SpiDmaParam spi_initparam; + memset(&spi_initparam, 0, sizeof(struct SpiDmaParam)); + +#ifdef BSP_USING_SPI1 + + static struct SpiBus spi_bus; + memset(&spi_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver spi_driver; + memset(&spi_driver, 0, sizeof(struct SpiDriver)); + + spi_initparam.spi_master_id = SPI_DEVICE_1; + spi_initparam.spi_dmac_txchannel = DMAC_CHANNEL1; + spi_initparam.spi_dmac_rxchannel = DMAC_CHANNEL2; + + spi_driver.configure = &(SpiDrvConfigure); + + ret = BoardSpiBusInit(&spi_bus, &spi_driver); + if (EOK != ret) { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardSpiDevBend(&spi_initparam); + if (EOK != ret) { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/hardware_spi.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/hardware_spi.c new file mode 100644 index 000000000..2947682d3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/hardware_spi.c @@ -0,0 +1,1523 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_spi.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +volatile spi_t *const spi[4] = +{ + (volatile spi_t *)SPI0_BASE_ADDR, + (volatile spi_t *)SPI1_BASE_ADDR, + (volatile spi_t *)SPI_SLAVE_BASE_ADDR, + (volatile spi_t *)SPI3_BASE_ADDR +}; + +typedef struct _spi_dma_context +{ + uint8_t *buffer; + size_t BufLen; + uint32_t *MallocBuffer; + spi_transfer_mode_t IntMode; + dmac_channel_number_t dmac_channel; + spi_device_num_t spi_num; + plic_instance_t spi_int_instance; +} spi_dma_context_t; + +spi_dma_context_t spi_dma_context[4]; + +typedef struct _spi_instance_t +{ + spi_device_num_t spi_num; + spi_transfer_mode_t TransferMode; + dmac_channel_number_t dmac_channel; + plic_instance_t spi_int_instance; + spinlock_t lock; +} spi_instance_t; + +static spi_instance_t g_spi_instance[4]; + +static spi_slave_instance_t g_instance; + +static spi_frame_format_t spi_get_frame_format(spi_device_num_t spi_num) +{ + uint8_t frf_offset; + switch(spi_num) + { + case 0: + case 1: + frf_offset = 21; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + frf_offset = 22; + break; + } + volatile spi_t *spi_adapter = spi[spi_num]; + return ((spi_adapter->ctrlr0 >> frf_offset) & 0x3); +} + +static spi_transfer_width_t spi_get_frame_size(size_t data_bit_length) +{ + if (data_bit_length < 8) + return SPI_TRANS_CHAR; + else if (data_bit_length < 16) + return SPI_TRANS_SHORT; + return SPI_TRANS_INT; +} + +static int spi_dma_irq(void *ctx) +{ + spi_instance_t *v_instance = (spi_instance_t *)ctx; + volatile spi_t *spi_handle = spi[v_instance->spi_num]; + dmac_irq_unregister(v_instance->dmac_channel); + while ((spi_handle->sr & 0x05) != 0x04); + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + spinlock_unlock(&v_instance->lock); + if(v_instance->spi_int_instance.callback) + { + v_instance->spi_int_instance.callback(v_instance->spi_int_instance.ctx); + } + return 0; +} + +static int spi_clk_init(uint8_t spi_num) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + if(spi_num == 3) + sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_SPI3, 1); + sysctl_clock_enable(SYSCTL_CLOCK_SPI0 + spi_num); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI0 + spi_num, 0); + return 0; +} + +static void spi_set_tmod(uint8_t spi_num, uint32_t tmod) +{ + configASSERT(spi_num < SPI_DEVICE_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + uint8_t tmod_offset = 0; + switch(spi_num) + { + case 0: + case 1: + case 2: + tmod_offset = 8; + break; + case 3: + default: + tmod_offset = 10; + break; + } + set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset); +} + +void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format, + size_t data_bit_length, uint32_t endian) +{ + configASSERT(data_bit_length >= 4 && data_bit_length <= 32); + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + spi_clk_init(spi_num); + + uint8_t dfs_offset, frf_offset, work_mode_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + frf_offset = 21; + work_mode_offset = 6; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + frf_offset = 22; + work_mode_offset = 8; + break; + } + + switch (frame_format) + { + case SPI_FF_DUAL: + configASSERT(data_bit_length % 2 == 0); + break; + case SPI_FF_QUAD: + configASSERT(data_bit_length % 4 == 0); + break; + case SPI_FF_OCTAL: + configASSERT(data_bit_length % 8 == 0); + break; + default: + break; + } + volatile spi_t *spi_adapter = spi[spi_num]; + if(spi_adapter->baudr == 0) + spi_adapter->baudr = 0x14; + spi_adapter->imr = 0x00; + spi_adapter->dmacr = 0x00; + spi_adapter->dmatdlr = 0x10; + spi_adapter->dmardlr = 0x00; + spi_adapter->ser = 0x00; + spi_adapter->ssienr = 0x00; + spi_adapter->ctrlr0 = (work_mode << work_mode_offset) | (frame_format << frf_offset) | ((data_bit_length - 1) << dfs_offset); + spi_adapter->spi_ctrlr0 = 0; + spi_adapter->endian = endian; +} + +void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length, + uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode) +{ + configASSERT(wait_cycles < (1 << 5)); + configASSERT(instruction_address_trans_mode < 3); + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + uint32_t inst_l = 0; + switch (instruction_length) + { + case 0: + inst_l = 0; + break; + case 4: + inst_l = 1; + break; + case 8: + inst_l = 2; + break; + case 16: + inst_l = 3; + break; + default: + configASSERT(!"Invalid instruction length"); + break; + } + + configASSERT(address_length % 4 == 0 && address_length <= 60); + uint32_t addr_l = address_length / 4; + + spi_handle->spi_ctrlr0 = (wait_cycles << 11) | (inst_l << 8) | (addr_l << 2) | instruction_address_trans_mode; +} + +uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk) +{ + uint32_t spi_baudr = SysctlClockGetFreq(SYSCTL_CLOCK_SPI0 + spi_num) / spi_clk; + if(spi_baudr < 2 ) + { + spi_baudr = 2; + } + else if(spi_baudr > 65534) + { + spi_baudr = 65534; + } + volatile spi_t *spi_adapter = spi[spi_num]; + spi_adapter->baudr = spi_baudr; + return SysctlClockGetFreq(SYSCTL_CLOCK_SPI0 + spi_num) / spi_baudr; +} + +void spi_send_data_normal(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint8_t v_misalign_flag = 0; + uint32_t v_send_data; + if((uintptr_t)tx_buff % frame_width) + v_misalign_flag = 1; + + spi_handle->ssienr = 0x01; + spi_handle->ser = 1U << chip_select; + uint32_t i = 0; + while (tx_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < tx_len ? fifo_len : tx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + fifo_len = fifo_len / 4 * 4; + if(v_misalign_flag) + { + for(index = 0; index < fifo_len; index +=4) + { + memcpy(&v_send_data, tx_buff + i , 4); + spi_handle->dr[0] = v_send_data; + i += 4; + } + } + else + { + for (index = 0; index < fifo_len / 4; index++) + spi_handle->dr[0] = ((uint32_t *)tx_buff)[i++]; + } + break; + case SPI_TRANS_SHORT: + fifo_len = fifo_len / 2 * 2; + if(v_misalign_flag) + { + for(index = 0; index < fifo_len; index +=2) + { + memcpy(&v_send_data, tx_buff + i, 2); + spi_handle->dr[0] = v_send_data; + i += 2; + } + } + else + { + for (index = 0; index < fifo_len / 2; index++) + spi_handle->dr[0] = ((uint16_t *)tx_buff)[i++]; + } + break; + default: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = tx_buff[i++]; + break; + } + tx_len -= fifo_len; + } + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + +} + +void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + uint8_t *v_buf = malloc(CmdLen + tx_len); + size_t i; + for(i = 0; i < CmdLen; i++) + v_buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + v_buf[CmdLen + i] = tx_buff[i]; + + spi_send_data_normal(spi_num, chip_select, v_buf, CmdLen + tx_len); + free((void *)v_buf); +} + +void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint8_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t *buf; + size_t v_send_len; + int i; + switch(frame_width) + { + case SPI_TRANS_INT: + buf = malloc(CmdLen + tx_len); + for(i = 0; i < CmdLen / 4; i++) + buf[i] = ((uint32_t *)CmdBuff)[i]; + for(i = 0; i < tx_len / 4; i++) + buf[CmdLen / 4 + i] = ((uint32_t *)tx_buff)[i]; + v_send_len = (CmdLen + tx_len) / 4; + break; + case SPI_TRANS_SHORT: + buf = malloc((CmdLen + tx_len) / 2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen / 2; i++) + buf[i] = ((uint16_t *)CmdBuff)[i]; + for(i = 0; i < tx_len / 2; i++) + buf[CmdLen / 2 + i] = ((uint16_t *)tx_buff)[i]; + v_send_len = (CmdLen + tx_len) / 2; + break; + default: + buf = malloc((CmdLen + tx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + buf[CmdLen + i] = tx_buff[i]; + v_send_len = CmdLen + tx_len; + break; + } + + spi_send_data_normal_dma(channel_num, spi_num, chip_select, buf, v_send_len, SPI_TRANS_INT); + + free((void *)buf); +} + +void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + uint32_t *buf; + int i; + switch(spi_transfer_width) + { + case SPI_TRANS_SHORT: + buf = malloc((tx_len) * sizeof(uint32_t)); + for(i = 0; i < tx_len; i++) + buf[i] = ((uint16_t *)tx_buff)[i]; + break; + case SPI_TRANS_INT: + buf = (uint32_t *)tx_buff; + break; + case SPI_TRANS_CHAR: + default: + buf = malloc((tx_len) * sizeof(uint32_t)); + for(i = 0; i < tx_len; i++) + buf[i] = ((uint8_t *)tx_buff)[i]; + break; + } + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t) channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(channel_num, buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, tx_len); + spi_handle->ser = 1U << chip_select; + dmac_wait_done(channel_num); + if(spi_transfer_width != SPI_TRANS_INT) + free((void *)buf); + + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) +{ + spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + size_t v_tx_len = tx_len / frame_width; + size_t v_rx_len = rx_len / frame_width; + + size_t v_max_len = v_tx_len > v_rx_len ? v_tx_len : v_rx_len; + + uint32_t *v_tx_buf = malloc(v_max_len * 4); + uint32_t *v_rx_buf = malloc(v_max_len * 4); + uint32_t i = 0; + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = ((uint32_t *)tx_buf)[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = ((uint16_t *)tx_buf)[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + default: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = tx_buf[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + } + + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(dma_receive_channel_num, (void *)(&spi_handle->dr[0]), v_rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, v_max_len); + + dmac_set_single_mode(dma_send_channel_num, v_tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, v_max_len); + + spi_handle->ser = 1U << chip_select; + dmac_wait_done(dma_send_channel_num); + dmac_wait_done(dma_receive_channel_num); + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_rx_len; i++) + ((uint32_t *)rx_buf)[i] = v_rx_buf[i]; + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_rx_len; i++) + ((uint16_t *)rx_buf)[i] = v_rx_buf[i]; + break; + default: + for(i = 0; i < v_rx_len; i++) + rx_buf[i] = v_rx_buf[i]; + break; + } + free(v_tx_buf); + free(v_rx_buf); +} + +void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + size_t index, fifo_len; + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t i = 0; + size_t v_cmd_len = CmdLen / frame_width; + uint32_t v_rx_len = rx_len / frame_width; + + spi_handle->ctrlr1 = (uint32_t)(v_rx_len - 1); + spi_handle->ssienr = 0x01; + + while (v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = ((uint32_t *)CmdBuff)[i++]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = ((uint16_t *)CmdBuff)[i++]; + break; + default: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = CmdBuff[i++]; + break; + } + spi_handle->ser = 1U << chip_select; + v_cmd_len -= fifo_len; + } + + if(CmdLen == 0) + { + spi_handle->dr[0] = 0xffffffff; + spi_handle->ser = 1U << chip_select; + } + + i = 0; + while (v_rx_len) + { + fifo_len = spi_handle->rxflr; + fifo_len = fifo_len < v_rx_len ? fifo_len : v_rx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; + break; + default: + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + break; + } + + v_rx_len -= fifo_len; + } + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +void spi_receive_data_normal_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const void *CmdBuff, + size_t CmdLen, void *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + + volatile spi_t *spi_handle = spi[spi_num]; + + spi_handle->ctrlr1 = (uint32_t)(rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + if(CmdLen) + sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(dma_receive_channel_num, (void *)(&spi_handle->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, rx_len); + if(CmdLen) + dmac_set_single_mode(dma_send_channel_num, CmdBuff, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, CmdLen); + if(CmdLen == 0 && spi_get_frame_format(spi_num) == SPI_FF_STANDARD) + spi[spi_num]->dr[0] = 0xffffffff; + spi_handle->ser = 1U << chip_select; + if(CmdLen) + dmac_wait_done(dma_send_channel_num); + dmac_wait_done(dma_receive_channel_num); + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + + +void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + size_t i; + + uint32_t *write_cmd; + uint32_t *ReadBuf; + size_t v_recv_len; + size_t v_cmd_len; + switch(frame_width) + { + case SPI_TRANS_INT: + write_cmd = malloc(CmdLen + rx_len); + for(i = 0; i < CmdLen / 4; i++) + write_cmd[i] = ((uint32_t *)CmdBuff)[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 4; + v_cmd_len = CmdLen / 4; + break; + case SPI_TRANS_SHORT: + write_cmd = malloc((CmdLen + rx_len) /2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen / 2; i++) + write_cmd[i] = ((uint16_t *)CmdBuff)[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 2; + v_cmd_len = CmdLen / 2; + break; + default: + write_cmd = malloc((CmdLen + rx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len; + v_cmd_len = CmdLen; + break; + } + + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, v_cmd_len, ReadBuf, v_recv_len); + + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_recv_len; i++) + ((uint32_t *)rx_buff)[i] = ReadBuf[i]; + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_recv_len; i++) + ((uint16_t *)rx_buff)[i] = ReadBuf[i]; + break; + default: + for(i = 0; i < v_recv_len; i++) + rx_buff[i] = ReadBuf[i]; + break; + } + + free(write_cmd); +} + +void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t v_cmd_len = CmdLen; + uint32_t i = 0; + + uint32_t v_rx_len = rx_len / frame_width; + + spi_handle->ctrlr1 = (uint32_t)(v_rx_len - 1); + spi_handle->ssienr = 0x01; + + while (v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = *CmdBuff++; + + spi_handle->ser = 1U << chip_select; + v_cmd_len -= fifo_len; + } + + if(CmdLen == 0) + { + spi_handle->ser = 1U << chip_select; + } + + while (v_rx_len) + { + fifo_len = spi_handle->rxflr; + fifo_len = fifo_len < v_rx_len ? fifo_len : v_rx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; + break; + default: + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + break; + } + + v_rx_len -= fifo_len; + } + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + +} + +void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + size_t i; + + uint32_t *write_cmd = NULL; + uint32_t *ReadBuf; + size_t v_recv_len; + switch(frame_width) + { + case SPI_TRANS_INT: + v_recv_len = rx_len / 4; + break; + case SPI_TRANS_SHORT: + write_cmd = malloc(CmdLen + rx_len /2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 2; + break; + default: + write_cmd = malloc(CmdLen + rx_len * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len; + break; + } + if(frame_width == SPI_TRANS_INT) + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, CmdBuff, CmdLen, rx_buff, v_recv_len); + else + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, CmdLen, ReadBuf, v_recv_len); + + switch(frame_width) + { + case SPI_TRANS_INT: + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_recv_len; i++) + ((uint16_t *)rx_buff)[i] = ReadBuf[i]; + break; + default: + for(i = 0; i < v_recv_len; i++) + rx_buff[i] = ReadBuf[i]; + break; + } + + if(frame_width != SPI_TRANS_INT) + free(write_cmd); +} + +void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + spi_handle->ssienr = 0x01; + spi_handle->ser = 1U << chip_select; + + size_t v_cmd_len = CmdLen * 4; + while(v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + fifo_len = fifo_len / 4 * 4; + for (index = 0; index < fifo_len / 4; index++) + spi_handle->dr[0] = *CmdBuff++; + v_cmd_len -= fifo_len; + } + spi_send_data_normal(spi_num, chip_select, tx_buff, tx_len); +} + +void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint32_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t *buf; + size_t v_send_len; + int i; + switch(frame_width) + { + case SPI_TRANS_INT: + buf = malloc(CmdLen * sizeof(uint32_t) + tx_len); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len / 4; i++) + buf[CmdLen + i] = ((uint32_t *)tx_buff)[i]; + v_send_len = CmdLen + tx_len / 4; + break; + case SPI_TRANS_SHORT: + buf = malloc(CmdLen * sizeof(uint32_t) + tx_len / 2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len / 2; i++) + buf[CmdLen + i] = ((uint16_t *)tx_buff)[i]; + v_send_len = CmdLen + tx_len / 2; + break; + default: + buf = malloc((CmdLen + tx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + buf[CmdLen + i] = tx_buff[i]; + v_send_len = CmdLen + tx_len; + break; + } + + spi_send_data_normal_dma(channel_num, spi_num, chip_select, buf, v_send_len, SPI_TRANS_INT); + + free((void *)buf); +} + +void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint32_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t)channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(channel_num, tx_buff, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, tx_len); + spi_handle->ser = 1U << chip_select; + dmac_wait_done(channel_num); + + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +static int spi_slave_irq(void *ctx) +{ + volatile spi_t *spi_handle = spi[2]; + + spi_handle->imr = 0x00; + *(volatile uint32_t *)((uintptr_t)spi_handle->icr); + if (g_instance.status == IDLE) + g_instance.status = COMMAND; + return 0; +} + +static void spi_slave_idle_mode(void) +{ + volatile spi_t *spi_handle = spi[2]; + uint32_t DataWidth = g_instance.data_bit_length / 8; + g_instance.status = IDLE; + spi_handle->ssienr = 0x00; + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_handle->rxftlr = 0x08 / DataWidth - 1; + + spi_handle->dmacr = 0x00; + spi_handle->imr = 0x10; + spi_handle->ssienr = 0x01; + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH); +} + +static void spi_slave_command_mode(void) +{ + volatile spi_t *spi_handle = spi[2]; + uint8_t CmdData[8], sum = 0; + + spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1); + uint32_t DataWidth = g_instance.data_bit_length / 8; + spi_device_num_t spi_num = SPI_DEVICE_2; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < 8 / 4; i++) + ((uint32_t *)CmdData)[i] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < 8 / 2; i++) + ((uint16_t *)CmdData)[i] = spi_handle->dr[0]; + break; + default: + for (uint32_t i = 0; i < 8; i++) + CmdData[i] = spi_handle->dr[0]; + break; + } + + for (uint32_t i = 0; i < 7; i++) + { + sum += CmdData[i]; + } + if (CmdData[7] != sum) + { + spi_slave_idle_mode(); + return; + } + g_instance.command.cmd = CmdData[0]; + g_instance.command.addr = CmdData[1] | (CmdData[2] << 8) | (CmdData[3] << 16) | (CmdData[4] << 24); + g_instance.command.len = CmdData[5] | (CmdData[6] << 8); + if (g_instance.command.len == 0) + g_instance.command.len = 65536; + if ((g_instance.command.cmd < WRITE_DATA_BLOCK) && (g_instance.command.len > 8)) + { + spi_slave_idle_mode(); + return; + } + g_instance.status = TRANSFER; + spi_handle->ssienr = 0x00; + if (g_instance.command.cmd == WRITE_CONFIG) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi[2]->rxftlr = g_instance.command.len / DataWidth - 1; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + } + else if (g_instance.command.cmd == READ_CONFIG) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->txftlr = 0x00; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < g_instance.command.len / 4; i++) + { + spi_handle->dr[0] = ((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < g_instance.command.len / 2; i++) + { + spi_handle->dr[0] = ((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + default: + for (uint32_t i = 0; i < g_instance.command.len; i++) + { + spi_handle->dr[0] = ((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BYTE) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi[2]->rxftlr = g_instance.command.len / DataWidth - 1; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + } + else if (g_instance.command.cmd == READ_DATA_BYTE) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->txftlr = 0x00; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < g_instance.command.len / 4; i++) + { + spi_handle->dr[0] = ((uint32_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < g_instance.command.len / 2; i++) + { + spi_handle->dr[0] = ((uint16_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + default: + for (uint32_t i = 0; i < g_instance.command.len; i++) + { + spi_handle->dr[0] = ((uint8_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BLOCK) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs); + + spi_handle->dmacr = 0x01; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + + sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(g_instance.dmac_channel, (void *)(&spi_handle->dr[0]), (void *)((uintptr_t)g_instance.command.addr & 0xFFFFFFF0), DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4); + } + else if (g_instance.command.cmd == READ_DATA_BLOCK) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->dmacr = 0x02; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + + sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(g_instance.dmac_channel, (void *)((uintptr_t)g_instance.command.addr & 0xFFFFFFF0), (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4); + } + else + { + spi_slave_idle_mode(); + return; + } + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_LOW); +} + +static void spi_slave_transfer_mode(void) +{ + spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1); + uint32_t command_len = 0; + + switch(frame_width) + { + case SPI_TRANS_INT: + command_len = g_instance.command.len / 4; + break; + case SPI_TRANS_SHORT: + command_len = g_instance.command.len / 2; + break; + default: + command_len = g_instance.command.len; + break; + } + volatile spi_t *spi_handle = spi[2]; + g_instance.command.err = 0; + if (g_instance.command.cmd == WRITE_CONFIG || g_instance.command.cmd == WRITE_DATA_BYTE) + { + if (spi_handle->rxflr < command_len - 1) + g_instance.command.err = 1; + } + else if (g_instance.command.cmd == READ_CONFIG || g_instance.command.cmd == READ_DATA_BYTE) + { + if (spi_handle->txflr != 0) + g_instance.command.err = 2; + } else if (g_instance.command.cmd == WRITE_DATA_BLOCK || g_instance.command.cmd == READ_DATA_BLOCK) + { + if (dmac->channel[g_instance.dmac_channel].intstatus != 0x02) + g_instance.command.err = 3; + } + else + { + spi_slave_idle_mode(); + return; + } + + if (g_instance.command.err == 0) + { + if (g_instance.command.cmd == WRITE_CONFIG) + { + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + default: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BYTE) + { + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint32_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint16_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + default: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint8_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + } + } + } + if(g_instance.callback != NULL) + { + g_instance.callback((void *)&g_instance.command); + } + spi_slave_idle_mode(); +} + +static void spi_slave_cs_irq(void) +{ + if (g_instance.status == IDLE) + spi_slave_idle_mode(); + else if (g_instance.status == COMMAND) + spi_slave_command_mode(); + else if (g_instance.status == TRANSFER) + spi_slave_transfer_mode(); +} + +void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback) +{ + g_instance.status = IDLE; + g_instance.config_ptr = data; + g_instance.config_len = len; + g_instance.work_mode = 6; + g_instance.slv_oe = 10; + g_instance.dfs = 16; + g_instance.data_bit_length = data_bit_length; + g_instance.ready_pin = ready_pin; + g_instance.int_pin = int_pin; + g_instance.callback = callback; + g_instance.dmac_channel = dmac_channel; + sysctl_reset(SYSCTL_RESET_SPI2); + sysctl_clock_enable(SYSCTL_CLOCK_SPI2); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI2, 9); + + uint32_t DataWidth = data_bit_length / 8; + volatile spi_t *spi_handle = spi[2]; + spi_handle->ssienr = 0x00; + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((data_bit_length - 1) << g_instance.dfs); + spi_handle->dmatdlr = 0x04; + spi_handle->dmardlr = 0x03; + spi_handle->dmacr = 0x00; + spi_handle->txftlr = 0x00; + spi_handle->rxftlr = 0x08 / DataWidth - 1; + spi_handle->imr = 0x10; + spi_handle->ssienr = 0x01; + + gpiohs_set_drive_mode(g_instance.ready_pin, GPIO_DM_OUTPUT); + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH); + + gpiohs_set_drive_mode(g_instance.int_pin, GPIO_DM_INPUT_PULL_UP); + gpiohs_set_pin_edge(g_instance.int_pin, GPIO_PE_RISING); + gpiohs_set_irq(g_instance.int_pin, 3, spi_slave_cs_irq); + + plic_set_priority(IRQN_SPI_SLAVE_INTERRUPT, 4); + plic_irq_enable(IRQN_SPI_SLAVE_INTERRUPT); + plic_irq_register(IRQN_SPI_SLAVE_INTERRUPT, spi_slave_irq, NULL); +} + +void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + configASSERT(chip_select < SPI_CHIP_SELECT_MAX); + switch(data.TransferMode) + { + case SPI_TMOD_TRANS_RECV: + case SPI_TMOD_EEROM: + configASSERT(data.tx_buf && data.tx_len && data.rx_buf && data.rx_len); + break; + case SPI_TMOD_TRANS: + configASSERT(data.tx_buf && data.tx_len); + break; + case SPI_TMOD_RECV: + configASSERT(data.rx_buf && data.rx_len); + break; + default: + configASSERT(!"Transfer Mode ERR"); + break; + } + configASSERT(data.tx_channel < DMAC_CHANNEL_MAX && data.rx_channel < DMAC_CHANNEL_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + + spinlock_lock(&g_spi_instance[spi_num].lock); + if(cb) + { + g_spi_instance[spi_num].spi_int_instance.callback = cb->callback; + g_spi_instance[spi_num].spi_int_instance.ctx = cb->ctx; + } + switch(data.TransferMode) + { + case SPI_TMOD_RECV: + spi_set_tmod(spi_num, SPI_TMOD_RECV); + if(data.rx_len > 65536) + data.rx_len = 65536; + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x03; + spi_handle->ssienr = 0x01; + if(spi_get_frame_format(spi_num) == SPI_FF_STANDARD) + spi_handle->dr[0] = 0xffffffff; + if(cb) + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + sysctl_dma_select((sysctl_dma_channel_t)data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + dmac_wait_idle(data.rx_channel); + break; + case SPI_TMOD_TRANS: + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + if(cb) + { + dmac_irq_register(data.tx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.tx_channel; + } + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + { + dmac_wait_idle(data.tx_channel); + while ((spi_handle->sr & 0x05) != 0x04) + ; + } + break; + case SPI_TMOD_EEROM: + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + if(data.rx_len > 65536) + data.rx_len = 65536; + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + if(cb) + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + sysctl_dma_select(data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + dmac_wait_idle(data.rx_channel); + break; + case SPI_TMOD_TRANS_RECV: + spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV); + if(data.rx_len > 65536) + data.rx_len = 65536; + + if(cb) + { + if(data.tx_len > data.rx_len) + { + dmac_irq_register(data.tx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.tx_channel; + } + else + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + } + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + sysctl_dma_select(data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + { + dmac_wait_idle(data.tx_channel); + dmac_wait_idle(data.rx_channel); + } + break; + } + if(!cb) + { + spinlock_unlock(&g_spi_instance[spi_num].lock); + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + } +} +