add w5500 support to xidatong-riscv64 and edu-riscv64 from Tu_Yuyang

it is OK
This commit is contained in:
xuedongliang 2022-11-24 14:27:29 +08:00
commit 2a01ff712d
56 changed files with 16271 additions and 414 deletions

View File

@ -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 <xizi.h>
#include "board.h"
#include <clint.h>
#include <sysctl.h>
#include "board.h"
#include "tick.h"
#include <xizi.h>
#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 <iot-vfs.h>
// #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 <iot-vfs.h>
#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 <iot-vfs.h>
#include <sd_spi.h>
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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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地址进行寻址)
<img src="imgs\ping w5500.png" style="zoom:60%;" />
<img src="imgs\ping baidu.png" style="zoom:60%;" />
- tcp server 测试在xizi中调用wiz_server_op指定port之后可以在pc中向该端口发送数据
- wiz_server 将额外启动一个线程执行server工作server将向client返回client发来的消息
<img src="imgs\server1.png" style="zoom:90%;" />
<img src="imgs\server0.png" style="zoom:60%;" />
- client 测试通过wiz_client_op可以向pc中打开的tcp server发送消息
- 由于wiz_client_test函数参数接收问题测试使用的ip地址暂时使用硬编码实现
<img src="imgs\client0.png" style="zoom:67%;" />
<img src="imgs\client1.png" style="zoom:67%;" />

View File

@ -0,0 +1,505 @@
#include "connect_w5500.h"
#include <bus.h>
#include <dev_pin.h>
#include <drv_io_config.h>
#include <fpioa.h>
#include <string.h>
#include <xs_base.h>
#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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -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 <ORGANIZATION> 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;
}

View File

@ -0,0 +1,35 @@
#include <assert.h>
#include <connect_w5500.h>
#include <drv_io_config.h>
#include <fpioa.h>
#include <sleep.h>
#include <xs_base.h>
#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); }

View File

@ -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 <ORGANIZATION> 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 <stdio.h>
#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

View File

@ -0,0 +1,250 @@
#include "wiz_ping.h"
#include <shell.h>
#include <stdio.h>
#include <string.h>
#include <xs_base.h>
#include <xs_ktask.h>
#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);

View File

@ -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

View File

@ -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 <ORGANIZATION> 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 <stddef.h>
//
#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();
}

View File

@ -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 <device.h>
#ifdef __cplusplus
extern "C" {
#endif
static struct Bus *spi_bus;
int HwWiznetInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -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

View File

@ -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 <ORGANIZATION> 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
* <b> Comparison between WIZnet and Berkeley SOCKET APIs </b>
* <table>
* <tr> <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td>
* </tr> <tr> <td>socket()</td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>bind()</b></td> <td>X</td> <td>O</td> </tr> <tr>
* <td><b>listen()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>connect()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>accept()</b></td> <td>X</td> <td>O</td> </tr> <tr>
* <td><b>recv()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>send()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>recvfrom()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>sendto()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td>
* </tr>
* </table>
* 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 "<Berkeley SOCKET API>"
* 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 "<WIZnet SOCKET API>"
*/
#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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
*
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <I>len</I> in socket buffer.
* \n In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I>
* is greater than data size in socket buffer. \n
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <I>len</I>. In non-block io mode, It
* return @ref SOCK_BUSY immediately when socket buffer is not enough.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <I>len</I> in socket buffer In non-block io
* mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than
* data size in socket buffer.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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
///< <I>flag</I> 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 <table> <tr> <td> @b cstype </td> <td> @b data type</td><td>@b
* value</td></tr> <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td>
* uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr> <tr> <td>
* @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0
* ~ 16K </td></tr> <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n
* @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind
* </td><td> @ref SIK_CONNECTED, etc. </td></tr>
* </table>
* @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 <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td> @b data type</td><td>@b
* value</td></tr> <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255
* </td> </tr> <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td>
* </tr> <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td>
* </tr> <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
* <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~
* 65535 </td></tr> <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td>
* null </td></tr> <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td>
* 0 ~ 255 </td></tr>
* </table>
* @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 <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td>@b data type</td><td>@b
* value</td></tr> <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref
* SF_ETHER_OWN, etc... </td> </tr> <tr> <td> @ref SO_TOS </td> <td> uint8_t
* </td><td> 0 ~ 255 </td> </tr> <tr> <td> @ref SO_MSS </td> <td> uint16_t
* </td><td> 0 ~ 65535 </td> </tr> <tr> <td> @ref SO_DESTIP </td> <td>
* uint8_t[4] </td><td> </td></tr> <tr> <td> @ref SO_DESTPORT </td> <td>
* uint16_t </td><td> </td></tr> <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td>
* uint8_t </td><td> 0 ~ 255 </td></tr> <tr> <td> @ref SO_SENDBUF </td> <td>
* uint16_t </td><td> 0 ~ 65535 </td></tr> <tr> <td> @ref SO_RECVBUF </td> <td>
* uint16_t </td><td> 0 ~ 65535 </td></tr> <tr> <td> @ref SO_STATUS </td> <td>
* uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr> <tr> <td> @ref
* SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr> <tr> <td>
* @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc...
* </td></tr>
* </table>
* @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_

File diff suppressed because it is too large Load Diff

View File

@ -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 <ORGANIZATION> 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 <stdint.h>
/**
* @brief Select WIZCHIP.
* @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b
* W5500 or etc. \n\n ex> <code> #define \_WIZCHIP_ W5500 </code>
*/
#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> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_
* </code>
*
*/
#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> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code>
*/
#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_

View File

@ -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 <xizi.h>
#include "board.h"
#include <clint.h>
#include <sysctl.h>
#include "board.h"
#include "tick.h"
#include <xizi.h>
#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 <iot-vfs.h>
#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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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地址进行寻址)
<img src="imgs\ping w5500.png" style="zoom:60%;" />
<img src="imgs\ping baidu.png" style="zoom:60%;" />
- tcp server 测试在xizi中调用wiz_server_op指定port之后可以在pc中向该端口发送数据
- wiz_server 将额外启动一个线程执行server工作server将向client返回client发来的消息
<img src="imgs\server1.png" style="zoom:90%;" />
<img src="imgs\server0.png" style="zoom:60%;" />
- client 测试通过wiz_client_op可以向pc中打开的tcp server发送消息
- 由于wiz_client_test函数参数接收问题测试使用的ip地址暂时使用硬编码实现
<img src="imgs\client0.png" style="zoom:67%;" />
<img src="imgs\client1.png" style="zoom:67%;" />

View File

@ -0,0 +1,505 @@
#include "connect_w5500.h"
#include <bus.h>
#include <dev_pin.h>
#include <drv_io_config.h>
#include <fpioa.h>
#include <string.h>
#include <xs_base.h>
#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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -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 <ORGANIZATION> 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;
}

