support ethernet with w5500

This commit is contained in:
wlyu 2022-09-16 15:12:02 +08:00
parent fb2b38061a
commit 0c40f20d40
13 changed files with 1761 additions and 0 deletions

View File

@ -144,4 +144,8 @@ menuconfig BSP_USING_ESP8266
bool "Using ESP8266 device"
default n
menuconfig BSP_USING_W5500
bool "Using W5500 device"
default n
endif # ARCH_BOARD_XIDATONG_RISCV64

View File

@ -0,0 +1,78 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ADD_NUTTX_FETURES=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="xidatong-riscv64"
CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y
CONFIG_ARCH_CHIP="k210"
CONFIG_ARCH_CHIP_K210=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BINFMT_DISABLE=y
CONFIG_BOARD_LOOPSPERMSEC=46000
CONFIG_BUILTIN=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_DISABLE_MKDIR=y
CONFIG_NSH_DISABLE_RM=y
CONFIG_NSH_DISABLE_RMDIR=y
CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=2097152
CONFIG_RAM_START=0x80400000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_CMD_HISTORY_LEN=100
CONFIG_READLINE_CMD_HISTORY_LINELEN=120
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=28
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_U16550_UART=y
CONFIG_U16550_UART2=y
CONFIG_U16550_UART2_BASE=0x50220000
CONFIG_U16550_UART2_CLOCK=195000000
CONFIG_U16550_UART2_IRQ=39
CONFIG_U16550_UART2_BAUD=115200
CONFIG_U16550_UART2_PARITY=0
CONFIG_U16550_UART2_BITS=8
CONFIG_U16550_UART2_2STOP=0
CONFIG_U16550_UART2_RXBUFSIZE=256
CONFIG_U16550_UART2_TXBUFSIZE=256
CONFIG_U16550_NO_SERIAL_CONSOLE=y
CONFIG_U16550_SUPRESS_INITIAL_CONFIG=y
CONFIG_SERIAL_UART_ARCH_MMIO=y
CONFIG_U16550_REGINCR=4
CONFIG_U16550_REGWIDTH=32
CONFIG_U16550_ADDRWIDTH=32
CONFIG_BSP_USING_ESP8266=y

View File

@ -0,0 +1,61 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ADD_NUTTX_FETURES=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="xidatong-riscv64"
CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y
CONFIG_ARCH_CHIP="k210"
CONFIG_ARCH_CHIP_K210=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BINFMT_DISABLE=y
CONFIG_BOARD_LOOPSPERMSEC=46000
CONFIG_BUILTIN=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_DISABLE_MKDIR=y
CONFIG_NSH_DISABLE_RM=y
CONFIG_NSH_DISABLE_RMDIR=y
CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=2097152
CONFIG_RAM_START=0x80400000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_CMD_HISTORY_LEN=100
CONFIG_READLINE_CMD_HISTORY_LINELEN=120
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=28
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BSP_USING_W5500=y

View File

@ -62,4 +62,8 @@ ifeq ($(CONFIG_BSP_USING_ESP8266),y)
CSRCS += k210_esp8266.c esp8266_demo.c
endif
ifeq ($(CONFIG_BSP_USING_W5500),y)
CSRCS += k210_w5500.c w5500.c w5500_demo.c
endif
include $(TOPDIR)/boards/Board.mk

View File

@ -57,6 +57,10 @@
# include "k210_esp8266.h"
#endif
#ifdef CONFIG_BSP_USING_W5500
# include "k210_w5500.h"
#endif
#include "k210_sysctl.h"
/****************************************************************************
@ -131,5 +135,10 @@ int k210_bringup(void)
board_esp8266_initialize();
#endif
#ifdef CONFIG_BSP_USING_W5500
k210_sysctl_init();
board_w5500_initialize();
#endif
return ret;
}

View File

@ -0,0 +1,470 @@
/*
* Copyright (c) 2022 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 k210_w5500.c
* @brief support to register w5500 pointer and function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-9-14
*/
#include <nuttx/fs/fs.h>
#include <nuttx/wqueue.h>
#include <sys/poll.h>
#include "ctype.h"
#include "k210_w5500.h"
#define w_print printf
/******************************************************************************/
struct w5500_dev_s g_w5500dev;
static char *w5500_dev_name = "/dev/w5500";
/******************************************************************************/
void w5500_print_buf(int size, uint8_t *buf)
{
char ch[10] = {0};
char temp[256] = {0};
if(size >= 256)
size = 256;
for(int i = 0; i < size; i++)
{
if(buf[i] == '\r')
{
strcat(temp, "\\r");
}
else if(buf[i] == '\n')
{
strcat(temp, "\\n");
}
else if(isascii(buf[i]))
{
snprintf(ch, sizeof(ch), "%c", buf[i]);
strcat(temp, ch);
}
else
{
snprintf(ch, sizeof(ch), "%#x ", buf[i]);
strcat(temp, ch);
}
}
if(size)
w_print("w5500 read %d data: %s\n", size, temp);
}
//int w5500_read_buf(void *dev, int *size, uint8_t *buf)
//{
// uart_dev_t *uart_dev = (uart_dev_t *)dev;
// int cur_size = uart_dev->recv.head - uart_dev->recv.tail;
// *size = *size > cur_size ? cur_size : *size;
// memcpy(buf, uart_dev->recv.buffer, *size);
// uart_dev->recv.head = uart_dev->recv.tail;
// w5500_print_buf(*size, buf);
// return *size;
//}
/****************************************************************************
* Name: w5500_data_work
*
* Description:
* thread task w5500_data_work
*
****************************************************************************/
static FAR void w5500_data_work(FAR void *arg)
{
struct w5500_dev_s *w5500_dev = (struct w5500_dev_s *)arg;
// uart_dev_t *uart_dev = w5500_dev->uart_dev;
nxsem_wait(&w5500_dev->waitsem);
w5500_dev->recv_size = W5500_RECV_BUF_SIZE;
// w5500_read_buf(uart_dev, &w5500_dev->recv_size, w5500_dev->recv_buf);
work_queue(HPWORK, &w5500_dev->irqwork, w5500_data_work, w5500_dev, W5500_INCREMENT);
// w5500info("uart size %d ok!\n", w5500_dev->recv_size);
}
static int w5500_bringup(struct w5500_dev_s *dev)
{
// struct w5500_dev_s *w5500_dev = &g_w5500dev;
dev->uart_fd = open(dev->dev_name, O_RDWR);
w5500info("open %s fd = %d\n", dev->dev_name, dev->uart_fd);
work_queue(HPWORK, &dev->irqwork, w5500_data_work, dev, W5500_INCREMENT);
return OK;
}
static int w5500_write_config(struct w5500_dev_s *dev)
{
return OK;
}
static int w5500_shutdown(struct w5500_dev_s *dev)
{
close(dev->uart_fd);
return OK;
}
static int w5500_open(FAR struct file *filep)
{
FAR struct inode *inode;
FAR struct w5500_dev_s *priv;
uint8_t ref_cnt;
int ret;
DEBUGASSERT(filep);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct w5500_dev_s *)inode->i_private;
/* Get exclusive access to the driver data structure */
ret = nxsem_wait(&priv->devsem);
if(ret < 0)
{
w5500err("ERROR: nxsem_wait failed: %d\n", ret);
return ret;
}
/* Increment the reference count */
ref_cnt = priv->crefs + 1;
if(ref_cnt == 0)
{
/* More than 255 opens; uint8_t overflows to zero */
nxsem_post(&priv->devsem);
return -EMFILE;
}
/* When the reference increments to 1, this is the first open event
* on the driver.. and the time when we must initialize the driver.
*/
if(ref_cnt == 1)
{
ret = w5500_bringup(priv);
if(ret < 0)
{
w5500err("ERROR: w5500_bringup failed: %d\n", ret);
nxsem_post(&priv->devsem);
return ret;
}
ret = w5500_write_config(priv);
if(ret < 0)
{
w5500err("ERROR: w5500_write_config failed: %d\n", ret);
nxsem_post(&priv->devsem);
return ret;
}
}
/* Save the new open count on success */
priv->crefs = ref_cnt;
nxsem_post(&priv->devsem);
return ret;
}
/****************************************************************************
* Name: w5500_close
****************************************************************************/
static int w5500_close(FAR struct file *filep)
{
FAR struct inode *inode;
FAR struct w5500_dev_s *priv;
int ret;
DEBUGASSERT(filep);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct w5500_dev_s *)inode->i_private;
/* Get exclusive access to the driver data structure */
ret = nxsem_wait(&priv->devsem);
if(ret < 0)
{
w5500err("ERROR: nxsem_wait failed: %d\n", ret);
return ret;
}
/* Decrement the reference count unless it would decrement a negative
* value.
*/
if(priv->crefs >= 1)
{
priv->crefs--;
}
/* When the count decrements to zero, there are no further open references
* to the driver and it w5500 be uninitialized.
*/
if(priv->crefs == 0)
{
w5500_shutdown(priv);
}
nxsem_post(&priv->devsem);
return OK;
}
/****************************************************************************
* Name: w5500_read
****************************************************************************/
static ssize_t w5500_read(FAR struct file *filep, FAR char *buffer, size_t len)
{
FAR struct inode *inode;
FAR struct w5500_dev_s *priv;
int ret, buf_size = len;
DEBUGASSERT(filep);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct w5500_dev_s *)inode->i_private;
ret = nxsem_wait(&priv->devsem);
if(ret < 0)
{
w5500err("ERROR: nxsem_wait failed: %d\n", ret);
return ret;
}
buf_size = len > priv->recv_size ? priv->recv_size : len;
memcpy(buffer, priv->recv_buf, buf_size);
nxsem_post(&priv->devsem);
return ret;
}
/****************************************************************************
* Name: w5500_write
****************************************************************************/
static ssize_t w5500_write(FAR struct file *filep, FAR const char *buffer, size_t len)
{
FAR struct inode *inode;
FAR struct w5500_dev_s *priv;
int ret;
DEBUGASSERT(filep);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct w5500_dev_s *)inode->i_private;
/* Get exclusive access to the driver data structure */
ret = nxsem_wait(&priv->devsem);
if(ret < 0)
{
w5500err("ERROR: nxsem_wait failed: %d\n", ret);
return ret;
}
ret = write(priv->uart_fd, buffer, len);
w5500info("write fd %d len %ld ret = %d\n", priv->uart_fd, len, ret);
nxsem_post(&priv->devsem);
return ret;
}
/****************************************************************************
* Name: w5500_ioctl
****************************************************************************/
static int w5500_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode;
FAR struct w5500_dev_s *priv;
FAR uint32_t *ptr;
int ret;
DEBUGASSERT(filep);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct w5500_dev_s *)inode->i_private;
/* Get exclusive access to the driver data structure */
ret = nxsem_wait(&priv->devsem);
if(ret < 0)
{
w5500err("ERROR: nxsem_wait failed: %d\n", ret);
return ret;
}
/* Process the IOCTL by command */
switch(cmd)
{
case W5500IOC_SETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
ptr = (FAR uint32_t *)((uintptr_t)arg);
DEBUGASSERT(priv->config != NULL && ptr != NULL);
break;
default:
ret = -ENOTTY;
break;
}
nxsem_post(&priv->devsem);
return ret;
}
void w5500_notify(uart_dev_t *dev)
{
nxsem_post(&g_w5500dev.waitsem);
}
/****************************************************************************
* Name: w5500_poll
****************************************************************************/
static int w5500_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
{
FAR struct inode *inode;
FAR struct w5500_dev_s *priv;
int ret;
w5500info("setup: %d\n", (int)setup);
DEBUGASSERT(filep && fds);
inode = filep->f_inode;
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct w5500_dev_s *)inode->i_private;
/* Are we setting up the poll? Or tearing it down? */
ret = nxsem_wait(&priv->devsem);
if(ret < 0)
{
w5500err("ERROR: nxsem_wait failed: %d\n", ret);
return ret;
}
if(setup)
{
/* Ignore waits that do not include POLLIN */
if((fds->events & POLLIN) == 0)
{
w5500err("ERROR: Missing POLLIN: revents: %08x\n", fds->revents);
nxsem_post(&priv->devsem);
return -EDEADLK;
}
w5500_notify(priv->uart_dev);
}
else if(fds->priv)
{
/* This is a request to tear down the poll. */
struct pollfd **slot = (struct pollfd **)fds->priv;
DEBUGASSERT(slot != NULL);
/* Remove all memory of the poll setup */
*slot = NULL;
fds->priv = NULL;
}
nxsem_post(&priv->devsem);
return ret;
}
static const struct file_operations w5500_fops =
{
w5500_open, /* open */
w5500_close, /* close */
w5500_read, /* read */
w5500_write, /* write */
NULL, /* seek */
w5500_ioctl, /* ioctl */
w5500_poll /* poll */
};
/****************************************************************************
* Name: w5500_register
*
* Description:
* Register /dev/ext_uartN
*
****************************************************************************/
static int w5500_register(FAR const char *devpath)
{
FAR struct w5500_dev_s *priv = &g_w5500dev;
int ret = 0;
nxsem_init(&priv->devsem, 0, 1);
nxsem_init(&priv->waitsem, 0, 0);
nxsem_set_protocol(&priv->waitsem, SEM_PRIO_NONE);
/* Register the driver */
ret = register_driver(devpath, &w5500_fops, 0666, priv);
if(ret < 0)
{
kmm_free(priv);
}
return ret;
}
/****************************************************************************
* Name: w5500_init
*
* Description:
* Ch376 default initialization function
*
****************************************************************************/
void board_w5500_initialize(void)
{
//simluate SPI bus
k210_fpioa_config(BSP_W5500_SCLK, HS_GPIO(FPIOA_W5500_SCLK) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_W5500_NRST, HS_GPIO(FPIOA_W5500_NRST) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_W5500_MOSI, HS_GPIO(FPIOA_W5500_MOSI) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_W5500_MISO, HS_GPIO(FPIOA_W5500_MISO) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_W5500_NCS, HS_GPIO(FPIOA_W5500_NCS) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_W5500_NINT, HS_GPIO(FPIOA_W5500_NINT) | K210_IOFLAG_GPIOHS);
k210_gpiohs_set_direction(FPIOA_W5500_MISO, GPIO_DM_INPUT);
k210_gpiohs_set_direction(FPIOA_W5500_NRST, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_W5500_SCLK, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_W5500_MOSI, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_W5500_NCS, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_W5500_NINT, GPIO_DM_INPUT);
k210_gpiohs_set_value(FPIOA_W5500_SCLK, GPIO_PV_HIGH);
k210_gpiohs_set_value(FPIOA_W5500_MOSI, GPIO_PV_HIGH);
k210_gpiohs_set_value(FPIOA_W5500_NCS, GPIO_PV_LOW);
k210_gpiohs_set_value(FPIOA_W5500_NRST, GPIO_PV_HIGH);
w5500_register(w5500_dev_name);
w5500info("dev %s ok!\n", w5500_dev_name);
}