View File

@ -0,0 +1,35 @@
#include <assert.h>
#include <connect_w5500.h>
#include <drv_io_config.h>
#include <fpioa.h>
#include <sleep.h>
#include <xs_base.h>
#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); }

View File

@ -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 <ORGANIZATION> 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 <stdio.h>
#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

View File

@ -0,0 +1,250 @@
#include "wiz_ping.h"
#include <shell.h>
#include <stdio.h>
#include <string.h>
#include <xs_base.h>
#include <xs_ktask.h>
#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);

View File

@ -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

View File

@ -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 <ORGANIZATION> 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 <stddef.h>
//
#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();
}

View File

@ -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 <xizi.h>
#include <fpioa.h>
#include "drv_io_config.h"
#include <sysctl.h>
#include <fpioa.h>
#include <sysctl.h>
#include <xizi.h>
#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;
}

View File

@ -26,6 +26,7 @@
#include "utils.h"
#include "fpioa.h"
#include "sysctl.h"
#include <xs_base.h>
#define GPIO_MAX_PINNO 8
volatile gpio_t* const gpio = (volatile gpio_t*)GPIO_BASE_ADDR;

View File

@ -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 <device.h>
#ifdef __cplusplus
extern "C" {
#endif
int HwSpiInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -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 <device.h>
#ifdef __cplusplus
extern "C" {
#endif
static struct Bus *spi_bus;
int HwWiznetInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -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 <xsconfig.h>
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);

View File

@ -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 <stdint.h>
#include <stddef.h>
#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__ */

View File

@ -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 <ORGANIZATION> 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
* <b> Comparison between WIZnet and Berkeley SOCKET APIs </b>
* <table>
* <tr> <td><b>API</b></td> <td><b>WIZnet</b></td> <td><b>Berkeley</b></td>
* </tr> <tr> <td>socket()</td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>bind()</b></td> <td>X</td> <td>O</td> </tr> <tr>
* <td><b>listen()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>connect()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>accept()</b></td> <td>X</td> <td>O</td> </tr> <tr>
* <td><b>recv()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>send()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>recvfrom()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>sendto()</b></td> <td>O</td> <td>O</td> </tr> <tr>
* <td><b>closesocket()</b></td> <td>O<br>close() & disconnect()</td> <td>O</td>
* </tr>
* </table>
* 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 "<Berkeley SOCKET API>"
* 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 "<WIZnet SOCKET API>"
*/
#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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
*
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <I>len</I> in socket buffer.
* \n In non-block io mode, it return @ref SOCK_BUSY immediately when <I>len</I>
* is greater than data size in socket buffer. \n
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <I>len</I>. In non-block io mode, It
* return @ref SOCK_BUSY immediately when socket buffer is not enough.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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 <I>len</I> in socket buffer In non-block io
* mode, it return @ref SOCK_BUSY immediately when <I>len</I> is greater than
* data size in socket buffer.
*
* @param sn Socket number. It should be <b>0 ~ @ref \_WIZCHIP_SOCK_NUM_</b>.
* @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
///< <I>flag</I> 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 <table> <tr> <td> @b cstype </td> <td> @b data type</td><td>@b
* value</td></tr> <tr> <td> @ref CS_SET_IOMODE \n @ref CS_GET_IOMODE </td> <td>
* uint8_t </td><td>@ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK</td></tr> <tr> <td>
* @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF </td> <td> uint16_t </td><td> 0
* ~ 16K </td></tr> <tr> <td> @ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n
* @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK </td> <td> @ref sockint_kind
* </td><td> @ref SIK_CONNECTED, etc. </td></tr>
* </table>
* @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 <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td> @b data type</td><td>@b
* value</td></tr> <tr> <td> @ref SO_TTL </td> <td> uint8_t </td><td> 0 ~ 255
* </td> </tr> <tr> <td> @ref SO_TOS </td> <td> uint8_t </td><td> 0 ~ 255 </td>
* </tr> <tr> <td> @ref SO_MSS </td> <td> uint16_t </td><td> 0 ~ 65535 </td>
* </tr> <tr> <td> @ref SO_DESTIP </td> <td> uint8_t[4] </td><td> </td></tr>
* <tr> <td> @ref SO_DESTPORT </td> <td> uint16_t </td><td> 0 ~
* 65535 </td></tr> <tr> <td> @ref SO_KEEPALIVESEND </td> <td> null </td><td>
* null </td></tr> <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td> uint8_t </td><td>
* 0 ~ 255 </td></tr>
* </table>
* @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 <I>sotype</I>. \n
* <table>
* <tr> <td> @b sotype </td> <td>@b data type</td><td>@b
* value</td></tr> <tr> <td> @ref SO_FLAG </td> <td> uint8_t </td><td> @ref
* SF_ETHER_OWN, etc... </td> </tr> <tr> <td> @ref SO_TOS </td> <td> uint8_t
* </td><td> 0 ~ 255 </td> </tr> <tr> <td> @ref SO_MSS </td> <td> uint16_t
* </td><td> 0 ~ 65535 </td> </tr> <tr> <td> @ref SO_DESTIP </td> <td>
* uint8_t[4] </td><td> </td></tr> <tr> <td> @ref SO_DESTPORT </td> <td>
* uint16_t </td><td> </td></tr> <tr> <td> @ref SO_KEEPALIVEAUTO </td> <td>
* uint8_t </td><td> 0 ~ 255 </td></tr> <tr> <td> @ref SO_SENDBUF </td> <td>
* uint16_t </td><td> 0 ~ 65535 </td></tr> <tr> <td> @ref SO_RECVBUF </td> <td>
* uint16_t </td><td> 0 ~ 65535 </td></tr> <tr> <td> @ref SO_STATUS </td> <td>
* uint8_t </td><td> @ref SOCK_ESTABLISHED, etc.. </td></tr> <tr> <td> @ref
* SO_REMAINSIZE </td> <td> uint16_t </td><td> 0~ 65535 </td></tr> <tr> <td>
* @ref SO_PACKINFO </td> <td> uint8_t </td><td> @ref PACK_FIRST, etc...
* </td></tr>
* </table>
* @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_

File diff suppressed because it is too large Load Diff

View File

@ -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 <ORGANIZATION> 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 <stdint.h>
/**
* @brief Select WIZCHIP.
* @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b
* W5500 or etc. \n\n ex> <code> #define \_WIZCHIP_ W5500 </code>
*/
#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> <code> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_
* </code>
*
*/
#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> <code> #define \_WIZCHIP_IO_BASE_ 0x00008000 </code>
*/
#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_

View File

@ -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

View File

@ -0,0 +1,3 @@
SRC_FILES := connect_spi.c hardware_spi.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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 <connect_spi.h>
#include <dmac.h>
#include <drv_io_config.h>
#include <gpiohs.h>
#include <hardware_spi.h>
#include <string.h>
#include <sysctl.h>
#include <utils.h>
#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;
}

File diff suppressed because it is too large Load Diff