View File

@ -0,0 +1,137 @@
/*
* Copyright (c) 2022 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 k210_w5500.h
* @brief define aiit-riscv64-board w5500 function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-09-14
*/
#ifndef __K210_W5500_H_
#define __K210_W5500_H_
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <debug.h>
#include <assert.h>
#include <fcntl.h>
#include <arch/board/board.h>
#include "riscv_internal.h"
#include "k210_config.h"
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
#include "xidatong-riscv64.h"
#include "nuttx/serial/serial.h"
/* Define W5500 PIN NUM */
#define BSP_W5500_SCLK 9
#define BSP_W5500_MISO 10
#define BSP_W5500_MOSI 11
#define BSP_W5500_NCS 12
#define BSP_W5500_NRST 13
#define BSP_W5500_NINT 14
/* Define w5500 FPIOA NUMBER */
//#define FPIOA_W5500_SCLK 83
//#define FPIOA_W5500_MISO 70
//#define FPIOA_W5500_MOSI 71
//#define FPIOA_W5500_NCS 78
//
//#define FPIOA_W5500_NRST 4
//#define FPIOA_W5500_INT 5
//#define FPIOA_W5500_NRST 0
//#define FPIOA_W5500_NINT 9
//#define FPIOA_W5500_SCLK 28
//#define FPIOA_W5500_MOSI 29
//#define FPIOA_W5500_MISO 23
//#define FPIOA_W5500_NCS 31
#define FPIOA_W5500_NRST 0
#define FPIOA_W5500_NINT 9
#define FPIOA_W5500_SCLK 28
#define FPIOA_W5500_MISO 29
#define FPIOA_W5500_MOSI 23
#define FPIOA_W5500_NCS 31
#define W5500_FUNC_GPIO(n) ((K210_IO_FUNC_GPIOHS0 + n) | K210_IOFLAG_GPIOHS)
#define W5500IOC_SETFREQUENCY _WLIOC(0x0001) /* arg: Pointer to uint32_t frequency value */
#define W5500IOC_GETFREQUENCY _WLIOC(0x0002) /* arg: Pointer to uint32_t frequency value */
/* w5500 debug */
#ifdef CONFIG_DEBUG_W5500_ERROR
# define w5500err _err
#else
# define w5500err _none
#endif
#ifdef CONFIG_DEBUG_W5500_WARN
# define w5500warn _warn
#else
# define w5500warn _none
#endif
#ifdef CONFIG_DEBUG_W5500_INFO
# define w5500info _info
#else
# define w5500info _none
#endif
#define W5500_RECV_BUF_SIZE 256
#define W5500_INCREMENT MSEC2TICK(33)
struct w5500_config_s
{
int (*attach)(FAR const struct w5500_config_s *config, xcpt_t isr,
FAR void *arg);
void (*enable)(FAR const struct w5500_config_s *config, bool enable);
void (*clear)(FAR const struct w5500_config_s *config);
void (*wakeup)(FAR const struct w5500_config_s *config);
void (*nreset)(FAR const struct w5500_config_s *config, bool state);
};
struct w5500_dev_s
{
uint8_t crefs; /* Number of times the device
* has been opened */
uint8_t nwaiters; /* Number of threads waiting for
* data */
sem_t devsem; /* Manages exclusive access to
* this structure */
sem_t waitsem; /* Used to wait for the
* availability of data */
FAR const struct w5500_config_s *config; /* Board configuration data */
struct work_s irqwork; /* Supports the interrupt
* handling "bottom half" */
char *dev_name;
int uart_fd;
uart_dev_t *uart_dev;
int recv_size;
uint8_t recv_buf[W5500_RECV_BUF_SIZE];
};
void board_w5500_initialize(void);
#endif

View File

@ -0,0 +1,673 @@
/*
* Copyright (c) 2022 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 w5500.c
* @brief w5500 driver based on simulated SPI
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-9-14
*/
#include "nuttx/arch.h"
#include "w5500.h"
#include "k210_w5500.h"
#include "k210_gpio_common.h"
/*----------------------------------------------------------------------------*/
#define w_print printf
#define w_delay() up_udelay(1)
#define NCS_L() k210_gpiohs_set_value(FPIOA_W5500_NCS, GPIO_PV_LOW); w_delay();
#define NCS_H() k210_gpiohs_set_value(FPIOA_W5500_NCS, GPIO_PV_HIGH); w_delay();
#define SCLK_L() k210_gpiohs_set_value(FPIOA_W5500_SCLK, GPIO_PV_LOW); w_delay();
#define SCLK_H() k210_gpiohs_set_value(FPIOA_W5500_SCLK, GPIO_PV_HIGH); w_delay();
#define MOSI_L() k210_gpiohs_set_value(FPIOA_W5500_MOSI, GPIO_PV_LOW); w_delay();
#define MOSI_H() k210_gpiohs_set_value(FPIOA_W5500_MOSI, GPIO_PV_HIGH); w_delay();
#define RST_L() k210_gpiohs_set_value(FPIOA_W5500_NRST, GPIO_PV_LOW); up_mdelay(200);
#define RST_H() k210_gpiohs_set_value(FPIOA_W5500_NRST, GPIO_PV_HIGH); up_mdelay(200);
#define SOCK_WR_REG(_sock) (VDM | RWB_WRITE | (_sock * 0x20 + 0x10))
/*----------------------------------------------------------------------------*/
/* network parameter definition */
w5500_param_t w5500_param;
#define W5500_BUF_LEN 30
char test_str[] = {"ping test!\r\n"};
/*----------------------------------------------------------------------------*/
static uint8_t spi_read_byte(void)
{
uint8_t i, dat = 0;
SCLK_L();
for(i = 0; i < 8; i++)
{
SCLK_H();
dat <<= 1;
dat |= k210_gpiohs_get_value(FPIOA_W5500_MISO);
w_delay();
SCLK_L();
}
return dat;
}
static void spi_write_byte(uint8_t dat)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
SCLK_L();
if((dat << i) & 0x80)
{
MOSI_H();
}
else
{
MOSI_L();
}
SCLK_H();
}
SCLK_L();
}
static void spi_write_short(uint16_t dat)
{
spi_write_byte((uint8_t)(dat / 256));
spi_write_byte(dat);
}
static void w5500_write_byte(uint16_t reg, uint8_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_WRITE | COMMON_R);
spi_write_byte(dat);
NCS_H();
}
static void w5500_write_short(uint16_t reg, uint16_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM2 | RWB_WRITE | COMMON_R);
spi_write_short(dat);
NCS_H();
}
static void w5500_write_bytes(uint16_t reg, uint8_t *dat, uint16_t size)
{
uint16_t i;
NCS_L();
spi_write_short(reg);
spi_write_byte(VDM | RWB_WRITE | COMMON_R);
for(i = 0; i < size; i++)
{
spi_write_byte(*dat++);
}
NCS_H();
}
void w5500_write_sock_byte(socket_t sock, uint16_t reg, uint8_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_WRITE | (sock * 0x20 + 0x08));
spi_write_byte(dat);
NCS_H();
}
void w5500_write_sock_short(socket_t sock, uint16_t reg, uint16_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM2 | RWB_WRITE | (sock * 0x20 + 0x08));
spi_write_short(dat);
NCS_H();
}
void w5500_write_sock_long(socket_t sock, uint16_t reg, uint8_t *dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM4 | RWB_WRITE | (sock * 0x20 + 0x08));
spi_write_byte(*dat++);
spi_write_byte(*dat++);
spi_write_byte(*dat++);
spi_write_byte(*dat++);
NCS_H();
}
uint8_t w5500_read_byte(uint16_t reg)
{
uint8_t val;
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_READ | COMMON_R);
val = spi_read_byte();
NCS_H();
return val;
}
uint8_t w5500_read_sock_byte(socket_t sock, uint16_t reg)
{
uint8_t val;
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_READ | (sock * 0x20 + 0x08));
val = spi_read_byte();
NCS_H();
return val;
}
uint16_t w5500_read_sock_short(socket_t sock, uint16_t reg)
{
uint16_t val;
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM2 | RWB_READ |(sock * 0x20 + 0x08));
val = spi_read_byte();
val *= 256;
val |= spi_read_byte();
NCS_H();
return val;
}
uint16_t w5500_read_sock_bytes(socket_t sock, uint8_t *dat)
{
uint16_t recv_size, write_addr;
uint16_t recv_addr;
uint16_t i;
uint8_t val;
recv_size = w5500_read_sock_short(sock, W5500_SN_RX_RSR_REG);
//no receive data
if(recv_size == 0)
{
return 0;
}
if(recv_size > W5500_MAX_PACK_SIZE)
{
recv_size = W5500_MAX_PACK_SIZE;
}
recv_addr = w5500_read_sock_short(sock, W5500_SN_RX_RD_REG);
write_addr = recv_addr;
//calculate physical address
recv_addr &= (SOCK_RECV_SIZE - 1);
NCS_L();
spi_write_short(recv_addr);
spi_write_byte(VDM | RWB_READ | (sock * 0x20 + 0x18));
if((recv_addr + recv_size) < SOCK_RECV_SIZE)
{
for(i = 0; i < recv_size; i++)
{
val = spi_read_byte();
*dat = val;
dat++;
}
}
else
{
recv_addr = SOCK_RECV_SIZE - recv_addr;
for(i = 0; i < recv_addr; i++)
{
val = spi_read_byte();
*dat = val;
dat++;
}
NCS_H();
NCS_L();
spi_write_short(0x00);
spi_write_byte(VDM | RWB_READ | (sock * 0x20 + 0x18));
for(; i < recv_size; i++)
{
val= spi_read_byte();
*dat = val;
dat++;
}
}
NCS_H();
write_addr += recv_size;
w5500_write_sock_short(sock, W5500_SN_RX_RD_REG, write_addr);
//start receive
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_RECV);
return recv_size;
}
void w5500_write_sock_bytes(socket_t sock, uint8_t *dat, uint16_t size)
{
uint16_t recv_addr, write_addr;
uint16_t i;
// if udp mode, set ip and port
if(w5500_read_sock_byte(sock, W5500_SN_MR_REG) != SOCK_UDP)
{
w5500_write_sock_long(sock, W5500_SN_DIPR_REG, w5500_param.udp_ip);
w5500_write_sock_short(sock, W5500_SN_DPORTR_REG, w5500_param.udp_port);
}
recv_addr = w5500_read_sock_short(sock, W5500_SN_TX_WR_REG);
write_addr = recv_addr;
recv_addr &= (SOCK_SEND_SIZE - 1);
NCS_L();
spi_write_short(recv_addr);
spi_write_byte(VDM | RWB_WRITE | (sock * 0x20 + 0x10));
if((recv_addr + size) < SOCK_SEND_SIZE)
{
for(i = 0; i < size; i++)
{
spi_write_byte(*dat++);
}
}
else
{
recv_addr = SOCK_SEND_SIZE - recv_addr;
for(i = 0; i < recv_addr; i++)
{
spi_write_byte(*dat++);
}
NCS_H();
NCS_L();
spi_write_short(0x00);
spi_write_byte(VDM | RWB_WRITE | (sock * 0x20 + 0x10));
for(; i < size; i++)
{
spi_write_byte(*dat++);
}
}
NCS_H();
write_addr += size;
w5500_write_sock_short(sock, W5500_SN_TX_WR_REG, write_addr);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_SEND);
}
/*w5500 reset pin keep 500us low at least*/
void w5500_reset(void)
{
uint8_t dat = 0;
RST_L();
RST_H();
//wait connect ok
while((dat & LINK) == 0)
{
up_mdelay(500);
dat = w5500_read_byte(W5500_PHYCFGR_REG);
w_print(" PHYCFG = %x\n", dat);
}
}
void w5500_config_init(void)
{
uint8_t i = 0;
//software reset, set 1 and auto clear 0
w5500_write_byte(W5500_MR_REG, MR_RST);
up_mdelay(100);
w5500_write_bytes(W5500_GAR_REG, w5500_param.gw_addr, 4);
w5500_write_bytes(W5500_SUBR_REG, w5500_param.ip_mask, 4);
w5500_write_bytes(W5500_SHAR_REG, w5500_param.mac_addr, 6);
w5500_write_bytes(W5500_SIPR_REG, w5500_param.ip_addr, 4);
//set socket rx and tx memory size 2k
for(i = 0; i < 8; i++)
{
w5500_write_sock_byte(i, W5500_SN_RXBUF_SIZE_REG, 0x02);
w5500_write_sock_byte(i, W5500_SN_TXBUF_SIZE_REG, 0x02);
}
//set retry time 200ms (0x07d0 = 2000)
w5500_write_short(W5500_RTR_REG, 0x07d0);
//retry time with 8, when exceed it, produce overtime interrupt, set W5500_SN_IR_REG(TIMEOUT)
w5500_write_byte(W5500_RCR_REG, 8);
}
uint8_t w5500_detect_gateway(void)
{
uint8_t ip_addr[4] = {w5500_param.ip_addr[0] + 1, w5500_param.ip_addr[1] + 1, w5500_param.ip_addr[2] + 1, w5500_param.ip_addr[3] + 1};
//check gateway and get gateway phyiscal address
w5500_write_sock_long(0, W5500_SN_DIPR_REG, ip_addr);
w5500_write_sock_byte(0, W5500_SN_MR_REG, SN_MR_TCP);
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(0, W5500_SN_SR_REG) != SOCK_INIT)
{
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
//set socket connection mode
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CONNECT);
do
{
uint8_t val = 0;
//read socket0 interrupt register
val = w5500_read_sock_byte(0, W5500_SN_IR_REG);
if(val != 0)
{
w5500_write_sock_byte(0, W5500_SN_IR_REG, val);
}
up_mdelay(5);
if((val & IR_TIMEOUT) == IR_TIMEOUT)
{
return FALSE;
}
else if(w5500_read_sock_byte(0, W5500_SN_DHAR_REG) != 0xff)
{
//close socket
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
return TRUE;
}
} while(1);
return TRUE;
}
// socket port (0 - 7) initialization
void w5500_socket_init(socket_t sock)
{
//max partition bytes = 30
w5500_write_sock_short(0, W5500_SN_MSSR_REG, 30);
switch(sock)
{
case 0:
w5500_write_sock_short(0, W5500_SN_PORT_REG, w5500_param.sock.local_port);
w5500_write_sock_short(0, W5500_SN_DPORTR_REG, w5500_param.sock.dst_port);
w5500_write_sock_long(0, W5500_SN_DIPR_REG, w5500_param.sock.dst_ip);
break;
default:
break;
}
}
uint8_t w5500_socket_connect(socket_t sock)
{
w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_TCP);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_INIT)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CONNECT);
return TRUE;
}
uint8_t w5500_socket_listen(socket_t sock)
{
w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_TCP);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_INIT)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_LISTEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_LISTEN)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
return TRUE;
}
uint8_t w5500_socket_set_udp(socket_t sock)
{
w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_UDP);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_UDP)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
return TRUE;
}
void w5500_irq_process(void)
{
uint8_t ir_flag, sn_flag;
ir_flag = w5500_read_byte(W5500_SIR_REG);
do
{
w_print("SIR = %x\n", ir_flag);
//handle socket0 event
if((ir_flag & S0_INT) == S0_INT)
{
sn_flag = w5500_read_sock_byte(0, W5500_SN_IR_REG);
w5500_write_sock_byte(0, W5500_SN_IR_REG, sn_flag);
if(sn_flag & IR_CON)
{
//socket connection finished
w5500_param.sock.flag |= SOCK_FLAG_CONN;
}
if(sn_flag & IR_DISCON)
{
//disconnect state
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
w5500_socket_init(0);
w5500_param.sock.flag = 0;
}
if(sn_flag & IR_SEND_OK)
{
//send one package ok
w5500_param.sock.state |= SOCK_STAT_SEND;
}
if(sn_flag & IR_RECV)
{
w5500_param.sock.state |= SOCK_STAT_RECV;
}
if(sn_flag & IR_TIMEOUT)
{
//close socket, connection failed
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
w5500_param.sock.flag = 0;
}
}
ir_flag = w5500_read_byte(W5500_SIR_REG);
}while(ir_flag);
w_print("Flag = %x State = %x\n", w5500_param.sock.flag, w5500_param.sock.state) ;
}
void w5500_intialization(void)
{
w5500_config_init();
w5500_detect_gateway();
w5500_socket_init(0);
}
char test_mac_addr[] = {0x0C, 0x29, 0xAB, 0x7C, 0x00, 0x01};
//char test_ip_addr[] = {192, 168, 250, 189};
//char test_ip_mask[] = {255, 255, 255, 0};
//char test_gw_addr[] = {192, 168, 250, 1};
//char test_dst_ip[] = {192, 168, 250, 1};
char test_ip_addr[] = {10, 0, 30, 50};
char test_ip_mask[] = {255, 255, 255, 0};
char test_gw_addr[] = {10, 0, 30, 1};
char test_dst_ip[] = {10, 0, 30, 57};
void w5500_load_param(void)
{
w5500_param_t *param = &w5500_param;
memcpy(param->ip_addr, test_ip_addr, sizeof(test_ip_addr));
memcpy(param->ip_mask, test_ip_mask, sizeof(test_ip_mask));
memcpy(param->gw_addr, test_gw_addr, sizeof(test_gw_addr));
memcpy(param->mac_addr, test_mac_addr, sizeof(test_mac_addr));
memcpy(param->sock.dst_ip, test_dst_ip, sizeof(test_dst_ip));
param->sock.local_port = 5000;
param->sock.dst_port = 6000;
param->sock.mode = SOCK_TCP_CLI;
}
void w5500_socket_config(void)
{
if(w5500_param.sock.flag == 0)
{
if(w5500_param.sock.mode == SOCK_TCP_SVR)
{
if(w5500_socket_listen(0) == TRUE)
{
w5500_param.sock.flag = SOCK_FLAG_INIT;
}
else
{
w5500_param.sock.flag = 0;
}
}
else if(w5500_param.sock.mode == SOCK_TCP_CLI)
{
if(w5500_socket_connect(0) == TRUE)
{
w5500_param.sock.flag = SOCK_FLAG_INIT;
}
else
{
w5500_param.sock.flag = 0;
}
w_print("TCP state = %d\n", w5500_param.sock.flag);
}
else
{
if(w5500_socket_set_udp(0) == TRUE)
{
w5500_param.sock.flag = SOCK_FLAG_INIT|SOCK_FLAG_CONN;
}
else
{
w5500_param.sock.flag = 0;
}
}
}
}
void w5500_socket_process(socket_t sock)
{
uint16_t size;
static uint8_t rx_buf[W5500_BUF_LEN] = {0};
static uint8_t tx_buf[W5500_BUF_LEN] = {0};
size = w5500_read_sock_bytes(sock, rx_buf);
memcpy(tx_buf, rx_buf, size);
w5500_write_sock_bytes(sock, tx_buf, size);
w_print("w5500: ");
for(int i = 0; i < W5500_BUF_LEN; i++)
{
w_print("%x ", rx_buf[i]);
}
w_print("\n");
}
int w5500_net_test(void)
{
uint32_t cnt = 0;
uint8_t tx_buf[W5500_BUF_LEN] = {0};
w5500_load_param();
w5500_reset();
w5500_intialization();
w_print("w5500_intialization()\n");
while(1)
{
w5500_socket_config();
w5500_irq_process();
if((w5500_param.sock.state & SOCK_STAT_RECV) == SOCK_STAT_RECV)
{
w5500_param.sock.state &= ~SOCK_STAT_RECV;
//receive and send data
w5500_socket_process(0);
}
else if(cnt >= 10)
{
w_print("write flag = %x state = %x\n", w5500_param.sock.flag, w5500_param.sock.state);
if(w5500_param.sock.flag == (SOCK_FLAG_INIT|SOCK_FLAG_CONN))
{
w5500_param.sock.state &= ~SOCK_STAT_SEND;
memcpy(tx_buf, test_str, strlen(test_str));
w5500_write_sock_bytes(0, tx_buf, strlen(test_str));
w_print("write %s ok!\n", test_str);
break;
}
cnt = 0;
}
up_mdelay(1000);
cnt++;
}
return 1;
}

View File

@ -0,0 +1,274 @@
/*
* Copyright (c) 2022 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 w5500.h
* @brief w5500 driver
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-9-15
*/
#ifndef _W5500_H_
#define _W5500_H_
/***************** Common Register *****************/
#define W5500_MR_REG 0x0000
#define MR_RST 0x80
#define MR_WOL 0x20
#define MR_PB 0x10
#define MR_PPP 0x08
#define MR_FARP 0x02
#define W5500_GAR_REG 0x0001
#define W5500_SUBR_REG 0x0005
#define W5500_SHAR_REG 0x0009
#define W5500_SIPR_REG 0x000f
#define W5500_INT_REG 0x0013
#define W5500_IR_REG 0x0015
#define IR_CONFLICT 0x80
#define IR_UNREACH 0x40
#define IR_PPPOE 0x20
#define IR_MP 0x10
#define W5500_IMR_REG 0x0016
#define IMR_IR7 0x80
#define IMR_IR6 0x40
#define IMR_IR5 0x20
#define IMR_IR4 0x10
#define W5500_SIR_REG 0x0017
#define S7_INT 0x80
#define S6_INT 0x40
#define S5_INT 0x20
#define S4_INT 0x10
#define S3_INT 0x08
#define S2_INT 0x04
#define S1_INT 0x02
#define S0_INT 0x01
#define W5500_SIMR_REG 0x0018
#define S7_IMR 0x80
#define S6_IMR 0x40
#define S5_IMR 0x20
#define S4_IMR 0x10
#define S3_IMR 0x08
#define S2_IMR 0x04
#define S1_IMR 0x02
#define S0_IMR 0x01
#define W5500_RTR_REG 0x0019
#define W5500_RCR_REG 0x001B
#define W5500_PTIMER_REG 0x001C
#define W5500_PMAGIC_REG 0x001D
#define W5500_PHA_REG 0x001E
#define W5500_PSID_REG 0x0024
#define W5500_PMRU_REG 0x0026
#define W5500_UIPR_REG 0x0028
#define W5500_UPORT_REG 0x002C
#define W5500_PHYCFGR_REG 0x002E
#define RST_PHY 0x80
#define OPMODE 0x40
#define DPX 0x04
#define SPD 0x02
#define LINK 0x01
#define W5500_VER_REG 0x0039
/********************* Socket Register *******************/
#define W5500_SN_MR_REG 0x0000
#define SN_MR_MULTI_MFEN 0x80
#define SN_MR_BCASTB 0x40
#define SN_MR_ND_MC_MMB 0x20
#define SN_MR_UCASTB_MIP6B 0x10
#define SN_MR_CLOSE 0x00
#define SN_MR_TCP 0x01
#define SN_MR_UDP 0x02
#define SN_MR_MACRAW 0x04
#define W5500_SN_CR_REG 0x0001
#define SN_CR_OPEN 0x01
#define SN_CR_LISTEN 0x02
#define SN_CR_CONNECT 0x04
#define SN_CR_DISCON 0x08
#define SN_CR_CLOSE 0x10
#define SN_CR_SEND 0x20
#define SN_CR_SEND_MAC 0x21
#define SN_CR_SEND_KEEP 0x22
#define SN_CR_RECV 0x40
#define W5500_SN_IR_REG 0x0002
#define IR_SEND_OK 0x10
#define IR_TIMEOUT 0x08
#define IR_RECV 0x04
#define IR_DISCON 0x02
#define IR_CON 0x01
#define W5500_SN_SR_REG 0x0003
#define SOCK_CLOSED 0x00
#define SOCK_INIT 0x13
#define SOCK_LISTEN 0x14
#define SOCK_ESTABLISHED 0x17
#define SOCK_CLOSE_WAIT 0x1C
#define SOCK_UDP 0x22
#define SOCK_MACRAW 0x02
#define SOCK_SYNSEND 0x15
#define SOCK_SYNRECV 0x16
#define SOCK_FIN_WAI 0x18
#define SOCK_CLOSING 0x1A
#define SOCK_TIME_WAIT 0x1B
#define SOCK_LAST_ACK 0x1D
#define W5500_SN_PORT_REG 0x0004
#define W5500_SN_DHAR_REG 0x0006
#define W5500_SN_DIPR_REG 0x000C
#define W5500_SN_DPORTR_REG 0x0010
#define W5500_SN_MSSR_REG 0x0012
#define W5500_SN_TOS_REG 0x0015
#define W5500_SN_TTL_REG 0x0016
#define W5500_SN_RXBUF_SIZE_REG 0x001E
#define W5500_SN_TXBUF_SIZE_REG 0x001F
#define W5500_SN_TX_FSR_REG 0x0020
#define W5500_SN_TX_RD_REG 0x0022
#define W5500_SN_TX_WR_REG 0x0024
#define W5500_SN_RX_RSR_REG 0x0026
#define W5500_SN_RX_RD_REG 0x0028
#define W5500_SN_RX_WR_REG 0x002A
#define W5500_SN_IMR_REG 0x002C
#define IMR_SENDOK 0x10
#define IMR_TIMEOUT 0x08
#define IMR_RECV 0x04
#define IMR_DISCON 0x02
#define IMR_CON 0x01
#define W5500_SN_FRAG_REG 0x002D
#define W5500_SN_KPALVTR_REG 0x002F
/************************ SPI Control Data *************************/
/* Operation mode bits */
#define VDM 0x00
#define FDM1 0x01
#define FDM2 0x02
#define FDM4 0x03
/* Read_Write control bit */
#define RWB_READ 0x00
#define RWB_WRITE 0x04
/* Block select bits */
#define COMMON_R 0x00
/* Socket 0 */
#define S0_REG 0x08
#define S0_TX_BUF 0x10
#define S0_RX_BUF 0x18
/* Socket 1 */
#define S1_REG 0x28
#define S1_TX_BUF 0x30
#define S1_RX_BUF 0x38
/* Socket 2 */
#define S2_REG 0x48
#define S2_TX_BUF 0x50
#define S2_RX_BUF 0x58
/* Socket 3 */
#define S3_REG 0x68
#define S3_TX_BUF 0x70
#define S3_RX_BUF 0x78
/* Socket 4 */
#define S4_REG 0x88
#define S4_TX_BUF 0x90
#define S4_RX_BUF 0x98
/* Socket 5 */
#define S5_REG 0xa8
#define S5_TX_BUF 0xb0
#define S5_RX_BUF 0xb8
/* Socket 6 */
#define S6_REG 0xc8
#define S6_TX_BUF 0xd0
#define S6_RX_BUF 0xd8
/* Socket 7 */
#define S7_REG 0xe8
#define S7_TX_BUF 0xf0
#define S7_RX_BUF 0xf8
// socket receive buffer size based on RMSR
#define SOCK_RECV_SIZE 2048
// socket send buffer size based on RMSR
#define SOCK_SEND_SIZE 2048
#define W5500_IP_ADDR_LEN 4
#define W5500_IP_MASK_LEN 4
#define W5500_GW_ADDR_LEN 4
#define W5500_MAC_ADDR_LEN 6
//for every socket
// socket mode
#define SOCK_TCP_SVR 0 //server mode
#define SOCK_TCP_CLI 1 //client mode
#define SOCK_UDP_MOD 2 //udp mode
// socket flag
#define SOCK_FLAG_INIT 1
#define SOCK_FLAG_CONN 2
// socket data state
#define SOCK_STAT_RECV 1
#define SOCK_STAT_SEND 2
typedef struct w5500_socket_s
{
uint16_t local_port;
uint8_t dst_ip[W5500_IP_ADDR_LEN];
uint16_t dst_port;
uint8_t mode; // 0: TCP Server; 1: TCP client; 2: UDP
uint8_t flag; // 1: init ok; 2: connected
uint8_t state; // 1: receive one; 2: send ok
}w5500_socket_t;
typedef struct
{
uint8_t ip_addr[W5500_IP_ADDR_LEN];
uint8_t ip_mask[W5500_IP_MASK_LEN];
uint8_t gw_addr[W5500_GW_ADDR_LEN];
uint8_t mac_addr[W5500_MAC_ADDR_LEN];
uint8_t udp_ip[4];
uint16_t udp_port;
w5500_socket_t sock;
}w5500_param_t;
#define W5500_MAX_PACK_SIZE 1460
typedef unsigned char socket_t;
int w5500_net_test(void);
#endif

View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2022 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 w5500_demo.c
* @brief xidatong-riscv64 w5500_demo.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.08.22
*/
#include "k210_w5500.h"
#include "w5500.h"
#define w_print printf
void W5500Demo(void)
{
w_print("start %s\n", __func__);
w5500_net_test();
}

View File

@ -1470,6 +1470,10 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb,
int cmd_Esp8266(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#if defined(CONFIG_BSP_USING_W5500) && !defined(CONFIG_NSH_DISABLE_W5500)
int cmd_W5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#if defined(CONFIG_K210_LCD) && !defined(CONFIG_NSH_DISABLE_LCD)
int cmd_Lcd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif

View File

@ -103,6 +103,19 @@ int cmd_Esp8266(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
}
#endif
/****************************************************************************
* Name: cmd_W5500
****************************************************************************/
#if defined(CONFIG_BSP_USING_W5500) && !defined(CONFIG_NSH_DISABLE_W5500)
extern void W5500Demo(void);
int cmd_W5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
nsh_output(vtbl, "Hello, W5500!\n");
W5500Demo();
return OK;
}
#endif
/****************************************************************************
* Name: cmd_lcd
****************************************************************************/

View File

@ -616,6 +616,10 @@ static const struct cmdmap_s g_cmdmap[] =
{ "esp8266", cmd_Esp8266, 1, 1, "[can demo cmd.]" },
#endif
#if defined(CONFIG_BSP_USING_W5500) && !defined(CONFIG_NSH_DISABLE_W5500)
{ "w5500", cmd_W5500, 1, 1, "[can demo cmd.]" },
#endif
#if defined(CONFIG_K210_LCD) && !defined(CONFIG_NSH_DISABLE_LCD)
{ "lcd", cmd_Lcd, 1, 1, "[LCD demo cmd.]" },
#endif