diff --git a/APP_Framework/Applications/Makefile b/APP_Framework/Applications/Makefile index b1c244996..6780a2b27 100644 --- a/APP_Framework/Applications/Makefile +++ b/APP_Framework/Applications/Makefile @@ -2,7 +2,7 @@ include $(KERNEL_ROOT)/.config ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) include $(APPDIR)/Make.defs - CSRCS += framework_init.c + CSRCS += include $(APPDIR)/Application.mk endif @@ -10,7 +10,7 @@ endif ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_DIR := general_functions app_test - SRC_FILES := main.c framework_init.c + SRC_FILES := main.c ifeq ($(CONFIG_LIB_LV),y) SRC_DIR += lv_app endif diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index e1e9b084e..1c2965bd2 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -105,6 +105,8 @@ menu "test app" menuconfig USER_TEST_HWTIMER select BSP_USING_HWTIMER select BSP_USING_GPIO + select RESOURCES_PIN + select BSP_USING_LED bool "Config test hwtimer" default n if USER_TEST_HWTIMER @@ -139,6 +141,21 @@ menu "test app" endif endif + menuconfig USER_TEST_TOUCH + select BSP_USING_TOUCH + bool "Config test touch" + default n + if USER_TEST_TOUCH + if ADD_XIZI_FETURES + config TOUCH_DEV_DRIVER + string "Set touch dev path" + default "/dev/touch_dev" + config TOUCH_LCD_DEV_DRIVER + string "Set lcd dev path" + default "/dev/lcd_dev" + endif + endif + menuconfig USER_TEST_I2C select BSP_USING_I2C bool "Config test i2c" @@ -151,6 +168,22 @@ menu "test app" endif endif + menuconfig USER_TEST_CAMERA + select BSP_USING_CAMERA + select BSP_USING_LCD + bool "Config test camera with lcd" + default n + if USER_TEST_CAMERA + if ADD_XIZI_FETURES + config CAMERA_DEV_DRIVER + string "Set camera dev path" + default "/dev/camera_dev" + config CAMERA_LCD_DEV_DRIVER + string "Set lcd dev path" + default "/dev/lcd_dev" + endif + endif + config USER_TEST_SEMC bool "Config test semc sdram" default n diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 8361d10a4..68801066a 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -75,7 +75,15 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) ifeq ($(CONFIG_USER_TEST_WDT),y) SRC_FILES += test_wdt.c - endif + endif + + ifeq ($(CONFIG_USER_TEST_TOUCH),y) + SRC_FILES += test_touch.c + endif + + ifeq ($(CONFIG_USER_TEST_CAMERA),y) + SRC_FILES += test_camera.c + endif include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_camera.c b/APP_Framework/Applications/app_test/test_camera.c new file mode 100644 index 000000000..f414dd2ee --- /dev/null +++ b/APP_Framework/Applications/app_test/test_camera.c @@ -0,0 +1,108 @@ +#include +#include +#include + +#define NULL_PARAMETER 0 + +#define DVP_INIT 0x00U +#define REG_SCCB_READ 0x12U +#define REG_SCCB_WRITE 0x13U +#define OUTPUT_CONFIG 0x20U +#define LCD_STRING_TYPE 0 +#define LCD_DOT_TYPE 1 +#define LCD_SIZE 320 + +static uint16_t image_buff[384000]; + +void TestCamera(int argc, char *argv[]) +{ + int frame_counter = 10000; + if (argc > 1) + { + frame_counter = atoi(argv[1]); + } + printf("This test will refresh %d frames\n", frame_counter); + + int camera_fd = PrivOpen(CAMERA_DEV_DRIVER, O_RDWR); + if (camera_fd < 0) + { + printf("open camera fd error:%d\n", camera_fd); + return; + } + int lcd_fd = PrivOpen(CAMERA_LCD_DEV_DRIVER, O_RDWR); + if (lcd_fd < 0) + { + printf("open lcd fd error:%d\n", lcd_fd); + return; + } + + //configure the camera's output address + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = CAMERA_TYPE; + struct CameraCfg camera_cfg ={ + .gain_manu_enable = 0, + .gain = 0xFF, + .window_w = 800, + .window_h = 600, + .output_w = IMAGE_WIDTH, + .output_h = IMAGE_HEIGHT, + .window_xoffset = 0, + .window_yoffset = 0 + }; + ioctl_cfg.args = &camera_cfg; + if (0 != PrivIoctl(camera_fd, OPE_CFG, &ioctl_cfg)) + { + printf("camera pin fd error %d\n", camera_fd); + PrivClose(camera_fd); + return; + } + + ioctl_cfg.args = (void *)image_buff; + + if (0 != PrivRead(camera_fd, image_buff, NULL_PARAMETER)) + { + printf("camera pin fd error %d\n", camera_fd); + PrivClose(camera_fd); + return; + } + + printf("address buff is %x\n", image_buff); + + + LcdWriteParam graph_param; + graph_param.type = LCD_DOT_TYPE; + + //clear the LCD + uint16_t back_color[LCD_SIZE]; + memset(back_color,0,sizeof(back_color)); + for (int i = 0; i < LCD_SIZE; i++) + { + graph_param.pixel_info.pixel_color = &back_color; + graph_param.pixel_info.x_startpos = 0; + graph_param.pixel_info.y_startpos = i; + graph_param.pixel_info.x_endpos = LCD_SIZE -1; + graph_param.pixel_info.y_endpos = i; + PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER); + } + + //refresh the LCD using photo of camera + while (frame_counter--) + { + for (int i = 0; i < IMAGE_HEIGHT; i++) + { + graph_param.pixel_info.pixel_color = image_buff + i * IMAGE_WIDTH; + graph_param.pixel_info.x_startpos = 0; + graph_param.pixel_info.y_startpos = i + (LCD_SIZE - IMAGE_HEIGHT) / 2; + graph_param.pixel_info.x_endpos = IMAGE_WIDTH - 1; + graph_param.pixel_info.y_endpos = i + (LCD_SIZE - IMAGE_HEIGHT) / 2; + PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER); + } + } + + // close test + PrivClose(lcd_fd); + PrivClose(camera_fd); + printf("The camera test is finished successfully\n"); +} + +PRIV_SHELL_CMD_FUNCTION(TestCamera, a camera test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_hwtimer.c b/APP_Framework/Applications/app_test/test_hwtimer.c index 985d7fac7..d8bd76543 100644 --- a/APP_Framework/Applications/app_test/test_hwtimer.c +++ b/APP_Framework/Applications/app_test/test_hwtimer.c @@ -6,28 +6,23 @@ #define NULL_PARAMETER 0 static uint16_t pinval=0; +static uint16_t pin_fd=0; void ledflip(void *parameter) { - int tmp_fd = *(int*)parameter; struct PinStat pin_led; pin_led.pin = BSP_LED_PIN; pin_led.val = !pinval; pinval = !pinval; - PrivWrite(tmp_fd,&pin_led,NULL_PARAMETER); - printf("Timer has callback once\n"); + PrivWrite(pin_fd,&pin_led,NULL_PARAMETER); + // printf("Timer has callback once:%d\n",pinval); } -void TestHwTimer(int argc, char *argv[]) +void TestHwTimer(void) { x_ticks_t period = 100;//uint:10ms - - if(argc>1){ - period = (x_ticks_t)atoi(argv[1]); - } - - int pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR); + pin_fd = PrivOpen(HWTIMER_PIN_DEV_DRIVER, O_RDWR); if(pin_fd<0){ printf("open pin fd error:%d\n",pin_fd); return; @@ -52,10 +47,6 @@ void TestHwTimer(int argc, char *argv[]) int32 timer_handle = KCreateTimer("LED on and off by 1s",&ledflip,&pin_fd,period,TIMER_TRIGGER_PERIODIC); KTimerStartRun(timer_handle); - PrivTaskDelay(10000); - KTimerQuitRun(timer_handle); - - KDeleteTimer(timer_handle); } diff --git a/APP_Framework/Applications/app_test/test_touch.c b/APP_Framework/Applications/app_test/test_touch.c index bccdbc1f0..1f2060fe9 100644 --- a/APP_Framework/Applications/app_test/test_touch.c +++ b/APP_Framework/Applications/app_test/test_touch.c @@ -41,3 +41,71 @@ void TestTouch(void) #endif #endif +#include +#include +#include + +#define NULL_PARAMETER 0 +#define LCD_DOT_TYPE 1 +#define LCD_SIZE 320 + + +void TestTouch(void) +{ + int touch_fd = PrivOpen(TOUCH_DEV_DRIVER, O_RDWR); + if (touch_fd < 0) + { + printf("open touch fd error:%d\n", touch_fd); + return; + } + int lcd_fd = PrivOpen(TOUCH_LCD_DEV_DRIVER, O_RDWR); + if (lcd_fd < 0) + { + printf("open lcd fd error:%d\n", lcd_fd); + return; + } + + // draw text + struct TouchDataStandard touch_pixel; + memset(&touch_pixel,0,sizeof(touch_pixel)); + LcdWriteParam graph_param; + + + graph_param.type = LCD_DOT_TYPE; + + uint16_t back_color[LCD_SIZE]; + memset(back_color,0x00,sizeof(back_color)); + for (int i = 0; i < LCD_SIZE; i++) + { + graph_param.pixel_info.pixel_color = &back_color; + graph_param.pixel_info.x_startpos = 0; + graph_param.pixel_info.y_startpos = i; + graph_param.pixel_info.x_endpos = LCD_SIZE -1; + graph_param.pixel_info.y_endpos = i; + PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER); + } + + uint16 color_select[LCD_SIZE]; + memset(color_select,0xff,sizeof(color_select)); + graph_param.pixel_info.pixel_color = &color_select; + while(1){ + if(0 > PrivRead(touch_fd, &touch_pixel, NULL_PARAMETER)){ + printf("read touch error\n"); + return; + } + printf("touch pixel position x:%d,y:%d\n",touch_pixel.x,touch_pixel.y); + graph_param.pixel_info.x_startpos = touch_pixel.x-10>0?touch_pixel.x-10:0; + graph_param.pixel_info.y_startpos = touch_pixel.y; + graph_param.pixel_info.x_endpos = touch_pixel.x+10; + graph_param.pixel_info.y_endpos = touch_pixel.y; + PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER); + graph_param.pixel_info.x_startpos = touch_pixel.x; + graph_param.pixel_info.y_startpos = touch_pixel.y-10>0?touch_pixel.y-10:0; + graph_param.pixel_info.x_endpos = touch_pixel.x; + graph_param.pixel_info.y_endpos = touch_pixel.y+10; + PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER); + } + PrivClose(touch_fd); +} + +PRIV_SHELL_CMD_FUNCTION(TestTouch, a touch test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c b/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c index da1dff600..b6e4f9428 100755 --- a/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c +++ b/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c @@ -164,7 +164,7 @@ void TcpSocketRecvTest(int argc, char *argv[]) } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip); + lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip); sys_thread_new("TcpSocketRecvTask", TcpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); #endif @@ -231,7 +231,7 @@ void TcpSocketSendTest(int argc, char *argv[]) } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip); + lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip); sys_thread_new("Tcp Socket Send", TcpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); #endif #ifdef ADD_NUTTX_FETURES diff --git a/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c b/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c index 62465d4bc..51c94a6c3 100755 --- a/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c +++ b/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c @@ -144,7 +144,7 @@ void UdpSocketRecvTest(int argc, char *argv[]) } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip); + lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip); sys_thread_new("UdpSocketRecvTask", UdpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); #endif @@ -207,7 +207,7 @@ void UdpSocketSendTest(int argc, char *argv[]) } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip); + lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip); sys_thread_new("UdpSocketSendTask", UdpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); #endif diff --git a/APP_Framework/Applications/control_app/plc_demo/omron/omron_cj2m.c b/APP_Framework/Applications/control_app/plc_demo/omron/omron_cj2m.c index b34d82dbf..5b770a5ac 100644 --- a/APP_Framework/Applications/control_app/plc_demo/omron/omron_cj2m.c +++ b/APP_Framework/Applications/control_app/plc_demo/omron/omron_cj2m.c @@ -18,6 +18,32 @@ * @date 2022.9.27 */ +#include +void ControlOmronTest(void) +{ + int i = 0; + uint16_t read_data_length = 0; + uint8_t read_data[1024] = {0}; + ControlProtocolType fins_protocol = ControlProtocolFind(); + if (NULL == fins_protocol) { + printf("%s get fins protocol %p failed\n", __func__, fins_protocol); + return; + } + printf("%s get fins protocol %p successfull\n", __func__, fins_protocol); + if (CONTROL_REGISTERED == fins_protocol->protocol_status) { + ControlProtocolOpen(fins_protocol); + + for (;;) { + read_data_length = ControlProtocolRead(fins_protocol, read_data, sizeof(read_data)); + printf("%s read [%d] fins data %d using receipe file\n", __func__, i, read_data_length); + i++; + PrivTaskDelay(100000); + } + + //ControlProtocolClose(fins_protocol); + } +} +PRIV_SHELL_CMD_FUNCTION(ControlOmronTest, Omron Plc FINS Demo, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/general_functions/Makefile b/APP_Framework/Applications/general_functions/Makefile index 57265e81c..564fc2a05 100644 --- a/APP_Framework/Applications/general_functions/Makefile +++ b/APP_Framework/Applications/general_functions/Makefile @@ -1,3 +1,3 @@ -SRC_DIR := list +SRC_DIR := list circular_area include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/APP_Framework/Applications/general_functions/circular_area/Makefile b/APP_Framework/Applications/general_functions/circular_area/Makefile new file mode 100644 index 000000000..30616891b --- /dev/null +++ b/APP_Framework/Applications/general_functions/circular_area/Makefile @@ -0,0 +1,11 @@ +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += circular_area_app.c + include $(APPDIR)/Application.mk +endif + +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + SRC_FILES := circular_area_app.c + include $(KERNEL_ROOT)/compiler.mk +endif \ No newline at end of file diff --git a/APP_Framework/Applications/general_functions/circular_area/SConscript b/APP_Framework/Applications/general_functions/circular_area/SConscript new file mode 100644 index 000000000..0268174f0 --- /dev/null +++ b/APP_Framework/Applications/general_functions/circular_area/SConscript @@ -0,0 +1,11 @@ +import os +from building import * +Import('RTT_ROOT') +Import('rtconfig') +cwd = GetCurrentDir() +DEPENDS = [""] + +SOURCES = ['circular_area_app.c'] +path = [cwd] +objs = DefineGroup('circular_area', src = SOURCES, depend = DEPENDS,CPPPATH = path) +Return("objs") \ No newline at end of file diff --git a/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c new file mode 100644 index 000000000..25e81c39c --- /dev/null +++ b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c @@ -0,0 +1,281 @@ +/* +* 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: circular_area_app.c +* @brief: circular area file for applications +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2022/11/21 +* +*/ + +#include "circular_area_app.h" + +/** + * This function will return whether the circular_area is full or not + * + * @param circular_area CircularAreaApp descriptor + */ +int CircularAreaAppIsFull(CircularAreaAppType circular_area) +{ + CA_PARAM_CHECK(circular_area); + + if((circular_area->readidx == circular_area->writeidx) && (circular_area->b_status)) { + printf("the circular area is full\n"); + return 1; + } else { + return 0; + } +} + +/** + * This function will return whether the circular_area is empty or not + * + * @param circular_area CircularAreaApp descriptor + */ +int CircularAreaAppIsEmpty(CircularAreaAppType circular_area) +{ + CA_PARAM_CHECK(circular_area); + + if((circular_area->readidx == circular_area->writeidx) && (!circular_area->b_status)) { + printf("the circular area is empty\n"); + return 1; + } else { + return 0; + } +} + +/** + * This function will reset the circular_area and set the descriptor to default + * + * @param circular_area CircularAreaApp descriptor + */ +void CircularAreaAppReset(CircularAreaAppType circular_area) +{ + circular_area->writeidx = 0; + circular_area->readidx = 0; + circular_area->b_status = 0; +} + +/** + * This function will release the circular_area descriptor and free the memory + * + * @param circular_area CircularAreaApp descriptor + */ +void CircularAreaAppRelease(CircularAreaAppType circular_area) +{ + circular_area->readidx = 0; + circular_area->writeidx = 0; + circular_area->p_head = NULL; + circular_area->p_tail = NULL; + circular_area->b_status = 0; + circular_area->area_length = 0; + + PrivFree(circular_area->data_buffer); + PrivFree(circular_area); +} + +/** + * This function will get the circual_area max length + * + * @param circular_area CircularAreaApp descriptor + */ +uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area) +{ + CA_PARAM_CHECK(circular_area); + + return circular_area->area_length; +} + +/** + * This function will get the data length of the circular_area + * + * @param circular_area CircularAreaApp descriptor + */ +uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area) +{ + CA_PARAM_CHECK(circular_area); + + if(CircularAreaAppIsFull(circular_area)) { + return circular_area->area_length; + } else { + return (circular_area->writeidx - circular_area->readidx + circular_area->area_length) % circular_area->area_length; + } +} + +/** + * This function will return whether it is need to divide the read data into two parts or not + * + * @param circular_area CircularAreaApp descriptor + * @param data_length output data length + */ +static uint32_t CircularAreaAppDivideRdData(CircularAreaAppType circular_area, uint32_t data_length) +{ + CA_PARAM_CHECK(circular_area); + + if(circular_area->readidx + data_length <= circular_area->area_length) { + return 0; + } else { + return 1; + } +} + +/** + * This function will return whether it is need to divide the write data into two parts or not + * + * @param circular_area CircularAreaApp descriptor + * @param data_length input data length + */ +static uint32_t CircularAreaAppDivideWrData(CircularAreaAppType circular_area, uint32_t data_length) +{ + CA_PARAM_CHECK(circular_area); + + if(circular_area->writeidx + data_length <= circular_area->area_length) { + return 0; + } else { + return 1; + } +} + +/** + * This function will read data from the circular_area + * + * @param circular_area CircularAreaApp descriptor + * @param output_buffer output data buffer poniter + * @param data_length output data length + */ +int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length) +{ + CA_PARAM_CHECK(circular_area); + CA_PARAM_CHECK(output_buffer); + CHECK(data_length > 0); + + if(CircularAreaAppIsEmpty(circular_area)) { + return -1; + } + + uint32_t read_length = (data_length > CircularAreaAppGetDataLength(circular_area)) ? CircularAreaAppGetDataLength(circular_area) : data_length; + // if (data_length > CircularAreaAppGetDataLength(circular_area)) { + // return -1; + // } + + if(CircularAreaAppDivideRdData(circular_area, read_length)) { + uint32_t read_len_up = circular_area->area_length - circular_area->readidx; + uint32_t read_len_down = read_length - read_len_up; + + memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_len_up); + memcpy(output_buffer + read_len_up, circular_area->p_head, read_len_down); + + circular_area->readidx = read_len_down; + } else { + memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_length); + circular_area->readidx = (circular_area->readidx + read_length) % circular_area->area_length; + } + + circular_area->b_status = 0; + + return read_length; +} + +/** + * This function will write data to the circular_area + * + * @param circular_area CircularAreaApp descriptor + * @param input_buffer input data buffer poniter + * @param data_length input data length + * @param b_force whether to force to write data disregard the length limit + */ +int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force) +{ + CA_PARAM_CHECK(circular_area); + CA_PARAM_CHECK(input_buffer); + CHECK(data_length > 0); + + if(CircularAreaAppIsFull(circular_area) && (!b_force)) { + return -1; + } + + uint32_t write_data_length = circular_area->area_length - CircularAreaAppGetDataLength(circular_area); + //data_length = (data_length > write_data_length) ? write_data_length : data_length; + if (data_length > write_data_length) { + return -1; + } + + if(CircularAreaAppDivideWrData(circular_area, data_length)) { + uint32_t write_len_up = circular_area->area_length - circular_area->writeidx; + uint32_t write_len_down = data_length - write_len_up; + + memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, write_len_up); + memcpy(circular_area->p_head, input_buffer + write_len_up, write_len_down); + + circular_area->writeidx = write_len_down; + } else { + memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, data_length); + circular_area->writeidx = (circular_area->writeidx + data_length) % circular_area->area_length; + } + + circular_area->b_status = 1; + + if(b_force) { + circular_area->readidx = circular_area->writeidx; + } + + return 0; +} + +static struct CircularAreaAppOps CircularAreaAppOperations = +{ + CircularAreaAppRead, + CircularAreaAppWrite, + CircularAreaAppRelease, + CircularAreaAppReset, +}; + +/** + * This function will initialize the circular_area + * + * @param circular_area_length circular_area length + */ +CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length) +{ + CHECK(circular_area_length > 0); + + circular_area_length = CA_ALIGN_DOWN(circular_area_length, 8); + + CircularAreaAppType circular_area = PrivMalloc(sizeof(struct CircularAreaApp)); + if(NULL == circular_area) { + printf("CircularAreaAppInit malloc struct circular_area failed\n"); + PrivFree(circular_area); + return NULL; + } + + CircularAreaAppReset(circular_area); + + circular_area->data_buffer = PrivMalloc(circular_area_length); + if(NULL == circular_area->data_buffer) { + printf("CircularAreaAppInit malloc circular_area data_buffer failed\n"); + PrivFree(circular_area->data_buffer); + return NULL; + } + + circular_area->p_head = circular_area->data_buffer; + circular_area->p_tail = circular_area->data_buffer + circular_area_length; + circular_area->area_length = circular_area_length; + + printf("CircularAreaAppInit done p_head %8p p_tail %8p length %u\n", + circular_area->p_head, circular_area->p_tail, circular_area->area_length); + + circular_area->CircularAreaAppOperations = &CircularAreaAppOperations; + + return circular_area; +} diff --git a/APP_Framework/Applications/general_functions/circular_area/circular_area_app.h b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.h new file mode 100644 index 000000000..7533248d3 --- /dev/null +++ b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.h @@ -0,0 +1,100 @@ +/* +* 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: circular_area_app.h +* @brief: function declaration and structure defintion of circular area for applications +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2022/11/21 +* +*/ + +#ifndef CIRCULAR_AREA_APP_H +#define CIRCULAR_AREA_APP_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CA_PARAM_CHECK(param) \ + do \ + { \ + if(param == NULL) { \ + KPrintf("PARAM CHECK FAILED ...%s %d %s is NULL.\n", __func__, __LINE__, #param); \ + while(1); \ + } \ + }while (0) + +#define CA_ALIGN_DOWN(size, align) ((size)/(align)*(align)) + +typedef struct CircularAreaApp *CircularAreaAppType; + +struct CircularAreaAppOps +{ + int (*read) (CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length); + int (*write) (CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force); + void (*release) (CircularAreaAppType circular_area); + void (*reset) (CircularAreaAppType circular_area); +}; + +struct CircularAreaApp +{ + uint8_t *data_buffer; + + uint32_t readidx; + uint32_t writeidx; + + uint8_t *p_head; + uint8_t *p_tail; + + uint32_t area_length; + int b_status; + + struct CircularAreaAppOps *CircularAreaAppOperations; +}; + +/*This function will return whether the circular_area is full or not*/ +int CircularAreaAppIsFull(CircularAreaAppType circular_area); + +/*This function will return whether the circular_area is empty or not*/ +int CircularAreaAppIsEmpty(CircularAreaAppType circular_area); + +/*This function will reset the circular_area and set the descriptor to default*/ +void CircularAreaAppReset(CircularAreaAppType circular_area); + +/*This function will release the circular_area descriptor and free the memory*/ +void CircularAreaAppRelease(CircularAreaAppType circular_area); + +/*This function will read data from the circular_area*/ +int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length); + +/*This function will write data to the circular_area*/ +int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force); + +/*This function will get the circual_area max length*/ +uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area); + +/*This function will get the data length of the circular_area*/ +uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area); + +/*This function will initialize the circular_area*/ +CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/APP_Framework/Applications/sensor_app/humidity_hs300x.c b/APP_Framework/Applications/sensor_app/humidity_hs300x.c index a35094a72..2cfeb4c8a 100644 --- a/APP_Framework/Applications/sensor_app/humidity_hs300x.c +++ b/APP_Framework/Applications/sensor_app/humidity_hs300x.c @@ -30,10 +30,10 @@ void HumiHs300x(void) int32_t humidity; struct SensorQuantity *humi = SensorQuantityFind(SENSOR_QUANTITY_HS300X_HUMIDITY, SENSOR_QUANTITY_HUMI); SensorQuantityOpen(humi); - for (i = 0; i < 100; i ++) { + for (i = 0; i < 10; i ++) { humidity = SensorQuantityReadValue(humi); printf("Humidity : %d.%d %%RH\n", humidity/10, humidity%10); - PrivTaskDelay(5000); + PrivTaskDelay(500); } SensorQuantityClose(humi); } \ No newline at end of file diff --git a/APP_Framework/Applications/sensor_app/temperature_hs300x.c b/APP_Framework/Applications/sensor_app/temperature_hs300x.c index bb5922f3a..98f6d9281 100644 --- a/APP_Framework/Applications/sensor_app/temperature_hs300x.c +++ b/APP_Framework/Applications/sensor_app/temperature_hs300x.c @@ -30,14 +30,14 @@ void TempHs300x(void) int32_t temperature; struct SensorQuantity *temp = SensorQuantityFind(SENSOR_QUANTITY_HS300X_TEMPERATURE, SENSOR_QUANTITY_TEMP); SensorQuantityOpen(temp); - for (i = 0; i < 100; i ++) { + for (i = 0; i < 10; i ++) { temperature = SensorQuantityReadValue(temp); if (temperature > 0) printf("Temperature : %d.%d ℃\n", temperature/10, temperature%10); else printf("Temperature : %d.%d ℃\n", temperature/10, -temperature%10); - PrivTaskDelay(5000); + PrivTaskDelay(500); } SensorQuantityClose(temp); diff --git a/APP_Framework/Framework/Make.defs b/APP_Framework/Framework/Make.defs index 40d65f37f..68a24a4f8 100644 --- a/APP_Framework/Framework/Make.defs +++ b/APP_Framework/Framework/Make.defs @@ -1,5 +1,6 @@ ############################################################################ # APP_Framework/Framework/Make.defs ############################################################################ +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/transform_layer/nuttx include $(wildcard $(APPDIR)/../../../APP_Framework/Framework/*/Make.defs) diff --git a/APP_Framework/Framework/Makefile b/APP_Framework/Framework/Makefile index d9e3e101e..32a3a1005 100644 --- a/APP_Framework/Framework/Makefile +++ b/APP_Framework/Framework/Makefile @@ -1,28 +1,40 @@ -SRC_DIR := transform_layer +include $(KERNEL_ROOT)/.config -ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y) - SRC_DIR += sensor +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += framework_init.c + include $(APPDIR)/Application.mk endif -ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y) - SRC_DIR += connection +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + SRC_FILES := framework_init.c + SRC_DIR := transform_layer + + ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y) + SRC_DIR += sensor + endif + + ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y) + SRC_DIR += connection + endif + + ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y) + SRC_DIR += knowing + endif + + ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y) + SRC_DIR += control + endif + + ifeq ($(CONFIG_CRYPTO),y) + SRC_DIR += security + endif + + ifeq ($(CONFIG_MBEDTLS), y) + SRC_DIR += security + endif + + include $(KERNEL_ROOT)/compiler.mk + endif -ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y) - SRC_DIR += knowing -endif - -ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y) - SRC_DIR += control -endif - -ifeq ($(CONFIG_CRYPTO),y) - SRC_DIR += security -endif - -ifeq ($(CONFIG_MBEDTLS), y) - SRC_DIR += security -endif - -include $(KERNEL_ROOT)/compiler.mk - diff --git a/APP_Framework/Framework/connection/adapter.c b/APP_Framework/Framework/connection/adapter.c index eb1356c14..3ac510f84 100644 --- a/APP_Framework/Framework/connection/adapter.c +++ b/APP_Framework/Framework/connection/adapter.c @@ -21,11 +21,8 @@ #include static DoublelistType adapter_list; -#ifdef ADD_XIZI_FETURES -static int adapter_list_lock; -#else static pthread_mutex_t adapter_list_lock; -#endif + /** * @description: Init adapter framework * @return 0 diff --git a/APP_Framework/Framework/connection/wifi/Makefile b/APP_Framework/Framework/connection/wifi/Makefile index cfa6cac9f..5e466adc5 100644 --- a/APP_Framework/Framework/connection/wifi/Makefile +++ b/APP_Framework/Framework/connection/wifi/Makefile @@ -17,5 +17,9 @@ ifeq ($(CONFIG_ADAPTER_ESP07S_WIFI),y) SRC_DIR += esp07s_wifi endif +ifeq ($(CONFIG_ADAPTER_ESP8285_WIFI),y) + SRC_DIR += esp8285_wifi +endif + include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig index f44e5d47a..6fea4cc6f 100644 --- a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig @@ -8,3 +8,9 @@ if ADD_NUTTX_FETURES default "/dev/ttyS1" endif +if ADD_XIZI_FETURES + config ADAPTER_ESP8285_DRIVER + string "ESP8285 device uart driver path" + default "/dev/uart1_dev1" +endif + diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile index c1ee6bd29..0431e2732 100644 --- a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile @@ -5,3 +5,8 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) include $(APPDIR)/Application.mk endif + +ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + SRC_FILES := esp8285_wifi.c + include $(KERNEL_ROOT)/compiler.mk +endif \ No newline at end of file diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c b/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c index f0a3b77c8..3c87225f1 100644 --- a/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c @@ -205,16 +205,16 @@ static int Esp8285WifiSetUp(struct Adapter *adapter) PrivTaskDelay(2000); /* connect the router */ memset(cmd,0,sizeof(cmd)); - strncpy(cmd,"AT+CWJAP=",strlen("AT+CWJAP=")); - strncat(cmd,"\"",1); - strncat(cmd,param->wifi_ssid,strlen(param->wifi_ssid)); + strcat(cmd,"AT+CWJAP="); + strcat(cmd,"\""); + strcat(cmd,param->wifi_ssid); - strncat(cmd,"\"",1); - strncat(cmd,",",1); - strncat(cmd,"\"",1); - strncat(cmd,param->wifi_pwd,strlen(param->wifi_pwd)); + strcat(cmd,"\""); + strcat(cmd,","); + strcat(cmd,"\""); + strcat(cmd,param->wifi_pwd); - strncat(cmd,"\"",1); + strcat(cmd,"\""); strcat(cmd,"\r\n"); ret = AtCmdConfigAndCheck(agent, cmd, "OK"); @@ -279,17 +279,17 @@ static int Esp8285WifiSetAddr(struct Adapter *adapter, const char *ip, const cha /* e.g. AT+CIPSTA_DEF="192.168.6.100","192.168.6.1","255.255.255.0" */ memset(cmd,0,sizeof(cmd)); strncpy(cmd,"AT+CIPAP_DEF=",strlen(" AT+CIPAP_DEF=")); - strncat(cmd,"\"",1); - strncat(cmd,ip,strlen(ip)); - strncat(cmd,"\"",1); - strncat(cmd,",",1); - strncat(cmd,"\"",1); - strncat(cmd,gateway,strlen(gateway)); - strncat(cmd,"\"",1); - strncat(cmd,",",1); - strncat(cmd,"\"",1); - strncat(cmd,netmask,strlen(netmask)); - strncat(cmd,"\"",1); + strcat(cmd,"\""); + strcat(cmd,ip); + strcat(cmd,"\""); + strcat(cmd,","); + strcat(cmd,"\""); + strcat(cmd,gateway); + strcat(cmd,"\""); + strcat(cmd,","); + strcat(cmd,"\""); + strcat(cmd,netmask); + strcat(cmd,"\""); strcat(cmd,"\r\n"); ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); @@ -314,9 +314,9 @@ static int Esp8285WifiPing(struct Adapter *adapter, const char *destination) memset(cmd,0,sizeof(cmd)); strncpy(cmd,"AT+PING=",strlen("AT+PING=")); - strncat(cmd,"\"",1); - strncat(cmd,destination,strlen(destination)); - strncat(cmd,"\"",1); + strcat(cmd,"\""); + strcat(cmd,destination); + strcat(cmd,"\""); strcat(cmd,"\r\n"); ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); ///< config as softAP+station mode @@ -387,15 +387,15 @@ static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role { //e.g. AT+CIPSTART="TCP","192.168.3.116",8080 protocol, server IP and port strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART=")); - strncat(cmd,"\"",1); - strncat(cmd,"TCP",strlen("TCP")); - strncat(cmd,"\"",1); - strncat(cmd, ",", 1); - strncat(cmd,"\"",1); - strncat(cmd, ip, strlen(ip)); - strncat(cmd, "\"", 1); - strncat(cmd, ",", 1); - strncat(cmd, port, strlen(port)); + strcat(cmd,"\""); + strcat(cmd,"TCP"); + strcat(cmd,"\""); + strcat(cmd, ","); + strcat(cmd,"\""); + strcat(cmd, ip); + strcat(cmd, "\""); + strcat(cmd, ","); + strcat(cmd, port); strcat(cmd,"\r\n"); ret = AtCmdConfigAndCheck(agent, cmd, "OK"); @@ -408,19 +408,19 @@ static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role { //e.g. AT+CIPSTART="UDP","192.168.3.116",8080,2233,0 UDP protocol, server IP, port,local port,udp mode strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART=")); - strncat(cmd,"\"",1); - strncat(cmd,"UDP",strlen("UDP")); - strncat(cmd,"\"",1); - strncat(cmd, ",", 1); - strncat(cmd,"\"",1); - strncat(cmd, ip, strlen(ip)); - strncat(cmd, "\"", 1); - strncat(cmd, ",", 1); - strncat(cmd, port, strlen(port)); - strncat(cmd, ",", 1); - strncat(cmd, "2233", strlen("2233")); ///< local port - strncat(cmd, ",", 1); - strncat(cmd, "0", 1); ///< udp transparent transmission mode must be 0 + strcat(cmd,"\""); + strcat(cmd,"UDP"); + strcat(cmd,"\""); + strcat(cmd, ","); + strcat(cmd,"\""); + strcat(cmd, ip); + strcat(cmd, "\""); + strcat(cmd, ","); + strcat(cmd, port); + strcat(cmd, ","); + strcat(cmd, "2233"); ///< local port + strcat(cmd, ","); + strcat(cmd, "0"); ///< udp transparent transmission mode must be 0 strcat(cmd,"\r\n"); ret = AtCmdConfigAndCheck(agent, cmd, "OK"); @@ -523,15 +523,15 @@ static int Esp8285WifiIoctl(struct Adapter *adapter, int cmd, void *args) itoa(baud_rate, baud_str, 10); strncpy(at_cmd, "AT+UART_DEF=", strlen("AT+UART_DEF=")); - strncat(at_cmd, baud_str, strlen(baud_str)); - strncat(at_cmd, ",", 1); - strncat(at_cmd, "8", 1); - strncat(at_cmd, ",", 1); - strncat(at_cmd, "1", 1); - strncat(at_cmd, ",", 1); - strncat(at_cmd, "0", 1); - strncat(at_cmd, ",", 1); - strncat(at_cmd, "3", 1); + strcat(at_cmd, baud_str); + strcat(at_cmd, ","); + strcat(at_cmd, "8"); + strcat(at_cmd, ","); + strcat(at_cmd, "1"); + strcat(at_cmd, ","); + strcat(at_cmd, "0"); + strcat(at_cmd, ","); + strcat(at_cmd, "3"); strcat(at_cmd,"\r\n"); ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK"); diff --git a/APP_Framework/Framework/control/Kconfig b/APP_Framework/Framework/control/Kconfig index 8c7e89ac4..e9e0a1753 100755 --- a/APP_Framework/Framework/control/Kconfig +++ b/APP_Framework/Framework/control/Kconfig @@ -2,8 +2,28 @@ menuconfig SUPPORT_CONTROL_FRAMEWORK bool "support control framework" default n select TRANSFORM_LAYER_ATTRIUBUTE + select BSP_USING_LWIP + select BSP_USING_SDIO + select MOUNT_SDCARD_FS + select LIB_USING_CJSON if SUPPORT_CONTROL_FRAMEWORK - source "$APP_DIR/Framework/control/ipc_protocol/Kconfig" - source "$APP_DIR/Framework/control/plc_protocol/Kconfig" + config CONTROL_RECIPE_FILE + string "control framework recipe file name" + default "test_recipe.json" + + menuconfig CONTROL_IPC_PROTOCOL + bool "Using ipc protocol" + default n + if CONTROL_IPC_PROTOCOL + source "$APP_DIR/Framework/control/ipc_protocol/Kconfig" + endif + + menuconfig CONTROL_PLC_PROTOCOL + bool "Using plc protocol" + default n + if CONTROL_PLC_PROTOCOL + source "$APP_DIR/Framework/control/plc_protocol/Kconfig" + endif + endif diff --git a/APP_Framework/Framework/control/Makefile b/APP_Framework/Framework/control/Makefile index b2fb7da93..3db840df4 100755 --- a/APP_Framework/Framework/control/Makefile +++ b/APP_Framework/Framework/control/Makefile @@ -1,3 +1,11 @@ -SRC_DIR := ipc_protocol plc_protocol shared +SRC_DIR := shared + +ifeq ($(CONFIG_CONTROL_IPC_PROTOCOL), y) + SRC_DIR += ipc_protocol +endif + +ifeq ($(CONFIG_CONTROL_PLC_PROTOCOL), y) + SRC_DIR += plc_protocol +endif include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/control/ipc_protocol/Kconfig b/APP_Framework/Framework/control/ipc_protocol/Kconfig index 139597f9c..bc72c4672 100755 --- a/APP_Framework/Framework/control/ipc_protocol/Kconfig +++ b/APP_Framework/Framework/control/ipc_protocol/Kconfig @@ -1,2 +1,8 @@ +config CONTROL_PROTOCOL_MODBUS_TCP + bool "Using modbus_tcp control protocol" + default n +config CONTROL_PROTOCOL_MODBUS_UART + bool "Using modbus_uart control protocol" + default n diff --git a/APP_Framework/Framework/control/ipc_protocol/Makefile b/APP_Framework/Framework/control/ipc_protocol/Makefile index 4c33eaf37..a22240e9a 100755 --- a/APP_Framework/Framework/control/ipc_protocol/Makefile +++ b/APP_Framework/Framework/control/ipc_protocol/Makefile @@ -1,4 +1,10 @@ -SRC_DIR := modbus_tcp modbus_uart +ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_TCP), y) + SRC_DIR := modbus_tcp +endif + +ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_UART), y) + SRC_DIR := modbus_uart +endif include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/control/plc/interoperability/socket/plc_socket.c b/APP_Framework/Framework/control/plc/interoperability/socket/plc_socket.c deleted file mode 100755 index 5c0dc8867..000000000 --- a/APP_Framework/Framework/control/plc/interoperability/socket/plc_socket.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (c) 2022 AIIT XUOS Lab - * XiUOS is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * http://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - -/** - * @file plc_socket.c - * @brief Demo for PLC socket communication function - * @version 1.0 - * @author AIIT XUOS Lab - * @date 2022.03.16 - */ - -#include "transform.h" -#include "plc_socket.h" -#include "sys_arch.h" -#include "lwip/sockets.h" -#include "control_file.h" - -// max support plc socket test commands number -#define PLC_SOCK_CMD_NUM CTL_CMD_NUM -#define PLC_SOCK_TIMEOUT 50000 - -// for saving PLC command index -int plc_cmd_index = 0; - -// only for test -#define SUPPORT_PLC_SIEMENS - -//siemens test -PlcBinCmdType TestPlcCmd[PLC_SOCK_CMD_NUM] = {0}; - -//Test information -//SIEMENS ip: 192.168.250.9 port: 102 -//S7-200 ip: 192.168.250.8 port: 102 -//S7-1200 ip: 192.168.250.6 port: 102 -//OML ip: 192.168.250.3 port: 9600 - -PlcSocketParamType plc_socket_demo_data = { -#ifdef SUPPORT_PLC_SIEMENS - .ip = {192, 168, 250, 6}, - .port = 102, - .device_type = PLC_DEV_TYPE_SIEMENS, - .socket_type = SOCK_STREAM, - .cmd_num = 3, -#else - .ip = {192, 168, 250, 3}, - .port = 9600, - .device_type = PLC_DEV_TYPE_OML, - .socket_type = SOCK_DGRAM, - .cmd_num = 1, -#endif - .recv_len = PLC_RECV_BUF_LEN, - .recv_buf = NULL, -}; - -#define OML_HEADER_LEN 78 -#define CHECK_OML_HEADER(_s) ((0xC0 == *(_s)) && (0x00 == *(_s + 1)) && (0x02 == *(_s + 2)) && (0x00 == *(_s + 3))) - -/******************************************************************************/ - -static void plc_print_array(char *title, int size, uint8_t *cmd) -{ - lw_notice("%s : %d - ", title, size); - for(int i = 0; i < size; i++) - { - lw_notice(" %#x", cmd[i]); - } - lw_notice("\n"); -} - -static void *PlcSocketStart(void *arg) -{ - int fd = -1; - int timeout, recv_len; - struct sockaddr_in sock_addr; - socklen_t addr_len = sizeof(struct sockaddr_in); - PlcSocketParamType *param = (PlcSocketParamType *)&plc_socket_demo_data; - - plc_print("start %d.%d.%d.%d:%d dev %d sock %d\n", - param->ip[0], - param->ip[1], - param->ip[2], - param->ip[3], - param->port, - param->device_type, - param->socket_type); - - param->recv_len = PLC_RECV_BUF_LEN; - - //malloc memory - param->recv_buf = (char *)malloc(param->recv_len); - if (param->recv_buf == NULL) - { - plc_error("No memory\n"); - return NULL; - } - - fd = socket(AF_INET, param->socket_type, 0); - if (fd < 0) - { - plc_error("Socket error %d\n", param->socket_type); - free(param->recv_buf); - return NULL; - } - - plc_print("start %d.%d.%d.%d:%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3], param->port); - - sock_addr.sin_family = AF_INET; - sock_addr.sin_port = htons(param->port); - sock_addr.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(param->ip[0], param->ip[1], param->ip[2], param->ip[3])); - memset(&(sock_addr.sin_zero), 0, sizeof(sock_addr.sin_zero)); - - if (connect(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr)) < 0) - { - plc_error("Unable to connect\n"); - closesocket(fd); - free(param->recv_buf); - return NULL; - } - - lw_notice("client %s connected\n", inet_ntoa(sock_addr.sin_addr)); - - for(int i = 0; i < param->cmd_num; i ++) - { - PlcBinCmdType *cmd = &TestPlcCmd[i]; - sendto(fd, cmd->cmd, cmd->cmd_len, 0, (struct sockaddr*)&sock_addr, addr_len); - plc_print_array("Send cmd", cmd->cmd_len, cmd->cmd); - - MdelayKTask(cmd->delay_ms); - timeout = PLC_SOCK_TIMEOUT; - memset(param->recv_buf, 0, param->recv_len); - while(timeout --) - { - recv_len = recvfrom(fd, param->recv_buf, param->recv_len, 0, (struct sockaddr *)&sock_addr, &addr_len); - if(recv_len > 0) - { - if(param->device_type == PLC_DEV_TYPE_OML) - { - if((recv_len == OML_HEADER_LEN) && (CHECK_OML_HEADER(param->recv_buf))) - { - lw_notice("This is Oml package!!!\n"); - } - } - lw_notice("Receive from : %s\n", inet_ntoa(sock_addr.sin_addr)); - plc_print_array("Receive data", recv_len, param->recv_buf); - break; - } - } - } - - closesocket(fd); - free(param->recv_buf); - return NULL; -} - -void PlcGetParamCmd(char *cmd) -{ - const char s[2] = ","; - char *token; - uint16_t cmd_index = 0; - char bin_cmd[PLC_BIN_CMD_LEN] = {0}; - token = strtok(cmd, s); - while(token != NULL) - { - sscanf(token, "%x", &bin_cmd[cmd_index]); - plc_print("%d - %s %d\n", cmd_index, token, bin_cmd[cmd_index]); - token = strtok(NULL, s); - cmd_index ++; - } - TestPlcCmd[plc_cmd_index].cmd_len = cmd_index; - memcpy(TestPlcCmd[plc_cmd_index].cmd, bin_cmd, cmd_index); - plc_print("get %d cmd len %d\n", plc_cmd_index, TestPlcCmd[plc_cmd_index].cmd_len); - plc_cmd_index ++; - plc_socket_demo_data.cmd_num = plc_cmd_index; -} - -void PlcShowUsage(void) -{ - plc_notice("------------------------------------\n"); - plc_notice("PlcSocket [ip].[ip].[ip].[ip]:[port]\n"); - plc_notice("PlcSocket support other param:\n"); - plc_notice("plc=[] 0: OML 1:SIEMENS\n"); - plc_notice("tcp=[] 0: udp 1:tcp\n"); - plc_notice("ip=[ip.ip.ip.ip]\n"); - plc_notice("port=port\n"); - plc_notice("file: use %s\n", PLC_SOCK_FILE_NAME); - plc_notice("------------------------------------\n"); -} - -#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON) -void PlcGetParamFromFile(char *file_name) -{ - PlcSocketParamType *param = &plc_socket_demo_data; - - char *file_buf = malloc(CTL_FILE_LEN); - if(file_buf == NULL) - { - plc_error("No enough buffer %d\n", CTL_FILE_LEN); - return; - } - memset(file_buf, 0, CTL_FILE_LEN); - - if(CtlFileReadWithFilename(file_name, CTL_FILE_LEN, file_buf) != EOK) - { - plc_error("Can't open file %s\n", file_name); - //try again default file - if(strcmp(file_name, PLC_SOCK_FILE_NAME) != 0) - { - if(CtlFileReadWithFilename(PLC_SOCK_FILE_NAME, CTL_FILE_LEN, file_buf) != EOK) - { - plc_error("Can't open file %s\n", file_name); - return; - } - } - else - { - return; - } - } - CtlParseJsonData(file_buf); - - memcpy(param->ip, ctl_file_param.ip, 4); - param->port = ctl_file_param.port; - param->cmd_num = ctl_file_param.cmd_num; - param->socket_type = ctl_file_param.tcp ? SOCK_STREAM : SOCK_DGRAM; - - for(int i = 0; i < param->cmd_num; i++) - { - TestPlcCmd[i].cmd_len = ctl_file_param.cmd_len[i]; - memcpy(TestPlcCmd[i].cmd, ctl_file_param.cmd[i], TestPlcCmd[i].cmd_len); - } - - plc_print("ip: %d.%d.%d.%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]); - plc_print("port: %d", param->port); - plc_print("tcp: %d", param->socket_type); - plc_print("cmd number: %d\n", param->cmd_num); - - for(int i = 0; i < param->cmd_num; i++) - { - plc_print_array("cmd", TestPlcCmd[i].cmd_len, TestPlcCmd[i].cmd); - } - free(file_buf); -} - -#endif - -void PlcCheckParam(int argc, char *argv[]) -{ - int i; - PlcSocketParamType *param = &plc_socket_demo_data; - plc_cmd_index = 0; - - for(i = 0; i < argc; i++) - { - char *str = argv[i]; - int is_tcp = 0; - char cmd_str[PLC_BIN_CMD_LEN] = {0}; - - plc_print("check %d %s\n", i, str); - -#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON) - if(strncmp(str, "file", 4) == 0) - { - char file_name[CTL_FILE_NAME_LEN] = {0}; - if(sscanf(str, "file=%s", file_name) == EOF) - { - strcpy(file_name, PLC_SOCK_FILE_NAME); - } - plc_notice("get %s parameter file %s\n", str, file_name); - PlcGetParamFromFile(file_name); - return; - } -#endif - if(sscanf(str, "ip=%d.%d.%d.%d", - ¶m->ip[0], - ¶m->ip[1], - ¶m->ip[2], - ¶m->ip[3]) == 4) - { - plc_print("find ip %d %d %d %d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]); - continue; - } - - if(sscanf(str, "port=%d", ¶m->port) == 1) - { - plc_print("find port %d\n", param->port); - continue; - } - - if(sscanf(str, "tcp=%d", &is_tcp) == 1) - { - plc_print("find tcp %d\n", is_tcp); - param->socket_type = is_tcp ? SOCK_STREAM:SOCK_DGRAM; - continue; - } - - if(sscanf(str, "plc=%d", ¶m->device_type) == 1) - { - plc_print("find device %d\n", param->device_type); - continue; - } - - if(sscanf(str, "cmd=%s", cmd_str) == 1) - { - plc_print("find cmd %s\n", cmd_str); - PlcGetParamCmd(cmd_str); - continue; - } - } - - if(argc >= 2) - { - if(sscanf(argv[1], "%d.%d.%d.%d:%d", - ¶m->ip[0], - ¶m->ip[1], - ¶m->ip[2], - ¶m->ip[3], - ¶m->port) != EOF) - { - return; - } - - if(sscanf(argv[1], "%d.%d.%d.%d", - ¶m->ip[0], - ¶m->ip[1], - ¶m->ip[2], - ¶m->ip[3]) != EOF) - { - return; - } - } - else - { - PlcShowUsage(); - } -} - -void PlcSocketTask(int argc, char *argv[]) -{ - int result = 0; - pthread_t th_id; - uint8_t enet_port = 0; ///< test enet port 0 - - pthread_attr_t attr; - attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO; - attr.stacksize = LWIP_TASK_STACK_SIZE; - PlcSocketParamType *param = &plc_socket_demo_data; - - PlcCheckParam(argc, argv); - - lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, param->ip); - PrivTaskCreate(&th_id, &attr, PlcSocketStart, param); -} - -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3), - PlcSocket, PlcSocketTask, Test PLC Socket); - diff --git a/APP_Framework/Framework/control/plc_protocol/Kconfig b/APP_Framework/Framework/control/plc_protocol/Kconfig index 139597f9c..9839fe26e 100755 --- a/APP_Framework/Framework/control/plc_protocol/Kconfig +++ b/APP_Framework/Framework/control/plc_protocol/Kconfig @@ -1,2 +1,15 @@ +config CONTROL_PROTOCOL_FINS + bool "Using fins control protocol" + default n +config CONTROL_PROTOCOL_MELSEC + bool "Using melsec control protocol" + default n +config CONTROL_PROTOCOL_OPCUA + bool "Using opcua control protocol" + default n + +config CONTROL_PROTOCOL_S7 + bool "Using s7 control protocol" + default n diff --git a/APP_Framework/Framework/control/plc_protocol/Makefile b/APP_Framework/Framework/control/plc_protocol/Makefile index ff2e46798..66e467295 100755 --- a/APP_Framework/Framework/control/plc_protocol/Makefile +++ b/APP_Framework/Framework/control/plc_protocol/Makefile @@ -1,4 +1,17 @@ -SRC_DIR := fins melsec opcua s7 +ifeq ($(CONFIG_CONTROL_PROTOCOL_FINS), y) + SRC_DIR := fins +endif + +ifeq ($(CONFIG_CONTROL_PROTOCOL_MELSEC), y) + SRC_DIR := melsec +endif + +ifeq ($(CONFIG_CONTROL_PROTOCOL_OPCUA), y) + SRC_DIR := opcua +endif + +ifeq ($(CONFIG_CONTROL_PROTOCOL_S7), y) + SRC_DIR := s7 +endif include $(KERNEL_ROOT)/compiler.mk - diff --git a/APP_Framework/Framework/control/plc_protocol/fins/Makefile b/APP_Framework/Framework/control/plc_protocol/fins/Makefile index 608656f03..020d8567a 100755 --- a/APP_Framework/Framework/control/plc_protocol/fins/Makefile +++ b/APP_Framework/Framework/control/plc_protocol/fins/Makefile @@ -1,4 +1,4 @@ -SRC_FILES := +SRC_FILES := fins.c include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/control/plc_protocol/fins/fins.c b/APP_Framework/Framework/control/plc_protocol/fins/fins.c new file mode 100644 index 000000000..1c20eba77 --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/fins/fins.c @@ -0,0 +1,436 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file fins.c + * @brief plc protocol fins + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-10-08 + */ + +#include + +#define FINS_COMMAND_LENGTH 34 + +static BasicSocketPlc plc_socket = {0}; + +static uint8_t handshake_require_command[] = {0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +static uint8_t handshake_respond_buff[24] = {0}; +static uint8_t recv_buff[1024] = {0}; + +/** + * @description: Fins Get Area Code + * @param area_char - area char + * @param type - fins data type + * @return success : area_char error : 0 + */ +static uint8_t FinsAreaCode(char area_char, FinsDataType type) +{ + uint8_t area_code = 0; + if (area_char == 'C') + area_code = (type == FINS_DATA_TYPE_BIT ? 0x30 : 0xB0); + if (area_char == 'W') + area_code = (type == FINS_DATA_TYPE_BIT ? 0x31 : 0xB1); + if (area_char == 'H') + area_code = (type == FINS_DATA_TYPE_BIT ? 0x32 : 0xB2); + if (area_char == 'D') + area_code = (type == FINS_DATA_TYPE_BIT ? 0x02 : 0x82); + return area_code; +} + +/** + * @description: Fins Cmd Genetare + * @param p_command - command pointer + * @param plc_ip_4 - last plc ip + * @param local_ip_4 - last local ip + * @param p_read_item - p_read_item pointer + * @return success : index error : 0 + */ +static uint16_t FinsCommandGenerate(uint8_t *p_command, uint16_t plc_ip_4, uint16_t local_ip_4, FinsReadItem *p_read_item) +{ + uint8_t index = 0; + uint16_t command_code = p_read_item->data_info.command_code; + uint8_t area_char = p_read_item->area_char; + uint16_t data_type = p_read_item->data_type; + uint16_t start_address = p_read_item->start_address; + uint8_t bit_address = p_read_item->bit_address; + uint16_t data_length = p_read_item->data_length; + + p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (3 * 8)); + p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (2 * 8)); + p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (1 * 8)); + p_command[index++] = (uint8_t)FINS_HEADER_HEAD; + p_command[index++] = (uint8_t)FINS_HEADER_READ_COMMAND_LENGTH >> (3 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (2 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (1 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH; + p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (3 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (2 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (1 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_COMMAND; + p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (3 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (2 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (1 * 8); + p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE; + p_command[index++] = FINS_ICF; + p_command[index++] = FINS_RSV; + p_command[index++] = FINS_GCT; + + p_command[index++] = FINS_DNA; + p_command[index++] = plc_ip_4; + p_command[index++] = FINS_DA2; + + p_command[index++] = FINS_SNA; + p_command[index++] = local_ip_4; + p_command[index++] = FINS_SA2; + + p_command[index++] = FINS_SID; + + p_command[index++] = command_code >> 8; + p_command[index++] = command_code; + p_command[index++] = FinsAreaCode(area_char, data_type); + p_command[index++] = start_address >> 8; + p_command[index++] = start_address; + p_command[index++] = bit_address; + p_command[index++] = data_length >> 8; + p_command[index++] = data_length; + + return index; +} + +/** + * @description: Fins Data Transform from Receive Buffer To Control-Data + * @param p_read_item - read item pointer + * @param recv_buff - receive buff + * @return success : 0 error : -1 + */ +static int FinsTransformRecvBuffToData(FinsReadItem *p_read_item, uint8_t *recv_buff) +{ + FinsDataInfo *p_fins_data_info = &(p_read_item->data_info); + uint8_t error_code = recv_buff[15]; + if (error_code) { + printf("Data abnormal, abnormal error code is 0x%x!\n", error_code); + return -1; + } + recv_buff += 30; + + FinsCommandCode command_code = p_fins_data_info->command_code; + if (FINS_COMMAND_CODE_READ == command_code) { + + uint16_t data_length = p_read_item->data_length; + ControlPrintfList("DATA", recv_buff, data_length * (FINS_DATA_TYPE_BIT == p_read_item->data_type ? 1 : 2)); + printf("Receive data is "); + + if (FINS_DATA_TYPE_BIT == p_read_item->data_type) { + memcpy(p_fins_data_info->base_data_info.p_data, recv_buff, data_length); + + printf("0x%x", p_fins_data_info->base_data_info.p_data[0]); + } else { + uint8_t *p_data = p_fins_data_info->base_data_info.p_data; + + for (uint16_t i = 0; i < data_length; i ++) { + p_data[2 * i] = recv_buff[2 * (data_length - i - 1)]; + p_data[2 * i + 1] = recv_buff[2 * (data_length - i - 1) + 1]; + printf("0x%x 0x%x", p_data[2 * i], p_data[2 * i + 1]); + } + } + + printf("\nRead fins plc data success!\n"); + } else if (FINS_COMMAND_CODE_WRITE == command_code) { + /*to do*/ + printf("Write fins plc cmd success!\n"); + } + + return 0; +} + +/** + * @description: Fins Protocol Handshake + * @param socket - socket + * @param local_ip_4 - last local ip + * @return success : 0 error : -1 -2 + */ +static int FinsHandshake(int32_t socket, uint16_t local_ip_4) +{ + handshake_require_command[18] = (uint8_t)(local_ip_4 >> 8); + handshake_require_command[19] = (uint8_t)local_ip_4; + uint8_t try_count = 0; + + while (try_count < 10) { + ControlPrintfList("SEND", (uint8_t *)handshake_require_command, sizeof(handshake_require_command)); + int32_t write_error = socket_write(socket, handshake_require_command, sizeof(handshake_require_command)); + if (write_error < 0) { + printf("Write socket error, errno is %d!", errno); + } else { + int32_t recv_length = socket_read(socket, (uint8_t *)handshake_respond_buff, sizeof(handshake_respond_buff)); + if (recv_length < 0) { + printf("Read socket error, errno is %d!", errno); + } else { + ControlPrintfList("RECV", (uint8_t *)handshake_respond_buff, recv_length); + + /*check fins handshake respond*/ + uint8_t error_code = handshake_respond_buff[15]; + if (error_code == 0 || error_code == 0x21) { + return 0; + } else { + printf("Fins handshake failed, errno is %05x!", handshake_respond_buff[15]); + return -1; + } + } + } + if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) { + printf("Send plc command failed, errno is %d!", errno); + continue; + } else { + break; + } + } + return -2; +} + +/** + * @description: Fins Get Data From Socket + * @param socket - socket + * @param p_read_item - read item pointer + * @return success : 0 error : -1 -2 + */ +static int FinsGetData(int32_t socket, FinsReadItem *p_read_item) +{ + uint8_t try_count = 0; + int32_t write_error = 0; + + FinsDataInfo *p_fins_data_info = &(p_read_item->data_info); + BasicPlcDataInfo *p_base_data_info = &(p_fins_data_info->base_data_info); + + memset(recv_buff, 0, sizeof(recv_buff)); + + while (try_count < 10) { + ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length); + try_count++; + + write_error = socket_write(socket, p_base_data_info->p_command, p_base_data_info->command_length); + if (write_error < 0) { + printf("Write socket error, errno is %d!", errno); + } else { + PrivTaskDelay(20); + + int32_t recv_length = socket_read(socket, recv_buff, sizeof(recv_buff)); + if (recv_length < 0) { + printf("Read socket error, errno is %d!", errno); + } else { + ControlPrintfList("RECV", recv_buff, recv_length); + return FinsTransformRecvBuffToData(p_read_item, recv_buff); + } + } + + if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) { + printf("Send plc command failed, errno is %d!", errno); + continue; + } else { + return -1; + } + } + return -2; +} + +/** + * @description: Fins Data Info Init + * @param p_read_item - read item pointer + * @param plc_ip_4 - last plc ip + * @param local_ip_4 - last local ip + * @param p_data - control-data pointer + * @return success : 0 error : -1 + */ +static int FinsInitialDataInfo(FinsReadItem *p_read_item, uint16_t plc_ip_4, uint16_t local_ip_4, uint8_t *p_data) +{ + uint16_t data_length = p_read_item->data_length; + + BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info); + switch (p_read_item->data_info.command_code) + { + case FINS_COMMAND_CODE_READ: + data_length *= (p_read_item->data_type == FINS_DATA_TYPE_BIT ? 1 : 2); + p_base_data_info->command_length = FINS_COMMAND_LENGTH; + p_base_data_info->p_command = PrivMalloc(FINS_COMMAND_LENGTH); + p_base_data_info->data_size = data_length; + p_base_data_info->p_data = p_data; + break; + case FINS_COMMAND_CODE_WRITE: + //To Do + break; + default: + return -1; + } + FinsCommandGenerate(p_base_data_info->p_command, plc_ip_4, local_ip_4, p_read_item); + + return 0; +} + +/** + * @description: Fins Receive Plc Data Task + * @param parameter - parameter pointer + * @return + */ +void *ReceivePlcDataTask(void *parameter) +{ + int i = 0; + uint8_t try_count = 0; + uint16_t data_length = 0; + uint8_t *fins_data; + uint16_t read_item_size = sizeof(FinsReadItem); + + struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter; + struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args; + FinsReadItem *fins_read_item = (FinsReadItem *)control_protocol->recipe->read_item; + fins_data = control_protocol->recipe->protocol_data.data; + data_length = control_protocol->recipe->protocol_data.data_length; + + memset(&plc_socket, 0, sizeof(BasicSocketPlc)); + memcpy(plc_socket.ip, control_protocol->recipe->socket_config.plc_ip, 4); + plc_socket.port = control_protocol->recipe->socket_config.port; + plc_socket.socket = -1; + plc_socket.secondary_connect_flag = 0; + + while (1) { + for (i = 0; i < control_protocol->recipe->read_item_count; i ++) { + /*only connect socket when close socket or init*/ + while (ControlConnectSocket(&plc_socket) < 0) { + PrivTaskDelay(1000); + } + + /*need to handshake after connect socket using FINS protocol*/ + if (0 == plc_socket.secondary_connect_flag) { + if (FinsHandshake(plc_socket.socket, control_protocol->recipe->socket_config.local_ip[3]) < 0) { + plc_socket.secondary_connect_flag = 0; + ControlDisconnectSocket(&plc_socket); + continue; + } + } + + plc_socket.secondary_connect_flag = 1; + + FinsGetData(plc_socket.socket, (FinsReadItem *)fins_read_item + i); + } + + /*read all variable item data, put them into circular_area*/ + if (i == control_protocol->recipe->read_item_count) { + printf("%s get %d item %d length\n", __func__, i, data_length); + CircularAreaAppWrite(circular_area, fins_data, data_length, 0); + } + + /*read data every single 200ms*/ + PrivTaskDelay(control_protocol->recipe->read_period); + } +} + +/** + * @description: Fins Protocol Open + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int FinsOpen(struct ControlProtocol *control_protocol) +{ + ControlProtocolOpenDef(control_protocol); + + return 0; +} + +/** + * @description: Fins Protocol Close + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int FinsClose(struct ControlProtocol *control_protocol) +{ + ControlDisconnectSocket(&plc_socket); + + ControlProtocolCloseDef(); + + return 0; +} + +/** + * @description: Fins Protocol Read Data + * @param control_protocol - control protocol pointer + * @param buf - read data buffer + * @param len - read data length + * @return success : data length error : 0 + */ +int FinsRead(struct ControlProtocol *control_protocol, void *buf, size_t len) +{ + struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args; + return CircularAreaAppRead(circular_area, buf, len); +} + +static struct ControlDone fins_protocol_done = +{ + ._open = FinsOpen, + ._close = FinsClose, + ._read = FinsRead, + ._write = NULL, + ._ioctl = NULL, +}; + +/** + * @description: Fins Protocol Cmd Generate + * @param p_recipe - recipe pointer + * @param protocol_format_info - protocol format info pointer + * @return success : 0 error : -1 + */ +int FinsProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info) +{ + int ret = 0; + + FinsReadItem *fins_read_item = (FinsReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index; + + fins_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint; + strncpy(fins_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20); + strncpy(&fins_read_item->area_char, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "area_char")->valuestring, 1); + fins_read_item->data_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_type")->valueint; + fins_read_item->data_info.command_code = FINS_COMMAND_CODE_READ; + fins_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint; + fins_read_item->bit_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "bit_address")->valueint; + fins_read_item->data_length = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_length")->valueint; + + ret = FinsInitialDataInfo(fins_read_item, + p_recipe->socket_config.plc_ip[3], + p_recipe->socket_config.local_ip[3], + protocol_format_info->p_read_item_data + protocol_format_info->last_item_size); + + ControlPrintfList("CMD", fins_read_item->data_info.base_data_info.p_command, fins_read_item->data_info.base_data_info.command_length); + protocol_format_info->last_item_size = GetValueTypeMemorySize(fins_read_item->value_type); + + return ret; +} + +/** + * @description: Fins Protocol Init + * @param p_recipe - recipe pointer + * @return success : 0 error : -1 + */ +int FinsProtocolInit(struct ControlRecipe *p_recipe) +{ + p_recipe->read_item = PrivMalloc(sizeof(FinsReadItem) * p_recipe->read_item_count); + if (NULL == p_recipe->read_item) { + PrivFree(p_recipe->read_item); + return -1; + } + + p_recipe->ControlProtocolFormatCmd = FinsProtocolFormatCmd; + + p_recipe->done = &fins_protocol_done; + + return 0; +} + + diff --git a/APP_Framework/Framework/control/plc_protocol/fins/test_recipe_fins.json b/APP_Framework/Framework/control/plc_protocol/fins/test_recipe_fins.json new file mode 100644 index 000000000..59075bd6e --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/fins/test_recipe_fins.json @@ -0,0 +1,331 @@ +{ + "device_id": 769, + "device_name": "S01", + "communication_type": 0, + "socket_config": { + "plc_ip": "192.168.250.22", + "local_ip": "192.168.250.233", + "gateway": "192.168.250.1", + "netmask": "255.255.254.0", + "port": 9600 + }, + "protocol_type": 5, + "read_period": 100, + "read_item_list": [ + { + "value_name": "", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 0, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "ֹͣ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 0, + "bit_address": 1, + "data_length": 1 + }, + { + "value_name": "ʹ", + "value_type": 1, + "area_char": "H", + "data_type": 0, + "start_address": 0, + "bit_address": 2, + "data_length": 1 + }, + { + "value_name": "", + "value_type": 1, + "area_char": "D", + "data_type": 0, + "start_address": 0, + "bit_address": 3, + "data_length": 1 + }, + { + "value_name": "ͣ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 0, + "bit_address": 4, + "data_length": 1 + }, + { + "value_name": "λ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 10, + "bit_address": 11, + "data_length": 1 + }, + { + "value_name": "λ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 10, + "bit_address": 12, + "data_length": 1 + }, + { + "value_name": "Զ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 200, + "bit_address": 5, + "data_length": 1 + }, + { + "value_name": "", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 200, + "bit_address": 6, + "data_length": 1 + }, + { + "value_name": "", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 200, + "bit_address": 7, + "data_length": 1 + }, + { + "value_name": "ֶģʽ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 300, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "Զģʽ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 300, + "bit_address": 1, + "data_length": 1 + }, + { + "value_name": "з", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 300, + "bit_address": 2, + "data_length": 1 + }, + { + "value_name": "λ", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 400, + "bit_address": 3, + "data_length": 1 + }, + { + "value_name": "1", + "value_type": 1, + "area_char": "W", + "data_type": 0, + "start_address": 400, + "bit_address": 4, + "data_length": 1 + }, + { + "value_name": "", + "value_type": 3, + "area_char": "D", + "data_type": 1, + "start_address": 10, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "1", + "value_type": 3, + "area_char": "D", + "data_type": 1, + "start_address": 11, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "2", + "value_type": 3, + "area_char": "D", + "data_type": 1, + "start_address": 20, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "3", + "value_type": 3, + "area_char": "D", + "data_type": 1, + "start_address": 100, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "4", + "value_type": 3, + "area_char": "W", + "data_type": 1, + "start_address": 100, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "5", + "value_type": 3, + "area_char": "W", + "data_type": 1, + "start_address": 101, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "6", + "value_type": 3, + "area_char": "W", + "data_type": 1, + "start_address": 110, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "7", + "value_type": 3, + "area_char": "H", + "data_type": 1, + "start_address": 10, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "8", + "value_type": 3, + "area_char": "H", + "data_type": 1, + "start_address": 20, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "9", + "value_type": 3, + "area_char": "H", + "data_type": 1, + "start_address": 21, + "bit_address": 0, + "data_length": 1 + }, + { + "value_name": "ٶ", + "value_type": 9, + "area_char": "D", + "data_type": 1, + "start_address": 2000, + "bit_address": 0, + "data_length": 2 + }, + { + "value_name": "ٶ", + "value_type": 9, + "area_char": "D", + "data_type": 1, + "start_address": 2002, + "bit_address": 0, + "data_length": 2 + }, + { + "value_name": "ٶ", + "value_type": 9, + "area_char": "D", + "data_type": 1, + "start_address": 2004, + "bit_address": 0, + "data_length": 2 + }, + { + "value_name": "ʼλ", + "value_type": 9, + "area_char": "D", + "data_type": 1, + "start_address": 300, + "bit_address": 0, + "data_length": 2 + }, + { + "value_name": "յλ", + "value_type": 9, + "area_char": "D", + "data_type": 1, + "start_address": 302, + "bit_address": 0, + "data_length": 2 + }, + { + "value_name": "ֵ", + "value_type": 9, + "area_char": "W", + "data_type": 1, + "start_address": 80, + "bit_address": 0, + "data_length": 2 + }, + { + "value_name": "1", + "value_type": 8, + "area_char": "H", + "data_type": 1, + "start_address": 100, + "bit_address": 0, + "data_length": 4 + }, + { + "value_name": "2", + "value_type": 8, + "area_char": "H", + "data_type": 1, + "start_address": 104, + "bit_address": 0, + "data_length": 4 + }, + { + "value_name": "3", + "value_type": 8, + "area_char": "H", + "data_type": 1, + "start_address": 108, + "bit_address": 0, + "data_length": 4 + }, + { + "value_name": "4", + "value_type": 8, + "area_char": "H", + "data_type": 1, + "start_address": 112, + "bit_address": 0, + "data_length": 4 + } + ] +} \ No newline at end of file diff --git a/APP_Framework/Framework/control/plc_protocol/include/fins.h b/APP_Framework/Framework/control/plc_protocol/include/fins.h new file mode 100644 index 000000000..a3501145f --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/include/fins.h @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file fins.h + * @brief plc protocol fins + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-10-08 + */ + +#ifndef FINS_H +#define FINS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FINS_HEADER_HEAD 0x46494E53 +#define FINS_HEADER_READ_COMMAND_LENGTH 0x0000001A +#define FINS_HEADER_COMMAND 0x00000002 +#define FINS_HEADER_ERROR_CODE 0x00000000 +#define FINS_ICF 0x80 +#define FINS_RSV 0x00 +#define FINS_REPLY_ICF 0xC0 +#define FINS_GCT 0x02 +#define FINS_DNA 0x00 +#define FINS_DA2 0x00 +#define FINS_SNA 0x00 +#define FINS_SA2 0x00 +#define FINS_SID 0x00 + +typedef enum +{ + FINS_COMMAND_CODE_READ = 0x0101, + FINS_COMMAND_CODE_WRITE = 0x0102 +}FinsCommandCode; + +typedef enum +{ + FINS_DATA_TYPE_BIT, + FINS_DATA_TYPE_WORD +}FinsDataType; + +typedef struct +{ + BasicPlcDataInfo base_data_info; + FinsCommandCode command_code; +}FinsDataInfo; + +typedef struct +{ + int32_t socket; + uint16_t plc_ip_4; +}FinsHandshakeParameter; + +typedef struct +{ + FinsDataInfo data_info; + + UniformValueType value_type; + uint8_t value_name[20]; + + uint8_t area_char; + FinsDataType data_type; + uint16_t start_address; + uint8_t bit_address; + uint16_t data_length; +}FinsReadItem; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/APP_Framework/Framework/control/shared/control_file.c b/APP_Framework/Framework/control/plc_protocol/include/melsec.h old mode 100755 new mode 100644 similarity index 85% rename from APP_Framework/Framework/control/shared/control_file.c rename to APP_Framework/Framework/control/plc_protocol/include/melsec.h index 198c166ef..2586fdd4e --- a/APP_Framework/Framework/control/shared/control_file.c +++ b/APP_Framework/Framework/control/plc_protocol/include/melsec.h @@ -11,11 +11,9 @@ */ /** - * @file control_file.c - * @brief control relative file operation + * @file melsec.h + * @brief plc protocol melsec * @version 3.0 * @author AIIT XUOS Lab - * @date 2022-09-37 - */ - - + * @date 2022-10-08 + */ \ No newline at end of file diff --git a/APP_Framework/Framework/control/shared/control_file.h b/APP_Framework/Framework/control/plc_protocol/include/opcua.h old mode 100755 new mode 100644 similarity index 78% rename from APP_Framework/Framework/control/shared/control_file.h rename to APP_Framework/Framework/control/plc_protocol/include/opcua.h index 5058c4def..898d0022d --- a/APP_Framework/Framework/control/shared/control_file.h +++ b/APP_Framework/Framework/control/plc_protocol/include/opcua.h @@ -11,16 +11,9 @@ */ /** - * @file control_file.h - * @brief control file function relative API + * @file opcua.h + * @brief control protocol opcua * @version 3.0 * @author AIIT XUOS Lab - * @date 2022-09-27 - */ - -#ifndef CONTROL_FILE_H -#define CONTROL_FILE_H - - -#endif - + * @date 2022-10-08 + */ \ No newline at end of file diff --git a/APP_Framework/Framework/control/plc_protocol/include/s7.h b/APP_Framework/Framework/control/plc_protocol/include/s7.h new file mode 100644 index 000000000..f89f1f122 --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/include/s7.h @@ -0,0 +1,19 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file s7.h + * @brief plc protocol s7 + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-10-08 + */ \ No newline at end of file diff --git a/APP_Framework/Framework/control/shared/Makefile b/APP_Framework/Framework/control/shared/Makefile index 633191b89..bd8322529 100755 --- a/APP_Framework/Framework/control/shared/Makefile +++ b/APP_Framework/Framework/control/shared/Makefile @@ -1,8 +1,4 @@ -SRC_FILES := control.c - -ifeq ($(CONFIG_MOUNT_SDCARD),y) - SRC_FILES += control_file.c -endif +SRC_FILES := control.c control_def.c control_io.c include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/control/shared/config.json b/APP_Framework/Framework/control/shared/config.json deleted file mode 100755 index 05b79a6a3..000000000 --- a/APP_Framework/Framework/control/shared/config.json +++ /dev/null @@ -1,38 +0,0 @@ -{ -"siemens plc": -{ - "device type": "PLC", - "control type": "HSC", - "info": - { - "plc ability" : 1, - "plc device id": 1, - "soft version" : 1, - "hardware version": 1, - "date": "2022-1-28", - "vendor": "siemens", - "model":"S300" - }, - - "serial config": - { - "serial type":"485", - "station id" : "station1", - "serial port" : 1 - }, - - "network config": - { - "ip addr" : "192.168.250.5", - "ip port" : 4840 - }, - - "interface": - { - "inhybridnet":"OPCUA", - "transport":"TCP", - "ip address": "192.168.250.5", - "attribute" : "1" - } -} -} diff --git a/APP_Framework/Framework/control/shared/control.c b/APP_Framework/Framework/control/shared/control.c index 8c880f693..871e31eb6 100755 --- a/APP_Framework/Framework/control/shared/control.c +++ b/APP_Framework/Framework/control/shared/control.c @@ -12,16 +12,278 @@ /** * @file control.c - * @brief control framework code + * @brief code for control framework app * @version 3.0 * @author AIIT XUOS Lab * @date 2022-09-27 */ #include +#include -void control_init(void) +ControlProtocolType control_protocol; + +/** + * @description: Control Framework Find certain Protocol + * @param void + * @return Control Protocol pointer + */ +ControlProtocolType ControlProtocolFind(void) { - //to do + return control_protocol; } +/** + * @description: Control Framework Protocol Init + * @param control_protocol - control protocol pointer + * @return success : 0 error : -1 + */ +static int ControlProtocolInit(ControlProtocolType control_protocol) +{ + CONTROL_PARAM_CHECK(control_protocol); + int ret = -1; + + control_protocol->protocol_status = CONTROL_INIT; + + ret = PrivMutexCreate(&control_protocol->lock, 0); + if(ret < 0) { + printf("ControlProtocolInit mutex create failed.\n"); + goto _out; + } + + ret = PrivSemaphoreCreate(&control_protocol->sem, 0, 0); + if (ret < 0) { + printf("ControlProtocolInit create sem error\n"); + goto _out; + } + +_out: + return ret; +} + +/** + * @description: Analyze Recipe + * @param control_protocol - Control Protocol pointer + * @param recipe_name - recipe name + * @return success : 0 error : -1 + */ +static int ControlAnalyzeRecipe(ControlProtocolType control_protocol, const char *recipe_name) +{ + int recipe_file_fd = -1; + struct stat recipe_file_status; + uint16_t recipe_file_length = 0; + char *recipe_file_buf; + + /*wait for SD-card mount done*/ + PrivTaskDelay(5000); + + //Step1 : read recipe file data from SD card or other store device + recipe_file_fd = PrivOpen(recipe_name, O_RDONLY); + if (recipe_file_fd < 0) { + printf("Open recipe file %s failed\n", recipe_name); + PrivClose(recipe_file_fd); + return -1; + } + + if (0 != fstat(recipe_file_fd, &recipe_file_status)) { + printf("Get recipe file information failed!\n"); + PrivClose(recipe_file_fd); + return -1; + } else { + recipe_file_length = recipe_file_status.st_size; + } + + recipe_file_buf = PrivMalloc(recipe_file_length); + if (NULL == recipe_file_buf) { + printf("Get recipe file memory failed!\n"); + PrivFree(recipe_file_buf); + PrivClose(recipe_file_fd); + return -1; + } + + if (PrivRead(recipe_file_fd, recipe_file_buf, recipe_file_length) < 0) { + printf("Read recipe file failed!\n"); + PrivFree(recipe_file_buf); + PrivClose(recipe_file_fd); + return -1; + } + + PrivClose(recipe_file_fd); + + //Step2 : CJSON analyze +#ifdef LIB_USING_CJSON + cJSON *recipe_file_json = cJSON_Parse(recipe_file_buf); + if (NULL == recipe_file_json) { + printf("Parse recipe_file_buf failed!\n"); + return -1; + } + + control_protocol->recipe = (struct ControlRecipe *)PrivMalloc(sizeof(struct ControlRecipe)); + memset(control_protocol->recipe, 0, sizeof(struct ControlRecipe)); + + /*Get basic information from recipe file*/ + if (RecipeBasicInformation(control_protocol->recipe, recipe_file_json) < 0) { + return -1; + } + + control_protocol->protocol_type = control_protocol->recipe->protocol_type; + + /*Get the variable need to read from recipe file*/ + RecipeReadVariableItem(control_protocol->recipe, recipe_file_json); + + control_protocol->done = control_protocol->recipe->done; + + cJSON_Delete(recipe_file_json); + + PrivFree(recipe_file_buf); + printf("Read and parse recipe file done!\n"); +#endif + + return 0; +} + +/** + * @description: Control Framework Protocol Open + * @param control_protocol - Control Protocol pointer + * @return success : 0 error : -1 + */ +int ControlProtocolOpen(struct ControlProtocol *control_protocol) +{ + CONTROL_PARAM_CHECK(control_protocol); + CONTROL_PARAM_CHECK(control_protocol->done); + int ret = -1; + + if (control_protocol->done->_open) { + ret = control_protocol->done->_open(control_protocol); + } + + return ret; +} + +/** + * @description: Control Framework Protocol Close + * @param control_protocol - Control Protocol pointer + * @return success : 0 error : -1 + */ +int ControlProtocolClose(struct ControlProtocol *control_protocol) +{ + CONTROL_PARAM_CHECK(control_protocol); + CONTROL_PARAM_CHECK(control_protocol->done); + int ret = -1; + + if (control_protocol->done->_close) { + ret = control_protocol->done->_close(control_protocol); + } + + return ret; +} + +/** + * @description: Control Framework Protocol Read Data + * @param control_protocol - Control Protocol pointer + * @param buf - read buffer + * @param len - read data length + * @return success : data length error : -1 + */ +int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len) +{ + CONTROL_PARAM_CHECK(control_protocol); + CONTROL_PARAM_CHECK(control_protocol->done); + int ret = -1; + + if (control_protocol->done->_read) { + ret = control_protocol->done->_read(control_protocol, buf, len); + } + + return ret; +} + +/** + * @description: Control Framework Protocol Write Cmd + * @param control_protocol - Control Protocol pointer + * @param buf - write buffer + * @param len - write data length + * @return success : data length error : -1 + */ +int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len) +{ + CONTROL_PARAM_CHECK(control_protocol); + CONTROL_PARAM_CHECK(control_protocol->done); + int ret = -1; + + if (control_protocol->done->_write) { + ret = control_protocol->done->_write(control_protocol, buf, len); + } + + return ret; +} + +/** + * @description: Control Framework Protocol Ioctl + * @param control_protocol - Control Protocol pointer + * @param cmd - ioctl cmd + * @param args - args + * @return success : 0 error : -1 + */ +int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args) +{ + CONTROL_PARAM_CHECK(control_protocol); + CONTROL_PARAM_CHECK(control_protocol->done); + int ret = -1; + + if (control_protocol->done->_ioctl) { + ret = control_protocol->done->_ioctl(control_protocol, cmd, args); + } + + return ret; +} + +/** + * @description: Control Framework Init + * @param void + * @return success : 0 error : -1 + */ +int ControlFrameworkInit(void) +{ + int ret = 0; + + control_protocol = (struct ControlProtocol *)PrivMalloc(sizeof(struct ControlProtocol)); + if (NULL == control_protocol) { + printf("%s malloc control protocol failed!\n", __func__); + PrivFree(control_protocol); + ret = -1; + goto _out; + } + + //Control Protocol Struct Init + ret = ControlProtocolInit(control_protocol); + if (ret < 0) { + printf("%s failed!\n", __func__); + PrivFree(control_protocol); + goto _out; + } + + printf("%s malloc CONTROL_RECIPE_FILE %s\n", __func__, CONTROL_RECIPE_FILE); + + //Read Recipe File, Get Control Protocol Configure Param + ret = ControlAnalyzeRecipe(control_protocol, CONTROL_RECIPE_FILE); + if (ret < 0) { + printf("%s failed!\n", __func__); + PrivFree(control_protocol); + goto _out; + } + + control_protocol->protocol_status = CONTROL_REGISTERED; + + ret = ControlPeripheralInit(control_protocol->recipe); + if (ret < 0) { + printf("%s failed!\n", __func__); + PrivFree(control_protocol); + goto _out; + } + + printf("%s ControlPeripheralInit done\n", __func__); + +_out: + return ret; +} diff --git a/APP_Framework/Framework/control/shared/control.h b/APP_Framework/Framework/control/shared/control.h index bbf5772b4..c64467a3e 100644 --- a/APP_Framework/Framework/control/shared/control.h +++ b/APP_Framework/Framework/control/shared/control.h @@ -12,13 +12,95 @@ /** * @file control.h - * @brief control framework code + * @brief DEFINE code for control framework app * @version 3.0 * @author AIIT XUOS Lab * @date 2022-09-27 */ -#include -#include +#ifndef CONTROL_H +#define CONTROL_H +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ControlProtocol; +typedef struct ControlProtocol *ControlProtocolType; + +struct ControlDone +{ + int (*_open)(struct ControlProtocol *control_protocol); + int (*_close)(struct ControlProtocol *control_protocol); + int (*_read)(struct ControlProtocol *control_protocol, void *buf, size_t len); + int (*_write)(struct ControlProtocol *control_protocol, const void *buf, size_t len); + int (*_ioctl)(struct ControlProtocol *control_protocol, int cmd, void *args); +}; + +typedef enum +{ + PROTOCOL_S7 = 1, + PROTOCOL_MODBUS_TCP, + PROTOCOL_MODBUS_UART, + PROTOCOL_OPC_UA, + PROTOCOL_FINS, + PROTOCOL_MELSEC_1E, + PROTOCOL_MELSEC_3E_Q_L, + PROTOCOL_MELSEC_3E_IQ_R, + PROTOCOL_MELSEC_1C, + PROTOCOL_MELSEC_3C, + PROTOCOL_END +}ProtocolType; + +typedef enum +{ + CONTROL_INIT, + CONTROL_REGISTERED, + CONTROL_UNREGISTERED, +}ProtocolStatus; + +struct ControlProtocol +{ + char *name; + ProtocolType protocol_type; + ProtocolStatus protocol_status; + + struct ControlRecipe *recipe; + struct ControlDone *done; + + void *args; + + sem_t sem; + pthread_mutex_t lock; +}; + +/*Control Framework Protocol Init*/ +int ControlFrameworkInit(void); + +/*Control Framework Find certain Protocol*/ +ControlProtocolType ControlProtocolFind(void); + +/*Control Framework Protocol Open*/ +int ControlProtocolOpen(struct ControlProtocol *control_protocol); + +/*Control Framework Protocol Close*/ +int ControlProtocolClose(struct ControlProtocol *control_protocol); + +/*Control Framework Protocol Read*/ +int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len); + +/*Control Framework Protocol Write*/ +int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len); + +/*Control Framework Protocol Ioctl*/ +int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/APP_Framework/Framework/control/shared/control_def.c b/APP_Framework/Framework/control/shared/control_def.c new file mode 100644 index 000000000..27ab2d761 --- /dev/null +++ b/APP_Framework/Framework/control/shared/control_def.c @@ -0,0 +1,446 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file control_def.c + * @brief code for control framework + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-10-9 + */ + +#include +#include + +/*using cirtular area to receive data*/ +#define PLC_DATA_LENGTH 1024 +struct CircularAreaApp *g_circular_area; +static pthread_t recv_plc_data_task; + +/*extern function*/ +extern void *ReceivePlcDataTask(void *parameter); + +#ifdef CONTROL_PROTOCOL_FINS +extern int FinsProtocolInit(struct ControlRecipe *p_recipe); +#endif + +/* +CONTROL FRAMEWORK READ DATA FORMAT: +| HEAD |device_id|read data length|read item count| data | +|2 Bytes| 2 Bytes | 2 Bytes | 2 Bytes |read data length Bytes| +*/ +#define CONTROL_DATA_HEAD_LENGTH 8 +#define CONTROL_DATA_HEAD_1 0xAA +#define CONTROL_DATA_HEAD_2 0xBB + +typedef int (*ControlProtocolInitFunc)(struct ControlRecipe *p_recipe); + +struct ControlProtocolInitParam +{ + int protocol_type; + const ControlProtocolInitFunc fn; +}; + +static struct ControlProtocolInitParam protocol_init[] = +{ +#ifdef CONTROL_PROTOCOL_FINS + { PROTOCOL_FINS, FinsProtocolInit }, +#endif + + { PROTOCOL_END, NULL }, +}; + +/** + * @description: Control Framework Sub_Protocol Desc Init + * @param p_recipe - Control recipe pointer + * @param sub_protocol_desc - sub_protocol desc + * @return success : 0 error : -1 + */ +static int ControlProtocolInitDesc(struct ControlRecipe *p_recipe, struct ControlProtocolInitParam sub_protocol_desc[]) +{ + int i = 0; + int ret = 0; + for( i = 0; sub_protocol_desc[i].fn != NULL; i++ ) { + if (p_recipe->protocol_type == sub_protocol_desc[i].protocol_type) { + ret = sub_protocol_desc[i].fn(p_recipe); + printf("%s initialize %d %s\n", __func__, sub_protocol_desc[i].protocol_type, ret == 0 ? "success" : "failed"); + break; + } + } + return ret; +} + +/** + * @description: Control Framework Protocol Data Header Format + * @param p_recipe - Control recipe pointer + * @return + */ +static void FormatDataHeader(struct ControlRecipe *p_recipe) +{ + uint16_t plc_read_data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;//Head length is CONTROL_DATA_HEAD_LENGTH + uint8_t *data = p_recipe->protocol_data.data; + + data[0] = CONTROL_DATA_HEAD_1; + data[1] = CONTROL_DATA_HEAD_2; + data[2] = (uint8_t)(p_recipe->device_id >> 8); + data[3] = (uint8_t)p_recipe->device_id; + data[4] = (uint8_t)(plc_read_data_length >> 8); + data[5] = (uint8_t)plc_read_data_length; + data[6] = (uint8_t)(p_recipe->read_item_count >> 8); + data[7] = (uint8_t)p_recipe->read_item_count; +} + +/** + * @description: Get Recipe Total Data Length + * @param read_item_list_json - read_item_list_json pointer + * @return success : total_data_length error : 0 + */ +static uint16_t GetRecipeTotalDataLength(cJSON* read_item_list_json) +{ + uint16_t read_item_count = cJSON_GetArraySize(read_item_list_json); + uint16_t total_data_length = 0; + for (uint16_t read_item_index = 0; read_item_index < read_item_count; read_item_index++) { + cJSON* read_item_json = cJSON_GetArrayItem(read_item_list_json, read_item_index); + UniformValueType value_type = cJSON_GetObjectItem(read_item_json, "value_type")->valueint; + total_data_length += GetValueTypeMemorySize(value_type); + } + return total_data_length; +} + +/** + * @description: Control Framework Basic Serial Configure + * @param p_recipe - Control recipe pointer + * @param p_recipe_file_json - p_recipe_file_json pointer + * @return + */ +static void ControlBasicSerialConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json) +{ + cJSON *p_serial_config_json = cJSON_GetObjectItem(p_recipe_file_json, "serial_config"); + p_recipe->serial_config.baud_rate = cJSON_GetObjectItem(p_serial_config_json, "baud_rate")->valueint; + p_recipe->serial_config.data_bits = cJSON_GetObjectItem(p_serial_config_json, "data_bits")->valueint; + p_recipe->serial_config.stop_bits = cJSON_GetObjectItem(p_serial_config_json, "stop_bits")->valueint; + p_recipe->serial_config.check_mode = cJSON_GetObjectItem(p_serial_config_json, "check_mode")->valueint; + printf("Serial_config: baud_rate: %d, data_bits: %d, stop_bits: %d, check_mode is %d\n", + p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode); +} + +/** + * @description: Control Framework Basic Socket Configure + * @param p_recipe - Control recipe pointer + * @param p_recipe_file_json - p_recipe_file_json pointer + * @return + */ +static void ControlBasicSocketConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json) +{ + cJSON *p_socket_address_json = cJSON_GetObjectItem(p_recipe_file_json, "socket_config"); + char *plc_ip_string = cJSON_GetObjectItem(p_socket_address_json, "plc_ip")->valuestring; + sscanf(plc_ip_string, "%d.%d.%d.%d", + p_recipe->socket_config.plc_ip, + p_recipe->socket_config.plc_ip + 1, + p_recipe->socket_config.plc_ip + 2, + p_recipe->socket_config.plc_ip + 3); + + char *local_ip_string = cJSON_GetObjectItem(p_socket_address_json, "local_ip")->valuestring; + sscanf(local_ip_string, "%d.%d.%d.%d", + p_recipe->socket_config.local_ip, + p_recipe->socket_config.local_ip + 1, + p_recipe->socket_config.local_ip + 2, + p_recipe->socket_config.local_ip + 3); + + char *gateway_ip_string = cJSON_GetObjectItem(p_socket_address_json, "gateway")->valuestring; + sscanf(gateway_ip_string, "%d.%d.%d.%d", + p_recipe->socket_config.gateway, + p_recipe->socket_config.gateway + 1, + p_recipe->socket_config.gateway + 2, + p_recipe->socket_config.gateway + 3); + + char *netmask_string = cJSON_GetObjectItem(p_socket_address_json, "netmask")->valuestring; + sscanf(netmask_string, "%d.%d.%d.%d", + p_recipe->socket_config.netmask, + p_recipe->socket_config.netmask + 1, + p_recipe->socket_config.netmask + 2, + p_recipe->socket_config.netmask + 3); + + p_recipe->socket_config.port = cJSON_GetObjectItem(p_socket_address_json, "port")->valueint; + printf("Socket_config: local ip is %s, plc ip is %s, gateway is %s, port is %d.\n", + local_ip_string, plc_ip_string, gateway_ip_string, p_recipe->socket_config.port); +} + +/** + * @description: Control Framework Printf List Function + * @param name - printf function name + * @param number_list - number_list pointer + * @param length - number_list length + * @return + */ +void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length) +{ + printf("\n******************%5s****************\n", name); + for (int32_t i = 0;i < length;i ++) { + printf("0x%x ", number_list[i]); + } + printf("\n**************************************\n"); +} + +/** + * @description: Control Framework Connect Socket + * @param p_plc - basic socket plc pointer + * @return success : 0 error : -1 -2 -3 -4 -5 + */ +int ControlConnectSocket(BasicSocketPlc *p_plc) +{ + if (p_plc->socket >= 0) + return 0; + + struct sockaddr_in plc_addr_in; + plc_addr_in.sin_family = AF_INET; + plc_addr_in.sin_port = htons(p_plc->port); + + char ip_string[20] = {0}; + sprintf(ip_string, "%u.%u.%u.%u", p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3]); + plc_addr_in.sin_addr.s_addr = inet_addr(ip_string); + memset(&(plc_addr_in.sin_zero), 0, sizeof(plc_addr_in.sin_zero)); + + int plc_socket = socket(AF_INET, SOCK_STREAM, 0); + int flag = 1; + + struct timeval timeout; + timeout.tv_sec = 10; + timeout.tv_usec = 0; + if (setsockopt(plc_socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag)) < 0) { + printf("Error setting TCP_NODELAY function!\n"); + return -1; + } + + if (setsockopt(plc_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) { + printf("Error setting SO_SNDTIMEO function!\n"); + return -2; + } + + if (setsockopt(plc_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) { + printf("Error setting SO_RCVTIMEO function!\n"); + return -3; + } + + if (plc_socket < 0) { + printf("Get socket error!\n"); + return -4; + } + + printf("%s %d ip %u.%u.%u.%u port %d\n", __func__, __LINE__, + p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3], + p_plc->port); + + if (connect(plc_socket, (struct sockaddr*)&plc_addr_in, sizeof(struct sockaddr)) == -1) { + printf("Connect plc socket failed!errno %d\n", errno); + closesocket(plc_socket); + return -5; + } else { + p_plc->socket = plc_socket; + printf("Connect plc socket success!\n"); + return 0; + } +} + +/** + * @description: Control Framework Disconnect Socket + * @param p_plc - basic socket plc pointer + * @return success : 0 error : -1 + */ +int ControlDisconnectSocket(BasicSocketPlc *p_plc) +{ + if (p_plc->socket < 0) + return -1; + + int error = closesocket(p_plc->socket); + if (0 == error) + p_plc->socket = -1; + + return error; +} + +/** + * @description: Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task + * @param control_protocol - Control protocol pointer + * @return success : 0 error : -1 + */ +int ControlProtocolOpenDef(struct ControlProtocol *control_protocol) +{ + g_circular_area = CircularAreaAppInit(PLC_DATA_LENGTH); + if (NULL == g_circular_area) { + printf("%s CircularAreaInit error\n", __func__); + return -1; + } + + control_protocol->args = (void *)g_circular_area; + + pthread_attr_t attr; + attr.schedparam.sched_priority = 19; + attr.stacksize = 2048; + + PrivTaskCreate(&recv_plc_data_task, &attr, &ReceivePlcDataTask, control_protocol); + PrivTaskStartup(&recv_plc_data_task); +} + +/** + * @description: Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task + * @param void + * @return success : 0 error : -1 + */ +int ControlProtocolCloseDef(void) +{ + CircularAreaAppRelease(g_circular_area); + + PrivTaskDelete(recv_plc_data_task, 0); + + return 0; +} + +/** + * @description: Control Framework Get Value Memory Size From Recipe File + * @param uniform_value_type - uniform value type + * @return success : size error : 0 + */ +uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type) +{ + switch (uniform_value_type) + { + case UNIFORM_BOOL: + case UNIFORM_INT8: + case UNIFORM_UINT8: + return 1; + break; + case UNIFORM_INT16: + case UNIFORM_UINT16: + return 2; + break; + case UNIFORM_INT32: + case UNIFORM_UINT32: + case UNIFORM_FLOAT: + return 4; + break; + case UNIFORM_DOUBLE: + return 8; + break; + default: + break; + } + + return 0; +} + +/** + * @description: Control Framework Peripheral Device Init + * @param p_recipe - Control recipe pointer + * @return success : 0 error : + */ +int ControlPeripheralInit(struct ControlRecipe *p_recipe) +{ + switch (p_recipe->communication_type) + { + case 0://Socket Init + SocketInit(p_recipe->socket_config.local_ip, p_recipe->socket_config.netmask, p_recipe->socket_config.gateway); + break; + case 1://Serial Init + SerialInit(p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode); + break; + default: + break; + } + + return 0; +} + +/** + * @description: Control Framework Get Recipe Basic Information + * @param p_recipe - Control recipe pointer + * @param p_recipe_file_json - recipe_file_json pointer + * @return success : 0 error : -1 + */ +int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json) +{ + p_recipe->protocol_type = (ProtocolType)(cJSON_GetObjectItem(p_recipe_file_json, "protocol_type")->valueint); + + p_recipe->device_id = cJSON_GetObjectItem(p_recipe_file_json, "device_id")->valueint; + strncpy(p_recipe->device_name, cJSON_GetObjectItem(p_recipe_file_json, "device_name")->valuestring, 20); + p_recipe->read_period = cJSON_GetObjectItem(p_recipe_file_json, "read_period")->valueint; + p_recipe->communication_type = cJSON_GetObjectItem(p_recipe_file_json, "communication_type")->valueint; + + printf("\n**************** RECIPE BASIC INFORMATION ******************\n"); + printf("\nprotocol_type: %d, communication_type: %d, device_id: %d, device_name: %s, read_period is %d\n", + p_recipe->protocol_type, p_recipe->communication_type, p_recipe->device_id, p_recipe->device_name, p_recipe->read_period); + + switch (p_recipe->communication_type) + { + case 0://Get Socket Config + ControlBasicSocketConfig(p_recipe, p_recipe_file_json); + break; + case 1://Get Serial Config + ControlBasicSerialConfig(p_recipe, p_recipe_file_json); + break; + default: + break; + } + + printf("\n************************************************************\n"); +} + +/** + * @description: Control Framework Read Variable Item Function + * @param p_recipe - Control recipe pointer + * @param p_recipe_file_json - recipe_file_json pointer + * @return + */ +void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json) +{ + int i, ret = 0; + + ProtocolFormatInfo protocol_format_info; + memset(&protocol_format_info, 0, sizeof(ProtocolFormatInfo)); + + cJSON *read_item_list_json = cJSON_GetObjectItem(p_recipe_file_json, "read_item_list"); + if (cJSON_IsArray(read_item_list_json)) { + /*Get Recipe Variable Item Count and total length*/ + p_recipe->read_item_count = cJSON_GetArraySize(read_item_list_json); + p_recipe->total_data_length = GetRecipeTotalDataLength(read_item_list_json); + + /*Malloc Read Data Pointer, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/ + p_recipe->protocol_data.data = PrivMalloc(CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length); + p_recipe->protocol_data.data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length; + memset(p_recipe->protocol_data.data, 0, p_recipe->protocol_data.data_length); + + protocol_format_info.p_read_item_data = p_recipe->protocol_data.data + CONTROL_DATA_HEAD_LENGTH; + + /*Init The Control Protocol*/ + ControlProtocolInitDesc(p_recipe, protocol_init); + + /*Format Data Header, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/ + FormatDataHeader(p_recipe); + + uint16_t read_item_count = p_recipe->read_item_count; + + for (i = 0; i < read_item_count; i ++) { + cJSON *read_single_item_json = cJSON_GetArrayItem(read_item_list_json, i); + + protocol_format_info.read_single_item_json = read_single_item_json; + protocol_format_info.read_item_index = i; + + /*Format Protocol Cmd By Analyze Variable Item One By One*/ + ret = p_recipe->ControlProtocolFormatCmd(p_recipe, &protocol_format_info); + if (ret < 0) { + printf("%s read %d item failed!\n", __func__, i); + continue; + } + } + } +} + diff --git a/APP_Framework/Framework/control/shared/control_def.h b/APP_Framework/Framework/control/shared/control_def.h new file mode 100644 index 000000000..9126c6c1d --- /dev/null +++ b/APP_Framework/Framework/control/shared/control_def.h @@ -0,0 +1,161 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file control_def.h + * @brief DEFINE code for control framework + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-10-08 + */ + +#ifndef CONTROL_DEF_H +#define CONTROL_DEF_H + +#include +#include +#include +#include +#include + +#ifdef LIB_USING_CJSON +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONTROL_PARAM_CHECK(param) \ + do \ + { \ + if(NULL == param) { \ + KPrintf("CONTROL CHECK FAILED ...%s %d %s is NULL.\n", __FUNCTION__, __LINE__, #param); \ + return -1; \ + } \ + }while (0) + +typedef enum +{ + UNIFORM_BOOL = 1, + UNIFORM_INT8, + UNIFORM_INT16, + UNIFORM_INT32, + UNIFORM_UINT8, + UNIFORM_UINT16, + UNIFORM_UINT32, + UNIFORM_DOUBLE, + UNIFORM_FLOAT +}UniformValueType; + +typedef struct +{ + uint8_t ip[4]; + uint16_t port; + int32_t socket; + int8_t secondary_connect_flag;//0: enble, no connected; 1: enable, connected; -1: disable +}BasicSocketPlc; + +typedef struct +{ + uint16_t command_length; + uint16_t data_size; + uint8_t *p_command; + uint8_t *p_data; +}BasicPlcDataInfo; + +typedef struct +{ + cJSON *read_single_item_json; + uint8_t *p_read_item_data; + uint16_t read_item_index;//Variable item index(1 ++) + uint8_t last_item_size; +}ProtocolFormatInfo; + +struct ProtocolData +{ + uint8_t *data; + uint16_t data_length; +}; + +struct SerialConfig +{ + uint32_t baud_rate; + uint8_t data_bits; + uint8_t stop_bits; + uint8_t check_mode; +}; + +struct SocketConfig +{ + uint16_t port; + uint8_t plc_ip[4]; + uint8_t local_ip[4]; + uint8_t gateway[4]; + uint8_t netmask[4]; +}; + +struct ControlRecipe +{ + uint8_t device_name[20]; + uint16_t device_id; + uint16_t read_period; + uint16_t read_item_count; + uint16_t total_data_length; + uint8_t communication_type; + + ProtocolType protocol_type; + + void *read_item; + struct ControlDone *done; + + struct SerialConfig serial_config; + struct SocketConfig socket_config; + + struct ProtocolData protocol_data; + + int (*ControlProtocolFormatCmd)(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info); +}; + +/*Get Value Type Memory Size*/ +uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type); + +/*Get basic information from recipe file*/ +int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json); + +/*Get the variable need to read from recipe file*/ +void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json); + +/*Control Framework Peripheral Device Init*/ +int ControlPeripheralInit(struct ControlRecipe *p_recipe); + +/*Control Framework Printf List Function*/ +void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length); + +/*Control Framework Connect Socket*/ +int ControlConnectSocket(BasicSocketPlc *p_plc); + +/*Control Framework Disconnect Socket*/ +int ControlDisconnectSocket(BasicSocketPlc *p_plc); + +/*Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task*/ +int ControlProtocolOpenDef(struct ControlProtocol *control_protocol); + +/*Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task*/ +int ControlProtocolCloseDef(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/APP_Framework/Framework/control/shared/control_io.c b/APP_Framework/Framework/control/shared/control_io.c new file mode 100644 index 000000000..eb7172883 --- /dev/null +++ b/APP_Framework/Framework/control/shared/control_io.c @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file control_io.c + * @brief low level io code for control framework + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-11-21 + */ + +#include + +/** + * @description: Control Framework Socket Init + * @param ip - local ip pointer + * @param mask - netmask pointer + * @param gw - gateway pointer + * @return + */ +void SocketInit(char *ip, char *mask, char *gw) +{ + printf("%s ip %d.%d.%d.%d mask %d.%d.%d.%d gw %d.%d.%d.%d\n", __func__, + ip[0], ip[1], ip[2], ip[3], + mask[0], mask[1], mask[2], mask[3], + gw[0], gw[1], gw[2], gw[3]); +#ifdef BSP_USING_LWIP + lwip_config_tcp(0, ip, mask, gw); +#endif +} + +/** + * @description: Control Framework Serial Init + * @param baud_rate - baud rate + * @param data_bits - data bits + * @param stop_bits - stop bits + * @param check_mode - check mode + * @return + */ +void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode) +{ + // Uart485Init(baud_rate, data_bits, stop_bits, check_mode); +} diff --git a/APP_Framework/Framework/control/shared/control_io.h b/APP_Framework/Framework/control/shared/control_io.h new file mode 100644 index 000000000..52c501486 --- /dev/null +++ b/APP_Framework/Framework/control/shared/control_io.h @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file control_io.h + * @brief code for control framework io adapter + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-11-21 + */ + +#ifndef CONTROL_IO_H +#define CONTROL_IO_H + +#include +#include + +#ifdef BSP_USING_LWIP +#include "lwip/sys.h" +#include "lwip/sockets.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef BSP_USING_LWIP +#define socket_write lwip_write +#define socket_read lwip_read +#endif + +/*Control Framework Socket Init*/ +void SocketInit(char *ip, char *mask, char *gw); + +/*Control Framework Serial Init*/ +void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/APP_Framework/Applications/framework_init.c b/APP_Framework/Framework/framework_init.c similarity index 96% rename from APP_Framework/Applications/framework_init.c rename to APP_Framework/Framework/framework_init.c index 9612fd635..20d56ab29 100644 --- a/APP_Framework/Applications/framework_init.c +++ b/APP_Framework/Framework/framework_init.c @@ -15,6 +15,7 @@ extern int SensorFrameworkInit(void); extern int AdapterFrameworkInit(void); +extern int ControlFrameworkInit(void); extern int Adapter4GInit(void); extern int AdapterNbiotInit(void); @@ -73,6 +74,10 @@ static struct InitDesc framework[] = { "connection_framework", AdapterFrameworkInit }, #endif +#ifdef SUPPORT_CONTROL_FRAMEWORK + { "control_framework", ControlFrameworkInit }, +#endif + { "NULL", NULL }, }; @@ -229,6 +234,10 @@ int FrameworkInit(void) ConnectionDeviceFrameworkInit(framework); #endif +#ifdef SUPPORT_CONTROL_FRAMEWORK + ControlFrameworkInit(); +#endif + #ifdef LIB_LV lv_port_init(); #endif diff --git a/APP_Framework/Framework/sensor/Makefile b/APP_Framework/Framework/sensor/Makefile index 1b0d11470..2ac3900a9 100644 --- a/APP_Framework/Framework/sensor/Makefile +++ b/APP_Framework/Framework/sensor/Makefile @@ -6,6 +6,12 @@ ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) endif +ifeq ($(ADD_XIZI_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += sensor.c + include $(APPDIR)/Application.mk +endif + ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES := sensor.c diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.c b/APP_Framework/Framework/transform_layer/xizi/transform.c index 8fc6d4e37..7e6128020 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.c +++ b/APP_Framework/Framework/transform_layer/xizi/transform.c @@ -173,6 +173,7 @@ int PrivIoctl(int fd, int cmd, void *args) case ADC_TYPE: case DAC_TYPE: case WDT_TYPE: + case CAMERA_TYPE: ret = ioctl(fd, cmd, ioctl_cfg->args); break; default: diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.h b/APP_Framework/Framework/transform_layer/xizi/transform.h index bac842a89..651192052 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.h +++ b/APP_Framework/Framework/transform_layer/xizi/transform.h @@ -168,9 +168,18 @@ enum IoctlDriverType DAC_TYPE, WDT_TYPE, RTC_TYPE, + CAMERA_TYPE, DEFAULT_TYPE, }; + +struct DvpRegConfigureInfo +{ + uint8_t device_addr; + uint16_t reg_addr; + uint8_t reg_value; +} ; + struct PrivIoctlCfg { enum IoctlDriverType ioctl_driver_type; @@ -198,6 +207,18 @@ typedef struct void* pixel_color; }LcdPixelParam; +struct CameraCfg +{ + uint16_t window_w; + uint16_t window_h; + uint16_t window_xoffset; + uint16_t window_yoffset; + uint16_t output_w; + uint16_t output_h; + uint8_t gain; + uint8_t gain_manu_enable; +}; + typedef struct { char type; // 0:write string;1:write dot @@ -212,6 +233,12 @@ typedef struct uint16_t press; }TouchDataParam; +struct TouchDataStandard +{ + uint16 x; + uint16 y; +}; + struct RtcDrvConfigureParam { int rtc_operation_cmd; diff --git a/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c b/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c index 053ba4d22..d4812a07b 100644 --- a/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c +++ b/APP_Framework/lib/lvgl/examples/porting/lv_port_indev_template.c @@ -3,7 +3,7 @@ * */ - /*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/ +/*Copy this file as "lv_port_indev.c" and set this value to "1" to enable content*/ #if 1 /********************* @@ -12,18 +12,18 @@ #include "lv_port_indev_template.h" #include "../../lvgl.h" -static int touch_fd = -1; -static TouchDataParam touch_data; +static int touch_fd = 0; /********************* * DEFINES *********************/ #define LV_USE_INDEV_TOUCHPAD 0x1u -#define LV_USE_INDEV_MOUSE 0x2u -#define LV_USE_INDEV_KEYPAD 0x4u -#define LV_USE_INDEV_ENCODER 0x8u -#define LV_USE_INDEV_BUTTUN 0x10u +#define LV_USE_INDEV_MOUSE 0x2u +#define LV_USE_INDEV_KEYPAD 0x4u +#define LV_USE_INDEV_ENCODER 0x8u +#define LV_USE_INDEV_BUTTUN 0x10u -#define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD ///< modify this DEFINE to enable the indev device. e.g #define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD | LV_USE_INDEV_KEYPAD +#define PRESS_FAILED_LIMIT 15 +#define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD ///< modify this DEFINE to enable the indev device. e.g #define LV_USE_INDEV LV_USE_INDEV_TOUCHPAD | LV_USE_INDEV_KEYPAD /********************** * TYPEDEFS @@ -34,33 +34,36 @@ static TouchDataParam touch_data; **********************/ #if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD static void touchpad_init(void); -static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); -static bool touchpad_is_pressed(void); -static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y); +static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data); +// static bool touchpad_is_pressed(void); +// static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y); +static bool touchpad_is_pressed(struct TouchDataStandard *touch_data_ptr); +static void touchpad_get_xy(struct TouchDataStandard *touch_data_ptr, + lv_coord_t *x, lv_coord_t *y); #endif #if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE static void mouse_init(void); -static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); +static void mouse_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data); static bool mouse_is_pressed(void); -static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y); +static void mouse_get_xy(lv_coord_t *x, lv_coord_t *y); #endif #if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD static void keypad_init(void); -static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); +static void keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data); static uint32_t keypad_get_key(void); #endif #if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER static void encoder_init(void); -static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); +static void encoder_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data); static void encoder_handler(void); #endif #if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN static void button_init(void); -static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); +static void button_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data); static int8_t button_get_pressed_id(void); static bool button_is_pressed(uint8_t id); #endif @@ -69,23 +72,23 @@ static bool button_is_pressed(uint8_t id); * STATIC VARIABLES **********************/ #if (LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD) == LV_USE_INDEV_TOUCHPAD -lv_indev_t * indev_touchpad; +lv_indev_t *indev_touchpad; #endif #if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE -lv_indev_t * indev_mouse; +lv_indev_t *indev_mouse; #endif #if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD -lv_indev_t * indev_keypad; +lv_indev_t *indev_keypad; #endif #if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER -lv_indev_t * indev_encoder; +lv_indev_t *indev_encoder; #endif #if (LV_USE_INDEV & LV_USE_INDEV_BUTTUN) == LV_USE_INDEV_BUTTUN -lv_indev_t * indev_button; +lv_indev_t *indev_button; #endif static int32_t encoder_diff; @@ -144,7 +147,7 @@ void lv_port_indev_init(void) indev_mouse = lv_indev_drv_register(&indev_drv); /*Set cursor. For simplicity set a HOME symbol now.*/ - lv_obj_t * mouse_cursor = lv_img_create(lv_scr_act()); + lv_obj_t *mouse_cursor = lv_img_create(lv_scr_act()); lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME); lv_indev_set_cursor(indev_mouse, mouse_cursor); #endif @@ -169,8 +172,6 @@ void lv_port_indev_init(void) *`lv_indev_set_group(indev_keypad, group);`*/ #endif - - #if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER /*------------------ * Encoder @@ -207,8 +208,8 @@ void lv_port_indev_init(void) /*Assign buttons to points on the screen*/ static const lv_point_t btn_points[2] = { - {10, 10}, /*Button 0 -> x:10; y:10*/ - {40, 100}, /*Button 1 -> x:40; y:100*/ + {10, 10}, /*Button 0 -> x:10; y:10*/ + {40, 100}, /*Button 1 -> x:40; y:100*/ }; lv_indev_set_button_points(indev_button, btn_points); #endif @@ -225,27 +226,37 @@ void lv_port_indev_init(void) /*Initialize your touchpad*/ static void touchpad_init(void) { - touch_fd = PrivOpen(PRIV_TOUCH_DEV,O_RDWR); - if(touch_fd >= 0) { + touch_fd = PrivOpen(PRIV_TOUCH_DEV, O_RDWR); + if (touch_fd >= 0) + { printf("touch fd = %d\n",touch_fd); - } else { - printf("open %s touch fd = %d failed.\n",PRIV_TOUCH_DEV,touch_fd); - touch_fd = -1; } + else + { + printf("open %s touch fd = %d failed.\n", PRIV_TOUCH_DEV, touch_fd); + } + /*Your code comes here*/ } +// static struct TouchDataStandard touch_data; + /*Will be called by the library to read the touchpad*/ -static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) +static void touchpad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { static lv_coord_t last_x = 0; static lv_coord_t last_y = 0; + static struct TouchDataStandard touch_data; + /*Save the pressed coordinates and the state*/ - if(touchpad_is_pressed()) { - touchpad_get_xy(&last_x, &last_y); + if (touchpad_is_pressed(&touch_data)) + { + touchpad_get_xy(&touch_data, &last_x, &last_y); data->state = LV_INDEV_STATE_PR; - } else { + } + else + { data->state = LV_INDEV_STATE_REL; } @@ -255,34 +266,68 @@ static void touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) } /*Return true is the touchpad is pressed*/ -static bool touchpad_is_pressed(void) +// static bool touchpad_is_pressed(void) +// { +// int ret; +// /*Your code comes here*/ +// // memset(&touch_data, 0 ,sizeof(TouchDataParam)); +// memset(&touch_data, 0 ,sizeof(struct TouchDataStandard)); +// ret = PrivRead(touch_fd, &touch_data, 1); +// if (ret && touch_data.x >= 0 && touch_data.x < MY_INDEV_X +// && touch_data.y >= 0 && touch_data.y < MY_INDEV_Y) +// { +// // printf("touch x %d touch y %d\n",touch_data.x,touch_data.y); +// return true; +// } + +// return false; +// } + +uint32_t press_failed_cnt = 0; +static bool touchpad_is_pressed(struct TouchDataStandard *touch_data_ptr) { int ret; /*Your code comes here*/ - memset(&touch_data, 0 ,sizeof(TouchDataParam)); - - if (touch_fd < 0) { - return false; - } - - ret = PrivRead(touch_fd, &touch_data, 1); - if(ret && touch_data.x >= 0 && touch_data.x < MY_INDEV_X && touch_data.y >= 0 && touch_data.y < MY_INDEV_Y) + memset(touch_data_ptr, 0, sizeof(struct TouchDataStandard)); + ret = PrivRead(touch_fd, touch_data_ptr, 1); + if (ret) { - // printf("touch x %d touch y %d\n",touch_data.x,touch_data.y); - return true; + if (touch_data_ptr->x > 0 && touch_data_ptr->x < MY_INDEV_X && touch_data_ptr->y > 0 && touch_data_ptr->y < MY_INDEV_Y) + { + press_failed_cnt = 0; + return true; + } + else + { + press_failed_cnt++; + if (press_failed_cnt >= PRESS_FAILED_LIMIT) + { + PrivClose(touch_fd); + touchpad_init(); + press_failed_cnt = 0; + } + } } - return false; } /*Get the x and y coordinates if the touchpad is pressed*/ -static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) +static void touchpad_get_xy(struct TouchDataStandard *touch_data_ptr, + lv_coord_t *x, lv_coord_t *y) { /*Your code comes here*/ - (*x) = touch_data.x; - (*y) = touch_data.y; + (*x) = touch_data_ptr->x; + (*y) = touch_data_ptr->y; } + +// static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y) +// { +// /*Your code comes here*/ + +// (*x) = touch_data.x; +// (*y) = touch_data.y; +// } #endif #if (LV_USE_INDEV & LV_USE_INDEV_MOUSE) == LV_USE_INDEV_MOUSE @@ -297,15 +342,18 @@ static void mouse_init(void) } /*Will be called by the library to read the mouse*/ -static void mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) +static void mouse_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { /*Get the current x and y coordinates*/ mouse_get_xy(&data->point.x, &data->point.y); /*Get whether the mouse button is pressed or released*/ - if(mouse_is_pressed()) { + if (mouse_is_pressed()) + { data->state = LV_INDEV_STATE_PR; - } else { + } + else + { data->state = LV_INDEV_STATE_REL; } } @@ -319,7 +367,7 @@ static bool mouse_is_pressed(void) } /*Get the x and y coordinates if the mouse is pressed*/ -static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y) +static void mouse_get_xy(lv_coord_t *x, lv_coord_t *y) { /*Your code comes here*/ @@ -328,8 +376,6 @@ static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y) } #endif - - #if (LV_USE_INDEV & LV_USE_INDEV_KEYPAD) == LV_USE_INDEV_KEYPAD /*------------------ * Keypad @@ -342,7 +388,7 @@ static void keypad_init(void) } /*Will be called by the library to read the mouse*/ -static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) +static void keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { static uint32_t last_key = 0; @@ -351,11 +397,13 @@ static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) /*Get whether the a key is pressed and save the pressed key*/ uint32_t act_key = keypad_get_key(); - if(act_key != 0) { + if (act_key != 0) + { data->state = LV_INDEV_STATE_PR; /*Translate the keys to LVGL control characters according to your key definitions*/ - switch(act_key) { + switch (act_key) + { case 1: act_key = LV_KEY_NEXT; break; @@ -374,7 +422,9 @@ static void keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) } last_key = act_key; - } else { + } + else + { data->state = LV_INDEV_STATE_REL; } @@ -390,8 +440,6 @@ static uint32_t keypad_get_key(void) } #endif - - #if (LV_USE_INDEV & LV_USE_INDEV_ENCODER) == LV_USE_INDEV_ENCODER /*------------------ * Encoder @@ -404,7 +452,7 @@ static void encoder_init(void) } /*Will be called by the library to read the encoder*/ -static void encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) +static void encoder_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { data->enc_diff = encoder_diff; @@ -433,7 +481,7 @@ static void button_init(void) } /*Will be called by the library to read the button*/ -static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) +static void button_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { static uint8_t last_btn = 0; @@ -441,10 +489,13 @@ static void button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) /*Get the pressed button's ID*/ int8_t btn_act = button_get_pressed_id(); - if(btn_act >= 0) { + if (btn_act >= 0) + { data->state = LV_INDEV_STATE_PR; last_btn = btn_act; - } else { + } + else + { data->state = LV_INDEV_STATE_REL; } @@ -458,9 +509,11 @@ static int8_t button_get_pressed_id(void) uint8_t i; /*Check to buttons see which is being pressed (assume there are 2 buttons)*/ - for(i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) + { /*Return the pressed button's ID*/ - if(button_is_pressed(i)) { + if (button_is_pressed(i)) + { return i; } } diff --git a/APP_Framework/lib/lvgl/lvgl.mk b/APP_Framework/lib/lvgl/lvgl.mk index 73466ddbb..d7ae3ff22 100644 --- a/APP_Framework/lib/lvgl/lvgl.mk +++ b/APP_Framework/lib/lvgl/lvgl.mk @@ -1,10 +1,10 @@ -# include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/porting/porting.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/examples/examples.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/extra/extra.mk + include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/core/lv_core.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/draw/lv_draw.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/font/lv_font.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/gpu/lv_gpu.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/hal/lv_hal.mk include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/misc/lv_misc.mk -include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets/lv_widgets.mk +include $(LVGL_DIR)/$(LVGL_DIR_NAME)/src/widgets/lv_widgets.mk \ No newline at end of file diff --git a/APP_Framework/lib/lvgl/porting/lv_port_indev_template.c b/APP_Framework/lib/lvgl/porting/lv_port_indev_template.c index 72652530f..aa7189e42 100644 --- a/APP_Framework/lib/lvgl/porting/lv_port_indev_template.c +++ b/APP_Framework/lib/lvgl/porting/lv_port_indev_template.c @@ -12,7 +12,6 @@ #include "lv_port_indev_template.h" #include "../lvgl.h" -#include static int touch_fd = 0; /********************* @@ -292,7 +291,7 @@ static bool touchpad_is_pressed(struct TouchDataStandard* touch_data_ptr) press_failed_cnt = 0; return true; } - + printf("lv_touch:%d,%d\n",touch_data_ptr->x,touch_data_ptr->y); press_failed_cnt++; if (press_failed_cnt >= PRESS_FAILED_LIMIT) { PrivClose(touch_fd); diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/Kconfig new file mode 100644 index 000000000..f66e3f567 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/Kconfig @@ -0,0 +1,42 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +if ARCH_BOARD_EDU_RISCV64 + +menuconfig BSP_USING_CH376 + bool "Using CH376 device" + default n + select K210_UART + select K210_UART3 + +if BSP_USING_CH376 + +choice + prompt "select ch376 function." + default CH376_USB_FUNCTION + +config CH376_USB_FUNCTION + bool "select ch376 usb function" + +config CH376_SD_FUNCTION + bool "select ch376 sd function" +endchoice + +config CH376_WORK_MODE + hex "ch376 work mode set:0x03 sd,0x06 u-disk" + default 0x03 if CH376_SD_FUNCTION + default 0x06 if CH376_USB_FUNCTION + +endif # BSP_USING_CH376 + +menuconfig BSP_USING_ENET + bool "Using ENET device" + default n + +menuconfig BSP_USING_TOUCH + bool "Using touch device" + default n + +endif # ARCH_BOARD_EDU_RISCV64 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/README.txt b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/README.txt new file mode 100644 index 000000000..2520cc71b --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/README.txt @@ -0,0 +1,42 @@ +1. Download and install toolchain and openocd-k210 + + $ curl https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz + $ export PATH=$PATH:/$TOOL_CHAIN_PATH/bin + +2. Build openocd-k210 + + $ git clone https://github.com/kendryte/openocd-kendryte + $ cd openocd-kendryte + $ ./bootstrap & ./configure & make + +3. Configure and build NuttX + + $ mkdir ./nuttx; cd ./nuttx + $ git clone https://github.com/apache/incubator-nuttx.git nuttx + $ git clone https://github.com/apache/incubator-nuttx-apps.git apps + $ cd nuttx + $ make distclean + $ ./tools/configure.sh edu-riscv64:nsh + $ make V=1 + +4. Download and run the nuttx from SRAM (not SPI-Flash) + + $ picocom -b 115200 /dev/ttyUSB0 + $ sudo ./src/openocd -s ./tcl -f ./tcl/kendryte.cfg -m 0 + $ riscv64-unknown-elf-gdb ./nuttx + (gdb) target extended-remote :3333 + (gdb) load nuttx + (gdb) c + +5. Write nuttx.bin to SPI-Flash + + $ pip3 install kflash + $ kflash -p /dev/ttyUSB0 -b 1500000 ./nuttx/nuttx.bin + + NOTE: The kflash_gui is not recommended because it's unstable + +6. TODO + + Support peripherals such as GPIO/SPI/I2C/... + Support FPU + Support RISC-V U-mode including memory protection diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/configs/loransh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/configs/loransh/defconfig new file mode 100644 index 000000000..3a71cf017 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/configs/loransh/defconfig @@ -0,0 +1,80 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="xidatong-riscv64" +CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y +CONFIG_ARCH_CHIP="k210" +CONFIG_ARCH_CHIP_K210=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=46000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=2097152 +CONFIG_RAM_START=0x80400000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=28 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_SCHED_HPWORK=y +CONFIG_DEV_GPIO=y +CONFIG_BOARDCTL_RESET=y +CONFIG_K210_UART=y +CONFIG_K210_UART2=y +CONFIG_K210_UART2_BASE=0x50220000 +CONFIG_K210_UART2_CLOCK=195000000 +CONFIG_K210_UART2_IRQ=39 +CONFIG_K210_UART2_BAUD=115200 +CONFIG_K210_UART2_PARITY=0 +CONFIG_K210_UART2_BITS=8 +CONFIG_K210_UART2_2STOP=0 +CONFIG_K210_UART2_RXBUFSIZE=128 +CONFIG_K210_UART2_TXBUFSIZE=128 +CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y +CONFIG_CONNECTION_FRAMEWORK_DEBUG=y +CONFIG_CONNECTION_ADAPTER_LORA=y +CONFIG_ADAPTER_E220=y +CONFIG_ADAPTER_LORA_E220="e220" +CONFIG_ADAPTER_E220_DRIVER_EXTUART=n +CONFIG_ADAPTER_E220_DRIVER="/dev/ttyS2" +CONFIG_ADAPTER_E220_M0_PATH="/dev/gpio0" +CONFIG_ADAPTER_E220_M1_PATH="/dev/gpio1" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/configs/nsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/configs/nsh/defconfig new file mode 100644 index 000000000..c93933657 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/configs/nsh/defconfig @@ -0,0 +1,60 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="edu-riscv64" +CONFIG_ARCH_BOARD_EDU_RISCV64=y +CONFIG_ARCH_CHIP="k210" +CONFIG_ARCH_CHIP_K210=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=46000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=2097152 +CONFIG_RAM_START=0x80400000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=28 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_SCHED_HPWORK=y +CONFIG_DEV_GPIO=y +CONFIG_BOARDCTL_RESET=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/K-Flash.jpg b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/K-Flash.jpg new file mode 100644 index 000000000..aa5ebc0f5 Binary files /dev/null and b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/K-Flash.jpg differ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/gccdir.jpg b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/gccdir.jpg new file mode 100644 index 000000000..00af7af3d Binary files /dev/null and b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/gccdir.jpg differ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/k210-shell.jpg b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/k210-shell.jpg new file mode 100644 index 000000000..72b137ae4 Binary files /dev/null and b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/k210-shell.jpg differ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfig.png b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfig.png new file mode 100644 index 000000000..ea275e1ff Binary files /dev/null and b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfig.png differ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfig1.png b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfig1.png new file mode 100644 index 000000000..cb8291f00 Binary files /dev/null and b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfig1.png differ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfigexit.png b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfigexit.png new file mode 100644 index 000000000..adb6c2192 Binary files /dev/null and b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/img/menuconfigexit.png differ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/include/board.h new file mode 100644 index 000000000..9843f5512 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/include/board.h @@ -0,0 +1,175 @@ +/* +* 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 board.h + * @brief edu-riscv64 board.h + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.03.17 + */ + +#ifndef __BOARDS_RISCV_K210_EDU_RISCV64_INCLUDE_BOARD_H +#define __BOARDS_RISCV_K210_EDU_RISCV64_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +#include "k210.h" + +#include "k210_fpioa.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + + + +/* Map pad 14 to gpiohs io 0 */ +#define BOARD_LED_IO_FUNC K210_IO_FUNC_GPIOHS0 + +#define LED_STARTED 0 /* N/C */ +#define LED_HEAPALLOCATE 1 /* N/C */ +#define LED_IRQSENABLED 2 /* N/C */ +#define LED_STACKCREATED 3 /* N/C */ +#define LED_INIRQ 4 /* N/C */ +#define LED_SIGNAL 5 /* N/C */ +#define LED_ASSERTION 6 /* N/C */ +#define LED_PANIC 7 /* blink */ + +/* GPIO pins used by the GPIO Subsystem */ + +#define BOARD_NGPIOOUT 3 /* Amount of register GPIO Output pins */ +#define BOARD_NGPIOINT 0 /* Amount of GPIO Input */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/*************************** GPIO define ***************************/ + +/* UART IO */ +#define GPIO_WIFI_RXD 7 +#define GPIO_WIFI_TXD 6 +#define GPIO_E220_RXD 21 +#define GPIO_E220_TXD 20 +#define GPIO_CH376T_RXD 22 +#define GPIO_CH376T_TXD 23 + +/* w5500 IO */ +#define BSP_ENET_SCLK 9 +#define BSP_ENET_MISO 10 +#define BSP_ENET_MOSI 11 +#define BSP_ENET_NCS 12 +#define BSP_ENET_NRST 13 +#define BSP_ENET_NINT 14 + +/* LCD IO */ +#define BSP_LCD_NRST 37 +#define BSP_LCD_SCLK 38 +#define BSP_LCD_MOSI 39 +#define BSP_LCD_MISO 40 +#define BSP_LCD_NCS 41 +#define BSP_LCD_BL_PIN 47 + +/* I2C */ +#define BSP_IIC_SDA 15 +#define BSP_IIC_SCL 17 + +/* other mode io */ +#define GPIO_E220_M0 32 +#define GPIO_E220_M1 33 +#define GPIO_E18_MODE 46 +#define GPIO_WIFI_EN 8 +#define GPIO_CAN_CFG 43 + +/************************** end GPIO define **************************/ + + +/*************************** FPIOA define ***************************/ + +/* UART FPOA */ +#define FPOA_USART1_RX K210_IO_FUNC_UART1_RX +#define FPOA_USART1_TX K210_IO_FUNC_UART1_TX +#define FPOA_USART2_RX K210_IO_FUNC_UART2_RX +#define FPOA_USART2_TX K210_IO_FUNC_UART2_TX +#define FPOA_USART3_RX K210_IO_FUNC_UART3_RX +#define FPOA_USART3_TX K210_IO_FUNC_UART3_TX + +/* w5500 FPIOA */ +#define FPIOA_ENET_NRST 0 +#define FPIOA_ENET_NINT 9 +#define FPIOA_ENET_SCLK 28 +#define FPIOA_ENET_MISO 29 +#define FPIOA_ENET_MOSI 23 +#define FPIOA_ENET_NCS 31 + +/* LCD FPIOA */ +#define FPIOA_LCD_NRST 0 +#define FPIOA_LCD_BL 9 +#define FPIOA_LCD_SCLK 28 +#define FPIOA_LCD_MOSI 29 +#define FPIOA_LCD_MISO 23 +#define FPIOA_LCD_NCS 31 + +/* I2C */ +#define FPIOA_IIC_SDA 7 +#define FPIOA_IIC_SCL 8 + +/* other mode FPIOA */ +#define FPIOA_E220_M0 1 +#define FPIOA_E220_M1 2 +#define FPIOA_E18_MODE 3 +#define FPIOA_WIFI_EN 4 +#define FPIOA_CAN_NCFG 5 + +/************************** end FPIOA define **************************/ + + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_boardinitialize + ****************************************************************************/ + +void k210_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISC-V_K210_EDU_RISCV64_INCLUDE_BOARD_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/kernel/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/kernel/Makefile new file mode 100644 index 000000000..43d582f0b --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/kernel/Makefile @@ -0,0 +1,92 @@ +############################################################################ +# boards/risc-v/k210/edu-riscv64/kernel/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you 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. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +# The entry point name (if none is provided in the .config file) + +CONFIG_INIT_ENTRYPOINT ?= user_start +ENTRYPT = $(patsubst "%",%,$(CONFIG_INIT_ENTRYPOINT)) + +# Get the paths to the libraries and the links script path in format that +# is appropriate for the host OS + +USER_LIBPATHS = $(addprefix -L,$(call CONVERT_PATH,$(addprefix $(TOPDIR)$(DELIM),$(dir $(USERLIBS))))) +USER_LDSCRIPT = -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)memory.ld) +USER_LDSCRIPT += -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)user-space.ld) +USER_HEXFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.hex) +USER_SRECFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.srec) +USER_BINFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.bin) + +USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(USER_LDSCRIPT) +USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS)))) +USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +# Source files + +CSRCS = k210_userspace.c +COBJS = $(CSRCS:.c=$(OBJEXT)) +OBJS = $(COBJS) + +# Targets: + +all: $(TOPDIR)$(DELIM)nuttx_user.elf $(TOPDIR)$(DELIM)User.map +.PHONY: nuttx_user.elf depend clean distclean + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +# Create the nuttx_user.elf file containing all of the user-mode code + +nuttx_user.elf: $(OBJS) + $(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) --start-group $(USER_LDLIBS) --end-group $(USER_LIBGCC) + +$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf + @echo "LD: nuttx_user.elf" + $(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf +ifeq ($(CONFIG_INTELHEX_BINARY),y) + @echo "CP: nuttx_user.hex" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE) +endif +ifeq ($(CONFIG_MOTOROLA_SREC),y) + @echo "CP: nuttx_user.srec" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O srec nuttx_user.elf $(USER_SRECFILE) +endif +ifeq ($(CONFIG_RAW_BINARY),y) + @echo "CP: nuttx_user.bin" + $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE) +endif + +$(TOPDIR)$(DELIM)User.map: nuttx_user.elf + @echo "MK: User.map" + $(Q) $(NM) -n nuttx_user.elf >$(TOPDIR)$(DELIM)User.map + $(Q) $(CROSSDEV)size nuttx_user.elf + +.depend: + +depend: .depend + +clean: + $(call DELFILE, nuttx_user.elf) + $(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*") + $(call DELFILE, "$(TOPDIR)$(DELIM)User.map") + $(call CLEAN) + +distclean: clean diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/kernel/k210_userspace.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/kernel/k210_userspace.c new file mode 100644 index 000000000..9fd37af39 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/kernel/k210_userspace.c @@ -0,0 +1,114 @@ +/* +* 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 k210_userspace.c + * @brief edu-riscv64 k210_userspace.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.03.17 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include + +#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#ifndef CONFIG_NUTTX_USERSPACE +# error "CONFIG_NUTTX_USERSPACE not defined" +#endif + +#if CONFIG_NUTTX_USERSPACE != 0x80100000 +# error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld" +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* These 'addresses' of these values are setup by the linker script. + * They are not actual uint32_t storage locations! + * They are only used meaningfully in the following way: + * + * - The linker script defines, for example, the symbol_sdata. + * - The declaration extern uint32_t _sdata; makes C happy. C will believe + * that the value _sdata is the address of a uint32_t variable _data + * (it is not!). + * - We can recover the linker value then by simply taking the address of + * of _data. like: uint32_t *pdata = &_sdata; + */ + +extern uint32_t _stext; /* Start of .text */ +extern uint32_t _etext; /* End_1 of .text + .rodata */ +extern const uint32_t _eronly; /* End+1 of read only section */ +extern uint32_t _sdata; /* Start of .data */ +extern uint32_t _edata; /* End+1 of .data */ +extern uint32_t _sbss; /* Start of .bss */ +extern uint32_t _ebss; /* End+1 of .bss */ + +/* This is the user space entry point */ + +int CONFIG_INIT_ENTRYPOINT(int argc, char *argv[]); + +const struct userspace_s userspace locate_data(".userspace") = +{ + /* General memory map */ + + .us_entrypoint = (main_t)CONFIG_INIT_ENTRYPOINT, + .us_textstart = (uintptr_t)&_stext, + .us_textend = (uintptr_t)&_etext, + .us_datasource = (uintptr_t)&_eronly, + .us_datastart = (uintptr_t)&_sdata, + .us_dataend = (uintptr_t)&_edata, + .us_bssstart = (uintptr_t)&_sbss, + .us_bssend = (uintptr_t)&_ebss, + + /* Memory manager heap structure */ + + .us_heap = &g_mmheap, + + /* Task/thread startup routines */ + + .task_startup = nxtask_startup, + + /* Signal handler trampoline */ + + .signal_handler = up_signal_handler, + + /* User-space work queue support (declared in include/nuttx/wqueue.h) */ + +#ifdef CONFIG_LIBC_USRWORK + .work_usrstart = work_usrstart, +#endif +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/readme.md b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/readme.md new file mode 100644 index 000000000..269c0187f --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/readme.md @@ -0,0 +1,174 @@ +# 从零开始构建矽璓工业物联操作系统:使用ARM架构的矽达通 + +# edu-riscv64 + +[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓XiUOS是一款面向智慧车间的工业物联网操作系统,主要由一个极简的微型实时操作系统内核和其上的工业物联框架构成,通过高效管理工业物联网设备、支撑工业物联应用,在生产车间内实现智能化的“感知环境、联网传输、知悉识别、控制调整”,促进以工业设备和工业控制系统为核心的人、机、物深度互联,帮助提升生产线的数字化和智能化水平。 + +## 1. 简介 + +| 硬件 | 描述 | +| -- | -- | +|芯片型号| 勘智K210 | +|架构| 双核riscv64 | +|主频| 400MHz | +|片内SRAM| 8M | +|外设支持| 内嵌AES与SHA256算法加速器 | +|| DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I²S、I²C、WDT、Timer与PWM | + +XiUOS板级当前支持使用CH438、GPIO、UART等。 + +## 2. 开发环境搭建 + +### 推荐使用: + +**操作系统:** ubuntu18.04 [https://ubuntu.com/download/desktop](https://ubuntu.com/download/desktop) + +更新`ubuntu 18.04`源的方法:(根据自身情况而定,可以不更改) + +第一步:打开sources.list文件 + +```c +sudo vim /etc/apt/sources.list +``` + +第二步:将以下内容复制到sources.list文件 + +```c +deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse +deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse +``` + +第三步:更新源和系统软件 + +```c +sudo apt-get update +sudo apt-get upgrade +``` + +**开发工具推荐使用 VSCode ,VScode下载地址为:** VSCode [https://code.visualstudio.com/](https://code.visualstudio.com/),推荐下载地址为 [http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb](http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb) + +### 依赖包安装: + +``` +$ sudo apt install build-essential pkg-config git +$ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev +``` + +**XiUOS操作系统源码下载,这个仓里的代码可能不是最新的,最好git clone自己仓里的代码:** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos) + +新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下: + +```c +mkdir test && cd test +git clone https://gitlink.org.cn/xuos/xiuos.git +git checkout origin/prepare_for_master (以实际分支为准) +``` + +打开XiUOS源码文件包可以看到以下目录: +| 名称 | 说明 | +| -- | -- | +| APP_Framework | 应用代码 | +| Ubiquitous | 板级支持包,支持NuttX、RT-Thread和XiZi内核 | + + +### 裁减配置工具的下载 + +裁减配置工具: + +**工具地址:** kconfig-frontends [https://www.gitlink.org.cn/xuos/kconfig-frontends](https://www.gitlink.org.cn/xuos/kconfig-frontends),下载与安装的具体命令如下: + +```c +mkdir kfrontends && cd kfrontends +git clone https://gitlink.org.cn/xuos/kconfig-frontends.git +``` + +下载源码后按以下步骤执行软件安装: + +```c +cd kconfig-frontends +./xs_build.sh +``` + +### 编译工具链: + +Riscv64: riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar,在我的个人仓保存有一份: + +https://gitlink.org.cn/wgzAIIT/build_tools.git + +下载后解压到Ubantu环境的/opt目录下。 + +再将/opt/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin目录下的全部二进制文件软连接到/usr/bin,例如 + +![gccdir](img/gccdir.jpg) + + + +## 3.编译bin包 + +1.XiUOS操作系统源码下载: [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos) + + 目前大家都使用的个人仓,请注意此处的路径及分支,如果需要须进行分支切换 + +2.在Ubuntu18.04环境中的代码路径,执行以下命令,生成配置文件 + +```shell +cd ./Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx +source build.sh + +执行完毕会自动进入./Ubiquitous/Nuttx_Fusion_XiUOS/nuttx下,继续执行 + +./tools/configure.sh edu-riscv64:nsh +make menuconfig +视情况而定,如果需要前面加sudo +``` + +3..在menuconfig界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后保存并退出(本例旨在演示简单的输出例程,所以没有需要配置的选项,双击快捷键ESC退出配置) + +![menuconfig](./img/menuconfig.png) + +退出时选择`yes`保存上面所配置的内容,如下图所示: + +![menuconfig1](./img/menuconfigexit.png) + +4.继续执行以下命令,进行编译 + +```shell +make +或 +make -j8 +``` + +make时加上V=1参数可以看到较为详细的编译信息,但是编译过程会比较慢。 + +5.如果编译正确无误,会在当前目录下产生nuttx.bin、nuttx、nuttx.hex等文件。 + +## 4. 烧写及运行 + +### 4.1 烧写 +1、烧写工具:K-Flash.exe,可https://gitlink.org.cn/wgzAIIT/build_tools.git下载 + +![K-Flash](img/K-Flash.jpg) + +在①选择串口 com 号 + +在②处选择波特率,选择 115200 + +在③处选择编译出的 nuttx.bin 文件 + +设备在上电时确保 Boot 和 GND 短接,这是升级模式。 + +点击④处 Flash 开始烧录,显示烧录完成即可,中间有报错的话,重新 Flash。 + +### 4.2 运行结果 + +烧写完毕重新上电,进入 shell。 + +![k210-shell](img/k210-shell.jpg) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/Make.defs b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/Make.defs new file mode 100644 index 000000000..c153000db --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/Make.defs @@ -0,0 +1,70 @@ +############################################################################ +# boards/risc-v/k210/edu-riscv64/scripts/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you 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. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs + +LDSCRIPT = ld.script + +ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g + ASARCHCPUFLAGS += -Wa,-g +endif + +MAXOPTIMIZATION = -Os + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing +endif + +ARCHCPUFLAGS += -mcmodel=medany -mstrict-align +ARCHCFLAGS = -fno-common -ffunction-sections -fdata-sections +ARCHCXXFLAGS = -fno-common -fno-exceptions -fcheck-new -fno-rtti +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef + +CFLAGS := $(APPPATHS) $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS) + +# Loadable module definitions + +CMODULEFLAGS = $(CFLAGS) + +LDMODULEFLAGS = -r -e module_initialize +LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld) + +# ELF module definitions + +CELFFLAGS = $(CFLAGS) +CXXELFFLAGS = $(CXXFLAGS) + +LDELFFLAGS = -r -e main +LDELFFLAGS += -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)gnu-elf.ld) + +# File extensions + +LDFLAGS += --gc-sections -melf64lriscv diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/gnu-elf.ld b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/gnu-elf.ld new file mode 100644 index 000000000..4cc79b314 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/gnu-elf.ld @@ -0,0 +1,115 @@ +/**************************************************************************** + * boards/risc-v/k210/edu-riscv64/scripts/gnu-elf.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +SECTIONS +{ + .text 0x00000000 : + { + _stext = . ; + *(.text) + *(.text.*) + *(.gnu.warning) + *(.stub) + *(.glue_7) + *(.glue_7t) + *(.jcr) + + /* C++ support: The .init and .fini sections contain specific logic + * to manage static constructors and destructors. + */ + + *(.gnu.linkonce.t.*) + *(.init) /* Old ABI */ + *(.fini) /* Old ABI */ + _etext = . ; + } + + .rodata : + { + _srodata = . ; + *(.rodata) + *(.rodata1) + *(.rodata.*) + *(.gnu.linkonce.r*) + _erodata = . ; + } + + .data : + { + _sdata = . ; + *(.data) + *(.data1) + *(.data.*) + *(.gnu.linkonce.d*) + . = ALIGN(4); + _edata = . ; + } + + /* C++ support. For each global and static local C++ object, + * GCC creates a small subroutine to construct the object. Pointers + * to these routines (not the routines themselves) are stored as + * simple, linear arrays in the .ctors section of the object file. + * Similarly, pointers to global/static destructor routines are + * stored in .dtors. + */ + + .ctors : + { + _sctors = . ; + *(.ctors) /* Old ABI: Unallocated */ + *(.init_array) /* New ABI: Allocated */ + _edtors = . ; + } + + .dtors : + { + _sdtors = . ; + *(.dtors) /* Old ABI: Unallocated */ + *(.fini_array) /* New ABI: Allocated */ + _edtors = . ; + } + + .bss : + { + _sbss = . ; + *(.bss) + *(.bss.*) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.b*) + *(COMMON) + _ebss = . ; + } + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/ld.script b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/ld.script new file mode 100644 index 000000000..efd5c05ad --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/ld.script @@ -0,0 +1,100 @@ +/**************************************************************************** + * boards/risc-v/k210/edu-riscv64/scripts/ld.script + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/* Reg Access Start addr End addr Size + * MEM0 CPU w/ cache 0x80000000 - 0x803fffff : 4MB + * MEM1 CPU w/ cache 0x80400000 - 0x805fffff : 2MB + * MEM0 CPU w/o cache 0x40000000 - 0x403fffff : 4MB + * MEM1 CPU w/o cache 0x40400000 - 0x405fffff : 4MB + */ + +MEMORY +{ + progmem (rx) : ORIGIN = 0x80000000, LENGTH = 4096K /* w/ cache */ + sram (rwx) : ORIGIN = 0x80400000, LENGTH = 2048K /* w/ cache */ +} + +OUTPUT_ARCH("riscv") + +ENTRY(_stext) +EXTERN(_vectors) +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.* .srodata .srodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > progmem + + .init_section : ALIGN(4) { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > progmem + + _eronly = ABSOLUTE(.); + + .data : ALIGN(4) { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > progmem + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(32); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/memory.ld b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/memory.ld new file mode 100644 index 000000000..c6d9b605c --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/memory.ld @@ -0,0 +1,37 @@ +/**************************************************************************** + * boards/risc-v/k210/edu-riscv64/scripts/memory.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/* Reg Access Start addr End addr Size + * MEM0 CPU w/ cache 0x80000000 - 0x803fffff : 4MB + * MEM1 CPU w/ cache 0x80400000 - 0x805fffff : 2MB + * MEM0 CPU w/o cache 0x40000000 - 0x403fffff : 4MB + * MEM1 CPU w/o cache 0x40400000 - 0x405fffff : 4MB + */ + +MEMORY +{ + kflash (rx) : ORIGIN = 0x80000000, LENGTH = 1024K /* w/ cache */ + uflash (rx) : ORIGIN = 0x80100000, LENGTH = 1024K /* w/ cache */ + xflash (rx) : ORIGIN = 0x80200000, LENGTH = 2048K /* w/ cache */ + + ksram (rwx) : ORIGIN = 0x80400000, LENGTH = 512K /* w/ cache */ + usram (rwx) : ORIGIN = 0x80480000, LENGTH = 512K /* w/ cache */ + xsram (rwx) : ORIGIN = 0x80500000, LENGTH = 1024K /* w/ cache */ +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/user-space.ld b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/user-space.ld new file mode 100644 index 000000000..0a899c79b --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/scripts/user-space.ld @@ -0,0 +1,94 @@ +/**************************************************************************** + * boards/risc-v/k210/edu-riscv64/scripts/user-space.ld + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/* NOTE: This depends on the memory.ld script having been included prior to + * this script. + */ + +OUTPUT_ARCH("riscv") + +SECTIONS +{ + .userspace : { + *(.userspace) + } > uflash + + .text : { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > uflash + + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > uflash + + __exidx_start = ABSOLUTE(.); + + __exidx_end = ABSOLUTE(.); + + _eronly = ABSOLUTE(.); + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > usram AT > uflash + + .bss : { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > usram + + /* Stabs debugging sections */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/Makefile new file mode 100644 index 000000000..e7ecd5934 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/Makefile @@ -0,0 +1,57 @@ +############################################################################ +# boards/risc-v/k210/edu-riscv64/src/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you 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. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +CSRCS = k210_bringup.c k210_boot.c + +ifeq ($(CONFIG_BOARDCTL_RESET),y) +CSRCS += k210_reset.c +endif + +ifeq ($(CONFIG_BOARDCTL),y) +CSRCS += k210_appinit.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += k210_leds.c +endif + +ifeq ($(CONFIG_K210_LCD),y) +CSRCS += k210_lcd.c +endif + +ifeq ($(CONFIG_DEV_GPIO),y) +CSRCS += k210_gpio.c +endif + +ifeq ($(CONFIG_BSP_USING_CH376),y) +CSRCS += k210_ch376.c ch376_demo.c +endif + +ifeq ($(CONFIG_BSP_USING_ENET),y) +CSRCS += k210_w5500.c +endif + +ifeq ($(CONFIG_BSP_USING_TOUCH),y) +CSRCS += k210_touch.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/ch376_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/ch376_demo.c new file mode 100644 index 000000000..ceb18d53f --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/ch376_demo.c @@ -0,0 +1,70 @@ +/* +* 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 ch376_demo.c + * @brief edu-riscv64 ch376_demo.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.10.11 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "k210_ch376.h" + +uint8_t buf[64]; + +void CH376Demo(void) +{ + uint8_t s; + s = mInitCH376Host(); + printf ("ch376 init stat=0x%02x\n",(uint16_t)s); + +#ifdef CONFIG_CH376_USB_FUNCTION + printf( "Wait Udisk/SD\n" ); + while ( CH376DiskConnect( ) != USB_INT_SUCCESS ) + { + up_mdelay( 100 ); + } +#endif + + for ( s = 0; s < 10; s ++ ) + { + up_mdelay( 50 ); + printf( "Ready ?\n" ); + if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break; + } + s = CH376ReadBlock( buf ); + if ( s == sizeof( INQUIRY_DATA ) ) + { + buf[ s ] = 0; + printf( "UdiskInfo: %s\n", ((P_INQUIRY_DATA)buf) -> VendorIdStr ); + } + + printf( "Create /YEAR2022/DEMO2022.TXT \n" ); + s = CH376DirCreate((PUINT8)"/YEAR2022" ); + printf("CH376DirCreate:0x%02x\n",(uint16_t)s ); + + s = CH376FileCreatePath((PUINT8)"/YEAR2022/DEMO2022.TXT" ); + printf( "CH376FileCreatePath:0x%02x\n",(uint16_t)s ); + + printf( "Write some data to file\n" ); + strcpy( (char *)buf, "This is test case!\xd\xa" ); + s = CH376ByteWrite(buf, strlen((char *)buf), NULL ); + printf( "CH376ByteWrite:0x%02x\n",(uint16_t)s ); + + printf( "Close\n" ); + s = CH376FileClose( TRUE ); + printf( "CH376FileClose:0x%02x\n",(uint16_t)s ); +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/ch376inc.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/ch376inc.h new file mode 100644 index 000000000..53c277f99 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/ch376inc.h @@ -0,0 +1,584 @@ +/* +* 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 ch376inc.h + * @brief edu-riscv64 ch376inc.h + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.10.10 + */ + +#ifndef __CH376INC_H__ +#define __CH376INC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Common types and constant definitions */ + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef NULL +#define NULL 0 +#endif + +#ifndef UINT8 +typedef unsigned char UINT8; +#endif +#ifndef UINT16 +typedef unsigned short UINT16; +#endif +#ifndef UINT32 +typedef unsigned long UINT32; +#endif +#ifndef PUINT8 +typedef unsigned char *PUINT8; +#endif +#ifndef PUINT16 +typedef unsigned short *PUINT16; +#endif +#ifndef PUINT32 +typedef unsigned long *PUINT32; +#endif +#ifndef UINT8V +typedef unsigned char volatile UINT8V; +#endif +#ifndef PUINT8V +typedef unsigned char volatile *PUINT8V; +#endif + +#define CH376_DAT_BLOCK_LEN 0x40 +#define CMD01_GET_IC_VER 0x01 +#define CMD21_SET_BAUDRATE 0x02 +#define CMD00_ENTER_SLEEP 0x03 +#define CMD00_RESET_ALL 0x05 +#define CMD11_CHECK_EXIST 0x06 +#define CMD20_CHK_SUSPEND 0x0B +#define CMD20_SET_SDO_INT 0x0B +#define CMD14_GET_FILE_SIZE 0x0C +#define CMD50_SET_FILE_SIZE 0x0D +#define CMD11_SET_USB_MODE 0x15 +#define CMD01_GET_STATUS 0x22 +#define CMD00_UNLOCK_USB 0x23 +#define CMD01_RD_USB_DATA0 0x27 +#define CMD01_RD_USB_DATA 0x28 +#define CMD10_WR_USB_DATA7 0x2B +#define CMD10_WR_HOST_DATA 0x2C +#define CMD01_WR_REQ_DATA 0x2D +#define CMD20_WR_OFS_DATA 0x2E +#define CMD10_SET_FILE_NAME 0x2F +#define CMD0H_DISK_CONNECT 0x30 +#define CMD0H_DISK_MOUNT 0x31 +#define CMD0H_FILE_OPEN 0x32 +#define CMD0H_FILE_ENUM_GO 0x33 +#define CMD0H_FILE_CREATE 0x34 +#define CMD0H_FILE_ERASE 0x35 +#define CMD1H_FILE_CLOSE 0x36 +#define CMD1H_DIR_INFO_READ 0x37 +#define CMD0H_DIR_INFO_SAVE 0x38 +#define CMD4H_BYTE_LOCATE 0x39 +#define CMD2H_BYTE_READ 0x3A +#define CMD0H_BYTE_RD_GO 0x3B +#define CMD2H_BYTE_WRITE 0x3C +#define CMD0H_BYTE_WR_GO 0x3D +#define CMD0H_DISK_CAPACITY 0x3E +#define CMD0H_DISK_QUERY 0x3F +#define CMD0H_DIR_CREATE 0x40 +#define CMD4H_SEC_LOCATE 0x4A +#define CMD1H_SEC_READ 0x4B +#define CMD1H_SEC_WRITE 0x4C +#define CMD0H_DISK_BOC_CMD 0x50 +#define CMD5H_DISK_READ 0x54 +#define CMD0H_DISK_RD_GO 0x55 +#define CMD5H_DISK_WRITE 0x56 +#define CMD0H_DISK_WR_GO 0x57 +#define CMD10_SET_USB_SPEED 0x04 +#define CMD11_GET_DEV_RATE 0x0A +#define CMD11_GET_TOGGLE 0x0A +#define CMD11_READ_VAR8 0x0A +#define CMD20_SET_RETRY 0x0B +#define CMD20_WRITE_VAR8 0x0B +#define CMD14_READ_VAR32 0x0C +#define CMD50_WRITE_VAR32 0x0D +#define CMD01_DELAY_100US 0x0F +#define CMD40_SET_USB_ID 0x12 +#define CMD10_SET_USB_ADDR 0x13 +#define CMD01_TEST_CONNECT 0x16 +#define CMD00_ABORT_NAK 0x17 +#define CMD10_SET_ENDP2 0x18 +#define CMD10_SET_ENDP3 0x19 +#define CMD10_SET_ENDP4 0x1A +#define CMD10_SET_ENDP5 0x1B +#define CMD10_SET_ENDP6 0x1C +#define CMD10_SET_ENDP7 0x1D +#define CMD00_DIRTY_BUFFER 0x25 +#define CMD10_WR_USB_DATA3 0x29 +#define CMD10_WR_USB_DATA5 0x2A +#define CMD1H_CLR_STALL 0x41 +#define CMD1H_SET_ADDRESS 0x45 +#define CMD1H_GET_DESCR 0x46 +#define CMD1H_SET_CONFIG 0x49 +#define CMD0H_AUTO_SETUP 0x4D +#define CMD2H_ISSUE_TKN_X 0x4E +#define CMD1H_ISSUE_TOKEN 0x4F +#define CMD0H_DISK_INIT 0x51 +#define CMD0H_DISK_RESET 0x52 +#define CMD0H_DISK_SIZE 0x53 +#define CMD0H_DISK_INQUIRY 0x58 +#define CMD0H_DISK_READY 0x59 +#define CMD0H_DISK_R_SENSE 0x5A +#define CMD0H_RD_DISK_SEC 0x5B +#define CMD0H_WR_DISK_SEC 0x5C +#define CMD0H_DISK_MAX_LUN 0x5D + +/* The following definitions are only for compatibility with the command name format in the INCLUDE file of CH375 */ + +#ifndef _NO_CH375_COMPATIBLE_ +#define CMD_GET_IC_VER CMD01_GET_IC_VER +#define CMD_SET_BAUDRATE CMD21_SET_BAUDRATE +#define CMD_ENTER_SLEEP CMD00_ENTER_SLEEP +#define CMD_RESET_ALL CMD00_RESET_ALL +#define CMD_CHECK_EXIST CMD11_CHECK_EXIST +#define CMD_CHK_SUSPEND CMD20_CHK_SUSPEND +#define CMD_SET_SDO_INT CMD20_SET_SDO_INT +#define CMD_GET_FILE_SIZE CMD14_GET_FILE_SIZE +#define CMD_SET_FILE_SIZE CMD50_SET_FILE_SIZE +#define CMD_SET_USB_MODE CMD11_SET_USB_MODE +#define CMD_GET_STATUS CMD01_GET_STATUS +#define CMD_UNLOCK_USB CMD00_UNLOCK_USB +#define CMD_RD_USB_DATA0 CMD01_RD_USB_DATA0 +#define CMD_RD_USB_DATA CMD01_RD_USB_DATA +#define CMD_WR_USB_DATA7 CMD10_WR_USB_DATA7 +#define CMD_WR_HOST_DATA CMD10_WR_HOST_DATA +#define CMD_WR_REQ_DATA CMD01_WR_REQ_DATA +#define CMD_WR_OFS_DATA CMD20_WR_OFS_DATA +#define CMD_SET_FILE_NAME CMD10_SET_FILE_NAME +#define CMD_DISK_CONNECT CMD0H_DISK_CONNECT +#define CMD_DISK_MOUNT CMD0H_DISK_MOUNT +#define CMD_FILE_OPEN CMD0H_FILE_OPEN +#define CMD_FILE_ENUM_GO CMD0H_FILE_ENUM_GO +#define CMD_FILE_CREATE CMD0H_FILE_CREATE +#define CMD_FILE_ERASE CMD0H_FILE_ERASE +#define CMD_FILE_CLOSE CMD1H_FILE_CLOSE +#define CMD_DIR_INFO_READ CMD1H_DIR_INFO_READ +#define CMD_DIR_INFO_SAVE CMD0H_DIR_INFO_SAVE +#define CMD_BYTE_LOCATE CMD4H_BYTE_LOCATE +#define CMD_BYTE_READ CMD2H_BYTE_READ +#define CMD_BYTE_RD_GO CMD0H_BYTE_RD_GO +#define CMD_BYTE_WRITE CMD2H_BYTE_WRITE +#define CMD_BYTE_WR_GO CMD0H_BYTE_WR_GO +#define CMD_DISK_CAPACITY CMD0H_DISK_CAPACITY +#define CMD_DISK_QUERY CMD0H_DISK_QUERY +#define CMD_DIR_CREATE CMD0H_DIR_CREATE +#define CMD_SEC_LOCATE CMD4H_SEC_LOCATE +#define CMD_SEC_READ CMD1H_SEC_READ +#define CMD_SEC_WRITE CMD1H_SEC_WRITE +#define CMD_DISK_BOC_CMD CMD0H_DISK_BOC_CMD +#define CMD_DISK_READ CMD5H_DISK_READ +#define CMD_DISK_RD_GO CMD0H_DISK_RD_GO +#define CMD_DISK_WRITE CMD5H_DISK_WRITE +#define CMD_DISK_WR_GO CMD0H_DISK_WR_GO +#define CMD_SET_USB_SPEED CMD10_SET_USB_SPEED +#define CMD_GET_DEV_RATE CMD11_GET_DEV_RATE +#define CMD_GET_TOGGLE CMD11_GET_TOGGLE +#define CMD_READ_VAR8 CMD11_READ_VAR8 +#define CMD_SET_RETRY CMD20_SET_RETRY +#define CMD_WRITE_VAR8 CMD20_WRITE_VAR8 +#define CMD_READ_VAR32 CMD14_READ_VAR32 +#define CMD_WRITE_VAR32 CMD50_WRITE_VAR32 +#define CMD_DELAY_100US CMD01_DELAY_100US +#define CMD_SET_USB_ID CMD40_SET_USB_ID +#define CMD_SET_USB_ADDR CMD10_SET_USB_ADDR +#define CMD_TEST_CONNECT CMD01_TEST_CONNECT +#define CMD_ABORT_NAK CMD00_ABORT_NAK +#define CMD_SET_ENDP2 CMD10_SET_ENDP2 +#define CMD_SET_ENDP3 CMD10_SET_ENDP3 +#define CMD_SET_ENDP4 CMD10_SET_ENDP4 +#define CMD_SET_ENDP5 CMD10_SET_ENDP5 +#define CMD_SET_ENDP6 CMD10_SET_ENDP6 +#define CMD_SET_ENDP7 CMD10_SET_ENDP7 +#define CMD_DIRTY_BUFFER CMD00_DIRTY_BUFFER +#define CMD_WR_USB_DATA3 CMD10_WR_USB_DATA3 +#define CMD_WR_USB_DATA5 CMD10_WR_USB_DATA5 +#define CMD_CLR_STALL CMD1H_CLR_STALL +#define CMD_SET_ADDRESS CMD1H_SET_ADDRESS +#define CMD_GET_DESCR CMD1H_GET_DESCR +#define CMD_SET_CONFIG CMD1H_SET_CONFIG +#define CMD_AUTO_SETUP CMD0H_AUTO_SETUP +#define CMD_ISSUE_TKN_X CMD2H_ISSUE_TKN_X +#define CMD_ISSUE_TOKEN CMD1H_ISSUE_TOKEN +#define CMD_DISK_INIT CMD0H_DISK_INIT +#define CMD_DISK_RESET CMD0H_DISK_RESET +#define CMD_DISK_SIZE CMD0H_DISK_SIZE +#define CMD_DISK_INQUIRY CMD0H_DISK_INQUIRY +#define CMD_DISK_READY CMD0H_DISK_READY +#define CMD_DISK_R_SENSE CMD0H_DISK_R_SENSE +#define CMD_RD_DISK_SEC CMD0H_RD_DISK_SEC +#define CMD_WR_DISK_SEC CMD0H_WR_DISK_SEC +#define CMD_DISK_MAX_LUN CMD0H_DISK_MAX_LUN +#endif + +/* ********************************************************************************************************************* */ +#ifndef PARA_STATE_INTB +#define PARA_STATE_INTB 0x80 +#define PARA_STATE_BUSY 0x10 +#endif + +#ifndef SER_CMD_TIMEOUT +#define SER_CMD_TIMEOUT 32 +#define SER_SYNC_CODE1 0x57 +#define SER_SYNC_CODE2 0xAB +#endif + +#ifndef CMD_RET_SUCCESS +#define CMD_RET_SUCCESS 0x51 +#define CMD_RET_ABORT 0x5F +#endif + +/***********************************************************************************************************************/ +#ifndef USB_INT_EP0_SETUP + +#define USB_INT_USB_SUSPEND 0x05 +#define USB_INT_WAKE_UP 0x06 +#define USB_INT_EP0_SETUP 0x0C +#define USB_INT_EP0_OUT 0x00 +#define USB_INT_EP0_IN 0x08 +#define USB_INT_EP1_OUT 0x01 +#define USB_INT_EP1_IN 0x09 +#define USB_INT_EP2_OUT 0x02 +#define USB_INT_EP2_IN 0x0A +#define USB_INT_BUS_RESET1 0x03 +#define USB_INT_BUS_RESET2 0x07 +#define USB_INT_BUS_RESET3 0x0B +#define USB_INT_BUS_RESET4 0x0F + +#endif + + +#ifndef USB_INT_SUCCESS +#define USB_INT_SUCCESS 0x14 +#define USB_INT_CONNECT 0x15 +#define USB_INT_DISCONNECT 0x16 +#define USB_INT_BUF_OVER 0x17 +#define USB_INT_USB_READY 0x18 +#define USB_INT_DISK_READ 0x1D +#define USB_INT_DISK_WRITE 0x1E +#define USB_INT_DISK_ERR 0x1F +#endif + +#ifndef ERR_DISK_DISCON +#define ERR_DISK_DISCON 0x82 +#define ERR_LARGE_SECTOR 0x84 +#define ERR_TYPE_ERROR 0x92 +#define ERR_BPB_ERROR 0xA1 +#define ERR_DISK_FULL 0xB1 +#define ERR_FDT_OVER 0xB2 +#define ERR_FILE_CLOSE 0xB4 +#define ERR_OPEN_DIR 0x41 +#define ERR_MISS_FILE 0x42 +#define ERR_FOUND_NAME 0x43 + + +#define ERR_MISS_DIR 0xB3 +#define ERR_LONG_BUF_OVER 0x48 +#define ERR_LONG_NAME_ERR 0x49 +#define ERR_NAME_EXIST 0x4A +#endif + +/* ******************************************************************************************************************** */ +#ifndef DEF_DISK_UNKNOWN +#define DEF_DISK_UNKNOWN 0x00 +#define DEF_DISK_DISCONN 0x01 +#define DEF_DISK_CONNECT 0x02 +#define DEF_DISK_MOUNTED 0x03 +#define DEF_DISK_READY 0x10 +#define DEF_DISK_OPEN_ROOT 0x12 +#define DEF_DISK_OPEN_DIR 0x13 +#define DEF_DISK_OPEN_FILE 0x14 +#endif + +/* **********************************************************************************************************************/ +#ifndef DEF_SECTOR_SIZE +#define DEF_SECTOR_SIZE 512 +#endif + +#ifndef DEF_WILDCARD_CHAR +#define DEF_WILDCARD_CHAR 0x2A +#define DEF_SEPAR_CHAR1 0x5C +#define DEF_SEPAR_CHAR2 0x2F +#define DEF_FILE_YEAR 2004 +#define DEF_FILE_MONTH 1 +#define DEF_FILE_DATE 1 +#endif + +#ifndef ATTR_DIRECTORY + +typedef struct _FAT_DIR_INFO { + UINT8 DIR_Name[11]; + UINT8 DIR_Attr; + UINT8 DIR_NTRes; + UINT8 DIR_CrtTimeTenth; + UINT16 DIR_CrtTime; + UINT16 DIR_CrtDate; + UINT16 DIR_LstAccDate; + UINT16 DIR_FstClusHI; + UINT16 DIR_WrtTime; + UINT16 DIR_WrtDate; + UINT16 DIR_FstClusLO; + UINT32 DIR_FileSize; +} FAT_DIR_INFO, *P_FAT_DIR_INFO; + +#define ATTR_READ_ONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME_ID 0x08 +#define ATTR_DIRECTORY 0x10 +#define ATTR_ARCHIVE 0x20 +#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID) +#define ATTR_LONG_NAME_MASK (ATTR_LONG_NAME | ATTR_DIRECTORY | ATTR_ARCHIVE) + +#define MAKE_FILE_TIME( h, m, s ) ( (h<<11) + (m<<5) + (s>>1) ) +#define MAKE_FILE_DATE( y, m, d ) ( ((y-1980)<<9) + (m<<5) + d ) + +#define LONE_NAME_MAX_CHAR (255*2) +#define LONG_NAME_PER_DIR (13*2) + +#endif + +/* ********************************************************************************************************************* */ +#ifndef SPC_CMD_INQUIRY + +#define SPC_CMD_INQUIRY 0x12 +#define SPC_CMD_READ_CAPACITY 0x25 +#define SPC_CMD_READ10 0x28 +#define SPC_CMD_WRITE10 0x2A +#define SPC_CMD_TEST_READY 0x00 +#define SPC_CMD_REQUEST_SENSE 0x03 +#define SPC_CMD_MODESENSE6 0x1A +#define SPC_CMD_MODESENSE10 0x5A +#define SPC_CMD_START_STOP 0x1B + +typedef struct _BULK_ONLY_CBW { + UINT32 CBW_Sig; + UINT32 CBW_Tag; + UINT8 CBW_DataLen0; + UINT8 CBW_DataLen1; + UINT16 CBW_DataLen2; + UINT8 CBW_Flag; + UINT8 CBW_LUN; + UINT8 CBW_CB_Len; + UINT8 CBW_CB_Buf[16]; +} BULK_ONLY_CBW, *P_BULK_ONLY_CBW; + +typedef struct _INQUIRY_DATA { + UINT8 DeviceType; + UINT8 RemovableMedia; + UINT8 Versions; + UINT8 DataFormatAndEtc; + UINT8 AdditionalLength; + UINT8 Reserved1; + UINT8 Reserved2; + UINT8 MiscFlag; + UINT8 VendorIdStr[8]; + UINT8 ProductIdStr[16]; + UINT8 ProductRevStr[4]; +} INQUIRY_DATA, *P_INQUIRY_DATA; + + +typedef struct _SENSE_DATA { + UINT8 ErrorCode; + UINT8 SegmentNumber; + UINT8 SenseKeyAndEtc; + UINT8 Information0; + UINT8 Information1; + UINT8 Information2; + UINT8 Information3; + UINT8 AdditSenseLen; + UINT8 CmdSpecInfo[4]; + UINT8 AdditSenseCode; + UINT8 AddSenCodeQual; + UINT8 FieldReplaUnit; + UINT8 SenseKeySpec[3]; +} SENSE_DATA, *P_SENSE_DATA; + +#endif + +/* ********************************************************************************************************************* */ +#ifndef MAX_FILE_NAME_LEN + +#define MAX_FILE_NAME_LEN (13+1) + +typedef union _CH376_CMD_DATA { + struct { + UINT8 mBuffer[ MAX_FILE_NAME_LEN ]; + } Default; + + INQUIRY_DATA DiskMountInq; + FAT_DIR_INFO OpenDirInfo; + FAT_DIR_INFO EnumDirInfo; + struct { + UINT8 mUpdateFileSz; + } FileCLose; + + struct { + UINT8 mDirInfoIndex; + } DirInfoRead; + + union { + UINT32 mByteOffset; + UINT32 mSectorLba; + } ByteLocate; + + struct { + UINT16 mByteCount; + } ByteRead; + + struct { + UINT16 mByteCount; + } ByteWrite; + + union { + UINT32 mSectorOffset; + UINT32 mSectorLba; + } SectorLocate; + + struct { + UINT8 mSectorCount; + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; + } SectorRead; + + struct { + UINT8 mSectorCount; + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; +} SectorWrite; + + struct { + UINT32 mDiskSizeSec; + } DiskCapacity; + + struct { + UINT32 mTotalSector; + UINT32 mFreeSector; + UINT8 mDiskFat; + } DiskQuery; + + BULK_ONLY_CBW DiskBocCbw; + + struct { + UINT8 mMaxLogicUnit; + } DiskMaxLun; + + INQUIRY_DATA DiskInitInq; + INQUIRY_DATA DiskInqData; + SENSE_DATA ReqSenseData; + struct { + UINT32 mDiskSizeSec; + } DiskSize; + + struct { + UINT32 mStartSector; + UINT8 mSectorCount; + } DiskRead; + + struct { + UINT32 mStartSector; + UINT8 mSectorCount; + } DiskWrite; +} CH376_CMD_DATA, *P_CH376_CMD_DATA; + +#endif + +/* ********************************************************************************************************************* */ + +#ifndef VAR_FILE_SIZE + +#define VAR_SYS_BASE_INFO 0x20 +#define VAR_RETRY_TIMES 0x25 +#define VAR_FILE_BIT_FLAG 0x26 +#define VAR_DISK_STATUS 0x2B +#define VAR_SD_BIT_FLAG 0x30 +#define VAR_UDISK_TOGGLE 0x31 +#define VAR_UDISK_LUN 0x34 +#define VAR_SEC_PER_CLUS 0x38 +#define VAR_FILE_DIR_INDEX 0x3B +#define VAR_CLUS_SEC_OFS 0x3C + +#define VAR_DISK_ROOT 0x44 +#define VAR_DSK_TOTAL_CLUS 0x48 +#define VAR_DSK_START_LBA 0x4C +#define VAR_DSK_DAT_START 0x50 +#define VAR_LBA_BUFFER 0x54 +#define VAR_LBA_CURRENT 0x58 +#define VAR_FAT_DIR_LBA 0x5C +#define VAR_START_CLUSTER 0x60 +#define VAR_CURRENT_CLUST 0x64 +#define VAR_FILE_SIZE 0x68 +#define VAR_CURRENT_OFFSET 0x6C + +#endif + +/* ********************************************************************************************************************* */ +#ifndef DEF_USB_PID_SETUP +#define DEF_USB_PID_NULL 0x00 +#define DEF_USB_PID_SOF 0x05 +#define DEF_USB_PID_SETUP 0x0D +#define DEF_USB_PID_IN 0x09 +#define DEF_USB_PID_OUT 0x01 +#define DEF_USB_PID_ACK 0x02 +#define DEF_USB_PID_NAK 0x0A +#define DEF_USB_PID_STALL 0x0E +#define DEF_USB_PID_DATA0 0x03 +#define DEF_USB_PID_DATA1 0x0B +#define DEF_USB_PID_PRE 0x0C +#endif + +#ifndef DEF_USB_REQ_TYPE +#define DEF_USB_REQ_READ 0x80 +#define DEF_USB_REQ_WRITE 0x00 +#define DEF_USB_REQ_TYPE 0x60 +#define DEF_USB_REQ_STAND 0x00 +#define DEF_USB_REQ_CLASS 0x20 +#define DEF_USB_REQ_VENDOR 0x40 +#define DEF_USB_REQ_RESERVE 0x60 +#endif + +#ifndef DEF_USB_GET_DESCR +#define DEF_USB_CLR_FEATURE 0x01 +#define DEF_USB_SET_FEATURE 0x03 +#define DEF_USB_GET_STATUS 0x00 +#define DEF_USB_SET_ADDRESS 0x05 +#define DEF_USB_GET_DESCR 0x06 +#define DEF_USB_SET_DESCR 0x07 +#define DEF_USB_GET_CONFIG 0x08 +#define DEF_USB_SET_CONFIG 0x09 +#define DEF_USB_GET_INTERF 0x0A +#define DEF_USB_SET_INTERF 0x0B +#define DEF_USB_SYNC_FRAME 0x0C +#endif + +/* ********************************************************************************************************************* */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/edu-riscv64.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/edu-riscv64.h new file mode 100644 index 000000000..3403bc946 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/edu-riscv64.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file edu-riscv64.h + * @brief edu-riscv64 edu-riscv64.h + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.03.17 + */ + +#ifndef __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H +#define __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +int k210_bringup(void); + +#ifdef CONFIG_DEV_GPIO +int k210_gpio_init(void); +#endif + +#endif /* __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_appinit.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_appinit.c new file mode 100644 index 000000000..ce8f9c6f3 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_appinit.c @@ -0,0 +1,76 @@ +/* +* 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 k210_appinit.c + * @brief edu-riscv64 k210_appinit.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.03.17 + */ + + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "k210.h" +#include "edu-riscv64.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform architecture specific initialization + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initialization logic and the + * matching application logic. The value could be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ +#ifdef CONFIG_BOARD_LATE_INITIALIZE + /* Board initialization already performed by board_late_initialize() */ + + return OK; +#else + /* Perform board-specific initialization */ + + return k210_bringup(); +#endif +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_boot.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_boot.c new file mode 100644 index 000000000..5d89d5e26 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_boot.c @@ -0,0 +1,59 @@ +/* +* 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 k210_boot.c + * @brief edu-riscv64 k210_boot.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.03.17 + */ + + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_boardinitialize + * + * Description: + * All K210 architectures must provide the following entry point. + * This entry point is called early in the initialization -- after all + * memory has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void k210_boardinitialize(void) +{ + board_autoled_initialize(); +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_bringup.c new file mode 100644 index 000000000..71b40df31 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_bringup.c @@ -0,0 +1,125 @@ +/* +* 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 k210_bringup.c + * @brief edu-riscv64 k210_bringup.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.03.17 + */ + + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "k210.h" +#include "k210_clockconfig.h" +#include "edu-riscv64.h" +#include +#include "k210_sysctl.h" +#include "k210_fpioa.h" +#include "k210_gpiohs.h" +#include "k210_gpio_common.h" + +#ifdef CONFIG_BSP_USING_CH438 +# include "k210_ch438.h" +#endif + +#ifdef CONFIG_BSP_USING_TOUCH +# include "k210_touch.h" +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_bringup + ****************************************************************************/ + +int k210_bringup(void) +{ + int ret = OK; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + serr("ERROR: Failed to mount procfs at %s: %d\n", "/proc", ret); + } +#endif + +#ifdef CONFIG_DEV_GPIO + ret = k210_gpio_init(); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret); + return ret; + } +#endif + +#ifdef CONFIG_K210_LCD + k210_sysctl_init(); + board_lcd_initialize(); +#endif + +#ifdef CONFIG_BSP_USING_TOUCH + board_touch_initialize(); +#endif + +#ifdef CONFIG_K210_UART1 + sysctl_clock_enable(SYSCTL_CLOCK_UART1); + sysctl_reset(SYSCTL_RESET_UART1); + + fpioa_set_function(GPIO_WIFI_TXD, FPOA_USART1_RX); + fpioa_set_function(GPIO_WIFI_RXD, FPOA_USART1_TX); + + fpioa_set_function(GPIO_WIFI_EN, K210_IO_FUNC_GPIOHS0 + FPIOA_WIFI_EN); + k210_gpiohs_set_direction(FPIOA_WIFI_EN, GPIO_DM_OUTPUT); + k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_LOW); + up_mdelay(50); + k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_HIGH); +#endif + +#ifdef CONFIG_K210_UART2 + sysctl_clock_enable(SYSCTL_CLOCK_UART2); + sysctl_reset(SYSCTL_RESET_UART2); + + fpioa_set_function(GPIO_E220_RXD, FPOA_USART2_RX); + fpioa_set_function(GPIO_E220_TXD, FPOA_USART2_TX); +#endif + +#ifdef CONFIG_K210_UART3 + sysctl_clock_enable(SYSCTL_CLOCK_UART3); + sysctl_reset(SYSCTL_RESET_UART3); + + fpioa_set_function(GPIO_CH376T_RXD, FPOA_USART3_RX); + fpioa_set_function(GPIO_CH376T_TXD, FPOA_USART3_TX); +#endif + + return ret; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_ch376.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_ch376.c new file mode 100644 index 000000000..fe4e04276 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_ch376.c @@ -0,0 +1,960 @@ +/* +* 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 k210_ch376.c + * @brief edu-riscv64 k210_ch376.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.10.10 + */ + + +#if 0 +#define DEF_IC_V43_U 1 +#endif + +#include "k210_ch376.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static int fd; + +/* Serial port mode is not used */ +void xEndCH376Cmd(void) +{ +} + +void xWriteCH376Cmd(UINT8 cmd) +{ + UINT8 temp[3]; + temp[0] = 0x57; + temp[1] = 0xab; + temp[2] = cmd; + up_udelay(5); + write(fd, temp, 3); +} + +void xWriteCH376Data(UINT8 dat) +{ + UINT8 tmp = dat; + write(fd, &tmp, 1); + up_udelay(2); +} + +UINT8 xReadCH376Data(void) +{ + UINT32 i; + UINT8 data; + int res; + for(i=0;i<500000;i++) + { + res = read(fd, &data, 1); + if(res == 1) + { + return ((UINT8)data); + } + up_udelay(1); + } + return ERR_USB_UNKNOWN; +} + +UINT8 CH376ReadBlock(PUINT8 buf) +{ + UINT8 s, l; + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + s = l = xReadCH376Data( ); + if ( l ) { + do { + *buf = xReadCH376Data( ); + buf ++; + } while ( -- l ); + } + xEndCH376Cmd( ); + return( s ); +} + +UINT8 Query376Interrupt(void) +{ + //When an interrupt occurs, the serial port will receive a data, read it directly, and discard it + if(xReadCH376Data() == ERR_USB_UNKNOWN) return FALSE ; + else return TRUE ; +} + +/* CH376 INIT */ +UINT8 mInitCH376Host(void) +{ + UINT8 res; + /* After power on, delay operation for at least 50ms */ + up_mdelay(50); + fd = open("/dev/ttyS3", O_RDWR); + up_mdelay(600); + /* Test the communication interface between SCM and CH376 */ + xWriteCH376Cmd(CMD11_CHECK_EXIST); + xWriteCH376Data(0x65); + res = xReadCH376Data(); + xEndCH376Cmd(); + if ( res != 0x9A ) return( ERR_USB_UNKNOWN ); + + xWriteCH376Cmd(CMD11_SET_USB_MODE); /* SET USB MODE */ + xWriteCH376Data(CONFIG_CH376_WORK_MODE); + up_udelay(20); + res = xReadCH376Data(); + xEndCH376Cmd(); + if (res == CMD_RET_SUCCESS) return(USB_INT_SUCCESS); + else return(ERR_USB_UNKNOWN); /* SET MODE ERROR */ + +} + +/* Write the requested data block to the internally specified buffer, and return the length */ +UINT8 CH376WriteReqBlock(PUINT8 buf) +{ + UINT8 s, l; + xWriteCH376Cmd( CMD01_WR_REQ_DATA ); + s = l = xReadCH376Data(); + if ( l ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- l ); + } + xEndCH376Cmd( ); + return( s ); +} + +/* Write data block to the send buffer of USB host endpoint */ +void CH376WriteHostBlock(PUINT8 buf, UINT8 len) +{ + xWriteCH376Cmd( CMD10_WR_HOST_DATA ); + xWriteCH376Data( len ); + if ( len ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + xEndCH376Cmd( ); +} + +/* Specify offset address to write data block to internal buffer */ +void CH376WriteOfsBlock( PUINT8 buf, UINT8 ofs, UINT8 len ) +{ + xWriteCH376Cmd( CMD20_WR_OFS_DATA ); + xWriteCH376Data( ofs ); /* Offset address */ + xWriteCH376Data( len ); /* length */ + if ( len ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + xEndCH376Cmd( ); +} + +/* Set the file name of the file to be operated on */ +void CH376SetFileName( PUINT8 name ) +{ + UINT8 c; +#ifndef DEF_IC_V43_U + UINT8 s; + xWriteCH376Cmd( CMD01_GET_IC_VER ); + if ( xReadCH376Data( ) < 0x43 ) { + if ( CH376ReadVar8( VAR_DISK_STATUS ) < DEF_DISK_READY ) { + xWriteCH376Cmd( CMD10_SET_FILE_NAME ); + xWriteCH376Data( 0 ); + s = CH376SendCmdWaitInt( CMD0H_FILE_OPEN ); + if ( s == USB_INT_SUCCESS ) { + s = CH376ReadVar8( 0xCF ); + if ( s ) { + CH376WriteVar32( 0x4C, CH376ReadVar32( 0x4C ) + ( (UINT16)s << 8 ) ); + CH376WriteVar32( 0x50, CH376ReadVar32( 0x50 ) + ( (UINT16)s << 8 ) ); + CH376WriteVar32( 0x70, 0 ); + } + } + } + } +#endif + xWriteCH376Cmd( CMD10_SET_FILE_NAME ); + c = *name; + xWriteCH376Data( c ); + while ( c ) { + name ++; + c = *name; + /* Force the file name to expire */ + if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) c = 0; + xWriteCH376Data( c ); + } + xEndCH376Cmd( ); +} + +/* Read 32-bit data from CH376 chip and end the command */ +UINT32 CH376Read32bitDat( void ) +{ + UINT8 c0, c1, c2, c3; + c0 = xReadCH376Data( ); + c1 = xReadCH376Data( ); + c2 = xReadCH376Data( ); + c3 = xReadCH376Data( ); + xEndCH376Cmd( ); + return( c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24 ); +} + + +UINT8 CH376ReadVar8( UINT8 var ) +{ + UINT8 c0; + xWriteCH376Cmd( CMD11_READ_VAR8 ); + xWriteCH376Data( var ); + c0 = xReadCH376Data( ); + xEndCH376Cmd( ); + return( c0 ); +} + +void CH376WriteVar8( UINT8 var, UINT8 dat ) +{ + xWriteCH376Cmd( CMD20_WRITE_VAR8 ); + xWriteCH376Data( var ); + xWriteCH376Data( dat ); + xEndCH376Cmd( ); +} + +UINT32 CH376ReadVar32( UINT8 var ) +{ + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( var ); + return( CH376Read32bitDat( ) ); +} + +void CH376WriteVar32( UINT8 var, UINT32 dat ) +{ + xWriteCH376Cmd( CMD50_WRITE_VAR32 ); + xWriteCH376Data( var ); + xWriteCH376Data( (UINT8)dat ); + xWriteCH376Data( (UINT8)( (UINT16)dat >> 8 ) ); + xWriteCH376Data( (UINT8)( dat >> 16 ) ); + xWriteCH376Data( (UINT8)( dat >> 24 ) ); + xEndCH376Cmd( ); +} + +void CH376EndDirInfo( void ) +{ + CH376WriteVar8( 0x0D, 0x00 ); +} + +UINT32 CH376GetFileSize( void ) +{ + return( CH376ReadVar32( VAR_FILE_SIZE ) ); +} + +UINT8 CH376GetDiskStatus( void ) +{ + return( CH376ReadVar8( VAR_DISK_STATUS ) ); +} + +UINT8 CH376GetIntStatus( void ) +{ + UINT8 s; + xWriteCH376Cmd( CMD01_GET_STATUS ); + s = xReadCH376Data( ); + xEndCH376Cmd( ); + return( s ); +} + +#ifndef NO_DEFAULT_CH376_INT +UINT8 Wait376Interrupt( void ) +{ +#ifdef DEF_INT_TIMEOUT +#if DEF_INT_TIMEOUT < 1 + while ( Query376Interrupt( ) == FALSE ); + return( CH376GetIntStatus( ) ); +#else + UINT32 i; + for ( i = 0; i < DEF_INT_TIMEOUT; i ++ ) { + if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) ); + } + return( ERR_USB_UNKNOWN ); +#endif +#else + UINT32 i; + for ( i = 0; i < 5000000; i ++ ) { + if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) ); + } + return( ERR_USB_UNKNOWN ); +#endif +} +#endif + +UINT8 CH376SendCmdWaitInt( UINT8 mCmd ) +{ + xWriteCH376Cmd( mCmd ); + xEndCH376Cmd( ); + return( Wait376Interrupt( ) ); +} + +UINT8 CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat ) +{ + xWriteCH376Cmd( mCmd ); + xWriteCH376Data( mDat ); + xEndCH376Cmd( ); + return(Wait376Interrupt()); +} + +UINT8 CH376DiskReqSense( void ) +{ + UINT8 s; + up_mdelay( 5 ); + s = CH376SendCmdWaitInt( CMD0H_DISK_R_SENSE ); + up_mdelay( 5 ); + return( s ); +} + +UINT8 CH376DiskConnect( void ) +{ + if ( Query376Interrupt( ) ) CH376GetIntStatus( ); + return( CH376SendCmdWaitInt( CMD0H_DISK_CONNECT ) ); +} + +UINT8 CH376DiskMount( void ) +{ + return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) ); +} + +UINT8 CH376FileOpen( PUINT8 name ) +{ + CH376SetFileName( name ); +#ifndef DEF_IC_V43_U + if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) CH376WriteVar32( VAR_CURRENT_CLUST, 0 ); +#endif + return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) ); +} + +UINT8 CH376FileCreate( PUINT8 name ) +{ + if ( name ) CH376SetFileName( name ); + return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) ); +} + +UINT8 CH376DirCreate( PUINT8 name ) +{ + CH376SetFileName( name ); +#ifndef DEF_IC_V43_U + if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) CH376WriteVar32( VAR_CURRENT_CLUST, 0 ); +#endif + return( CH376SendCmdWaitInt( CMD0H_DIR_CREATE ) ); +} + +UINT8 CH376SeparatePath( PUINT8 path ) +{ + PUINT8 pName; + for ( pName = path; *pName != 0; ++ pName ); + while ( *pName != DEF_SEPAR_CHAR1 && *pName != DEF_SEPAR_CHAR2 && pName != path ) pName --; + if ( pName != path ) pName ++; + return( pName - path ); +} + +UINT8 CH376FileOpenDir( PUINT8 PathName, UINT8 StopName ) +{ + UINT8 i, s; + s = 0; + i = 1; + while ( 1 ) { + while ( PathName[i] != DEF_SEPAR_CHAR1 && PathName[i] != DEF_SEPAR_CHAR2 && PathName[i] != 0 ) ++ i; + if ( PathName[i] ) i ++; + else i = 0; + s = CH376FileOpen( &PathName[s] ); + if ( i && i != StopName ) { + if ( s != ERR_OPEN_DIR ) { + if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); + else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); + else return( s ); + } + s = i; + } + else return( s ); + } +} + +UINT8 CH376FileOpenPath( PUINT8 PathName ) +{ + return( CH376FileOpenDir( PathName, 0xFF ) ); +} + +UINT8 CH376FileCreatePath( PUINT8 PathName ) +{ + UINT8 s; + UINT8 Name; + Name = CH376SeparatePath( PathName ); + if ( Name ) { + s = CH376FileOpenDir( PathName, Name ); + if ( s != ERR_OPEN_DIR ) { + if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); + else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); + else return( s ); + } + } + return( CH376FileCreate( &PathName[Name] ) ); +} + +#ifdef EN_DIR_CREATE +UINT8 CH376DirCreatePath( PUINT8 PathName ) +{ + UINT8 s; + UINT8 Name; + UINT8 ClustBuf[4]; + Name = CH376SeparatePath( PathName ); + if ( Name ) { + s = CH376FileOpenDir( PathName, Name ); + if ( s != ERR_OPEN_DIR ) { + if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME ); + else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR ); + else return( s ); + } + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_START_CLUSTER ); + for ( s = 0; s != 4; s ++ ) ClustBuf[ s ] = xReadCH376Data( ); + xEndCH376Cmd( ); + s = CH376DirCreate( &PathName[Name] ); + if ( s != USB_INT_SUCCESS ) return( s ); + CH376WriteVar32( VAR_FILE_SIZE, sizeof(FAT_DIR_INFO) * 2 ); + s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusHI ) ); + if ( s != USB_INT_SUCCESS ) return( s ); + s = CH376ByteWrite( &ClustBuf[2], 2, NULL ); + if ( s != USB_INT_SUCCESS ) return( s ); + s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusLO ) ); + if ( s != USB_INT_SUCCESS ) return( s ); + s = CH376ByteWrite( ClustBuf, 2, NULL ); + if ( s != USB_INT_SUCCESS ) return( s ); + s = CH376ByteLocate( 0 ); + if ( s != USB_INT_SUCCESS ) return( s ); + CH376WriteVar32( VAR_FILE_SIZE, 0 ); + return( s ); + } + else { + if ( PathName[0] == DEF_SEPAR_CHAR1 || PathName[0] == DEF_SEPAR_CHAR2 ) return( CH376DirCreate( PathName ) ); + else return( ERR_MISS_DIR ); + } +} +#endif + +UINT8 CH376FileErase( PUINT8 PathName ) +{ + UINT8 s; + if ( PathName ) { + for ( s = 1; PathName[s] != DEF_SEPAR_CHAR1 && PathName[s] != DEF_SEPAR_CHAR2 && PathName[s] != 0; ++ s ); + if ( PathName[s] ) { + s = CH376FileOpenPath( PathName ); + if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s ); + } + else CH376SetFileName( PathName ); + } + return( CH376SendCmdWaitInt( CMD0H_FILE_ERASE ) ); +} + +UINT8 CH376FileClose( UINT8 UpdateSz ) +{ + return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) ); +} + +UINT8 CH376DirInfoRead( void ) +{ + return( CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, 0xFF ) ); +} + +UINT8 CH376DirInfoSave( void ) +{ + return( CH376SendCmdWaitInt( CMD0H_DIR_INFO_SAVE ) ); +} + +UINT8 CH376ByteLocate( UINT32 offset ) +{ + xWriteCH376Cmd( CMD4H_BYTE_LOCATE ); + xWriteCH376Data( (UINT8)offset ); + xWriteCH376Data( (UINT8)((UINT16)offset>>8) ); + xWriteCH376Data( (UINT8)(offset>>16) ); + xWriteCH376Data( (UINT8)(offset>>24) ); + xEndCH376Cmd( ); + return( Wait376Interrupt( ) ); +} + +UINT8 CH376ByteRead( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) +{ + UINT8 s; + xWriteCH376Cmd( CMD2H_BYTE_READ ); + xWriteCH376Data( (UINT8)ReqCount ); + xWriteCH376Data( (UINT8)(ReqCount>>8) ); + xEndCH376Cmd( ); + if ( RealCount ) *RealCount = 0; + while ( 1 ) { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_READ ) { + s = CH376ReadBlock( buf ); + xWriteCH376Cmd( CMD0H_BYTE_RD_GO ); + xEndCH376Cmd( ); + buf += s; + if ( RealCount ) *RealCount += s; + } + else return( s ); + } +} + +UINT8 CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ) +{ + UINT8 s; + xWriteCH376Cmd( CMD2H_BYTE_WRITE ); + xWriteCH376Data( (UINT8)ReqCount ); + xWriteCH376Data( (UINT8)(ReqCount>>8) ); + xEndCH376Cmd( ); + if ( RealCount ) *RealCount = 0; + while ( 1 ) { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_WRITE ) { + s = CH376WriteReqBlock( buf ); + xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); + xEndCH376Cmd( ); + buf += s; + if ( RealCount ) *RealCount += s; + } + else return( s ); + } +} + +#ifdef EN_DISK_QUERY + +UINT8 CH376DiskCapacity( PUINT32 DiskCap ) +{ + UINT8 s; + s = CH376SendCmdWaitInt( CMD0H_DISK_CAPACITY ); + if ( s == USB_INT_SUCCESS ) { + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); + *DiskCap = CH376Read32bitDat( ); + } + else *DiskCap = 0; + return( s ); +} + +UINT8 CH376DiskQuery( PUINT32 DiskFre ) +{ + UINT8 s; + UINT8 c0, c1, c2, c3; +#ifndef DEF_IC_V43_U + xWriteCH376Cmd( CMD01_GET_IC_VER ); + if ( xReadCH376Data( ) < 0x43 ) { + if ( CH376ReadVar8( VAR_DISK_STATUS ) >= DEF_DISK_READY ) CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_MOUNTED ); + } +#endif + s = CH376SendCmdWaitInt( CMD0H_DISK_QUERY ); + if ( s == USB_INT_SUCCESS ) { + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + c0 = xReadCH376Data( ); + c1 = xReadCH376Data( ); + c2 = xReadCH376Data( ); + c3 = xReadCH376Data( ); + *DiskFre = c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24; + xReadCH376Data( ); + xEndCH376Cmd( ); + } + else *DiskFre = 0; + return( s ); +} + +#endif + +UINT8 CH376SecLocate( UINT32 offset ) +{ + xWriteCH376Cmd( CMD4H_SEC_LOCATE ); + xWriteCH376Data( (UINT8)offset ); + xWriteCH376Data( (UINT8)((UINT16)offset>>8) ); + xWriteCH376Data( (UINT8)(offset>>16) ); + xWriteCH376Data( 0 ); + xEndCH376Cmd( ); + return( Wait376Interrupt( ) ); +} + +#ifdef EN_SECTOR_ACCESS + +UINT8 CH376DiskReadSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ) + +{ + UINT8 s, err; + UINT16 mBlockCount; + for ( err = 0; err != 3; ++ err ) { + xWriteCH376Cmd( CMD5H_DISK_READ ); + xWriteCH376Data( (UINT8)iLbaStart ); + xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) ); + xWriteCH376Data( iSectorCount ); + xEndCH376Cmd( ); + for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_READ ) { + s = CH376ReadBlock( buf ); + xWriteCH376Cmd( CMD0H_DISK_RD_GO ); + xEndCH376Cmd( ); + buf += s; + } + else break; + } + if ( mBlockCount == 0 ) { + s = Wait376Interrupt( ); + if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); + } + if ( s == USB_INT_DISCONNECT ) return( s ); + CH376DiskReqSense( ); + } + return( s ); +} + +UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ) +{ + UINT8 s, err; + UINT16 mBlockCount; + for ( err = 0; err != 3; ++ err ) { + xWriteCH376Cmd( CMD5H_DISK_WRITE ); + xWriteCH376Data( (UINT8)iLbaStart ); + xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) ); + xWriteCH376Data( iSectorCount ); + xEndCH376Cmd( ); + for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_WRITE ) { + CH376WriteHostBlock( buf, CH376_DAT_BLOCK_LEN ); + xWriteCH376Cmd( CMD0H_DISK_WR_GO ); + xEndCH376Cmd( ); + buf += CH376_DAT_BLOCK_LEN; + } + else break; + } + if ( mBlockCount == 0 ) { + s = Wait376Interrupt( ); + if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); + } + if ( s == USB_INT_DISCONNECT ) return( s ); + CH376DiskReqSense( ); + } + return( s ); +} + +UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) +{ + UINT8 s; + UINT8 cnt; + UINT32 StaSec; +#ifndef DEF_IC_V43_U + UINT32 fsz, fofs; +#endif + if ( RealCount ) *RealCount = 0; + do { +#ifndef DEF_IC_V43_U + xWriteCH376Cmd( CMD01_GET_IC_VER ); + cnt = xReadCH376Data( ); + if ( cnt == 0x41 ) { + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_FILE_SIZE ); + xReadCH376Data( ); + fsz = xReadCH376Data( ); + fsz |= (UINT16)(xReadCH376Data( )) << 8; + cnt = xReadCH376Data( ); + fsz |= (UINT32)cnt << 16; + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_CURRENT_OFFSET ); + xReadCH376Data( ); + fofs = xReadCH376Data( ); + fofs |= (UINT16)(xReadCH376Data( )) << 8; + fofs |= (UINT32)(xReadCH376Data( )) << 16; + if ( fsz >= fofs + 510 ) CH376WriteVar8( VAR_FILE_SIZE + 3, 0xFF ); + else cnt = 0xFF; + } + else cnt = 0xFF; +#endif + xWriteCH376Cmd( CMD1H_SEC_READ ); + xWriteCH376Data( ReqCount ); + xEndCH376Cmd( ); + s = Wait376Interrupt( ); +#ifndef DEF_IC_V43_U + if ( cnt != 0xFF ) CH376WriteVar8( VAR_FILE_SIZE + 3, cnt ); +#endif + if ( s != USB_INT_SUCCESS ) return( s ); + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); + cnt = xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + StaSec = CH376Read32bitDat( ); + if ( cnt == 0 ) break; + s = CH376DiskReadSec( buf, StaSec, cnt ); + if ( s != USB_INT_SUCCESS ) return( s ); + buf += cnt * DEF_SECTOR_SIZE; + if ( RealCount ) *RealCount += cnt; + ReqCount -= cnt; + } while ( ReqCount ); + return( s ); +} + +UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) +{ + UINT8 s; + UINT8 cnt; + UINT32 StaSec; + if ( RealCount ) *RealCount = 0; + do { + xWriteCH376Cmd( CMD1H_SEC_WRITE ); + xWriteCH376Data( ReqCount ); + xEndCH376Cmd( ); + s = Wait376Interrupt( ); + if ( s != USB_INT_SUCCESS ) return( s ); + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); + cnt = xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + StaSec = CH376Read32bitDat( ); + if ( cnt == 0 ) break; + s = CH376DiskWriteSec( buf, StaSec, cnt ); + if ( s != USB_INT_SUCCESS ) return( s ); + buf += cnt * DEF_SECTOR_SIZE; + if ( RealCount ) *RealCount += cnt; + ReqCount -= cnt; + } while ( ReqCount ); + return( s ); +} + +#endif + +#ifdef EN_LONG_NAME + +UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount ) +{ + UINT8 s; +#ifndef DEF_IC_V43_U + UINT8 c; + c = CH376ReadVar8( VAR_DISK_STATUS ); + if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_OPEN_DIR ); +#endif + xWriteCH376Cmd( CMD2H_BYTE_WRITE ); + xWriteCH376Data( (UINT8)ReqCount ); + xWriteCH376Data( (UINT8)(ReqCount>>8) ); + xEndCH376Cmd( ); + while ( 1 ) { + s = Wait376Interrupt( ); + if ( s == USB_INT_DISK_WRITE ) { + if ( buf ) buf += CH376WriteReqBlock( buf ); + else { + xWriteCH376Cmd( CMD01_WR_REQ_DATA ); + s = xReadCH376Data( ); + while ( s -- ) xWriteCH376Data( 0 ); + } + xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); + xEndCH376Cmd( ); + } + else { +#ifndef DEF_IC_V43_U + if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, c ); +#endif + return( s ); + } + } +} + +UINT8 CH376CheckNameSum( PUINT8 DirName ) +{ + UINT8 NameLen; + UINT8 CheckSum; + CheckSum = 0; + for ( NameLen = 0; NameLen != 11; NameLen ++ ) CheckSum = ( CheckSum & 1 ? 0x80 : 0x00 ) + ( CheckSum >> 1 ) + *DirName++; + return( CheckSum ); +} + +UINT8 CH376LocateInUpDir( PUINT8 PathName ) +{ + UINT8 s; + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_FAT_DIR_LBA ); + for ( s = 4; s != 8; s ++ ) GlobalBuf[ s ] = xReadCH376Data( ); + xEndCH376Cmd( ); + s = CH376SeparatePath( PathName ); + if ( s ) s = CH376FileOpenDir( PathName, s ); + else s = CH376FileOpen( "/" ); + if ( s != ERR_OPEN_DIR ) return( s ); + *(PUINT32)(&GlobalBuf[0]) = 0; + while ( 1 ) { + s = CH376SecLocate( *(PUINT32)(&GlobalBuf[0]) ); + if ( s != USB_INT_SUCCESS ) return( s ); + CH376ReadBlock( &GlobalBuf[8] ); + if ( *(PUINT32)(&GlobalBuf[8]) == *(PUINT32)(&GlobalBuf[4]) ) return( USB_INT_SUCCESS ); + xWriteCH376Cmd( CMD50_WRITE_VAR32 ); + xWriteCH376Data( VAR_FAT_DIR_LBA ); + for ( s = 8; s != 12; s ++ ) xWriteCH376Data( GlobalBuf[ s ] ); + xEndCH376Cmd( ); + ++ *(PUINT32)(&GlobalBuf[0]); + } +} + +UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName ) +{ + UINT8 s; + UINT16 NameCount; + s = CH376FileOpenPath( PathName ); + if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s ); + s = CH376DirInfoRead( ); + if ( s != USB_INT_SUCCESS ) return( s ); + CH376ReadBlock( GlobalBuf ); + CH376EndDirInfo( ); + GlobalBuf[32] = CH376CheckNameSum( GlobalBuf ); + GlobalBuf[33] = CH376ReadVar8( VAR_FILE_DIR_INDEX ); + NameCount = 0; + while ( 1 ) { + if ( GlobalBuf[33] == 0 ) { + s = CH376LocateInUpDir( PathName ); + if ( s != USB_INT_SUCCESS ) break; + if ( CH376ReadVar32( VAR_CURRENT_OFFSET ) == 0 ) { + s = ERR_LONG_NAME_ERR; + break; + } + GlobalBuf[33] = DEF_SECTOR_SIZE / sizeof( FAT_DIR_INFO ); + } + GlobalBuf[33] --; + s = CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, GlobalBuf[33] ); + if ( s != USB_INT_SUCCESS ) break; + CH376ReadBlock( GlobalBuf ); + CH376EndDirInfo( ); + if ( ( GlobalBuf[11] & ATTR_LONG_NAME_MASK ) != ATTR_LONG_NAME || GlobalBuf[13] != GlobalBuf[32] ) { + s = ERR_LONG_NAME_ERR; + break; + } + for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) { + if ( s == 1 + 5 * 2 ) s = 14; + else if ( s == 14 + 6 * 2 ) s = 28; + LongName[ NameCount++ ] = GlobalBuf[ s ]; + LongName[ NameCount++ ] = GlobalBuf[ s + 1 ]; + if ( GlobalBuf[ s ] == 0 && GlobalBuf[ s + 1 ] == 0 ) break; + if ( NameCount >= LONG_NAME_BUF_LEN ) { + s = ERR_LONG_BUF_OVER; + goto CH376GetLongNameE; + } + } + if ( GlobalBuf[0] & 0x40 ) { + if ( s >= sizeof( FAT_DIR_INFO ) ) *(PUINT16)( &LongName[ NameCount ] ) = 0x0000; + s = USB_INT_SUCCESS; + break; + } + } +CH376GetLongNameE: + CH376FileClose( FALSE ); + return( s ); +} + +UINT8 CH376CreateLongName( PUINT8 PathName, PUINT8 LongName ) +{ + UINT8 s, i; + UINT8 DirBlockCnt; + UINT16 count; + UINT16 NameCount; + UINT32 NewFileLoc; + for ( count = 0; count < LONG_NAME_BUF_LEN; count += 2 ) if ( *(PUINT16)(&LongName[count]) == 0 ) break; + if ( count == 0 || count >= LONG_NAME_BUF_LEN || count > LONE_NAME_MAX_CHAR ) return( ERR_LONG_NAME_ERR ); + DirBlockCnt = count / LONG_NAME_PER_DIR; + i = count - DirBlockCnt * LONG_NAME_PER_DIR; + if ( i ) { + if ( ++ DirBlockCnt * LONG_NAME_PER_DIR > LONG_NAME_BUF_LEN ) return( ERR_LONG_BUF_OVER ); + count += 2; + i += 2; + if ( i < LONG_NAME_PER_DIR ) { + while ( i++ < LONG_NAME_PER_DIR ) LongName[count++] = 0xFF; + } + } + s = CH376FileOpenPath( PathName ); + if ( s == USB_INT_SUCCESS ) { + s = ERR_NAME_EXIST; + goto CH376CreateLongNameE; + } + if ( s != ERR_MISS_FILE ) return( s ); + s = CH376FileCreatePath( PathName ); + if ( s != USB_INT_SUCCESS ) return( s ); + i = CH376ReadVar8( VAR_FILE_DIR_INDEX ); + s = CH376LocateInUpDir( PathName ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET ) + i * sizeof(FAT_DIR_INFO); + s = CH376ByteLocate( NewFileLoc ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + s = CH376ByteRead( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO), NULL ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + for ( i = DirBlockCnt; i != 0; -- i ) { + s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + if ( count == 0 ) break; + if ( GlobalBuf[0] && GlobalBuf[0] != 0xE5 ) { + s = CH376ByteLocate( NewFileLoc ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + GlobalBuf[ 0 ] = 0xE5; + for ( s = 1; s != sizeof(FAT_DIR_INFO); s ++ ) GlobalBuf[ s ] = GlobalBuf[ sizeof(FAT_DIR_INFO) + s ]; + s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + do { + s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + } while ( count && GlobalBuf[0] ); + NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET ); + i = DirBlockCnt + 1; + if ( count == 0 ) break; + NewFileLoc -= sizeof(FAT_DIR_INFO); + } + } + if ( i ) { + s = CH376ReadVar8( VAR_SEC_PER_CLUS ); + if ( s == 128 ) { + s = ERR_FDT_OVER; + goto CH376CreateLongNameE; + } + count = s * DEF_SECTOR_SIZE; + if ( count < i * sizeof(FAT_DIR_INFO) ) count <<= 1; + s = CH376LongNameWrite( NULL, count ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + } + s = CH376ByteLocate( NewFileLoc ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + GlobalBuf[11] = ATTR_LONG_NAME; + GlobalBuf[12] = 0x00; + GlobalBuf[13] = CH376CheckNameSum( &GlobalBuf[ sizeof(FAT_DIR_INFO) ] ); + GlobalBuf[26] = 0x00; + GlobalBuf[27] = 0x00; + for ( s = 0; DirBlockCnt != 0; ) { + GlobalBuf[0] = s ? DirBlockCnt : DirBlockCnt | 0x40; + DirBlockCnt --; + NameCount = DirBlockCnt * LONG_NAME_PER_DIR; + for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) { + if ( s == 1 + 5 * 2 ) s = 14; + else if ( s == 14 + 6 * 2 ) s = 28; + GlobalBuf[ s ] = LongName[ NameCount++ ]; + GlobalBuf[ s + 1 ] = LongName[ NameCount++ ]; + } + s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) ); + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + } + s = CH376LongNameWrite( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO) ); +CH376CreateLongNameE: + CH376FileClose( FALSE ); + return( s ); +} + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_ch376.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_ch376.h new file mode 100644 index 000000000..614f4731c --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_ch376.h @@ -0,0 +1,124 @@ +/* +* 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 k210_ch376.h + * @brief edu-riscv64 k210_ch376.h + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.10.10 + * */ + +#ifndef __CH376_FS_H__ +#define __CH376_FS_H__ + +#include "ch376inc.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "k210_uart.h" + +#define ERR_USB_UNKNOWN 0xFA + +void xEndCH376Cmd( void ); +void xWriteCH376Cmd( UINT8 mCmd ); +void xWriteCH376Data( UINT8 mData ); +UINT8 xReadCH376Data( void ); +UINT8 Query376Interrupt( void ); +UINT8 mInitCH376Host( void ); + +#define STRUCT_OFFSET( s, m ) ( (UINT8)( & ((s *)0) -> m ) ) + +#ifdef EN_LONG_NAME +#ifndef LONG_NAME_BUF_LEN +#define LONG_NAME_BUF_LEN ( LONG_NAME_PER_DIR * 20 ) +#endif +#endif + +UINT8 CH376ReadBlock( PUINT8 buf ); +UINT8 CH376WriteReqBlock( PUINT8 buf ); +void CH376WriteHostBlock( PUINT8 buf, UINT8 len ); +void CH376WriteOfsBlock( PUINT8 buf, UINT8 ofs, UINT8 len ); +void CH376SetFileName( PUINT8 name ); +UINT32 CH376Read32bitDat( void ); +UINT8 CH376ReadVar8( UINT8 var ); +void CH376WriteVar8( UINT8 var, UINT8 dat ); +UINT32 CH376ReadVar32( UINT8 var ); +void CH376WriteVar32( UINT8 var, UINT32 dat ); +void CH376EndDirInfo( void ); +UINT32 CH376GetFileSize( void ); +UINT8 CH376GetDiskStatus( void ); +UINT8 CH376GetIntStatus( void ); + +#ifndef NO_DEFAULT_CH376_INT +UINT8 Wait376Interrupt( void ); +#endif + +UINT8 CH376SendCmdWaitInt( UINT8 mCmd ); +UINT8 CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat ); +UINT8 CH376DiskReqSense( void ); +UINT8 CH376DiskConnect( void ); +UINT8 CH376DiskMount( void ); +UINT8 CH376FileOpen( PUINT8 name ); +UINT8 CH376FileCreate( PUINT8 name ); +UINT8 CH376DirCreate( PUINT8 name ); +UINT8 CH376SeparatePath( PUINT8 path ); +UINT8 CH376FileOpenDir( PUINT8 PathName, UINT8 StopName ); +UINT8 CH376FileOpenPath( PUINT8 PathName ); +UINT8 CH376FileCreatePath( PUINT8 PathName ); + +#ifdef EN_DIR_CREATE +UINT8 CH376DirCreatePath( PUINT8 PathName ); +#endif + +UINT8 CH376FileErase( PUINT8 PathName ); +UINT8 CH376FileClose( UINT8 UpdateSz ); +UINT8 CH376DirInfoRead( void ); +UINT8 CH376DirInfoSave( void ); +UINT8 CH376ByteLocate( UINT32 offset ); +UINT8 CH376ByteRead( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ); +UINT8 CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount ); + +#ifdef EN_DISK_QUERY +UINT8 CH376DiskCapacity( PUINT32 DiskCap ); +UINT8 CH376DiskQuery( PUINT32 DiskFre ); +#endif + +UINT8 CH376SecLocate( UINT32 offset ); + +#ifdef EN_SECTOR_ACCESS +UINT8 CH376DiskReadSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ); +UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ); +UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ); +UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ); +#endif + +#ifdef EN_LONG_NAME +UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount ); +UINT8 CH376CheckNameSum( PUINT8 DirName ); +UINT8 CH376LocateInUpDir( PUINT8 PathName ); +UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName ); +UINT8 CH376CreateLongName( PUINT8 PathName, PUINT8 LongName ); +#endif + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_gpio.c new file mode 100644 index 000000000..622815449 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_gpio.c @@ -0,0 +1,180 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file k210_gpio.c + * @brief edu-riscv64 k210_gpio.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.06.08 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "k210_fpioa.h" +#include "k210_gpiohs.h" + +#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Pin 1 and 2 are used for this example as GPIO outputs. */ + + + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct k210gpio_dev_s +{ + struct gpio_dev_s gpio; + uint8_t id; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +#if BOARD_NGPIOOUT > 0 +static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value); +static int gpout_write(FAR struct gpio_dev_s *dev, bool value); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if BOARD_NGPIOOUT > 0 +static const struct gpio_operations_s gpout_ops = +{ + .go_read = gpout_read, + .go_write = gpout_write, + .go_attach = NULL, + .go_enable = NULL, +}; + +/* This array maps the GPIO pins used as OUTPUT */ + +static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = +{ + GPIO_E220_M0, + GPIO_E220_M1, + GPIO_E18_MODE +}; + +static const uint32_t g_fpioa[BOARD_NGPIOOUT] = +{ + FPIOA_E220_M0, + FPIOA_E220_M1, + FPIOA_E18_MODE +}; + +static struct k210gpio_dev_s g_gpout[BOARD_NGPIOOUT]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: gpout_read + ****************************************************************************/ + +#if BOARD_NGPIOOUT > 0 +static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value) +{ + FAR struct k210gpio_dev_s *k210gpio = + (FAR struct k210gpio_dev_s *)dev; + + DEBUGASSERT(k210gpio != NULL && value != NULL); + DEBUGASSERT(k210gpio->id < BOARD_NGPIOOUT); + gpioinfo("Reading...\n"); + + *value = (int) k210_gpiohs_get_value(g_fpioa[k210gpio->id]); + return OK; +} + +/**************************************************************************** + * Name: gpout_write + ****************************************************************************/ + +static int gpout_write(FAR struct gpio_dev_s *dev, bool value) +{ + FAR struct k210gpio_dev_s *k210gpio = + (FAR struct k210gpio_dev_s *)dev; + + DEBUGASSERT(k210gpio != NULL); + DEBUGASSERT(k210gpio->id < BOARD_NGPIOOUT); + gpioinfo("Writing %d\n", (int)value); + + k210_gpiohs_set_value(g_fpioa[k210gpio->id], value); + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_gpio_init + ****************************************************************************/ + +int k210_gpio_init(void) +{ + int i; + int pincount = 0; + +#if BOARD_NGPIOOUT > 0 + for (i = 0; i < BOARD_NGPIOOUT; i++) + { + /* Setup and register the GPIO pin */ + + g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN; + g_gpout[i].gpio.gp_ops = &gpout_ops; + g_gpout[i].id = i; + gpio_pin_register(&g_gpout[i].gpio, pincount); + + /* Configure the pins that will be used as output */ + + k210_fpioa_config(g_gpiooutputs[i], + (K210_IO_FUNC_GPIOHS0 + g_fpioa[i]) | K210_IOFLAG_GPIOHS); + k210_gpiohs_set_direction(g_fpioa[i], GPIO_DM_OUTPUT); + k210_gpiohs_set_value(g_fpioa[i], false); + pincount++; + } +#endif + + return OK; +} +#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_lcd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_lcd.c new file mode 100644 index 000000000..e5a54f668 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_lcd.c @@ -0,0 +1,353 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file k210_lcd.c + * @brief LCD relative driver + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.7.21 + */ + + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include +#include "k210_fpioa.h" +#include "k210_gpiohs.h" +#include "nuttx/arch.h" +#include "nuttx/lcd/lt768.h" +#include "nuttx/lcd/lt768_lib.h" +#include "nuttx/lcd/if_port.h" +#include "nuttx/lcd/lt768_learn.h" +#include +#include +#include +#include +#ifdef CONFIG_LCD_LCDDRV_SPIIF +#include "nuttx/lcd/lcddrv_spiif.h" +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +#define NCS_H() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_HIGH); up_udelay(20) +#define NCS_L() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_LOW); up_udelay(20) +#define CLK_H() k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_HIGH); up_udelay(20) +#define CLK_L() k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_LOW); up_udelay(20) +#define MOSI_H() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_HIGH) +#define MOSI_L() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_LOW) + +static int lcd_open(FAR struct file *filep); +static int lcd_close(FAR struct file *filep); +static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen); +static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* LCD POSIX interface */ +static const struct file_operations g_lcdfops = +{ + lcd_open, + lcd_close, + lcd_read, + lcd_write, + NULL, + NULL, + NULL +}; +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void lcd_pin_init(void) +{ + k210_fpioa_config(BSP_LCD_NRST, HS_GPIO(FPIOA_LCD_NRST) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_LCD_SCLK, HS_GPIO(FPIOA_LCD_SCLK) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_LCD_MOSI, HS_GPIO(FPIOA_LCD_MOSI) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_LCD_MISO, HS_GPIO(FPIOA_LCD_MISO) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_LCD_NCS, HS_GPIO(FPIOA_LCD_NCS) | K210_IOFLAG_GPIOHS); + + k210_gpiohs_set_direction(FPIOA_LCD_MISO, GPIO_DM_INPUT); + k210_gpiohs_set_direction(FPIOA_LCD_NRST, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_LCD_SCLK, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_LCD_MOSI, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_LCD_NCS, GPIO_DM_OUTPUT); + + k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_HIGH); + k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_HIGH); + k210_gpiohs_set_value(FPIOA_LCD_NRST, GPIO_PV_HIGH); +} + +void lcd_backlight_init(bool enable) +{ + k210_fpioa_config(BSP_LCD_BL_PIN, HS_GPIO(FPIOA_LCD_BL) | K210_IOFLAG_GPIOHS); + k210_gpiohs_set_direction(FPIOA_LCD_BL, GPIO_DM_OUTPUT); + k210_gpiohs_set_value(FPIOA_LCD_BL, enable); +} + +#ifdef CONFIG_LCD_LCDDRV_SPIIF +int spiif_backlight(FAR struct lcddrv_lcd_s *lcd, int level) +{ + lcd_backlight_init(true); + return 1; +} +#endif + +uint8_t lcd_transfer_byte(uint8_t dat) +{ + uint8_t i, rx_data = 0; + + for(i = 0; i < 8; i++) + { + CLK_H(); + + // MOSI during falling edge + if((dat << i) & 0x80) + { + MOSI_H(); + } + else + { + MOSI_L(); + } + + CLK_L(); + + // MISO during rising edge + rx_data <<= 1; + if(k210_gpiohs_get_value(FPIOA_LCD_MISO)) + rx_data ++; + } + CLK_H(); + return rx_data; +} + +void LCD_CmdWrite(uint8_t cmd) +{ + NCS_L(); + lcd_transfer_byte(0x00); + lcd_transfer_byte(cmd); + NCS_H(); +} + +void LCD_DataWrite(uint8_t data) +{ + NCS_L(); + lcd_transfer_byte(0x80); + lcd_transfer_byte(data); + NCS_H(); +} + +void LCD_DataWrite_Pixel(uint8_t data) +{ + NCS_L(); + lcd_transfer_byte(0x80); + lcd_transfer_byte(data); + NCS_H(); + NCS_L(); + lcd_transfer_byte(0x80); + lcd_transfer_byte(data >> 8); + NCS_H(); +} + +uint8_t LCD_StatusRead(void) +{ + uint8_t temp = 0; + NCS_L(); + lcd_transfer_byte(0x40); + temp = lcd_transfer_byte(0xff); + NCS_H(); + return temp; +} + +uint8_t LCD_DataRead(void) +{ + uint8_t temp = 0; + NCS_L(); + lcd_transfer_byte(0xc0); + temp = lcd_transfer_byte(0xff); + NCS_H(); + return temp; +} + +/*****************************************************************************/ + +void lcd_drv_init(void) +{ + uint8_t PwmControl = 100; + + lcd_pin_init(); + lt768_init(); + Select_SFI_Dual_Mode0(); + + // PWM1 enable backlight + LT768_PWM1_Init(1, 0, 200, 100, PwmControl); + + // enable RGB output + Display_ON(); + + Main_Image_Start_Address(LCD_START_ADDR); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0, 0); + Canvas_Image_Start_address(LCD_START_ADDR); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0, 0); + Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT); + up_mdelay(10); + Canvas_Image_Start_address(LCD_START_ADDR); + + //fill blue background + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); +} + +/**************************************************************************** + * Name: k210_backlight + * + * Description: + * If CONFIG_K210_LCD_BACKLIGHT is defined, then the board-specific + * logic must provide this interface to turn the backlight on and off. + * + ****************************************************************************/ + +#ifdef CONFIG_K210_LCD_BACKLIGHT +void k210_backlight(bool blon) +{ + lcd_backlight_init(blon); +} +#endif + + +/**************************************************************************** + * Name: lcd_open + ****************************************************************************/ +static int lcd_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lcd_close + ****************************************************************************/ +static int lcd_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lcd_read + ****************************************************************************/ +static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + return OK; +} + +/**************************************************************************** + * Name: ch438_write + ****************************************************************************/ + static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +{ + ssize_t ret = buflen; + if (buffer == NULL) + { + return -ERROR; + } + LcdWriteParam * show = (LcdWriteParam *)buffer; + + /* output string */ + switch (show->type) + { + + /* output string */ + case SHOW_STRING: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + LT768_Select_Internal_Font_Init(show->string_info.height, 1, 1, 1, 1); + LT768_Print_Internal_Font_String(show->string_info.x_pos, show->string_info.y_pos, show->string_info.font_color,show->string_info.back_color,show->string_info.addr); + break; + + /* output dot */ + case SHOW_WDOT: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + LT768_DrawSquare_Fill(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos, *(uint32_t *)(show->pixel_info.pixel_color)); + break; + + /* output rgb */ + case SHOW_RGB: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_RGB(); + break; + + /* output pip */ + case SHOW_PIP: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_PIP(); + break; + + /* output Internal Font */ + case SHOW_INTERNAL_FONT: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Internal_Font(); + break; + + /* output Outside Font */ + case SHOW_OUTSIDE_FONT: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Outside_Font(); + break; + + /* output Triangle */ + case SHOW_TRIANGLE: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Triangle(); + break; + + /* output picture */ + case SHOW_PICTURE: + LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE); + Display_Picture(); + break; + + default: + ret = -ERROR; + break; + } + + return ret; +} +/**************************************************************************** + * Name: k210_lcd_initialize + * + * Description: + * Initialize the LCD. Setup backlight (initially off) + * + ****************************************************************************/ +int board_lcd_initialize(void) +{ + /* Configure the LCD backlight (and turn the backlight off) */ + lcd_backlight_init(true); + lcd_drv_init(); + up_mdelay(10); + Main_Image_Start_Address(LCD_START_ADDR); + Main_Image_Width(LCD_XSIZE_TFT); + Main_Window_Start_XY(0, 0); + Canvas_Image_Start_address(LCD_START_ADDR); + Canvas_image_width(LCD_XSIZE_TFT); + Active_Window_XY(0, 0); + Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT); + up_mdelay(10); + Canvas_Image_Start_address(LCD_START_ADDR); + /* register device */ + register_driver("/dev/lcd_dev", &g_lcdfops, 0666, NULL); + return OK; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_leds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_leds.c new file mode 100644 index 000000000..0967b6421 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_leds.c @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file k210_leds.c + * @brief edu-riscv64 k210_leds.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.06.08 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "k210_fpioa.h" +#include "k210_gpiohs.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void board_autoled_initialize(void) +{ +} + +void board_autoled_on(int led) +{ +} + +void board_autoled_off(int led) +{ +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_reset.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_reset.c new file mode 100644 index 000000000..bb96e664c --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_reset.c @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file k210_reset.c + * @brief k210_reset.c support reboot + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.06.27 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#ifdef CONFIG_BOARDCTL_RESET + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_reset + * + * Description: + * Reset board. Support for this function is required by board-level + * logic if CONFIG_BOARDCTL_RESET is selected. + * + * Input Parameters: + * status - Status information provided with the reset event. This + * meaning of this status information is board-specific. If not + * used by a board, the value zero may be provided in calls to + * board_reset(). + * + * Returned Value: + * If this function returns, then it was not possible to power-off the + * board due to some constraints. The return value int this case is a + * board-specific reason for the failure to shutdown. + * + ****************************************************************************/ +int board_reset(int status) +{ + up_systemreset(); + return 0; +} + +#endif /* CONFIG_BOARDCTL_RESET */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_touch.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_touch.c new file mode 100644 index 000000000..288de316c --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_touch.c @@ -0,0 +1,475 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file k210_touch.c + * @brief gt911 touch driver + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.10.25 + */ + + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include "k210_touch.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +static void IIC_Init(void); +static void SDA_IN(void); +static void SDA_OUT(void); +static uint8_t READ_SDA(void); +static void IIC_SCL(uint8_t val); +static void IIC_SDA(uint8_t val); +static void IIC_Start(void); +static void IIC_Stop(void); +static uint8_t IIC_Wait_Ack(void); +static void IIC_Ack(void); +static void IIC_NAck(void); +static void IIC_Send_Byte(uint8_t txd); +static uint8_t IIC_Read_Byte(uint8_t ack); +static bool GT911_Scan(POINT* point); + +static int touch_open(FAR struct file *filep); +static int touch_close(FAR struct file *filep); +static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen); +static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* touch POSIX interface */ +static const struct file_operations g_touchfops = +{ + touch_open, + touch_close, + touch_read, + touch_write, + NULL, + NULL, + NULL +}; + +/**************************************************************************** + * Name: IIC_Init + * Description: i2c pin mode configure + * input: None + * output: None + * return:none + ****************************************************************************/ +static void IIC_Init(void) +{ + /* config simluate IIC bus */ + k210_fpioa_config(BSP_IIC_SDA, GT911_FUNC_GPIO(FPIOA_IIC_SDA)); + k210_fpioa_config(BSP_IIC_SCL, GT911_FUNC_GPIO(FPIOA_IIC_SCL)); + + k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_IIC_SCL, GPIO_DM_OUTPUT); +} + +/**************************************************************************** + * Name: SDA_IN + * Description: set sda input mode + * input: None + * output: None + * return:none + ****************************************************************************/ +static void SDA_IN(void) +{ + k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_INPUT_PULL_UP); +} + +/**************************************************************************** + * Name: SDA_OUT + * Description: set sda output mode + * input: None + * output: None + * return:none + ****************************************************************************/ +static void SDA_OUT(void) +{ + k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_OUTPUT); +} + +/**************************************************************************** + * Name: READ_SDA + * Description: read sda value + * input: None + * output: None + * return: sda pin value + ****************************************************************************/ +static uint8_t READ_SDA(void) +{ + return k210_gpiohs_get_value(FPIOA_IIC_SDA); +} + +/**************************************************************************** + * Name: IIC_SCL + * Description: set the value of scl + * input: val:the value to be set + * output: None + * return: None + ****************************************************************************/ +static void IIC_SCL(uint8_t val) +{ + if (val) + k210_gpiohs_set_value(FPIOA_IIC_SCL,GPIO_PV_HIGH); + else + { + k210_gpiohs_set_value(FPIOA_IIC_SCL,GPIO_PV_LOW); + } +} + +/**************************************************************************** + * Name: IIC_SDA + * Description: set the value of sda + * input: val:the value to be set + * output: None + * return: None + ****************************************************************************/ +static void IIC_SDA(uint8_t val) +{ + if (val) + k210_gpiohs_set_value(FPIOA_IIC_SDA,GPIO_PV_HIGH); + else + { + k210_gpiohs_set_value(FPIOA_IIC_SDA,GPIO_PV_LOW); + } +} + +/**************************************************************************** + * Name: IIC_Start + * Description: Generate i2c start signal + * input: None + * output: None + * return: None + ****************************************************************************/ +static void IIC_Start(void) +{ + SDA_OUT(); + IIC_SDA(1); + IIC_SCL(1); + up_mdelay(30); + IIC_SDA(0); + up_mdelay(2); + IIC_SCL(0); +} + +/**************************************************************************** + * Name: IIC_Start + * Description: Generate i2c stop signal + * input: None + * output: None + * return: None + ****************************************************************************/ +static void IIC_Stop(void) +{ + SDA_OUT(); + IIC_SCL(1); + up_mdelay(30); + IIC_SDA(0); + up_mdelay(2); + IIC_SDA(1); +} + +/******************************************************************************************* + * Name: IIC_Wait_Ack + * Description: Wait for the reply signal to arrive + * input: None + * output: None + * return: Return value: 1:failed to receive response,0:the received response is successful. +********************************************************************************************/ +static uint8_t IIC_Wait_Ack(void) +{ + uint16_t ucErrTime=0; + SDA_IN(); + IIC_SDA(1); + IIC_SCL(1); + up_mdelay(2); + while(READ_SDA()) + { + ucErrTime++; + if(ucErrTime>2500) + { + IIC_Stop(); + return 1; + } + up_mdelay(2); + } + IIC_SCL(0); + return 0; +} + +/**************************************************************************** + * Name: IIC_Ack + * Description: generate ack response + * input: None + * output: None + * return: None + ****************************************************************************/ +static void IIC_Ack(void) +{ + IIC_SCL(0); + SDA_OUT(); + up_mdelay(2); + IIC_SDA(0); + up_mdelay(2); + IIC_SCL(1); + up_mdelay(2); + IIC_SCL(0); +} + +/**************************************************************************** + * Name: IIC_NAck + * Description: No ACK response is generated + * input: None + * output: None + * return: None + ****************************************************************************/ +static void IIC_NAck(void) +{ + IIC_SCL(0); + SDA_OUT(); + up_mdelay(2); + IIC_SDA(1); + up_mdelay(2); + IIC_SCL(1); + up_mdelay(2); + IIC_SCL(0); +} + +/**************************************************************************** + * Name: IIC_Send_Byte + * Description: IIC sends a byte,Return whether the slave has a response + * input: None + * output: None + * return: 1:there is a response,0:no response + ****************************************************************************/ +static void IIC_Send_Byte(uint8_t txd) +{ + uint8_t t; + SDA_OUT(); + IIC_SCL(0); + up_mdelay(2); + for(t=0;t<8;t++) + { + IIC_SDA((txd&0x80)>>7); + txd<<=1; + IIC_SCL(1); + up_mdelay(2); + IIC_SCL(0); + up_mdelay(2); + } +} + +/**************************************************************************** + * Name: IIC_Read_Byte + * Description: Read 1 byte, when ack=1, send ACK, when ack=0, send nACK + * input: None + * output: None + * return: Returns one byte of data read + ****************************************************************************/ +static uint8_t IIC_Read_Byte(uint8_t ack) +{ + uint8_t i,receive=0; + SDA_IN(); + up_mdelay(30); + for(i=0;i<8;i++ ) + { + IIC_SCL(0); + up_mdelay(2); + IIC_SCL(1); + up_udelay(1); + receive<<=1; + if(READ_SDA())receive++; + up_udelay(1); + } + if (!ack) + IIC_NAck(); + else + IIC_Ack(); + return receive; +} + +/*********************************************************************************** + * Name: GT911_WR_Reg + * Description: Write data to GT911 once + * input: reg: start register address,buf: data cache area,len: write data length + * output: None + * return: Return value: 0, success; 1, failure. + ***********************************************************************************/ +static uint8_t GT911_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len) +{ + uint8_t i; + uint8_t ret=0; + IIC_Start(); + IIC_Send_Byte(CT_CMD_WR); + IIC_Wait_Ack(); + IIC_Send_Byte(reg>>8); + IIC_Wait_Ack(); + IIC_Send_Byte(reg&0XFF); + IIC_Wait_Ack(); + for(i=0;i>8); + IIC_Wait_Ack(); + IIC_Send_Byte(reg&0XFF); + IIC_Wait_Ack(); + IIC_Stop(); + + IIC_Start(); + IIC_Send_Byte(CT_CMD_RD); + IIC_Wait_Ack(); + for(i=0;i 5) || (Dev_Now.TouchCount == 0) ) + { + GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1); + return false; + } + GT911_RD_Reg(GT911_READ_XY_REG + 1, &buf[1], Dev_Now.TouchCount*8); + GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1); + + for (uint8_t i = 0;i < Dev_Now.TouchCount; i++) + { + Dev_Now.Touchkeytrackid[i] = buf[1+(8*i)]; + Dev_Now.X[i] = ((uint16_t)buf[3+(8*i)] << 8) + buf[2+(8*i)]; + Dev_Now.Y[i] = ((uint16_t)buf[5+(8*i)] << 8) + buf[4+(8*i)]; + Dev_Now.S[i] = ((uint16_t)buf[7+(8*i)] << 8) + buf[6+(8*i)]; + + + if(Dev_Now.Y[i] < 20) Dev_Now.Y[i] = 20; + if(Dev_Now.Y[i] > GT911_MAX_HEIGHT -20) Dev_Now.Y[i]=GT911_MAX_HEIGHT - 20; + if(Dev_Now.X[i] < 20) Dev_Now.X[i] = 20; + if(Dev_Now.X[i] > GT911_MAX_WIDTH-20) Dev_Now.X[i] = GT911_MAX_WIDTH - 20; + point->x = Dev_Now.X[i]; + point->y = Dev_Now.Y[i]; + } + } + return true; +} + +/**************************************************************************** + * Name: touch_open + ****************************************************************************/ +static int touch_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: touch_close + ****************************************************************************/ +static int touch_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lcd_read + ****************************************************************************/ +static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen) +{ + int ret = -ERROR; + POINT touch_point = {0, 0, 0}; + + if (buffer == NULL) + { + return -ERROR; + } + + POINT* data = (POINT*)buffer; + while(1) + { + if(GT911_Scan(&touch_point)) + { + data->x = touch_point.x; + data->y = touch_point.y; + ret = buflen; + break; + } + } + return ret; +} + +/**************************************************************************** + * Name: lcd_read + ****************************************************************************/ +static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen) +{ + return OK; +} + +/*********************************************************************************** + * Name: board_touch_initialize + * Description: touch initialize + * input: None + * output: None + * return: None + ***********************************************************************************/ +void board_touch_initialize(void) +{ + IIC_Init(); + /* register device */ + register_driver("/dev/touch_dev", &g_touchfops, 0666, NULL); +} \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_touch.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_touch.h new file mode 100644 index 000000000..0956f2fce --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_touch.h @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file k210_touch.h + * @brief gt911 touch driver + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.10.25 + */ + +#ifndef _K210_TOUCH_H_ +#define _K210_TOUCH_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "k210_config.h" +#include "k210_fpioa.h" +#include "k210_gpiohs.h" +#include "nuttx/arch.h" +#include "k210_gpio_common.h" + +#define GT911_FUNC_GPIO(n) ((K210_IO_FUNC_GPIOHS0 + n) | K210_IOFLAG_GPIOHS) + +#define GT911_MAX_WIDTH (uint16_t)800 +#define GT911_MAX_HEIGHT (uint16_t)480 +#define CT_CMD_WR (uint8_t)0XBA +#define CT_CMD_RD (uint8_t)0XBB +#define CT_MAX_TOUCH (uint8_t)5 +#define GT911_COMMAND_REG (uint16_t)0x8040 +#define GT911_CONFIG_REG (uint16_t)0x8047 +#define GT911_PRODUCT_ID_REG (uint16_t)0x8140 +#define GT911_FIRMWARE_VERSION_REG (uint16_t)0x8144 +#define GT911_READ_XY_REG (uint16_t)0x814E + +typedef struct +{ + uint8_t TouchCount; + uint8_t Touchkeytrackid[CT_MAX_TOUCH]; + uint16_t X[CT_MAX_TOUCH]; + uint16_t Y[CT_MAX_TOUCH]; + uint16_t S[CT_MAX_TOUCH]; +}GT911_Dev; + +typedef struct +{ + uint16_t x; + uint16_t y; + uint16_t press; +}POINT; + +void board_touch_initialize(void); + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_w5500.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_w5500.c new file mode 100644 index 000000000..755404f91 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_w5500.c @@ -0,0 +1,840 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file k210_w5500.c +* @brief w5500 driver based on simulated SPI +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-9-14 +*/ + +#include "nuttx/arch.h" +#include "k210_w5500.h" +#include "k210_gpio_common.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ +w5500_param_t w5500_param; + +static uint8_t rx_buf[256]; +static uint8_t tx_buf[256]; + +static uint8_t config_ip_addr[] = {10, 0, 30, 50}; +static uint8_t config_ip_mask[] = {255, 255, 255, 0}; +static uint8_t config_gw_addr[] = {10, 0, 30, 1}; +static uint8_t config_mac_addr[] = {0x0C, 0x29, 0xAB, 0x7C, 0x00, 0x01}; +static uint8_t config_dst_ip[] = {10, 0, 30, 57}; +static uint16_t config_local_port = 5000; +static uint16_t config_dst_port = 6000; +static uint8_t config_mode = SOCK_TCP_CLI; + +/**************************************************************************** + * Name: spi_read_byte + * Description: Read one byte spi data returned + * input: None + * output: None + * return:Read register data + ****************************************************************************/ +static uint8_t spi_read_byte(void) +{ + uint8_t i, dat = 0; + SCLK_L(); + + for(i = 0; i < 8; i++) + { + SCLK_H(); + dat <<= 1; + dat |= k210_gpiohs_get_value(FPIOA_ENET_MISO); + up_udelay(1); + SCLK_L(); + } + + return dat; +} + +/**************************************************************************** + * Name: spi_write_byte + * Description: send 1 byte to spi + * input: data + * output: None + * return: None + ****************************************************************************/ +static void spi_write_byte(uint8_t dat) +{ + uint8_t i; + + for(i = 0; i < 8; i++) + { + SCLK_L(); + + if((dat << i) & 0x80) + { + MOSI_H(); + } + else + { + MOSI_L(); + } + + SCLK_H(); + } + + SCLK_L(); +} + +/**************************************************************************** + * Name: spi_write_short + * Description: send 2 bytes to spi + * input: data + * output: None + * return: None + ****************************************************************************/ +static void spi_write_short(uint16_t dat) +{ + spi_write_byte((uint8_t)(dat / 256)); + spi_write_byte(dat); +} + +/**************************************************************************** + * Name: w5500_write_byte + *Description: Write 1 byte data to the specified address register through SPI + *Input: reg: 16 bit register address, dat: data to be written + * output: None + * return: None + ****************************************************************************/ +static void w5500_write_byte(uint16_t reg, uint8_t dat) +{ + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM1 | RWB_WRITE | COMMON_R); + spi_write_byte(dat); + NCS_H(); +} + +/**************************************************************************** + * Name: w5500_write_short + * Description: Write 2 bytes data to the specified address register through SPI + * Input: reg: 16 bit register address, dat: data to be written + * output: None + * return: None + ****************************************************************************/ +static void w5500_write_short(uint16_t reg, uint16_t dat) +{ + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM2 | RWB_WRITE | COMMON_R); + spi_write_short(dat); + NCS_H(); +} + +/**************************************************************************** + * Name: w5500_write_bytes + * Description: Write n bytes data to the specified address register through SPI + * Input: reg: 16 bit register address, dat: data to be written,size:Length of data to be written + * output: None + * return: None + ****************************************************************************/ +static void w5500_write_bytes(uint16_t reg, uint8_t *dat, uint16_t size) +{ + uint16_t i; + NCS_L(); + spi_write_short(reg); + spi_write_byte(VDM | RWB_WRITE | COMMON_R); + + for(i = 0; i < size; i++) + { + spi_write_byte(*dat++); + } + + NCS_H(); +} + +/**************************************************************************** + * Name: w5500_write_sock_byte + * Description: Write 1 byte data to the specified port register through SPI + * Input: sock: port number, reg: 16 bit register address, dat: data to be written + * Output: None + * return: None + ****************************************************************************/ +void w5500_write_sock_byte(socket_t sock, uint16_t reg, uint8_t dat) +{ + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM1 | RWB_WRITE | (sock * 0x20 + 0x08)); + spi_write_byte(dat); + NCS_H(); +} + +/**************************************************************************** + * Name: w5500_write_sock_short + * Description: Write 2 bytes data to the specified port register through SPI + * Input: sock: port number, reg: 16 bit register address, dat: data to be written + * Output: None + * return: None + ****************************************************************************/ +void w5500_write_sock_short(socket_t sock, uint16_t reg, uint16_t dat) +{ + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM2 | RWB_WRITE | (sock * 0x20 + 0x08)); + spi_write_short(dat); + NCS_H(); +} + +/**************************************************************************** + * Name: w5500_write_sock_long + * Description: Write 4 bytes data to the specified port register through SPI + * Input: sock: port number, reg: 16 bit register address, dat: 4 byte buffer pointers to be written + * Output: None + * return: None + ****************************************************************************/ +void w5500_write_sock_long(socket_t sock, uint16_t reg, uint8_t *dat) +{ + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM4 | RWB_WRITE | (sock * 0x20 + 0x08)); + spi_write_byte(*dat++); + spi_write_byte(*dat++); + spi_write_byte(*dat++); + spi_write_byte(*dat++); + NCS_H(); +} + +/******************************************************************************* +*Function name: w5500_read_byte +*Description: Read 1 byte data of W5500 specified address register +*Input: reg: 16 bit register address +*Output: None +*Return : 1 byte data read from the register +*******************************************************************************/ +uint8_t w5500_read_byte(uint16_t reg) +{ + uint8_t val; + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM1 | RWB_READ | COMMON_R); + val = spi_read_byte(); + NCS_H(); + return val; +} + +/******************************************************************************* +*Function name: w5500_read_sock_byte +*Description: Read 1 byte data of W5500 specified port register +*Input: sock: port number, reg: 16 bit register address +*Output: None +*Return: 1 byte data read from the register +*Description: None +*******************************************************************************/ +uint8_t w5500_read_sock_byte(socket_t sock, uint16_t reg) +{ + uint8_t val; + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM1 | RWB_READ | (sock * 0x20 + 0x08)); + val = spi_read_byte(); + NCS_H(); + return val; +} + +/******************************************************************************* +*Function name: w5500_read_sock_short +*Description: Read 2 bytes of W5500 specified port register +*Input: sock: port number, reg: 16 bit register address +*Output: None +*Return: read 2 bytes of data from the register (16 bits) +*******************************************************************************/ +uint16_t w5500_read_sock_short(socket_t sock, uint16_t reg) +{ + uint16_t val; + NCS_L(); + spi_write_short(reg); + spi_write_byte(FDM2 | RWB_READ |(sock * 0x20 + 0x08)); + val = spi_read_byte(); + val *= 256; + val |= spi_read_byte(); + NCS_H(); + return val; +} + +/******************************************************************************* +*Function name: w5500_read_sock_bytes +*Description: Read data from W5500 receive data buffer +*Input: sock: port number, * dat: data saving buffer pointer +*Output: None +*Return: read data length +*******************************************************************************/ +uint16_t w5500_read_sock_bytes(socket_t sock, uint8_t *dat) +{ + uint16_t recv_size, write_addr; + uint16_t recv_addr; + uint16_t i; + uint8_t val; + recv_size = w5500_read_sock_short(sock, W5500_SN_RX_RSR_REG); + + /* no receive data */ + if(recv_size == 0) + { + return 0; + } + + if(recv_size > W5500_MAX_PACK_SIZE) + { + recv_size = W5500_MAX_PACK_SIZE; + } + + recv_addr = w5500_read_sock_short(sock, W5500_SN_RX_RD_REG); + write_addr = recv_addr; + + /* calculate physical address */ + recv_addr &= (SOCK_RECV_SIZE - 1); + NCS_L(); + spi_write_short(recv_addr); + spi_write_byte(VDM | RWB_READ | (sock * 0x20 + 0x18)); + + if((recv_addr + recv_size) < SOCK_RECV_SIZE) + { + for(i = 0; i < recv_size; i++) + { + val = spi_read_byte(); + *dat = val; + dat++; + } + } + else + { + recv_addr = SOCK_RECV_SIZE - recv_addr; + + for(i = 0; i < recv_addr; i++) + { + val = spi_read_byte(); + *dat = val; + dat++; + } + + NCS_H(); + NCS_L(); + spi_write_short(0x00); + spi_write_byte(VDM | RWB_READ | (sock * 0x20 + 0x18)); + + for(; i < recv_size; i++) + { + val= spi_read_byte(); + *dat = val; + dat++; + } + } + + NCS_H(); + write_addr += recv_size; + + w5500_write_sock_short(sock, W5500_SN_RX_RD_REG, write_addr); + /* start receive */ + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_RECV); + return recv_size; +} + +/******************************************************************************* +*Function name: w5500_write_sock_bytes +*Description: Write data to the data sending buffer of W5500 +*Input: sock: port number, dat: data storage buffer pointer, size: length of data to be written +*Output: None +*Return: None +*******************************************************************************/ +void w5500_write_sock_bytes(socket_t sock, uint8_t *dat, uint16_t size) +{ + uint16_t recv_addr, write_addr; + uint16_t i; + + /* if udp mode, set ip and port */ + if(w5500_read_sock_byte(sock, W5500_SN_MR_REG) != SOCK_UDP) + { + w5500_write_sock_long(sock, W5500_SN_DIPR_REG, w5500_param.udp_ip); + w5500_write_sock_short(sock, W5500_SN_DPORTR_REG, w5500_param.udp_port); + } + + recv_addr = w5500_read_sock_short(sock, W5500_SN_TX_WR_REG); + write_addr = recv_addr; + recv_addr &= (SOCK_SEND_SIZE - 1); + + NCS_L(); + spi_write_short(recv_addr); + spi_write_byte(VDM | RWB_WRITE | (sock * 0x20 + 0x10)); + + if((recv_addr + size) < SOCK_SEND_SIZE) + { + for(i = 0; i < size; i++) + { + spi_write_byte(*dat++); + } + } + else + { + recv_addr = SOCK_SEND_SIZE - recv_addr; + + for(i = 0; i < recv_addr; i++) + { + spi_write_byte(*dat++); + } + + NCS_H(); + NCS_L(); + + spi_write_short(0x00); + spi_write_byte(VDM | RWB_WRITE | (sock * 0x20 + 0x10)); + + for(; i < size; i++) + { + spi_write_byte(*dat++); + } + } + + NCS_H(); + write_addr += size; + + w5500_write_sock_short(sock, W5500_SN_TX_WR_REG, write_addr); + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_SEND); +} + +/******************************************************************************* +*Function name: w5500_reset +*Description: Hardware reset W5500 +*Input: None +*Output: None +*Return value: None +*Note: The reset pin of the W5500 can be encircled only when the low level is at least 500us +*******************************************************************************/ +void w5500_reset(void) +{ + uint8_t dat = 0; + + RST_L(); + RST_H(); + + /* wait connect ok */ + while((dat & LINK) == 0) + { + up_mdelay(500); + dat = w5500_read_byte(W5500_PHYCFGR_REG); + } +} + +/******************************************************************************* +*Function name: w5500_config_init +*Description: Initialize W5500 register functions +*Input: None +*Output: None +*Return value: None +*Note: Before using W5500, initialize W5500 +*******************************************************************************/ +void w5500_config_init(void) +{ + uint8_t i = 0; + + /* software reset, set 1 and auto clear 0 */ + w5500_write_byte(W5500_MR_REG, MR_RST); + up_mdelay(100); + + w5500_write_bytes(W5500_GAR_REG, w5500_param.gw_addr, 4); + w5500_write_bytes(W5500_SUBR_REG, w5500_param.ip_mask, 4); + w5500_write_bytes(W5500_SHAR_REG, w5500_param.mac_addr, 6); + w5500_write_bytes(W5500_SIPR_REG, w5500_param.ip_addr, 4); + + /* set socket rx and tx memory size 2k */ + for(i = 0; i < 8; i++) + { + w5500_write_sock_byte(i, W5500_SN_RXBUF_SIZE_REG, 0x02); + w5500_write_sock_byte(i, W5500_SN_TXBUF_SIZE_REG, 0x02); + } + + /* set retry time 200ms (0x07d0 = 2000) */ + w5500_write_short(W5500_RTR_REG, 0x07d0); + + /* retry time with 8, when exceed it, produce overtime interrupt, set W5500_SN_IR_REG(TIMEOUT) */ + w5500_write_byte(W5500_RCR_REG, 8); +} + +/******************************************************************************* +*Function name: Detect_Gateway +*Description: Check the gateway server +*Input: None +*Output: None +*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure +*******************************************************************************/ +uint8_t w5500_detect_gateway(void) +{ + uint8_t ip_addr[4] = {w5500_param.ip_addr[0] + 1, w5500_param.ip_addr[1] + 1, w5500_param.ip_addr[2] + 1, w5500_param.ip_addr[3] + 1}; + + /* check gateway and get gateway phyiscal address */ + w5500_write_sock_long(0, W5500_SN_DIPR_REG, ip_addr); + w5500_write_sock_byte(0, W5500_SN_MR_REG, SN_MR_TCP); + w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_OPEN); + up_mdelay(5); + + if(w5500_read_sock_byte(0, W5500_SN_SR_REG) != SOCK_INIT) + { + w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE); + return FALSE; + } + + /* set socket connection mode */ + w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CONNECT); + + do + { + uint8_t val = 0; + /* read socket0 interrupt register */ + val = w5500_read_sock_byte(0, W5500_SN_IR_REG); + + if(val != 0) + { + w5500_write_sock_byte(0, W5500_SN_IR_REG, val); + } + + up_mdelay(5); + + if((val & IR_TIMEOUT) == IR_TIMEOUT) + { + return FALSE; + } + else if(w5500_read_sock_byte(0, W5500_SN_DHAR_REG) != 0xff) + { + /* close socket */ + w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE); + return TRUE; + } + } while(1); + return TRUE; +} + +/******************************************************************************* +*Function name: w5500_socket_init +*Description: Specify Socket (0~7) initialization +*Input: sock: port to be initialized +*Output: None +*Return value: None +*******************************************************************************/ +void w5500_socket_init(socket_t sock) +{ + /* max partition bytes = 30 */ + w5500_write_sock_short(0, W5500_SN_MSSR_REG, 30); + + switch(sock) + { + case 0: + w5500_write_sock_short(0, W5500_SN_PORT_REG, w5500_param.sock.local_port); + w5500_write_sock_short(0, W5500_SN_DPORTR_REG, w5500_param.sock.dst_port); + w5500_write_sock_long(0, W5500_SN_DIPR_REG, w5500_param.sock.dst_ip); + break; + + default: + break; + } +} + +/******************************************************************************* +*Function name: w5500_socket_connect +*Description: Set the specified Socket (0~7) as the client to connect with the remote server +*Input: sock: port to be set +*Output: None +*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure +*******************************************************************************/ +uint8_t w5500_socket_connect(socket_t sock) +{ + w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_TCP); + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN); + up_mdelay(5); + + if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_INIT) + { + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE); + return FALSE; + } + + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CONNECT); + return TRUE; +} + +/******************************************************************************* +*Function name: w5500_socket_listen +*Description: Set the specified Socket (0~7) as the server to wait for the connection of the remote host +*Input: sock: port to be set +*Output: None +*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure +*******************************************************************************/ +uint8_t w5500_socket_listen(socket_t sock) +{ + w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_TCP); + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN); + up_mdelay(5); + + if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_INIT) + { + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE); + return FALSE; + } + + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_LISTEN); + up_mdelay(5); + + if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_LISTEN) + { + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE); + return FALSE; + } + + return TRUE; +} + +/******************************************************************************* +*Function name: w5500_socket_set_udp +*Description: Set the specified Socket (0~7) to UDP mode +*Input: sock: port to be set +*Output: None +*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure +*******************************************************************************/ +uint8_t w5500_socket_set_udp(socket_t sock) +{ + w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_UDP); + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN); + up_mdelay(5); + + if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_UDP) + { + w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE); + return FALSE; + } + return TRUE; +} + +/******************************************************************************* +*Function name: w5500_irq_process +*Description: W5500 interrupt handler framework +*Input: None +*Output: None +*Return value: None +*Description: None +*******************************************************************************/ +void w5500_irq_process(void) +{ + uint8_t ir_flag, sn_flag; + ir_flag = w5500_read_byte(W5500_SIR_REG); + do + { + /* handle socket0 event */ + if((ir_flag & S0_INT) == S0_INT) + { + sn_flag = w5500_read_sock_byte(0, W5500_SN_IR_REG); + w5500_write_sock_byte(0, W5500_SN_IR_REG, sn_flag); + + if(sn_flag & IR_CON) + { + /* socket connection finished */ + w5500_param.sock.flag |= SOCK_FLAG_CONN; + } + + if(sn_flag & IR_DISCON) + { + /* disconnect state */ + w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE); + w5500_socket_init(0); + w5500_param.sock.flag = 0; + } + + if(sn_flag & IR_SEND_OK) + { + /* send one package ok */ + w5500_param.sock.state |= SOCK_STAT_SEND; + } + + if(sn_flag & IR_RECV) + { + w5500_param.sock.state |= SOCK_STAT_RECV; + } + + if(sn_flag & IR_TIMEOUT) + { + /* close socket, connection failed */ + w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE); + w5500_param.sock.flag = 0; + } + } + ir_flag = w5500_read_byte(W5500_SIR_REG); + }while(ir_flag); +} + +/******************************************************************************* +*Function name: w5500_intialization +*Description: W5500 initial configuration +*Input: None +*Output: None +*Return value: None +*******************************************************************************/ +void w5500_intialization(void) +{ + w5500_config_init(); + w5500_detect_gateway(); + w5500_socket_init(0); +} + +/******************************************************************************* +*Function name: w5500_load_param +*Description: load param to w5500_param +*Input: None +*Output: None +*Return value: None +*******************************************************************************/ +void w5500_load_param(void) +{ + w5500_param_t *param = &w5500_param; + memcpy(param->ip_addr, config_ip_addr, sizeof(config_ip_addr)); + memcpy(param->ip_mask, config_ip_mask, sizeof(config_ip_mask)); + memcpy(param->gw_addr, config_gw_addr, sizeof(config_gw_addr)); + memcpy(param->mac_addr, config_mac_addr, sizeof(config_mac_addr)); + memcpy(param->sock.dst_ip, config_dst_ip, sizeof(config_dst_ip)); + param->sock.local_port = config_local_port; + param->sock.dst_port = config_dst_port; + param->sock.mode = config_mode; +} + +/******************************************************************************* +*Function name: w5500_socket_config +*Description: W5500 port initialization configuration +*Input: None +*Output: None +*Return value: None +*******************************************************************************/ +void w5500_socket_config(void) +{ + if(w5500_param.sock.flag == 0) + { + /* TCP Sever */ + if(w5500_param.sock.mode == SOCK_TCP_SVR) + { + if(w5500_socket_listen(0) == TRUE) + w5500_param.sock.flag = SOCK_FLAG_INIT; + else + w5500_param.sock.flag = 0; + } + + /* TCP Client */ + else if(w5500_param.sock.mode == SOCK_TCP_CLI) + { + if(w5500_socket_connect(0) == TRUE) + w5500_param.sock.flag = SOCK_FLAG_INIT; + else + w5500_param.sock.flag = 0; + } + + /* UDP */ + else + { + if(w5500_socket_set_udp(0) == TRUE) + w5500_param.sock.flag = SOCK_FLAG_INIT|SOCK_FLAG_CONN; + else + w5500_param.sock.flag = 0; + } + } +} + +/******************************************************************************* +*Function name: Process_Socket_Data +*Description: W5500 receives and sends the received data +*Input: sock: port number +*Output: None +*Return value: receive data length +*******************************************************************************/ +uint16_t Process_Socket_Data(socket_t sock) +{ + uint16_t size; + size = w5500_read_sock_bytes(sock, rx_buf); + memcpy(tx_buf, rx_buf, size); + w5500_write_sock_bytes(sock, tx_buf, size); + + return size; + +} + +/**************************************************************************** + * Name: SPI_Configuration + * Description: spi pin mode configure + * input: None + * output: None + * return:none + ****************************************************************************/ +void SPI_Configuration(void) +{ + /* config simluate SPI bus */ + k210_fpioa_config(BSP_ENET_SCLK, HS_GPIO(FPIOA_ENET_SCLK) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_ENET_NRST, HS_GPIO(FPIOA_ENET_NRST) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_ENET_MOSI, HS_GPIO(FPIOA_ENET_MOSI) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_ENET_MISO, HS_GPIO(FPIOA_ENET_MISO) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_ENET_NCS, HS_GPIO(FPIOA_ENET_NCS) | K210_IOFLAG_GPIOHS); + k210_fpioa_config(BSP_ENET_NINT, HS_GPIO(FPIOA_ENET_NINT) | K210_IOFLAG_GPIOHS); + + k210_gpiohs_set_direction(FPIOA_ENET_MISO, GPIO_DM_INPUT); + k210_gpiohs_set_direction(FPIOA_ENET_NRST, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_ENET_SCLK, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_ENET_MOSI, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_ENET_NCS, GPIO_DM_OUTPUT); + k210_gpiohs_set_direction(FPIOA_ENET_NINT, GPIO_DM_INPUT); + + k210_gpiohs_set_value(FPIOA_ENET_SCLK, GPIO_PV_HIGH); + k210_gpiohs_set_value(FPIOA_ENET_MOSI, GPIO_PV_HIGH); + k210_gpiohs_set_value(FPIOA_ENET_NCS, GPIO_PV_LOW); + k210_gpiohs_set_value(FPIOA_ENET_NRST, GPIO_PV_HIGH); +} + +void w5500_test(void) +{ + uint8_t cnt = 0; + uint8_t length = 0; + SPI_Configuration(); + w5500_load_param(); + w5500_reset(); + w5500_intialization(); + while(1) + { + w5500_socket_config(); + w5500_irq_process(); + + /* If Socket0 receives data */ + if((w5500_param.sock.state & SOCK_STAT_RECV) == SOCK_STAT_RECV) + { + w5500_param.sock.state &= ~SOCK_STAT_RECV; + length = Process_Socket_Data(0); + printf("w5500 receive: "); + for(int i = 0; i < length; i++) + { + printf("%x ", rx_buf[i]); + } + printf("\n"); + } + + /* Otherwise, send data regularly */ + else if(cnt >= 5) + { + if(w5500_param.sock.flag == (SOCK_FLAG_INIT|SOCK_FLAG_CONN)) + { + w5500_param.sock.state &= ~SOCK_STAT_SEND; + memcpy(tx_buf, "\r\nWelcome To internet!\r\n", 21); + w5500_write_sock_bytes(0, tx_buf, 21); + } + cnt = 0; + } + up_mdelay(100); + cnt++; + } + +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_w5500.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_w5500.h new file mode 100644 index 000000000..86e238b03 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/edu-riscv64/src/k210_w5500.h @@ -0,0 +1,319 @@ +/* +* Copyright (c) 2022 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file k210_w5500.h +* @brief w5500 driver +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-9-15 +*/ + +#ifndef _K210_W5500_H_ +#define _K210_W5500_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "k210_config.h" +#include "k210_fpioa.h" +#include "k210_gpiohs.h" +#include "nuttx/arch.h" +#include "k210_gpio_common.h" + +/***************** Common Register *****************/ +#define W5500_MR_REG 0x0000 +#define MR_RST 0x80 +#define MR_WOL 0x20 +#define MR_PB 0x10 +#define MR_PPP 0x08 +#define MR_FARP 0x02 + +#define W5500_GAR_REG 0x0001 +#define W5500_SUBR_REG 0x0005 +#define W5500_SHAR_REG 0x0009 +#define W5500_SIPR_REG 0x000f + +#define W5500_INT_REG 0x0013 + +#define W5500_IR_REG 0x0015 +#define IR_CONFLICT 0x80 +#define IR_UNREACH 0x40 +#define IR_PPPOE 0x20 +#define IR_MP 0x10 + +#define W5500_IMR_REG 0x0016 +#define IMR_IR7 0x80 +#define IMR_IR6 0x40 +#define IMR_IR5 0x20 +#define IMR_IR4 0x10 + +#define W5500_SIR_REG 0x0017 +#define S7_INT 0x80 +#define S6_INT 0x40 +#define S5_INT 0x20 +#define S4_INT 0x10 +#define S3_INT 0x08 +#define S2_INT 0x04 +#define S1_INT 0x02 +#define S0_INT 0x01 + +#define W5500_SIMR_REG 0x0018 +#define S7_IMR 0x80 +#define S6_IMR 0x40 +#define S5_IMR 0x20 +#define S4_IMR 0x10 +#define S3_IMR 0x08 +#define S2_IMR 0x04 +#define S1_IMR 0x02 +#define S0_IMR 0x01 + +#define W5500_RTR_REG 0x0019 +#define W5500_RCR_REG 0x001B + +#define W5500_PTIMER_REG 0x001C +#define W5500_PMAGIC_REG 0x001D +#define W5500_PHA_REG 0x001E +#define W5500_PSID_REG 0x0024 +#define W5500_PMRU_REG 0x0026 + +#define W5500_UIPR_REG 0x0028 +#define W5500_UPORT_REG 0x002C + +#define W5500_PHYCFGR_REG 0x002E +#define RST_PHY 0x80 +#define OPMODE 0x40 +#define DPX 0x04 +#define SPD 0x02 +#define LINK 0x01 + +#define W5500_VER_REG 0x0039 + +/********************* Socket Register *******************/ +#define W5500_SN_MR_REG 0x0000 +#define SN_MR_MULTI_MFEN 0x80 +#define SN_MR_BCASTB 0x40 +#define SN_MR_ND_MC_MMB 0x20 +#define SN_MR_UCASTB_MIP6B 0x10 +#define SN_MR_CLOSE 0x00 +#define SN_MR_TCP 0x01 +#define SN_MR_UDP 0x02 +#define SN_MR_MACRAW 0x04 + +#define W5500_SN_CR_REG 0x0001 +#define SN_CR_OPEN 0x01 +#define SN_CR_LISTEN 0x02 +#define SN_CR_CONNECT 0x04 +#define SN_CR_DISCON 0x08 +#define SN_CR_CLOSE 0x10 +#define SN_CR_SEND 0x20 +#define SN_CR_SEND_MAC 0x21 +#define SN_CR_SEND_KEEP 0x22 +#define SN_CR_RECV 0x40 + +#define W5500_SN_IR_REG 0x0002 +#define IR_SEND_OK 0x10 +#define IR_TIMEOUT 0x08 +#define IR_RECV 0x04 +#define IR_DISCON 0x02 +#define IR_CON 0x01 + +#define W5500_SN_SR_REG 0x0003 +#define SOCK_CLOSED 0x00 +#define SOCK_INIT 0x13 +#define SOCK_LISTEN 0x14 +#define SOCK_ESTABLISHED 0x17 +#define SOCK_CLOSE_WAIT 0x1C +#define SOCK_UDP 0x22 +#define SOCK_MACRAW 0x02 + +#define SOCK_SYNSEND 0x15 +#define SOCK_SYNRECV 0x16 +#define SOCK_FIN_WAI 0x18 +#define SOCK_CLOSING 0x1A +#define SOCK_TIME_WAIT 0x1B +#define SOCK_LAST_ACK 0x1D + +#define W5500_SN_PORT_REG 0x0004 +#define W5500_SN_DHAR_REG 0x0006 +#define W5500_SN_DIPR_REG 0x000C +#define W5500_SN_DPORTR_REG 0x0010 + +#define W5500_SN_MSSR_REG 0x0012 +#define W5500_SN_TOS_REG 0x0015 +#define W5500_SN_TTL_REG 0x0016 + +#define W5500_SN_RXBUF_SIZE_REG 0x001E +#define W5500_SN_TXBUF_SIZE_REG 0x001F +#define W5500_SN_TX_FSR_REG 0x0020 +#define W5500_SN_TX_RD_REG 0x0022 +#define W5500_SN_TX_WR_REG 0x0024 +#define W5500_SN_RX_RSR_REG 0x0026 +#define W5500_SN_RX_RD_REG 0x0028 +#define W5500_SN_RX_WR_REG 0x002A + +#define W5500_SN_IMR_REG 0x002C +#define IMR_SENDOK 0x10 +#define IMR_TIMEOUT 0x08 +#define IMR_RECV 0x04 +#define IMR_DISCON 0x02 +#define IMR_CON 0x01 + +#define W5500_SN_FRAG_REG 0x002D +#define W5500_SN_KPALVTR_REG 0x002F + +/************************ SPI Control Data *************************/ + +/* Operation mode bits */ + +#define VDM 0x00 +#define FDM1 0x01 +#define FDM2 0x02 +#define FDM4 0x03 + +/* Read_Write control bit */ +#define RWB_READ 0x00 +#define RWB_WRITE 0x04 + +/* Block select bits */ +#define COMMON_R 0x00 + +/* Socket 0 */ +#define S0_REG 0x08 +#define S0_TX_BUF 0x10 +#define S0_RX_BUF 0x18 + +/* Socket 1 */ +#define S1_REG 0x28 +#define S1_TX_BUF 0x30 +#define S1_RX_BUF 0x38 + +/* Socket 2 */ +#define S2_REG 0x48 +#define S2_TX_BUF 0x50 +#define S2_RX_BUF 0x58 + +/* Socket 3 */ +#define S3_REG 0x68 +#define S3_TX_BUF 0x70 +#define S3_RX_BUF 0x78 + +/* Socket 4 */ +#define S4_REG 0x88 +#define S4_TX_BUF 0x90 +#define S4_RX_BUF 0x98 + +/* Socket 5 */ +#define S5_REG 0xa8 +#define S5_TX_BUF 0xb0 +#define S5_RX_BUF 0xb8 + +/* Socket 6 */ +#define S6_REG 0xc8 +#define S6_TX_BUF 0xd0 +#define S6_RX_BUF 0xd8 + +/* Socket 7 */ +#define S7_REG 0xe8 +#define S7_TX_BUF 0xf0 +#define S7_RX_BUF 0xf8 + +// socket receive buffer size based on RMSR +#define SOCK_RECV_SIZE 2048 +// socket send buffer size based on RMSR +#define SOCK_SEND_SIZE 2048 + +#define W5500_IP_ADDR_LEN 4 +#define W5500_IP_MASK_LEN 4 +#define W5500_GW_ADDR_LEN 4 +#define W5500_MAC_ADDR_LEN 6 + +//for every socket + +// socket mode +#define SOCK_TCP_SVR 0 //server mode +#define SOCK_TCP_CLI 1 //client mode +#define SOCK_UDP_MOD 2 //udp mode + +// socket flag +#define SOCK_FLAG_INIT 1 +#define SOCK_FLAG_CONN 2 + +// socket data state +#define SOCK_STAT_RECV 1 +#define SOCK_STAT_SEND 2 + +typedef struct w5500_socket_s +{ + uint16_t local_port; + uint8_t dst_ip[W5500_IP_ADDR_LEN]; + uint16_t dst_port; + uint8_t mode; // 0: TCP Server; 1: TCP client; 2: UDP + uint8_t flag; // 1: init ok; 2: connected + uint8_t state; // 1: receive one; 2: send ok +}w5500_socket_t; + +typedef struct +{ + uint8_t ip_addr[W5500_IP_ADDR_LEN]; + uint8_t ip_mask[W5500_IP_MASK_LEN]; + uint8_t gw_addr[W5500_GW_ADDR_LEN]; + uint8_t mac_addr[W5500_MAC_ADDR_LEN]; + uint8_t udp_ip[4]; + uint16_t udp_port; + w5500_socket_t sock; +}w5500_param_t; + + +#define W5500_MAX_PACK_SIZE 1460 +typedef unsigned char socket_t; + +#define NCS_L() k210_gpiohs_set_value(FPIOA_ENET_NCS, GPIO_PV_LOW); up_udelay(1); +#define NCS_H() k210_gpiohs_set_value(FPIOA_ENET_NCS, GPIO_PV_HIGH); up_udelay(1); +#define SCLK_L() k210_gpiohs_set_value(FPIOA_ENET_SCLK, GPIO_PV_LOW); up_udelay(1); +#define SCLK_H() k210_gpiohs_set_value(FPIOA_ENET_SCLK, GPIO_PV_HIGH); up_udelay(1); +#define MOSI_L() k210_gpiohs_set_value(FPIOA_ENET_MOSI, GPIO_PV_LOW); up_udelay(1); +#define MOSI_H() k210_gpiohs_set_value(FPIOA_ENET_MOSI, GPIO_PV_HIGH); up_udelay(1); +#define RST_L() k210_gpiohs_set_value(FPIOA_ENET_NRST, GPIO_PV_LOW); up_mdelay(200); +#define RST_H() k210_gpiohs_set_value(FPIOA_ENET_NRST, GPIO_PV_HIGH); up_mdelay(200); + +void w5500_write_sock_byte(socket_t sock, uint16_t reg, uint8_t dat); +void w5500_write_sock_short(socket_t sock, uint16_t reg, uint16_t dat); +void w5500_write_sock_long(socket_t sock, uint16_t reg, uint8_t *dat); +uint8_t w5500_read_byte(uint16_t reg); +uint8_t w5500_read_sock_byte(socket_t sock, uint16_t reg); +uint16_t w5500_read_sock_short(socket_t sock, uint16_t reg); +void w5500_write_sock_bytes(socket_t sock, uint8_t *dat, uint16_t size); +void w5500_reset(void); +void w5500_config_init(void); +uint8_t w5500_detect_gateway(void); +void w5500_socket_init(socket_t sock); +uint8_t w5500_socket_connect(socket_t sock); +uint8_t w5500_socket_listen(socket_t sock); +uint8_t w5500_socket_set_udp(socket_t sock); +void w5500_irq_process(void); +void w5500_intialization(void); +void w5500_load_param(void); +void w5500_socket_config(void); +uint16_t Process_Socket_Data(socket_t sock); +void SPI_Configuration(void); +void w5500_test(void); + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig index 1c4b20310..423429416 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig @@ -8,8 +8,8 @@ if ARCH_BOARD_XIDATONG_RISCV64 menuconfig BSP_USING_CH376 bool "Using CH376 device" default n - select K210_16550_UART - select K210_16550_UART3 + select K210_UART + select K210_UART3 if BSP_USING_CH376 @@ -40,8 +40,8 @@ menuconfig BSP_USING_TOUCH default n menuconfig BSP_USING_CAN - select K210_16550_UART - select K210_16550_UART1 + select K210_UART + select K210_UART1 bool "Using CAN device" default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig index 88480a614..9f8bf526d 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig @@ -58,17 +58,17 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_SCHED_HPWORK=y CONFIG_DEV_GPIO=y CONFIG_BOARDCTL_RESET=y -CONFIG_K210_16550_UART=y -CONFIG_K210_16550_UART2=y -CONFIG_K210_16550_UART2_BASE=0x50220000 -CONFIG_K210_16550_UART2_CLOCK=195000000 -CONFIG_K210_16550_UART2_IRQ=39 -CONFIG_K210_16550_UART2_BAUD=115200 -CONFIG_K210_16550_UART2_PARITY=0 -CONFIG_K210_16550_UART2_BITS=8 -CONFIG_K210_16550_UART2_2STOP=0 -CONFIG_K210_16550_UART2_RXBUFSIZE=128 -CONFIG_K210_16550_UART2_TXBUFSIZE=128 +CONFIG_K210_UART=y +CONFIG_K210_UART2=y +CONFIG_K210_UART2_BASE=0x50220000 +CONFIG_K210_UART2_CLOCK=195000000 +CONFIG_K210_UART2_IRQ=39 +CONFIG_K210_UART2_BAUD=115200 +CONFIG_K210_UART2_PARITY=0 +CONFIG_K210_UART2_BITS=8 +CONFIG_K210_UART2_2STOP=0 +CONFIG_K210_UART2_RXBUFSIZE=128 +CONFIG_K210_UART2_TXBUFSIZE=128 CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y CONFIG_CONNECTION_FRAMEWORK_DEBUG=y CONFIG_CONNECTION_ADAPTER_4G=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/cannsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/cannsh/defconfig index cedd3946d..d0df672e4 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/cannsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/cannsh/defconfig @@ -58,16 +58,16 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_SCHED_HPWORK=y CONFIG_DEV_GPIO=y CONFIG_BOARDCTL_RESET=y -CONFIG_K210_16550_UART=y -CONFIG_K210_16550_UART1=y -CONFIG_K210_16550_UART1_BASE=0x50210000 -CONFIG_K210_16550_UART1_CLOCK=195000000 -CONFIG_K210_16550_UART1_IRQ=38 -CONFIG_K210_16550_UART1_BAUD=115200 -CONFIG_K210_16550_UART1_PARITY=0 -CONFIG_K210_16550_UART1_BITS=8 -CONFIG_K210_16550_UART1_2STOP=0 -CONFIG_K210_16550_UART1_RXBUFSIZE=128 -CONFIG_K210_16550_UART1_TXBUFSIZE=128 +CONFIG_K210_UART=y +CONFIG_K210_UART1=y +CONFIG_K210_UART1_BASE=0x50210000 +CONFIG_K210_UART1_CLOCK=195000000 +CONFIG_K210_UART1_IRQ=38 +CONFIG_K210_UART1_BAUD=115200 +CONFIG_K210_UART1_PARITY=0 +CONFIG_K210_UART1_BITS=8 +CONFIG_K210_UART1_2STOP=0 +CONFIG_K210_UART1_RXBUFSIZE=128 +CONFIG_K210_UART1_TXBUFSIZE=128 CONFIG_BSP_USING_CAN=y CONFIG_SERIAL_TERMIOS=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig index 67f5f8c4a..09d0c7329 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig @@ -58,6 +58,6 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_SCHED_HPWORK=y CONFIG_DEV_GPIO=y CONFIG_BOARDCTL_RESET=y -CONFIG_K210_16550_UART=y -CONFIG_K210_16550_UART3=y +CONFIG_K210_UART=y +CONFIG_K210_UART3=y CONFIG_BSP_USING_TOUCH=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/wifinsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/wifinsh/defconfig index 791657efc..327ac8b74 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/wifinsh/defconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/wifinsh/defconfig @@ -58,17 +58,17 @@ CONFIG_READLINE_TABCOMPLETION=y CONFIG_SCHED_HPWORK=y CONFIG_DEV_GPIO=y CONFIG_BOARDCTL_RESET=y -CONFIG_K210_16550_UART=y -CONFIG_K210_16550_UART1=y -CONFIG_K210_16550_UART1_BASE=0x50210000 -CONFIG_K210_16550_UART1_CLOCK=195000000 -CONFIG_K210_16550_UART1_IRQ=38 -CONFIG_K210_16550_UART1_BAUD=115200 -CONFIG_K210_16550_UART1_PARITY=0 -CONFIG_K210_16550_UART1_BITS=8 -CONFIG_K210_16550_UART1_2STOP=0 -CONFIG_K210_16550_UART1_RXBUFSIZE=128 -CONFIG_K210_16550_UART1_TXBUFSIZE=128 +CONFIG_K210_UART=y +CONFIG_K210_UART1=y +CONFIG_K210_UART1_BASE=0x50210000 +CONFIG_K210_UART1_CLOCK=195000000 +CONFIG_K210_UART1_IRQ=38 +CONFIG_K210_UART1_BAUD=115200 +CONFIG_K210_UART1_PARITY=0 +CONFIG_K210_UART1_BITS=8 +CONFIG_K210_UART1_2STOP=0 +CONFIG_K210_UART1_RXBUFSIZE=128 +CONFIG_K210_UART1_TXBUFSIZE=128 CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y CONFIG_CONNECTION_FRAMEWORK_DEBUG=y CONFIG_CONNECTION_ADAPTER_WIFI=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/can_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/can_demo.c index 9a98e1446..950b90639 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/can_demo.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/can_demo.c @@ -40,7 +40,7 @@ #include #include #include -#include "k210_uart_16550.h" +#include "k210_uart.h" #include "k210_fpioa.h" #include "k210_gpiohs.h" #include "k210_gpio_common.h" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c index 48e1f7fbc..4fd961542 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c @@ -95,7 +95,7 @@ int k210_bringup(void) board_touch_initialize(); #endif -#ifdef CONFIG_K210_16550_UART1 +#ifdef CONFIG_K210_UART1 #ifdef CONFIG_ADAPTER_ESP8285_WIFI sysctl_clock_enable(SYSCTL_CLOCK_UART1); sysctl_reset(SYSCTL_RESET_UART1); @@ -121,7 +121,7 @@ int k210_bringup(void) #endif #endif -#ifdef CONFIG_K210_16550_UART2 +#ifdef CONFIG_K210_UART2 sysctl_clock_enable(SYSCTL_CLOCK_UART2); sysctl_reset(SYSCTL_RESET_UART2); @@ -129,7 +129,7 @@ int k210_bringup(void) fpioa_set_function(GPIO_EC200T_TXD, FPOA_USART2_TX); #endif -#ifdef CONFIG_K210_16550_UART3 +#ifdef CONFIG_K210_UART3 sysctl_clock_enable(SYSCTL_CLOCK_UART3); sysctl_reset(SYSCTL_RESET_UART3); diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h index 23f6b7838..645fe97fe 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h @@ -36,7 +36,7 @@ #include #include #include -#include "k210_uart_16550.h" +#include "k210_uart.h" #define ERR_USB_UNKNOWN 0xFA diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh index ab7a4426c..7ab8bbe9c 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/build.sh @@ -18,6 +18,7 @@ cp -rf $current/apps $nuttx cp -rf $nuttx/aiit_board/aiit-arm32-board $nuttx/nuttx/boards/arm/stm32 cp -rf $nuttx/aiit_board/aiit-riscv64-board $nuttx/nuttx/boards/risc-v/k210 cp -rf $nuttx/aiit_board/xidatong-riscv64 $nuttx/nuttx/boards/risc-v/k210 +cp -rf $nuttx/aiit_board/edu-riscv64 $nuttx/nuttx/boards/risc-v/k210 cp -rf $nuttx/aiit_board/xidatong-arm32 $nuttx/nuttx/boards/arm/imxrt cp -rf $nuttx/aiit_board/hc32f4a0 $nuttx/nuttx/boards/arm/hc32 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig index bc34095b5..c4ee6ad08 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig @@ -40,13 +40,13 @@ config K210_LCD_BACKLIGHT endmenu -menuconfig K210_16550_UART - bool "K210 16550 UART Chip support" +menuconfig K210_UART + bool "K210 UART Chip support" select ARCH_HAVE_SERIAL_TERMIOS default n -if K210_16550_UART - config K210_16550_SERIAL_DISABLE_REORDERING +if K210_UART + config K210_SERIAL_DISABLE_REORDERING bool "Disable reordering of ttySx devices." default n ---help--- @@ -54,227 +54,227 @@ if K210_16550_UART console is always on /dev/ttyS0. If more than one UART is in use this can, however, have the side-effect that all port mappings (hardware USART1 -> /dev/ttyS0) change if the console is moved to another - UART. This option disables that re-ordering for 16550 UARTs. + UART. This option disables that re-ordering for UARTs. - config K210_16550_UART1 - bool "K210 16550 UART1" + config K210_UART1 + bool "K210 UART1" default n - if K210_16550_UART1 + if K210_UART1 - config K210_16550_UART1_BASE - hex "K210 16550 UART1 base address" + config K210_UART1_BASE + hex "K210 UART1 base address" default 0x50210000 - config K210_16550_UART1_CLOCK - int "K210 16550 UART1 clock" + config K210_UART1_CLOCK + int "K210 UART1 clock" default 195000000 - config K210_16550_UART1_IRQ - int "K210 16550 UART1 IRQ number" + config K210_UART1_IRQ + int "K210 UART1 IRQ number" default 38 - config K210_16550_UART1_BAUD - int "K210 16550 UART1 BAUD" + config K210_UART1_BAUD + int "K210 UART1 BAUD" default 115200 - config K210_16550_UART1_PARITY - int "K210 16550 UART1 parity" + config K210_UART1_PARITY + int "K210 UART1 parity" default 0 range 0 2 ---help--- - K210 16550 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None + K210 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None - config K210_16550_UART1_BITS - int "K210 16550 UART1 number of bits" + config K210_UART1_BITS + int "K210 UART1 number of bits" default 8 ---help--- - K210 16550 UART1 number of bits. Default: 8 + K210 UART1 number of bits. Default: 8 - config K210_16550_UART1_2STOP - int "K210 16550 UART1 two stop bits" + config K210_UART1_2STOP + int "K210 UART1 two stop bits" default 0 ---help--- 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit - config K210_16550_UART1_RXBUFSIZE - int "K210 16550 UART1 Rx buffer size" + config K210_UART1_RXBUFSIZE + int "K210 UART1 Rx buffer size" default 256 ---help--- - K210 16550 UART1 Rx buffer size. Default: 128 + K210 UART1 Rx buffer size. Default: 128 - config K210_16550_UART1_TXBUFSIZE - int "K210 16550 UART1 Tx buffer size" + config K210_UART1_TXBUFSIZE + int "K210 UART1 Tx buffer size" default 256 ---help--- - K210 16550 UART1 Tx buffer size. Default: 128 + K210 UART1 Tx buffer size. Default: 128 - config K210_16550_UART1_IFLOWCONTROL - bool "K210 16550 UART1 RTS flow control" + config K210_UART1_IFLOWCONTROL + bool "K210 UART1 RTS flow control" default n select SERIAL_IFLOWCONTROL ---help--- - Enable K210 16550 UART1 RTS flow control + Enable K210 UART1 RTS flow control - config K210_16550_UART1_OFLOWCONTROL - bool "K210 16550 UART1 CTS flow control" + config K210_UART1_OFLOWCONTROL + bool "K210 UART1 CTS flow control" default n select SERIAL_OFLOWCONTROL ---help--- - Enable K210 16550 UART1 CTS flow control + Enable K210 UART1 CTS flow control - endif # K210_16550_UART1 + endif # K210_UART1 - config K210_16550_UART2 - bool "K210 16550 UART2" + config K210_UART2 + bool "K210 UART2" default n - if K210_16550_UART2 + if K210_UART2 - config K210_16550_UART2_BASE - hex "K210 16550 UART2 base address" + config K210_UART2_BASE + hex "K210 UART2 base address" default 0x50220000 - config K210_16550_UART2_CLOCK - int "K210 16550 UART2 clock" + config K210_UART2_CLOCK + int "K210 UART2 clock" default 195000000 - config K210_16550_UART2_IRQ - int "K210 16550 UART2 IRQ number" + config K210_UART2_IRQ + int "K210 UART2 IRQ number" default 39 - config K210_16550_UART2_BAUD - int "K210 16550 UART2 BAUD" + config K210_UART2_BAUD + int "K210 UART2 BAUD" default 115200 - config K210_16550_UART2_PARITY - int "K210 16550 UART2 parity" + config K210_UART2_PARITY + int "K210 UART2 parity" default 0 range 0 2 ---help--- - K210 16550 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None + K210 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None - config K210_16550_UART2_BITS - int "K210 16550 UART2 number of bits" + config K210_UART2_BITS + int "K210 UART2 number of bits" default 8 ---help--- - K210 16550 UART2 number of bits. Default: 8 + K210 UART2 number of bits. Default: 8 - config K210_16550_UART2_2STOP - int "K210 16550 UART2 two stop bits" + config K210_UART2_2STOP + int "K210 UART2 two stop bits" default 0 ---help--- 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit - config K210_16550_UART2_RXBUFSIZE - int "K210 16550 UART2 Rx buffer size" + config K210_UART2_RXBUFSIZE + int "K210 UART2 Rx buffer size" default 256 ---help--- - K210 16550 UART2 Rx buffer size. Default: 128 + K210 UART2 Rx buffer size. Default: 128 - config K210_16550_UART2_TXBUFSIZE - int "K210 16550 UART2 Tx buffer size" + config K210_UART2_TXBUFSIZE + int "K210 UART2 Tx buffer size" default 256 ---help--- - K210 16550 UART2 Tx buffer size. Default: 128 + K210 UART2 Tx buffer size. Default: 128 - config K210_16550_UART2_IFLOWCONTROL - bool "K210 16550 UART2 RTS flow control" + config K210_UART2_IFLOWCONTROL + bool "K210 UART2 RTS flow control" default n select SERIAL_IFLOWCONTROL ---help--- - Enable K210 16550 UART2 RTS flow control + Enable K210 UART2 RTS flow control - config K210_16550_UART2_OFLOWCONTROL - bool "K210 16550 UART2 CTS flow control" + config K210_UART2_OFLOWCONTROL + bool "K210 UART2 CTS flow control" default n select SERIAL_OFLOWCONTROL ---help--- - Enable K210 16550 UART2 CTS flow control + Enable K210 UART2 CTS flow control - endif # K210_16550_UART2 + endif # K210_UART2 - config K210_16550_UART3 - bool "K210 16550 UART3" + config K210_UART3 + bool "K210 UART3" default n - if K210_16550_UART3 + if K210_UART3 - config K210_16550_UART3_BASE - hex "K210 16550 UART3 base address" + config K210_UART3_BASE + hex "K210 UART3 base address" default 0x50230000 - config K210_16550_UART3_CLOCK - int "K210 16550 UART3 clock" + config K210_UART3_CLOCK + int "K210 UART3 clock" default 195000000 - config K210_16550_UART3_IRQ - int "K210 16550 UART3 IRQ number" + config K210_UART3_IRQ + int "K210 UART3 IRQ number" default 40 - config K210_16550_UART3_BAUD - int "K210 16550 UART3 BAUD" + config K210_UART3_BAUD + int "K210 UART3 BAUD" default 115200 - config K210_16550_UART3_PARITY - int "K210 16550 UART3 parity" + config K210_UART3_PARITY + int "K210 UART3 parity" default 0 range 0 2 ---help--- - K210 16550 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None + K210 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None - config K210_16550_UART3_BITS - int "K210 16550 UART3 number of bits" + config K210_UART3_BITS + int "K210 UART3 number of bits" default 8 ---help--- - K210 16550 UART3 number of bits. Default: 8 + K210 UART3 number of bits. Default: 8 - config K210_16550_UART3_2STOP - int "K210 16550 UART3 two stop bits" + config K210_UART3_2STOP + int "K210 UART3 two stop bits" default 0 ---help--- 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit - config K210_16550_UART3_RXBUFSIZE - int "K210 16550 UART3 Rx buffer size" + config K210_UART3_RXBUFSIZE + int "K210 UART3 Rx buffer size" default 256 ---help--- - K210 16550 UART3 Rx buffer size. Default: 128 + K210 UART3 Rx buffer size. Default: 128 - config K210_16550_UART3_TXBUFSIZE - int "K210 16550 UART3 Tx buffer size" + config K210_UART3_TXBUFSIZE + int "K210 UART3 Tx buffer size" default 256 ---help--- - K210 16550 UART3 Tx buffer size. Default: 128 + K210 UART3 Tx buffer size. Default: 128 - config K210_16550_UART3_IFLOWCONTROL - bool "K210 16550 UART3 RTS flow control" + config K210_UART3_IFLOWCONTROL + bool "K210 UART3 RTS flow control" default n select SERIAL_IFLOWCONTROL ---help--- - Enable K210 16550 UART3 RTS flow control + Enable K210 UART3 RTS flow control - config K210_16550_UART3_OFLOWCONTROL - bool "K210 16550 UART3 CTS flow control" + config K210_UART3_OFLOWCONTROL + bool "K210 UART3 CTS flow control" default n select SERIAL_OFLOWCONTROL ---help--- - Enable K210 16550 UART3 CTS flow control + Enable K210 UART3 CTS flow control - endif # K210_16550_UART3 + endif # K210_UART3 - config K210_16550_SUPRESS_CONFIG - bool "Suppress K210 16550 configuration" + config K210_UART_SUPRESS_CONFIG + bool "Suppress K210 configuration" default n - config K210_16550_SUPRESS_INITIAL_CONFIG - bool "Suppress initial K210 16550 configuration" - depends on !K210_16550_SUPRESS_CONFIG + config K210_UART_SUPRESS_INITIAL_CONFIG + bool "Suppress initial K210 configuration" + depends on !K210_UART_SUPRESS_CONFIG default y ---help--- This option is useful, for example, if you are using a bootloader - that configures the K210_16550_UART. In that case, you may want to + that configures the K210_UART. In that case, you may want to just leave the existing console configuration in place. Default: n config SERIAL_UART_ARCH_MMIO @@ -285,21 +285,21 @@ if K210_16550_UART bool "Platform has own custom IOCTL" default n - config K210_16550_REGINCR - int "Address increment between K210 16550 registers" + config K210_UART_REGINCR + int "Address increment between K210 registers" default 4 ---help--- - The address increment between K210 16550 registers. Options are 1, 2, or 4. + The address increment between K210 registers. Options are 1, 2, or 4. Default: 1 - config K210_16550_REGWIDTH - int "Bit width of K210 16550 registers" + config K210_UART_REGWIDTH + int "Bit width of K210 registers" default 32 ---help--- The bit width of registers. Options are 8, 16, or 32. Default: 32 - config K210_16550_ADDRWIDTH - int "Address width of K210 16550 registers" + config K210_UART_ADDRWIDTH + int "Address width of K210 registers" default 32 ---help--- The bit width of registers. Options are 0, 8, 16, or 32. diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs index 4089b0be4..99114df86 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs @@ -57,7 +57,7 @@ CHIP_CSRCS = k210_allocateheap.c k210_clockconfig.c CHIP_CSRCS += k210_irq.c k210_irq_dispatch.c k210_systemreset.c CHIP_CSRCS += k210_lowputc.c k210_serial.c k210_fpioa.c fpioa.c CHIP_CSRCS += k210_start.c k210_timerisr.c k210_gpiohs.c k210_gpio.c -CHIP_CSRCS += k210_sysctl.c k210_uart_16550.c +CHIP_CSRCS += k210_sysctl.c k210_uart.c ifeq ($(CONFIG_BUILD_PROTECTED),y) CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c index d35ba2d02..bae546945 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c @@ -52,7 +52,7 @@ #include "k210_config.h" #include "chip.h" #include "k210.h" -#include "k210_uart_16550.h" +#include "k210_uart.h" /**************************************************************************** * Pre-processor Definitions @@ -649,9 +649,9 @@ void riscv_serialinit(void) /* Register all UARTs */ uart_register("/dev/ttyS0", &TTYS0_DEV); -#ifdef CONFIG_K210_16550_UART +#ifdef CONFIG_K210_UART /* Register UART1-UART3 */ - k210_uart_16550_register(); + k210_uart_register(); #endif } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart.c similarity index 63% rename from Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c rename to Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart.c index c52c7cde9..74e9efe9b 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart.c @@ -11,7 +11,7 @@ */ /** - * @file k210_uart_16550.c + * @file k210_uart.c * @brief k210 uart1-uart3 support * @version 1.0 * @author AIIT XUOS Lab @@ -37,13 +37,13 @@ #include #include #include -#include "k210_uart_16550.h" +#include "k210_uart.h" #ifdef CONFIG_SERIAL_TERMIOS # include #endif -#ifdef CONFIG_K210_16550_UART +#ifdef CONFIG_K210_UART /**************************************************************************** @@ -58,31 +58,31 @@ * Private Function Prototypes ****************************************************************************/ -static int k210_16550_setup(FAR struct uart_dev_s *dev); -static void k210_16550_shutdown(FAR struct uart_dev_s *dev); -static int k210_16550_attach(FAR struct uart_dev_s *dev); -static void k210_16550_detach(FAR struct uart_dev_s *dev); -static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg); -static int k210_16550_ioctl(FAR struct file *filep, int cmd, unsigned long arg); -static int k210_16550_receive(FAR struct uart_dev_s *dev, unsigned int *status); -static void k210_16550_rxint(FAR struct uart_dev_s *dev, bool enable); -static bool k210_16550_rxavailable(FAR struct uart_dev_s *dev); +static int k210_uart_setup(FAR struct uart_dev_s *dev); +static void k210_uart_shutdown(FAR struct uart_dev_s *dev); +static int k210_uart_attach(FAR struct uart_dev_s *dev); +static void k210_uart_detach(FAR struct uart_dev_s *dev); +static int k210_uart_interrupt(int irq, FAR void *context, FAR void *arg); +static int k210_uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg); +static int k210_uart_receive(FAR struct uart_dev_s *dev, unsigned int *status); +static void k210_uart_rxint(FAR struct uart_dev_s *dev, bool enable); +static bool k210_uart_rxavailable(FAR struct uart_dev_s *dev); #ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev, +static bool k210_uart_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, bool upper); #endif #ifdef CONFIG_SERIAL_TXDMA -static void k210_16550_dmasend(FAR struct uart_dev_s *dev); -static void k210_16550_dmatxavail(FAR struct uart_dev_s *dev); +static void k210_uart_dmasend(FAR struct uart_dev_s *dev); +static void k210_uart_dmatxavail(FAR struct uart_dev_s *dev); #endif #ifdef CONFIG_SERIAL_RXDMA -static void k210_16550_dmareceive(FAR struct uart_dev_s *dev); -static void k210_16550_dmarxfree(FAR struct uart_dev_s *dev); +static void k210_uart_dmareceive(FAR struct uart_dev_s *dev); +static void k210_uart_dmarxfree(FAR struct uart_dev_s *dev); #endif -static void k210_16550_send(FAR struct uart_dev_s *dev, int ch); -static void k210_16550_txint(FAR struct uart_dev_s *dev, bool enable); -static bool k210_16550_txready(FAR struct uart_dev_s *dev); -static bool k210_16550_txempty(FAR struct uart_dev_s *dev); +static void k210_uart_send(FAR struct uart_dev_s *dev, int ch); +static void k210_uart_txint(FAR struct uart_dev_s *dev, bool enable); +static bool k210_uart_txready(FAR struct uart_dev_s *dev); +static bool k210_uart_txempty(FAR struct uart_dev_s *dev); /**************************************************************************** * Private Data @@ -90,64 +90,64 @@ static bool k210_16550_txempty(FAR struct uart_dev_s *dev); static const struct uart_ops_s g_uart_ops = { - .setup = k210_16550_setup, - .shutdown = k210_16550_shutdown, - .attach = k210_16550_attach, - .detach = k210_16550_detach, - .ioctl = k210_16550_ioctl, - .receive = k210_16550_receive, - .rxint = k210_16550_rxint, - .rxavailable = k210_16550_rxavailable, + .setup = k210_uart_setup, + .shutdown = k210_uart_shutdown, + .attach = k210_uart_attach, + .detach = k210_uart_detach, + .ioctl = k210_uart_ioctl, + .receive = k210_uart_receive, + .rxint = k210_uart_rxint, + .rxavailable = k210_uart_rxavailable, #ifdef CONFIG_SERIAL_IFLOWCONTROL - .rxflowcontrol = k210_16550_rxflowcontrol, + .rxflowcontrol = k210_uart_rxflowcontrol, #endif #ifdef CONFIG_SERIAL_TXDMA - .dmasend = k210_16550_dmasend, + .dmasend = k210_uart_dmasend, #endif #ifdef CONFIG_SERIAL_RXDMA - .dmareceive = k210_16550_dmareceive, - .dmarxfree = k210_16550_dmarxfree, + .dmareceive = k210_uart_dmareceive, + .dmarxfree = k210_uart_dmarxfree, #endif #ifdef CONFIG_SERIAL_TXDMA - .dmatxavail = k210_16550_dmatxavail, + .dmatxavail = k210_uart_dmatxavail, #endif - .send = k210_16550_send, - .txint = k210_16550_txint, - .txready = k210_16550_txready, - .txempty = k210_16550_txempty, + .send = k210_uart_send, + .txint = k210_uart_txint, + .txready = k210_uart_txready, + .txempty = k210_uart_txempty, }; /* I/O buffers */ -#ifdef CONFIG_K210_16550_UART1 -static char g_uart1rxbuffer[CONFIG_K210_16550_UART1_RXBUFSIZE]; -static char g_uart1txbuffer[CONFIG_K210_16550_UART1_TXBUFSIZE]; +#ifdef CONFIG_K210_UART1 +static char g_uart1rxbuffer[CONFIG_K210_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_K210_UART1_TXBUFSIZE]; #endif -#ifdef CONFIG_K210_16550_UART2 -static char g_uart2rxbuffer[CONFIG_K210_16550_UART2_RXBUFSIZE]; -static char g_uart2txbuffer[CONFIG_K210_16550_UART2_TXBUFSIZE]; +#ifdef CONFIG_K210_UART2 +static char g_uart2rxbuffer[CONFIG_K210_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_K210_UART2_TXBUFSIZE]; #endif -#ifdef CONFIG_K210_16550_UART3 -static char g_uart3rxbuffer[CONFIG_K210_16550_UART3_RXBUFSIZE]; -static char g_uart3txbuffer[CONFIG_K210_16550_UART3_TXBUFSIZE]; +#ifdef CONFIG_K210_UART3 +static char g_uart3rxbuffer[CONFIG_K210_UART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_K210_UART3_TXBUFSIZE]; #endif -/* This describes the state of the 16550 uart1 port. */ +/* This describes the state of the uart1 port. */ -#ifdef CONFIG_K210_16550_UART1 -static struct k210_16550_s g_uart1priv = +#ifdef CONFIG_K210_UART1 +static struct k210_uart_s g_uart1priv = { - .uartbase = CONFIG_K210_16550_UART1_BASE, -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - .baud = CONFIG_K210_16550_UART1_BAUD, - .uartclk = CONFIG_K210_16550_UART1_CLOCK, + .uartbase = CONFIG_K210_UART1_BASE, +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + .baud = CONFIG_K210_UART1_BAUD, + .uartclk = CONFIG_K210_UART1_CLOCK, #endif - .irq = CONFIG_K210_16550_UART1_IRQ, -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - .parity = CONFIG_K210_16550_UART1_PARITY, - .bits = CONFIG_K210_16550_UART1_BITS, - .stopbits2 = CONFIG_K210_16550_UART1_2STOP, -#if defined(CONFIG_K210_16550_UART1_IFLOWCONTROL) || defined(CONFIG_K210_16550_UART1_OFLOWCONTROL) + .irq = CONFIG_K210_UART1_IRQ, +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + .parity = CONFIG_K210_UART1_PARITY, + .bits = CONFIG_K210_UART1_BITS, + .stopbits2 = CONFIG_K210_UART1_2STOP, +#if defined(CONFIG_K210_UART1_IFLOWCONTROL) || defined(CONFIG_K210_UART1_OFLOWCONTROL) .flow = true, #endif #endif @@ -157,12 +157,12 @@ static uart_dev_t g_uart1port = { .recv = { - .size = CONFIG_K210_16550_UART1_RXBUFSIZE, + .size = CONFIG_K210_UART1_RXBUFSIZE, .buffer = g_uart1rxbuffer, }, .xmit = { - .size = CONFIG_K210_16550_UART1_TXBUFSIZE, + .size = CONFIG_K210_UART1_TXBUFSIZE, .buffer = g_uart1txbuffer, }, .ops = &g_uart_ops, @@ -170,22 +170,22 @@ static uart_dev_t g_uart1port = }; #endif -/* This describes the state of the 16550 uart2 port. */ +/* This describes the state of the uart2 port. */ -#ifdef CONFIG_K210_16550_UART2 -static struct k210_16550_s g_uart2priv = +#ifdef CONFIG_K210_UART2 +static struct k210_uart_s g_uart2priv = { - .uartbase = CONFIG_K210_16550_UART2_BASE, -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - .baud = CONFIG_K210_16550_UART2_BAUD, - .uartclk = CONFIG_K210_16550_UART2_CLOCK, + .uartbase = CONFIG_K210_UART2_BASE, +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + .baud = CONFIG_K210_UART2_BAUD, + .uartclk = CONFIG_K210_UART2_CLOCK, #endif - .irq = CONFIG_K210_16550_UART2_IRQ, -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - .parity = CONFIG_K210_16550_UART2_PARITY, - .bits = CONFIG_K210_16550_UART2_BITS, - .stopbits2 = CONFIG_K210_16550_UART2_2STOP, -#if defined(CONFIG_K210_16550_UART2_IFLOWCONTROL) || defined(CONFIG_K210_16550_UART2_OFLOWCONTROL) + .irq = CONFIG_K210_UART2_IRQ, +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + .parity = CONFIG_K210_UART2_PARITY, + .bits = CONFIG_K210_UART2_BITS, + .stopbits2 = CONFIG_K210_UART2_2STOP, +#if defined(CONFIG_K210_UART2_IFLOWCONTROL) || defined(CONFIG_K210_UART2_OFLOWCONTROL) .flow = true, #endif #endif @@ -195,12 +195,12 @@ static uart_dev_t g_uart2port = { .recv = { - .size = CONFIG_K210_16550_UART2_RXBUFSIZE, + .size = CONFIG_K210_UART2_RXBUFSIZE, .buffer = g_uart2rxbuffer, }, .xmit = { - .size = CONFIG_K210_16550_UART2_TXBUFSIZE, + .size = CONFIG_K210_UART2_TXBUFSIZE, .buffer = g_uart2txbuffer, }, .ops = &g_uart_ops, @@ -209,22 +209,22 @@ static uart_dev_t g_uart2port = #endif -/* This describes the state of the 16550 uart1 port. */ +/* This describes the state of the uart1 port. */ -#ifdef CONFIG_K210_16550_UART3 -static struct k210_16550_s g_uart3priv = +#ifdef CONFIG_K210_UART3 +static struct k210_uart_s g_uart3priv = { - .uartbase = CONFIG_K210_16550_UART3_BASE, -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - .baud = CONFIG_K210_16550_UART3_BAUD, - .uartclk = CONFIG_K210_16550_UART3_CLOCK, + .uartbase = CONFIG_K210_UART3_BASE, +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + .baud = CONFIG_K210_UART3_BAUD, + .uartclk = CONFIG_K210_UART3_CLOCK, #endif - .irq = CONFIG_K210_16550_UART3_IRQ, -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - .parity = CONFIG_K210_16550_UART3_PARITY, - .bits = CONFIG_K210_16550_UART3_BITS, - .stopbits2 = CONFIG_K210_16550_UART3_2STOP, -#if defined(CONFIG_K210_16550_UART3_IFLOWCONTROL) || defined(CONFIG_K210_16550_UART3_OFLOWCONTROL) + .irq = CONFIG_K210_UART3_IRQ, +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + .parity = CONFIG_K210_UART3_PARITY, + .bits = CONFIG_K210_UART3_BITS, + .stopbits2 = CONFIG_K210_UART3_2STOP, +#if defined(CONFIG_K210_UART3_IFLOWCONTROL) || defined(CONFIG_K210_UART3_OFLOWCONTROL) .flow = true, #endif #endif @@ -234,12 +234,12 @@ static uart_dev_t g_uart3port = { .recv = { - .size = CONFIG_K210_16550_UART3_RXBUFSIZE, + .size = CONFIG_K210_UART3_RXBUFSIZE, .buffer = g_uart3rxbuffer, }, .xmit = { - .size = CONFIG_K210_16550_UART3_TXBUFSIZE, + .size = CONFIG_K210_UART3_TXBUFSIZE, .buffer = g_uart3txbuffer, }, .ops = &g_uart_ops, @@ -253,10 +253,10 @@ static uart_dev_t g_uart3port = ****************************************************************************/ /**************************************************************************** - * Name: k210_16550_serialin + * Name: k210_uart_serialin ****************************************************************************/ -static inline uart_datawidth_t k210_16550_serialin(FAR struct k210_16550_s *priv, +static inline uart_datawidth_t k210_uart_serialin(FAR struct k210_uart_s *priv, int offset) { #ifdef CONFIG_SERIAL_UART_ARCH_MMIO @@ -267,10 +267,10 @@ static inline uart_datawidth_t k210_16550_serialin(FAR struct k210_16550_s *priv } /**************************************************************************** - * Name: k210_16550_serialout + * Name: k210_uart_serialout ****************************************************************************/ -static inline void k210_16550_serialout(FAR struct k210_16550_s *priv, int offset, +static inline void k210_uart_serialout(FAR struct k210_uart_s *priv, int offset, uart_datawidth_t value) { #ifdef CONFIG_SERIAL_UART_ARCH_MMIO @@ -281,10 +281,10 @@ static inline void k210_16550_serialout(FAR struct k210_16550_s *priv, int offse } /**************************************************************************** - * Name: k210_16550_disableuartint + * Name: k210_uart_disableuartint ****************************************************************************/ -static inline void k210_16550_disableuartint(FAR struct k210_16550_s *priv, +static inline void k210_uart_disableuartint(FAR struct k210_uart_s *priv, FAR uart_datawidth_t *ier) { if (ier) @@ -293,28 +293,28 @@ static inline void k210_16550_disableuartint(FAR struct k210_16550_s *priv, } priv->ier &= ~UART_IER_ALLIE; - k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); + k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier); } /**************************************************************************** - * Name: k210_16550_restoreuartint + * Name: k210_uart_restoreuartint ****************************************************************************/ -static inline void k210_16550_restoreuartint(FAR struct k210_16550_s *priv, +static inline void k210_uart_restoreuartint(FAR struct k210_uart_s *priv, uint32_t ier) { priv->ier |= ier & UART_IER_ALLIE; - k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); + k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier); } /**************************************************************************** - * Name: k210_16550_enablebreaks + * Name: k210_uart_enablebreaks ****************************************************************************/ -static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv, +static inline void k210_uart_enablebreaks(FAR struct k210_uart_s *priv, bool enable) { - uint32_t lcr = k210_16550_serialin(priv, UART_LCR_OFFSET); + uint32_t lcr = k210_uart_serialin(priv, UART_LCR_OFFSET); if (enable) { @@ -325,11 +325,11 @@ static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv, lcr &= ~UART_LCR_BRK; } - k210_16550_serialout(priv, UART_LCR_OFFSET, lcr); + k210_uart_serialout(priv, UART_LCR_OFFSET, lcr); } /**************************************************************************** - * Name: k210_16550_divisor + * Name: k210_uart_divisor * * Description: * Select a divider to produce the BAUD from the UART_CLK. @@ -341,8 +341,8 @@ static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv, * ****************************************************************************/ -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG -static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv) +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG +static inline uint32_t k210_uart_divisor(FAR struct k210_uart_s *priv) { return (priv->uartclk / (uint32_t)priv->baud); // return (priv->uartclk + (priv->baud << 3)) / (priv->baud << 4); @@ -350,7 +350,7 @@ static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv) #endif /**************************************************************************** - * Name: k210_16550_setup + * Name: k210_uart_setup * * Description: * Configure the UART baud, bits, parity, fifos, etc. This @@ -359,10 +359,10 @@ static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv) * ****************************************************************************/ -static int k210_16550_setup(FAR struct uart_dev_s *dev) +static int k210_uart_setup(FAR struct uart_dev_s *dev) { -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; uint16_t div; uint8_t dlh, dll, dlf; uint32_t lcr; @@ -372,17 +372,17 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev) /* Clear fifos */ - k210_16550_serialout(priv, UART_FCR_OFFSET, + k210_uart_serialout(priv, UART_FCR_OFFSET, (UART_FCR_RXRST | UART_FCR_TXRST)); /* Set trigger */ - k210_16550_serialout(priv, UART_FCR_OFFSET, + k210_uart_serialout(priv, UART_FCR_OFFSET, (UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8)); /* Set up the IER */ - priv->ier = k210_16550_serialin(priv, UART_IER_OFFSET); + priv->ier = k210_uart_serialin(priv, UART_IER_OFFSET); /* Set up the LCR */ @@ -423,33 +423,33 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev) /* Enter DLAB=1 */ - k210_16550_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + k210_uart_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); /* Set the BAUD divisor */ - div = k210_16550_divisor(priv); + div = k210_uart_divisor(priv); dlh = div >> 12; dll = (div - (dlh << 12)) / 16; dlf = div - (dlh << 12) - dll * 16; - k210_16550_serialout(priv, UART_DLM_OFFSET, dlh); - k210_16550_serialout(priv, UART_DLL_OFFSET, dll); - k210_16550_serialout(priv, UART_DLF_OFFSET, dlf); + k210_uart_serialout(priv, UART_DLM_OFFSET, dlh); + k210_uart_serialout(priv, UART_DLL_OFFSET, dll); + k210_uart_serialout(priv, UART_DLF_OFFSET, dlf); /* Clear DLAB */ - k210_16550_serialout(priv, UART_LCR_OFFSET, lcr); + k210_uart_serialout(priv, UART_LCR_OFFSET, lcr); /* Configure the FIFOs */ - k210_16550_serialout(priv, UART_FCR_OFFSET, + k210_uart_serialout(priv, UART_FCR_OFFSET, (UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST | UART_FCR_FIFOEN)); /* Set up the auto flow control */ #if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) - mcr = k210_16550_serialin(priv, UART_MCR_OFFSET); + mcr = k210_uart_serialin(priv, UART_MCR_OFFSET); if (priv->flow) { mcr |= UART_MCR_AFCE; @@ -461,9 +461,9 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev) mcr |= UART_MCR_RTS; - k210_16550_serialout(priv, UART_MCR_OFFSET, mcr); + k210_uart_serialout(priv, UART_MCR_OFFSET, mcr); - k210_16550_serialout(priv, UART_SRT_OFFSET, 0x0); + k210_uart_serialout(priv, UART_SRT_OFFSET, 0x0); #endif /* defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) */ @@ -472,7 +472,7 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev) } /**************************************************************************** - * Name: k210_16550_shutdown + * Name: k210_uart_shutdown * * Description: * Disable the UART. This method is called when the serial @@ -480,14 +480,14 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev) * ****************************************************************************/ -static void k210_16550_shutdown(struct uart_dev_s *dev) +static void k210_uart_shutdown(struct uart_dev_s *dev) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; - k210_16550_disableuartint(priv, NULL); + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; + k210_uart_disableuartint(priv, NULL); } /**************************************************************************** - * Name: k210_16550_attach + * Name: k210_uart_attach * * Description: * Configure the UART to operation in interrupt driven mode. This method @@ -502,14 +502,14 @@ static void k210_16550_shutdown(struct uart_dev_s *dev) * ****************************************************************************/ -static int k210_16550_attach(struct uart_dev_s *dev) +static int k210_uart_attach(struct uart_dev_s *dev) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; int ret; /* Attach and enable the IRQ */ - ret = irq_attach(priv->irq, k210_16550_interrupt, dev); + ret = irq_attach(priv->irq, k210_uart_interrupt, dev); #ifndef CONFIG_ARCH_NOINTC if (ret == OK) { @@ -525,7 +525,7 @@ static int k210_16550_attach(struct uart_dev_s *dev) } /**************************************************************************** - * Name: k210_16550_detach + * Name: k210_uart_detach * * Description: * Detach UART interrupts. This method is called when the serial port is @@ -534,36 +534,36 @@ static int k210_16550_attach(struct uart_dev_s *dev) * ****************************************************************************/ -static void k210_16550_detach(FAR struct uart_dev_s *dev) +static void k210_uart_detach(FAR struct uart_dev_s *dev) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; up_disable_irq(priv->irq); irq_detach(priv->irq); } /**************************************************************************** - * Name: k210_16550_interrupt + * Name: k210_uart_interrupt * * Description: * This is the UART interrupt handler. It will be invoked when an * interrupt received on the 'irq' It should call uart_transmitchars or * uart_receivechar to perform the appropriate data transfers. The * interrupt handling logic must be able to map the 'irq' number into the - * appropriate k210_16550_s structure in order to call these functions. + * appropriate k210_uart_s structure in order to call these functions. * ****************************************************************************/ -static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg) +static int k210_uart_interrupt(int irq, FAR void *context, FAR void *arg) { FAR struct uart_dev_s *dev = (struct uart_dev_s *)arg; - FAR struct k210_16550_s *priv; + FAR struct k210_uart_s *priv; uint32_t status; int passes; uint8_t v_int_status; DEBUGASSERT(dev != NULL && dev->priv != NULL); - priv = (FAR struct k210_16550_s *)dev->priv; + priv = (FAR struct k210_uart_s *)dev->priv; /* Loop until there are no characters to be transferred or, * until we have been looping for a long time. @@ -575,7 +575,7 @@ static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg) * termination conditions */ - status = k210_16550_serialin(priv, UART_IIR_OFFSET); + status = k210_uart_serialin(priv, UART_IIR_OFFSET); if (status == 0) { @@ -603,18 +603,18 @@ static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg) } /**************************************************************************** - * Name: k210_16550_ioctl + * Name: k210_uart_ioctl * * Description: * All ioctl calls will be routed through this method * ****************************************************************************/ -static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg) +static int k210_uart_ioctl(struct file *filep, int cmd, unsigned long arg) { FAR struct inode *inode = filep->f_inode; FAR struct uart_dev_s *dev = inode->i_private; - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; int ret; #ifdef CONFIG_SERIAL_UART_ARCH_IOCTL @@ -634,14 +634,14 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg) #ifdef CONFIG_SERIAL_TIOCSERGSTRUCT case TIOCSERGSTRUCT: { - FAR struct k210_16550_s *user = (FAR struct k210_16550_s *)arg; + FAR struct k210_uart_s *user = (FAR struct k210_uart_s *)arg; if (!user) { ret = -EINVAL; } else { - memcpy(user, dev, sizeof(struct k210_16550_s)); + memcpy(user, dev, sizeof(struct k210_uart_s)); } } break; @@ -650,7 +650,7 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg) case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ { irqstate_t flags = enter_critical_section(); - k210_16550_enablebreaks(priv, true); + k210_uart_enablebreaks(priv, true); leave_critical_section(flags); } break; @@ -659,12 +659,12 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg) { irqstate_t flags; flags = enter_critical_section(); - k210_16550_enablebreaks(priv, false); + k210_uart_enablebreaks(priv, false); leave_critical_section(flags); } break; -#if defined(CONFIG_SERIAL_TERMIOS) && !defined(CONFIG_K210_16550_SUPRESS_CONFIG) +#if defined(CONFIG_SERIAL_TERMIOS) && !defined(CONFIG_K210_UART_SUPRESS_CONFIG) case TCGETS: { FAR struct termios *termiosp = (FAR struct termios *)arg; @@ -758,7 +758,7 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg) priv->flow = (termiosp->c_cflag & CRTSCTS) != 0; #endif - k210_16550_setup(dev); + k210_uart_setup(dev); leave_critical_section(flags); } break; @@ -773,7 +773,7 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg) } /**************************************************************************** - * Name: k210_16550_receive + * Name: k210_uart_receive * * Description: * Called (usually) from the interrupt level to receive one @@ -782,26 +782,26 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg) * ****************************************************************************/ -static int k210_16550_receive(struct uart_dev_s *dev, unsigned int *status) +static int k210_uart_receive(struct uart_dev_s *dev, unsigned int *status) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; uint32_t rbr = 0; - *status = k210_16550_serialin(priv, UART_LSR_OFFSET); - rbr = k210_16550_serialin(priv, UART_RBR_OFFSET); + *status = k210_uart_serialin(priv, UART_LSR_OFFSET); + rbr = k210_uart_serialin(priv, UART_RBR_OFFSET); return rbr; } /**************************************************************************** - * Name: k210_16550_rxint + * Name: k210_uart_rxint * * Description: * Call to enable or disable RX interrupts * ****************************************************************************/ -static void k210_16550_rxint(struct uart_dev_s *dev, bool enable) +static void k210_uart_rxint(struct uart_dev_s *dev, bool enable) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; if (enable) { @@ -812,25 +812,25 @@ static void k210_16550_rxint(struct uart_dev_s *dev, bool enable) priv->ier &= ~UART_IER_ERBFI; } - k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); + k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier); } /**************************************************************************** - * Name: k210_16550_rxavailable + * Name: k210_uart_rxavailable * * Description: * Return true if the receive fifo is not empty * ****************************************************************************/ -static bool k210_16550_rxavailable(struct uart_dev_s *dev) +static bool k210_uart_rxavailable(struct uart_dev_s *dev) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; - return ((k210_16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_DR) != 0); + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; + return ((k210_uart_serialin(priv, UART_LSR_OFFSET) & UART_LSR_DR) != 0); } /**************************************************************************** - * Name: k210_16550_dma* + * Name: k210_uart_dma* * * Description: * Stubbed out DMA-related methods @@ -838,11 +838,11 @@ static bool k210_16550_rxavailable(struct uart_dev_s *dev) ****************************************************************************/ #ifdef CONFIG_SERIAL_IFLOWCONTROL -static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev, +static bool k210_uart_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered, bool upper) { -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; if (priv->flow) { @@ -853,7 +853,7 @@ static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev, * input is received. */ - k210_16550_rxint(dev, !upper); + k210_uart_rxint(dev, !upper); return true; } #endif @@ -863,7 +863,7 @@ static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev, #endif /**************************************************************************** - * Name: k210_16550_dma* + * Name: k210_uart_dma* * * Description: * Stub functions used when serial DMA is enabled. @@ -871,59 +871,59 @@ static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev, ****************************************************************************/ #ifdef CONFIG_SERIAL_TXDMA -static void k210_16550_dmasend(FAR struct uart_dev_s *dev) +static void k210_uart_dmasend(FAR struct uart_dev_s *dev) { } #endif #ifdef CONFIG_SERIAL_RXDMA -static void k210_16550_dmareceive(FAR struct uart_dev_s *dev) +static void k210_uart_dmareceive(FAR struct uart_dev_s *dev) { } -static void k210_16550_dmarxfree(FAR struct uart_dev_s *dev) +static void k210_uart_dmarxfree(FAR struct uart_dev_s *dev) { } #endif #ifdef CONFIG_SERIAL_TXDMA -static void k210_16550_dmatxavail(FAR struct uart_dev_s *dev) +static void k210_uart_dmatxavail(FAR struct uart_dev_s *dev) { } #endif /**************************************************************************** - * Name: k210_16550_send + * Name: k210_uart_send * * Description: * This method will send one byte on the UART * ****************************************************************************/ -static void k210_16550_send(struct uart_dev_s *dev, int ch) +static void k210_uart_send(struct uart_dev_s *dev, int ch) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; - k210_16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch); + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; + k210_uart_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch); } /**************************************************************************** - * Name: k210_16550_txint + * Name: k210_uart_txint * * Description: * Call to enable or disable TX interrupts * ****************************************************************************/ -static void k210_16550_txint(struct uart_dev_s *dev, bool enable) +static void k210_uart_txint(struct uart_dev_s *dev, bool enable) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; irqstate_t flags; flags = enter_critical_section(); if (enable) { priv->ier |= UART_IER_ETBEI; - k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); + k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier); /* Fake a TX interrupt here by just calling uart_xmitchars() with * interrupts disabled (note this may recurse). @@ -934,38 +934,38 @@ static void k210_16550_txint(struct uart_dev_s *dev, bool enable) else { priv->ier &= ~UART_IER_ETBEI; - k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); + k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier); } leave_critical_section(flags); } /**************************************************************************** - * Name: k210_16550_txready + * Name: k210_uart_txready * * Description: * Return true if the tranmsit fifo is not full * ****************************************************************************/ -static bool k210_16550_txready(struct uart_dev_s *dev) +static bool k210_uart_txready(struct uart_dev_s *dev) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; - return (((k210_16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0)); + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; + return (((k210_uart_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0)); } /**************************************************************************** - * Name: k210_16550_txempty + * Name: k210_uart_txempty * * Description: * Return true if the transmit fifo is empty * ****************************************************************************/ -static bool k210_16550_txempty(struct uart_dev_s *dev) +static bool k210_uart_txempty(struct uart_dev_s *dev) { - FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; - return ((k210_16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_TEMT) != 0); + FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv; + return ((k210_uart_serialin(priv, UART_LSR_OFFSET) & UART_LSR_TEMT) != 0); } /**************************************************************************** @@ -973,7 +973,7 @@ static bool k210_16550_txempty(struct uart_dev_s *dev) ****************************************************************************/ /**************************************************************************** - * Name: k210_uart_16550_register + * Name: k210_uart_register * * Description: * Register serial console and serial ports. This assumes that @@ -981,20 +981,20 @@ static bool k210_16550_txempty(struct uart_dev_s *dev) * ****************************************************************************/ -void k210_uart_16550_register(void) +void k210_uart_register(void) { -#if defined(CONFIG_K210_16550_UART1) - k210_16550_setup(&g_uart1port); +#if defined(CONFIG_K210_UART1) + k210_uart_setup(&g_uart1port); uart_register("/dev/ttyS1", &g_uart1port); #endif -#if defined(CONFIG_K210_16550_UART2) - k210_16550_setup(&g_uart2port); +#if defined(CONFIG_K210_UART2) + k210_uart_setup(&g_uart2port); uart_register("/dev/ttyS2", &g_uart2port); #endif -#if defined(CONFIG_K210_16550_UART3) - k210_16550_setup(&g_uart3port); +#if defined(CONFIG_K210_UART3) + k210_uart_setup(&g_uart3port); uart_register("/dev/ttyS3", &g_uart3port); #endif } -#endif /* CONFIG_K210_16550_UART */ +#endif /* CONFIG_K210_UART */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart.h similarity index 73% rename from Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h rename to Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart.h index dbf2f4cbf..e932531de 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart.h @@ -18,8 +18,8 @@ * @date 2022.09.28 */ -#ifndef __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H -#define __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H +#ifndef __INCLUDE_NUTTX_SERIAL_UART_K210_H +#define __INCLUDE_NUTTX_SERIAL_UART_K210_H /**************************************************************************** * Included Files @@ -27,7 +27,7 @@ #include -#ifdef CONFIG_K210_16550_UART +#ifdef CONFIG_K210_UART /**************************************************************************** * Pre-processor Definitions @@ -38,7 +38,7 @@ /* Are any UARTs enabled? */ #undef HAVE_UART -#if defined(CONFIG_K210_16550_UART1) || defined(CONFIG_K210_16550_UART2) || defined(CONFIG_K210_16550_UART3) +#if defined(CONFIG_K210_UART1) || defined(CONFIG_K210_UART2) || defined(CONFIG_K210_UART3) # define HAVE_UART 1 #endif @@ -46,78 +46,78 @@ * register bit width. */ -#ifndef CONFIG_K210_16550_REGINCR -# error "CONFIG_K210_16550_REGINCR not defined" +#ifndef CONFIG_K210_UART_REGINCR +# error "CONFIG_K210_UART_REGINCR not defined" #endif -#if CONFIG_K210_16550_REGINCR != 1 && CONFIG_K210_16550_REGINCR != 2 && CONFIG_K210_16550_REGINCR != 4 -# error "CONFIG_K210_16550_REGINCR not supported" +#if CONFIG_K210_UART_REGINCR != 1 && CONFIG_K210_UART_REGINCR != 2 && CONFIG_K210_UART_REGINCR != 4 +# error "CONFIG_K210_UART_REGINCR not supported" #endif -#ifndef CONFIG_K210_16550_REGWIDTH -# error "CONFIG_K210_16550_REGWIDTH not defined" +#ifndef CONFIG_K210_UART_REGWIDTH +# error "CONFIG_K210_UART_REGWIDTH not defined" #endif -#if CONFIG_K210_16550_REGWIDTH != 8 && CONFIG_K210_16550_REGWIDTH != 16 && CONFIG_K210_16550_REGWIDTH != 32 -# error "CONFIG_K210_16550_REGWIDTH not supported" +#if CONFIG_K210_UART_REGWIDTH != 8 && CONFIG_K210_UART_REGWIDTH != 16 && CONFIG_K210_UART_REGWIDTH != 32 +# error "CONFIG_K210_UART_REGWIDTH not supported" #endif -#ifndef CONFIG_K210_16550_ADDRWIDTH -# error "CONFIG_K210_16550_ADDRWIDTH not defined" +#ifndef CONFIG_K210_UART_ADDRWIDTH +# error "CONFIG_K210_UART_ADDRWIDTH not defined" #endif -#if CONFIG_K210_16550_ADDRWIDTH != 0 && CONFIG_K210_16550_ADDRWIDTH != 8 && \ - CONFIG_K210_16550_ADDRWIDTH != 16 && CONFIG_K210_16550_ADDRWIDTH != 32 && \ - CONFIG_K210_16550_ADDRWIDTH != 64 -# error "CONFIG_K210_16550_ADDRWIDTH not supported" +#if CONFIG_K210_UART_ADDRWIDTH != 0 && CONFIG_K210_UART_ADDRWIDTH != 8 && \ + CONFIG_K210_UART_ADDRWIDTH != 16 && CONFIG_K210_UART_ADDRWIDTH != 32 && \ + CONFIG_K210_UART_ADDRWIDTH != 64 +# error "CONFIG_K210_UART_ADDRWIDTH not supported" #endif /* If a UART is enabled, then its base address, clock, and IRQ * must also be provided */ -#ifdef CONFIG_K210_16550_UART1 -# ifndef CONFIG_K210_16550_UART1_BASE -# error "CONFIG_K210_16550_UART1_BASE not provided" -# undef CONFIG_K210_16550_UART1 +#ifdef CONFIG_K210_UART1 +# ifndef CONFIG_K210_UART1_BASE +# error "CONFIG_K210_UART1_BASE not provided" +# undef CONFIG_K210_UART1 # endif -# ifndef CONFIG_K210_16550_UART1_CLOCK -# error "CONFIG_K210_16550_UART1_CLOCK not provided" -# undef CONFIG_K210_16550_UART1 +# ifndef CONFIG_K210_UART1_CLOCK +# error "CONFIG_K210_UART1_CLOCK not provided" +# undef CONFIG_K210_UART1 # endif -# ifndef CONFIG_K210_16550_UART1_IRQ -# error "CONFIG_K210_16550_UART1_IRQ not provided" -# undef CONFIG_K210_16550_UART1 +# ifndef CONFIG_K210_UART1_IRQ +# error "CONFIG_K210_UART1_IRQ not provided" +# undef CONFIG_K210_UART1 # endif #endif -#ifdef CONFIG_K210_16550_UART2 -# ifndef CONFIG_K210_16550_UART2_BASE -# error "CONFIG_K210_16550_UART2_BASE not provided" -# undef CONFIG_K210_16550_UART2 +#ifdef CONFIG_K210_UART2 +# ifndef CONFIG_K210_UART2_BASE +# error "CONFIG_K210_UART2_BASE not provided" +# undef CONFIG_K210_UART2 # endif -# ifndef CONFIG_K210_16550_UART2_CLOCK -# error "CONFIG_K210_16550_UART2_CLOCK not provided" -# undef CONFIG_K210_16550_UART2 +# ifndef CONFIG_K210_UART2_CLOCK +# error "CONFIG_K210_UART2_CLOCK not provided" +# undef CONFIG_K210_UART2 # endif -# ifndef CONFIG_K210_16550_UART2_IRQ -# error "CONFIG_K210_16550_UART2_IRQ not provided" -# undef CONFIG_K210_16550_UART2 +# ifndef CONFIG_K210_UART2_IRQ +# error "CONFIG_K210_UART2_IRQ not provided" +# undef CONFIG_K210_UART2 # endif #endif -#ifdef CONFIG_K210_16550_UART3 -# ifndef CONFIG_K210_16550_UART3_BASE -# error "CONFIG_K210_16550_UART3_BASE not provided" -# undef CONFIG_K210_16550_UART3 +#ifdef CONFIG_K210_UART3 +# ifndef CONFIG_K210_UART3_BASE +# error "CONFIG_K210_UART3_BASE not provided" +# undef CONFIG_K210_UART3 # endif -# ifndef CONFIG_K210_16550_UART3_CLOCK -# error "CONFIG_K210_16550_UART3_CLOCK not provided" -# undef CONFIG_K210_16550_UART3 +# ifndef CONFIG_K210_UART3_CLOCK +# error "CONFIG_K210_UART3_CLOCK not provided" +# undef CONFIG_K210_UART3 # endif -# ifndef CONFIG_K210_16550_UART3_IRQ -# error "CONFIG_K210_16550_UART3_IRQ not provided" -# undef CONFIG_K210_16550_UART3 +# ifndef CONFIG_K210_UART3_IRQ +# error "CONFIG_K210_UART3_IRQ not provided" +# undef CONFIG_K210_UART3 # endif #endif @@ -143,21 +143,21 @@ #define UART_DLF_INCR 48 /* Divisor factor Register*/ #define UART_CPR_INCR 61 /* Component Register */ -#define UART_RBR_OFFSET (CONFIG_K210_16550_REGINCR*UART_RBR_INCR) -#define UART_THR_OFFSET (CONFIG_K210_16550_REGINCR*UART_THR_INCR) -#define UART_DLL_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLL_INCR) -#define UART_DLM_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLM_INCR) -#define UART_IER_OFFSET (CONFIG_K210_16550_REGINCR*UART_IER_INCR) -#define UART_IIR_OFFSET (CONFIG_K210_16550_REGINCR*UART_IIR_INCR) -#define UART_FCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_FCR_INCR) -#define UART_LCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_LCR_INCR) -#define UART_MCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_MCR_INCR) -#define UART_LSR_OFFSET (CONFIG_K210_16550_REGINCR*UART_LSR_INCR) -#define UART_MSR_OFFSET (CONFIG_K210_16550_REGINCR*UART_MSR_INCR) -#define UART_SCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_SCR_INCR) -#define UART_SRT_OFFSET (CONFIG_K210_16550_REGINCR*UART_SRT_INCR) -#define UART_DLF_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLF_INCR) -#define UART_CPR_OFFSET (CONFIG_K210_16550_REGINCR*UART_CPR_INCR) +#define UART_RBR_OFFSET (CONFIG_K210_UART_REGINCR*UART_RBR_INCR) +#define UART_THR_OFFSET (CONFIG_K210_UART_REGINCR*UART_THR_INCR) +#define UART_DLL_OFFSET (CONFIG_K210_UART_REGINCR*UART_DLL_INCR) +#define UART_DLM_OFFSET (CONFIG_K210_UART_REGINCR*UART_DLM_INCR) +#define UART_IER_OFFSET (CONFIG_K210_UART_REGINCR*UART_IER_INCR) +#define UART_IIR_OFFSET (CONFIG_K210_UART_REGINCR*UART_IIR_INCR) +#define UART_FCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_FCR_INCR) +#define UART_LCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_LCR_INCR) +#define UART_MCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_MCR_INCR) +#define UART_LSR_OFFSET (CONFIG_K210_UART_REGINCR*UART_LSR_INCR) +#define UART_MSR_OFFSET (CONFIG_K210_UART_REGINCR*UART_MSR_INCR) +#define UART_SCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_SCR_INCR) +#define UART_SRT_OFFSET (CONFIG_K210_UART_REGINCR*UART_SRT_INCR) +#define UART_DLF_OFFSET (CONFIG_K210_UART_REGINCR*UART_DLF_INCR) +#define UART_CPR_OFFSET (CONFIG_K210_UART_REGINCR*UART_CPR_INCR) /* Register bit definitions *************************************************/ @@ -267,36 +267,36 @@ * Public Types ****************************************************************************/ -#if CONFIG_K210_16550_REGWIDTH == 8 +#if CONFIG_K210_UART_REGWIDTH == 8 typedef uint8_t uart_datawidth_t; -#elif CONFIG_K210_16550_REGWIDTH == 16 +#elif CONFIG_K210_UART_REGWIDTH == 16 typedef uint16_t uart_datawidth_t; -#elif CONFIG_K210_16550_REGWIDTH == 32 +#elif CONFIG_K210_UART_REGWIDTH == 32 typedef uint32_t uart_datawidth_t; #endif -#if CONFIG_K210_16550_ADDRWIDTH == 0 +#if CONFIG_K210_UART_ADDRWIDTH == 0 typedef uintptr_t uart_addrwidth_t; -#elif CONFIG_K210_16550_ADDRWIDTH == 8 +#elif CONFIG_K210_UART_ADDRWIDTH == 8 typedef uint8_t uart_addrwidth_t; -#elif CONFIG_K210_16550_ADDRWIDTH == 16 +#elif CONFIG_K210_UART_ADDRWIDTH == 16 typedef uint16_t uart_addrwidth_t; -#elif CONFIG_K210_16550_ADDRWIDTH == 32 +#elif CONFIG_K210_UART_ADDRWIDTH == 32 typedef uint32_t uart_addrwidth_t; -#elif CONFIG_K210_16550_ADDRWIDTH == 64 +#elif CONFIG_K210_UART_ADDRWIDTH == 64 typedef uint64_t uart_addrwidth_t; #endif -struct k210_16550_s +struct k210_uart_s { uart_addrwidth_t uartbase; /* Base address of UART registers */ -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG uint32_t baud; /* Configured baud */ uint32_t uartclk; /* UART clock frequency */ #endif uart_datawidth_t ier; /* Saved IER value */ uint8_t irq; /* IRQ associated with this UART */ -#ifndef CONFIG_K210_16550_SUPRESS_CONFIG +#ifndef CONFIG_K210_UART_SUPRESS_CONFIG uint8_t parity; /* 0=none, 1=odd, 2=even */ uint8_t bits; /* Number of bits (7 or 8) */ int stopbits2; /* true: Configure with 2 stop bits instead of 1 */ @@ -319,7 +319,7 @@ struct k210_16550_s * * Description: * These functions must be provided by the processor-specific code in order - * to correctly access 16550 registers + * to correctly access registers * uart_ioctl() is optional to provide custom IOCTLs * ****************************************************************************/ @@ -334,6 +334,6 @@ void uart_putreg(uart_addrwidth_t base, struct file; /* Forward reference */ int uart_ioctl(struct file *filep, int cmd, unsigned long arg); -void k210_uart_16550_register(void); -#endif /* CONFIG_K210_16550_UART */ +void k210_uart_register(void); +#endif /* CONFIG_K210_UART */ #endif /* __INCLUDE_NUTTX_SERIAL_UART_16550_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/boards/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/boards/Kconfig index 0dd66009b..41c7b0ef4 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/boards/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/boards/Kconfig @@ -702,6 +702,14 @@ config ARCH_BOARD_XIDATONG_RISCV64 This is the board configuration for the port of NuttX to the xidatong-riscv64 board. This board features the RISC-V K210 +config ARCH_BOARD_EDU_RISCV64 + bool "edu riscv64 board" + depends on ARCH_CHIP_K210 + select ARCH_HAVE_LEDS if !K210_WITH_QEMU + ---help--- + This is the board configuration for the port of NuttX to the + edu-riscv64 board. This board features the RISC-V K210 + config ARCH_BOARD_SMARTL_C906 bool "smartl evaluation board for C906" depends on ARCH_CHIP_C906 @@ -2502,6 +2510,7 @@ config ARCH_BOARD default "maix-bit" if ARCH_BOARD_MAIX_BIT default "aiit-riscv64-board" if ARCH_BOARD_AIIT_RISCV64 default "xidatong-riscv64" if ARCH_BOARD_XIDATONG_RISCV64 + default "edu-riscv64" if ARCH_BOARD_EDU_RISCV64 default "smartl-c906" if ARCH_BOARD_SMARTL_C906 default "icicle" if ARCH_BOARD_ICICLE_MPFS default "m100pfsevp" if ARCH_BOARD_M100PFSEVP_MPFS @@ -3338,6 +3347,9 @@ endif if ARCH_BOARD_XIDATONG_RISCV64 source "boards/risc-v/k210/xidatong-riscv64/Kconfig" endif +if ARCH_BOARD_EDU_RISCV64 +source "boards/risc-v/k210/edu-riscv64/Kconfig" +endif if ARCH_BOARD_SMARTL_C906 source "boards/risc-v/c906/smartl-c906/Kconfig" endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c index 1f37845f3..ad4ec5406 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -14,47 +14,51 @@ */ /** -* @file board.c -* @brief support kd233-board init configure and start-up -* @version 1.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file board.c + * @brief support kd233-board init configure and start-up + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: board.c Description: support edu-riscv64-board init configure and driver/task/... init Others: https://canaan-creative.com/developer -History: +History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab -Modification: +Modification: 1. support edu-riscv64-board InitBoardHardware 2. support edu-riscv64-board Kd233Start 3. support edu-riscv64-board shell cmd, include reboot, shutdown *************************************************/ -#include +#include "board.h" + #include #include -#include "board.h" -#include "tick.h" +#include + +#include "connect_gpio.h" +#include "connect_hwtimer.h" +#include "connect_rtc.h" +#include "connect_soft_spi.h" #include "connect_uart.h" +#include "connect_w5500.h" +#include "connect_wdt.h" +#include "connect_dvp.h" +#include "dmac.h" #include "encoding.h" #include "fpioa.h" -#include "dmac.h" -#include "connect_gpio.h" -#include "connect_soft_spi.h" -#include "connect_rtc.h" -#include "connect_hwtimer.h" -#include "connect_wdt.h" +#include "tick.h" // #if defined(FS_VFS) // #include // #endif -#define CPU0 (0) -#define CPU1 (1) +#define CPU0 (0) +#define CPU1 (1) extern x_base cpu2_boot_flag; extern void entry(void); extern void SecondaryCpuCStart(void); @@ -65,6 +69,7 @@ extern int HwCh376Init(void); extern int HwLcdInit(void); extern int HwSpiInit(void); extern int HwSoftSPIInit(void); +extern int HwWiznetInit(void); #include #ifdef MOUNT_USB @@ -72,199 +77,206 @@ extern int HwSoftSPIInit(void); * @description: Mount USB * @return 0 */ -int MountUsb(void) -{ - if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0) - KPrintf("usb mount to '/'\n"); - else - KPrintf("usb mount to '/' failed!\n"); - - return 0; +int MountUsb(void) { + if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, + FSTYPE_CH376, "/") == 0) + KPrintf("usb mount to '/'\n"); + else + KPrintf("usb mount to '/' failed!\n"); + + return 0; } #endif -#if defined(FS_VFS) && defined (MOUNT_SDCARD) +#if defined(FS_VFS) && defined(MOUNT_SDCARD) #include #include -extern SpiSdDeviceType SpiSdInit(struct Bus *bus, const char *dev_name, const char *drv_name, const char *sd_name); +extern SpiSdDeviceType SpiSdInit(struct Bus *bus, const char *dev_name, + const char *drv_name, const char *sd_name); /** * @description: Mount SD card * @return 0 */ -int MountSDCard(void) -{ - struct Bus *spi_bus; - spi_bus = BusFind(SOFT_SPI_BUS_NAME); - if (NONE == SpiSdInit(spi_bus, SOFT_SPI_DEVICE_NAME, SOFT_SPI_DRV_NAME, SPI_SD_NAME)) { - KPrintf("MountSDCard SpiSdInit error!\n"); - return -1; - } - if (EOK != MountFilesystem(SOFT_SPI_BUS_NAME, SPI_SD_NAME, SOFT_SPI_DRV_NAME, FSTYPE_FATFS, "/")) { - return -1; - } +int MountSDCard(void) { + struct Bus *spi_bus; + spi_bus = BusFind(SOFT_SPI_BUS_NAME); + if (NONE == SpiSdInit(spi_bus, SOFT_SPI_DEVICE_NAME, SOFT_SPI_DRV_NAME, + SPI_SD_NAME)) { + KPrintf("MountSDCard SpiSdInit error!\n"); + return -1; + } + if (EOK != MountFilesystem(SOFT_SPI_BUS_NAME, SPI_SD_NAME, SOFT_SPI_DRV_NAME, + FSTYPE_FATFS, "/")) { + return -1; + } - KPrintf("SPI SD card fatfs mounted\n"); - return 0; + KPrintf("SPI SD card fatfs mounted\n"); + return 0; } #endif +void InitBss(void) { + unsigned int *dst; - -void InitBss(void) -{ - unsigned int *dst; - - dst = &__bss_start; - while (dst < &__bss_end){ - *dst++ = 0; - } + dst = &__bss_start; + while (dst < &__bss_end) { + *dst++ = 0; + } } -void Kd233Start(uint32_t mhartid) -{ - switch(mhartid) { - case CPU0: - InitBss(); +void Kd233Start(uint32_t mhartid) { + switch (mhartid) { + case CPU0: + InitBss(); - /*kernel start entry*/ - entry(); - break; - case CPU1: - while(0x2018050420191010 != cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core + /*kernel start entry*/ + entry(); + break; + case CPU1: + while (0x2018050420191010 != + cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core #ifndef ARCH_SMP - asm volatile("wfi"); + asm volatile("wfi"); #endif - } + } #ifdef ARCH_SMP - SecondaryCpuCStart(); + SecondaryCpuCStart(); #endif - break; + break; - default: - break; - } + default: + break; + } } -int Freq(void) -{ - uint64 value = 0; +int Freq(void) { + uint64 value = 0; - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); - KPrintf("PLL0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); - KPrintf("PLL1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); - KPrintf("PLL2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); - KPrintf("CPU : %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); - KPrintf("APB0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); - KPrintf("APB1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); - KPrintf("APB2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); - KPrintf("HCLK: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); + KPrintf("PLL0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); + KPrintf("PLL1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); + KPrintf("PLL2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + KPrintf("CPU : %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + KPrintf("APB0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + KPrintf("APB1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); + KPrintf("APB2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); + KPrintf("HCLK: %d\n", value); - value = clint_get_time(); - KPrintf("mtime: %d\n", value); + value = clint_get_time(); + KPrintf("mtime: %d\n", value); - return 0; + return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Freq, Freq, show frequency information ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Freq, Freq, show frequency information); #ifdef ARCH_SMP extern int EnableHwclintIpi(void); #endif -struct InitSequenceDesc _board_init[] = -{ +struct InitSequenceDesc _board_init[] = { #ifdef BSP_USING_GPIO - { "hw_pin", HwGpioInit }, - { "io_config", IoConfigInit }, + {"hw_pin", HwGpioInit}, + {"io_config", IoConfigInit}, #endif #ifdef BSP_USING_I2C - { "hw_i2c", HwI2cInit }, + {"hw_i2c", HwI2cInit}, #endif #ifdef BSP_USING_RTC - { "hw_rtc", HwRtcInit }, + {"hw_rtc", HwRtcInit}, #endif #ifdef BSP_USING_SPI - { "hw_spi", HwSpiInit }, + {"hw_spi", HwSpiInit}, #endif #ifdef BSP_USING_LCD - { "hw_lcd", HwLcdInit }, + {"hw_lcd", HwLcdInit}, #endif #ifdef BSP_USING_USB - { "hw_usb", HwCh376Init}, + {"hw_usb", HwCh376Init}, #endif #ifdef BSP_USING_TOUCH - {"touch", HwTouchInit }, + {"touch", HwTouchInit}, #endif #ifdef BSP_USING_SOFT_SPI - {"soft_spi", HwSoftSPIInit }, + {"soft_spi", HwSoftSPIInit}, #endif #ifdef BSP_USING_HWTIMER - {"hw_timer", HwTimerInit }, + {"hw_timer", HwTimerInit}, #endif #ifdef BSP_USING_WDT - {"hw_wdt", HwWdtInit }, + {"hw_wdt", HwWdtInit}, +#endif +#ifdef BSP_USING_W5500 + {"w5500", HwWiznetInit}, +#endif +#ifdef BSP_USING_CAMERA + {"hw_camera", HwDvpInit }, #endif { " NONE ",NONE }, }; +void InitBoardHardware(void) { + int i = 0; + int ret = 0; -void InitBoardHardware(void) -{ - int i = 0; - int ret = 0; - - SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); - SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); + SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); + SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); #ifdef BSP_USING_GPIO - /* Init FPIOA */ - FpioaInit(); + /* Init FPIOA */ + FpioaInit(); #endif #ifdef BSP_USING_DMA - /* Dmac init */ - DmacInit(); + /* Dmac init */ + DmacInit(); #endif - /* initalize interrupt */ - InitHwinterrupt(); -#ifdef BSP_USING_UART - HwUartInit(); + /* initalize interrupt */ + InitHwinterrupt(); +#ifdef BSP_USING_UART + HwUartInit(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); #ifdef KERNEL_CONSOLE - /* set console device */ - InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); - KPrintf("\nconsole init completed.\n"); - KPrintf("board initialization......\n"); + /* set console device */ + InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, + KERNEL_CONSOLE_DEVICE_NAME); + KPrintf("\nconsole init completed.\n"); + KPrintf("board initialization......\n"); #endif /* KERNEL_CONSOLE */ - InitHwTick(); + InitHwTick(); #ifdef ARCH_SMP - EnableHwclintIpi(); + EnableHwclintIpi(); #endif #ifdef KERNEL_COMPONENTS_INIT - for(i = 0; _board_init[i].fn != NONE; i++) { - ret = _board_init[i].fn(); - KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed"); - } + for (i = 0; _board_init[i].fn != NONE; i++) { + ret = _board_init[i].fn(); + KPrintf("initialize %s %s\n", _board_init[i].fn_name, + ret == 0 ? "success" : "failed"); + } #endif - KPrintf("board init done.\n"); - KPrintf("start kernel...\n"); + KPrintf("board init done.\n"); + KPrintf("start kernel...\n"); } -void HwCpuReset(void) -{ - sysctl->soft_reset.soft_reset = 1; - while(RET_TRUE); +void HwCpuReset(void) { + sysctl->soft_reset.soft_reset = 1; + while (RET_TRUE) + ; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Reboot, HwCpuReset, reset machine ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Reboot, HwCpuReset, reset machine); diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig index 11ecca978..f6322f544 100755 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig @@ -112,3 +112,20 @@ 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 + +menuconfig BSP_USING_CAMERA + bool "Using camera device" + default y + select RESOURCES_CAMERA + if BSP_USING_CAMERA + source "$BSP_DIR/third_party_driver/dvp/Kconfig" + endif + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile index b8f466166..7c5f9ad84 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile @@ -56,5 +56,12 @@ ifeq ($(CONFIG_BSP_USING_WDT),y) SRC_DIR += watchdog endif +ifeq ($(CONFIG_BSP_USING_WIZCHIP),y) + SRC_DIR += ethernet +endif +ifeq ($(CONFIG_BSP_USING_CAMERA),y) + SRC_DIR += dvp +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/Kconfig new file mode 100644 index 000000000..f7f10a646 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/Kconfig @@ -0,0 +1,46 @@ +if BSP_USING_CAMERA + config DVP_XCLK_RATE + int "Camera interface clk rate" + default 24000000 + config IMAGE_WIDTH + int "Camera photo width" + default 320 + config IMAGE_HEIGHT + int "Camera photo height" + default 240 + config DVP_BURST_ENABLE + bool "brust mode enable" + default y + config DVP_AUTO_ENABLE + bool "auto recv image mode enable" + default n + config DVP_AI_OUTPUT + bool "ai output enable" + default n + config DVP_INTERRUPT_ENABLE + bool "interrupt enable" + default y + + config CAMERA_BUS_NAME + string "camera bus name" + default "camera" + config CAMERA_DRV_NAME + string "camera driver name" + default "camera_drv" + config CAMERA_DEVICE_NAME + string "camera device name" + default "camera_dev" + + choice + prompt "set camera framesize and fps" + default SVGA_25FPS_MODE + + config UXGA_15FPS_MODE + bool "using uxga in 15fps" + + config SVGA_25FPS_MODE + bool "using svag in 25fps" + endchoice + + +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/Makefile new file mode 100644 index 000000000..38326d7ab --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_dvp.c dvp.c ov2640.c + + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/connect_dvp.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/connect_dvp.c new file mode 100644 index 000000000..04463832b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/connect_dvp.c @@ -0,0 +1,243 @@ +#include +#include +#include +#include "sysctl.h" +#include "bsp.h" +#include "plic.h" +#include + +#define REG_SCCB_READ 0x12U +#define REG_SCCB_WRITE 0x13U +#define SCCB_REG_LENGTH 0x08U + +// irq interrupt function +static int on_irq_dvp(int irq, void *arg) +{ + if (dvp_get_interrupt(DVP_STS_FRAME_FINISH)) + { + dvp_clear_interrupt(DVP_STS_FRAME_FINISH); + } + else + { + dvp_start_convert(); + dvp_clear_interrupt(DVP_STS_FRAME_START); + } + return 0; +} + +struct DvpRegConfigureInfo +{ + uint8_t device_addr; + uint16_t reg_addr; + uint8_t reg_value; +}; + +static struct CameraCfg sensor_config = { + .output_h = IMAGE_HEIGHT,//will be resize from window below in ov2640 + .output_w = IMAGE_WIDTH, + .window_h = 600, //register configure in ov2640.h + .window_w = 800, //to make window as large as cmos selected size + .window_xoffset = 0, + .window_yoffset = 0, + .gain_manu_enable = 0, + .gain = 0x00 + }; + +static uint32 DvpDrvInit(void) +{ + x_err_t ret = EOK; + dvp_init(SCCB_REG_LENGTH); + dvp_set_xclk_rate(DVP_XCLK_RATE); + dvp_set_image_format(DVP_CFG_RGB_FORMAT); + dvp_set_image_size(IMAGE_WIDTH, IMAGE_HEIGHT); + dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 0); + dvp_set_output_enable(DVP_OUTPUT_AI, 0); + ov2640_init(); + SensorConfigure(&sensor_config); + + sysctl_set_spi0_dvp_data(1); +#ifdef DVP_BURST_ENABLE + dvp_enable_burst(); +#endif +#ifdef DVP_AUTO_ENABLE + dvp_disable_auto(); +#endif +#ifdef DVP_AI_OUTPUT + dvp_set_output_enable(DVP_OUTPUT_AI, 1); + dvp_set_ai_addr((uint32_t)DVP_AI_RED_ADRESS, (uint32_t)DVP_AI_GREEN_ADRESS, (uint32_t)DVP_AI_BLUE_ADRESS); +#endif +#ifdef DVP_INTERRUPT_ENABLE + dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0); + isrManager.done->registerIrq(IRQN_DVP_INTERRUPT, (IsrHandlerType)on_irq_dvp, NULL); + isrManager.done->enableIrq(IRQN_DVP_INTERRUPT); + dvp_clear_interrupt(DVP_STS_FRAME_START | DVP_STS_FRAME_FINISH); + dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1); + KPrintf("camera interrupt has open!\n"); +#endif + return ret; +} + +static uint32 ReadDvpReg(void *drv, struct DvpRegConfigureInfo *reg_info) +{ + x_err_t ret = EOK; + reg_info->reg_value = dvp_sccb_receive_data(reg_info->device_addr, reg_info->reg_addr); + return ret; +} + +static uint32 WriteDvpReg(void *drv, struct DvpRegConfigureInfo *reg_info) +{ + x_err_t ret = EOK; + dvp_sccb_send_data(reg_info->device_addr, reg_info->reg_addr, reg_info->reg_value); + return ret; +} + +static uint32 DvpOpen(void *dev) +{ + x_err_t ret = EOK; + DvpDrvInit(); + return ret; +} + +static uint32 DvpClose(void *dev) +{ + x_err_t ret = EOK; + dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0); + dvp_set_output_enable(DVP_OUTPUT_AI, 0); + dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 0); + return ret; +} + +static uint32 DvpRead(void *dev, struct BusBlockReadParam *read_param) +{ + x_err_t ret = EOK; + + // change the output buff address by read + dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 0); + dvp_set_display_addr((uintptr_t)read_param->buffer); + dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 1); + + return ret; +} + +static uint32 DvpDrvConfigure(void *drv, struct BusConfigureInfo *args) +{ + x_err_t ret = EOK; + + int cmd_type = args->configure_cmd; + struct CameraCfg* tmp_cfg; + switch (cmd_type) + { + case OPE_INT: + break; + case OPE_CFG: + tmp_cfg = (struct CameraCfg *)args->private_data; + SensorConfigure(tmp_cfg); + dvp_set_image_size(tmp_cfg->output_w, tmp_cfg->output_h); + break; + case REG_SCCB_READ: + ReadDvpReg(drv, (struct DvpRegConfigureInfo *)args->private_data); + break; + case REG_SCCB_WRITE: + //for ov2640,write reg 0x04 to Horizontal mirror or Vertical flip + WriteDvpReg(drv, (struct DvpRegConfigureInfo *)args->private_data); + break; + default: + break; + } + return ret; +} + +/*manage the camera device operations*/ +static const struct CameraDevDone camera_dev_done = + { + .dev_open = DvpOpen, + .dev_close = DvpClose, + .dev_write = NONE, + .dev_read = DvpRead, +}; + +/*Init camera bus*/ +static int BoardCameraBusInit(struct CameraBus *camera_bus, struct CameraDriver *camera_driver) +{ + x_err_t ret = EOK; + + /*Init the camera bus */ + camera_bus->private_data = (void *)&camera_dev_done; + ret = CameraBusInit(camera_bus, CAMERA_BUS_NAME); + if (EOK != ret) + { + KPrintf("board_camera_init CameraBusInit error %d\n", ret); + return ERROR; + } + + /*Init the camera driver*/ + camera_driver->private_data = (void *)&camera_dev_done; + ret = CameraDriverInit(camera_driver, CAMERA_DRV_NAME); + if (EOK != ret) + { + KPrintf("board_camera_init CameraDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the camera driver to the camera bus*/ + ret = CameraDriverAttachToBus(CAMERA_DRV_NAME, CAMERA_BUS_NAME); + if (EOK != ret) + { + KPrintf("board_camera_init CameraDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the camera device to the camera bus*/ +static int BoardCameraDevBend(void) +{ + x_err_t ret = EOK; + static struct CameraHardwareDevice camera_device; + memset(&camera_device, 0, sizeof(struct CameraHardwareDevice)); + + camera_device.camera_dev_done = &camera_dev_done; + + ret = CameraDeviceRegister(&camera_device, NONE, CAMERA_DEVICE_NAME); + if (EOK != ret) + { + KPrintf("board_camera_init CameraDeviceInit device %s error %d\n", CAMERA_DEVICE_NAME, ret); + return ERROR; + } + + ret = CameraDeviceAttachToBus(CAMERA_DEVICE_NAME, CAMERA_BUS_NAME); + if (EOK != ret) + { + KPrintf("board_camera_init CameraDeviceAttachToBus device %s error %d\n", CAMERA_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwDvpInit(void) +{ + x_err_t ret = EOK; + static struct CameraBus camera_bus; + memset(&camera_bus, 0, sizeof(struct CameraBus)); + + static struct CameraDriver camera_driver; + memset(&camera_driver, 0, sizeof(struct CameraDriver)); + + camera_driver.configure = DvpDrvConfigure; + ret = BoardCameraBusInit(&camera_bus, &camera_driver); + if (EOK != ret) + { + KPrintf("board_camera_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardCameraDevBend(); + if (EOK != ret) + { + KPrintf("board_camera_Init error ret %u\n", ret); + return ERROR; + } + return ret; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/dvp.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/dvp.c new file mode 100644 index 000000000..50cc8ff6c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/dvp.c @@ -0,0 +1,288 @@ +/* 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. + */ +#include +#include +#include "dvp.h" +#include "utils.h" +#include "fpioa.h" +#include "sysctl.h" +#include +#include + +volatile dvp_t* const dvp = (volatile dvp_t*)DVP_BASE_ADDR; +static uint8_t g_sccb_reg_len = 8; + + +static void dvp_sccb_clk_init(void) +{ + uint32_t tmp; + + tmp = dvp->sccb_cfg & (~(DVP_SCCB_SCL_LCNT_MASK | DVP_SCCB_SCL_HCNT_MASK)); + tmp |= DVP_SCCB_SCL_LCNT(255) | DVP_SCCB_SCL_HCNT(255); + + dvp->sccb_cfg = tmp; +} + +uint32_t dvp_sccb_set_clk_rate(uint32_t clk_rate) +{ + uint32_t tmp; + uint32_t v_sccb_freq = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + uint16_t v_period_clk_cnt = round(v_sccb_freq / clk_rate / 2.0); + if(v_period_clk_cnt > 255) + { + return 0; + } + tmp = dvp->sccb_cfg & (~(DVP_SCCB_SCL_LCNT_MASK | DVP_SCCB_SCL_HCNT_MASK)); + tmp |= DVP_SCCB_SCL_LCNT(v_period_clk_cnt) | DVP_SCCB_SCL_HCNT(v_period_clk_cnt); + dvp->sccb_cfg = tmp; + return SysctlClockGetFreq(SYSCTL_CLOCK_DVP) / (v_period_clk_cnt * 2); +} + +static void dvp_sccb_start_transfer(void) +{ + while (dvp->sts & DVP_STS_SCCB_EN) + ; + dvp->sts = DVP_STS_SCCB_EN | DVP_STS_SCCB_EN_WE; + while (dvp->sts & DVP_STS_SCCB_EN) + ; +} + +void dvp_sccb_send_data(uint8_t dev_addr, uint16_t reg_addr, uint8_t reg_data) +{ + uint32_t tmp; + + tmp = dvp->sccb_cfg & (~DVP_SCCB_BYTE_NUM_MASK); + + (g_sccb_reg_len == 8) ? (tmp |= DVP_SCCB_BYTE_NUM_3) : (tmp |= DVP_SCCB_BYTE_NUM_4); + + dvp->sccb_cfg = tmp; + + if (g_sccb_reg_len == 8) + { + dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr) | DVP_SCCB_WDATA_BYTE0(reg_data); + } + else + { + dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr >> 8) | DVP_SCCB_WDATA_BYTE0(reg_addr & 0xff) | DVP_SCCB_WDATA_BYTE1(reg_data); + } + dvp_sccb_start_transfer(); +} + +uint8_t dvp_sccb_receive_data(uint8_t dev_addr, uint16_t reg_addr) +{ + uint32_t tmp; + + tmp = dvp->sccb_cfg & (~DVP_SCCB_BYTE_NUM_MASK); + + if (g_sccb_reg_len == 8) + tmp |= DVP_SCCB_BYTE_NUM_2; + else + tmp |= DVP_SCCB_BYTE_NUM_3; + + dvp->sccb_cfg = tmp; + + if (g_sccb_reg_len == 8) + { + dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr); + } + else + { + dvp->sccb_ctl = DVP_SCCB_WRITE_DATA_ENABLE | DVP_SCCB_DEVICE_ADDRESS(dev_addr) | DVP_SCCB_REG_ADDRESS(reg_addr >> 8) | DVP_SCCB_WDATA_BYTE0(reg_addr & 0xff); + } + dvp_sccb_start_transfer(); + + dvp->sccb_ctl = DVP_SCCB_DEVICE_ADDRESS(dev_addr); + + dvp_sccb_start_transfer(); + + return (uint8_t) DVP_SCCB_RDATA_BYTE(dvp->sccb_cfg); +} + +static void dvp_reset(void) +{ + /* First power down */ + dvp->cmos_cfg |= DVP_CMOS_POWER_DOWN; + msleep(200); + dvp->cmos_cfg &= ~DVP_CMOS_POWER_DOWN; + msleep(200); + + /* Second reset */ + dvp->cmos_cfg &= ~DVP_CMOS_RESET; + msleep(200); + dvp->cmos_cfg |= DVP_CMOS_RESET; + msleep(200); +} + +void dvp_init(uint8_t reg_len) +{ + g_sccb_reg_len = reg_len; + sysctl_clock_enable(SYSCTL_CLOCK_DVP); + sysctl_reset(SYSCTL_RESET_DVP); + dvp->cmos_cfg &= (~DVP_CMOS_CLK_DIV_MASK); + dvp->cmos_cfg |= DVP_CMOS_CLK_DIV(3) | DVP_CMOS_CLK_ENABLE; + dvp_sccb_clk_init(); + dvp_reset(); +} + +uint32_t dvp_set_xclk_rate(uint32_t xclk_rate) +{ + uint32_t v_apb1_clk = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + uint32_t v_period; + if(v_apb1_clk > xclk_rate * 2) + v_period = round(v_apb1_clk / (xclk_rate * 2.0)) - 1; + else + v_period = 0; + if(v_period > 255) + v_period = 255; + dvp->cmos_cfg &= (~DVP_CMOS_CLK_DIV_MASK); + dvp->cmos_cfg |= DVP_CMOS_CLK_DIV(v_period) | DVP_CMOS_CLK_ENABLE; + dvp_reset(); + return v_apb1_clk / ((v_period + 1) * 2); +} + +void dvp_set_image_format(uint32_t format) +{ + uint32_t tmp; + + tmp = dvp->dvp_cfg & (~DVP_CFG_FORMAT_MASK); + dvp->dvp_cfg = tmp | format; +} + +void dvp_enable_burst(void) +{ + dvp->dvp_cfg |= DVP_CFG_BURST_SIZE_4BEATS; + + dvp->axi &= (~DVP_AXI_GM_MLEN_MASK); + dvp->axi |= DVP_AXI_GM_MLEN_4BYTE; +} + +void dvp_disable_burst(void) +{ + dvp->dvp_cfg &= (~DVP_CFG_BURST_SIZE_4BEATS); + + dvp->axi &= (~DVP_AXI_GM_MLEN_MASK); + dvp->axi |= DVP_AXI_GM_MLEN_1BYTE; +} + +void dvp_set_image_size(uint32_t width, uint32_t height) +{ + uint32_t tmp; + + tmp = dvp->dvp_cfg & (~(DVP_CFG_HREF_BURST_NUM_MASK | DVP_CFG_LINE_NUM_MASK)); + + tmp |= DVP_CFG_LINE_NUM(height); + + if (dvp->dvp_cfg & DVP_CFG_BURST_SIZE_4BEATS) + tmp |= DVP_CFG_HREF_BURST_NUM(width / 8 / 4); + else + tmp |= DVP_CFG_HREF_BURST_NUM(width / 8 / 1); + + dvp->dvp_cfg = tmp; +} + +void dvp_set_ai_addr(uint32_t r_addr, uint32_t g_addr, uint32_t b_addr) +{ + dvp->r_addr = r_addr; + dvp->g_addr = g_addr; + dvp->b_addr = b_addr; +} + +void dvp_set_display_addr(uint32_t addr) +{ + dvp->rgb_addr = addr; +} + +void dvp_start_frame(void) +{ + while (!(dvp->sts & DVP_STS_FRAME_START)) + ; + dvp->sts = (DVP_STS_FRAME_START | DVP_STS_FRAME_START_WE); +} + +void dvp_start_convert(void) +{ + dvp->sts = DVP_STS_DVP_EN | DVP_STS_DVP_EN_WE; +} + +void dvp_finish_convert(void) +{ + while (!(dvp->sts & DVP_STS_FRAME_FINISH)) + ; + dvp->sts = DVP_STS_FRAME_FINISH | DVP_STS_FRAME_FINISH_WE; +} + +void dvp_get_image(void) +{ + while (!(dvp->sts & DVP_STS_FRAME_START)) + ; + dvp->sts = DVP_STS_FRAME_START | DVP_STS_FRAME_START_WE; + while (!(dvp->sts & DVP_STS_FRAME_START)) + ; + dvp->sts = DVP_STS_FRAME_FINISH | DVP_STS_FRAME_FINISH_WE | DVP_STS_FRAME_START | DVP_STS_FRAME_START_WE | DVP_STS_DVP_EN | DVP_STS_DVP_EN_WE; + while (!(dvp->sts & DVP_STS_FRAME_FINISH)) + ; +} + +void dvp_config_interrupt(uint32_t interrupt, uint8_t enable) +{ + if (enable) + dvp->dvp_cfg |= interrupt; + else + dvp->dvp_cfg &= (~interrupt); +} + +int dvp_get_interrupt(uint32_t interrupt) +{ + if (dvp->sts & interrupt) + return 1; + return 0; +} + +void dvp_clear_interrupt(uint32_t interrupt) +{ + interrupt |= (interrupt << 1); + dvp->sts |= interrupt; +} + +void dvp_enable_auto(void) +{ + dvp->dvp_cfg |= DVP_CFG_AUTO_ENABLE; +} + +void dvp_disable_auto(void) +{ + dvp->dvp_cfg &= (~DVP_CFG_AUTO_ENABLE); +} + +void dvp_set_output_enable(dvp_output_mode_t index, int enable) +{ + configASSERT(index < 2); + + if (index == 0) + { + if (enable) + dvp->dvp_cfg |= DVP_CFG_AI_OUTPUT_ENABLE; + else + dvp->dvp_cfg &= ~DVP_CFG_AI_OUTPUT_ENABLE; + } + else + { + if (enable) + dvp->dvp_cfg |= DVP_CFG_DISPLAY_OUTPUT_ENABLE; + else + dvp->dvp_cfg &= ~DVP_CFG_DISPLAY_OUTPUT_ENABLE; + } +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/ov2640.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/ov2640.c new file mode 100644 index 000000000..991a8982a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dvp/ov2640.c @@ -0,0 +1,463 @@ +/* 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. + */ +#include +#include "ov2640.h" +#include "dvp.h" +#include "plic.h" +#include "board.h" + +#if defined SVGA_25FPS_MODE +const uint8_t ov2640_config[][2]= +{ + {0xff, 0x01}, + {0x12, 0x80}, + {0xff, 0x00}, + {0x2c, 0xff}, + {0x2e, 0xdf}, + {0xff, 0x01}, + {0x3c, 0x32}, + {0x11, 0x00}, + {0x09, 0x02}, + {0x04, 0x28}, + {0x13, 0xe5}, + {0x14, 0x48}, + {0x2c, 0x0c}, + {0x33, 0x78}, + {0x3a, 0x33}, + {0x3b, 0xfb}, + {0x3e, 0x00}, + {0x43, 0x11}, + {0x16, 0x10}, + {0x39, 0x92}, + {0x35, 0xda}, + {0x22, 0x1a}, + {0x37, 0xc3}, + {0x23, 0x00}, + {0x34, 0xc0}, + {0x36, 0x1a}, + {0x06, 0x88}, + {0x07, 0xc0}, + {0x0d, 0x87}, + {0x0e, 0x41}, + {0x4c, 0x00}, + {0x48, 0x00}, + {0x5b, 0x00}, + {0x42, 0x03}, + {0x4a, 0x81}, + {0x21, 0x99}, + {0x24, 0x40}, + {0x25, 0x38}, + {0x26, 0x82}, + {0x5c, 0x00}, + {0x63, 0x00}, + {0x46, 0x22}, + {0x0c, 0x3c}, + {0x61, 0x70}, + {0x62, 0x80}, + {0x7c, 0x05}, + {0x20, 0x80}, + {0x28, 0x30}, + {0x6c, 0x00}, + {0x6d, 0x80}, + {0x6e, 0x00}, + {0x70, 0x02}, + {0x71, 0x94}, + {0x73, 0xc1}, + {0x3d, 0x34}, + {0x5a, 0x57}, + {0x12, 0x40}, + {0x17, 0x11}, + {0x18, 0x43}, + {0x19, 0x00}, + {0x1a, 0x97}, + {0x32, 0x09}, + {0x37, 0xc0}, + {0x4f, 0xca}, + {0x50, 0xa8}, + {0x5a, 0x23}, + {0x6d, 0x00}, + {0x3d, 0x38}, + {0xff, 0x00}, + {0xe5, 0x7f}, + {0xf9, 0xc0}, + {0x41, 0x24}, + {0xe0, 0x14}, + {0x76, 0xff}, + {0x33, 0xa0}, + {0x42, 0x20}, + {0x43, 0x18}, + {0x4c, 0x00}, + {0x87, 0xd5}, + {0x88, 0x3f}, + {0xd7, 0x03}, + {0xd9, 0x10}, + {0xd3, 0x82}, + {0xc8, 0x08}, + {0xc9, 0x80}, + {0x7c, 0x00}, + {0x7d, 0x00}, + {0x7c, 0x03}, + {0x7d, 0x48}, + {0x7d, 0x48}, + {0x7c, 0x08}, + {0x7d, 0x20}, + {0x7d, 0x10}, + {0x7d, 0x0e}, + {0x90, 0x00}, + {0x91, 0x0e}, + {0x91, 0x1a}, + {0x91, 0x31}, + {0x91, 0x5a}, + {0x91, 0x69}, + {0x91, 0x75}, + {0x91, 0x7e}, + {0x91, 0x88}, + {0x91, 0x8f}, + {0x91, 0x96}, + {0x91, 0xa3}, + {0x91, 0xaf}, + {0x91, 0xc4}, + {0x91, 0xd7}, + {0x91, 0xe8}, + {0x91, 0x20}, + {0x92, 0x00}, + {0x93, 0x06}, + {0x93, 0xe3}, + {0x93, 0x05}, + {0x93, 0x05}, + {0x93, 0x00}, + {0x93, 0x04}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x96, 0x00}, + {0x97, 0x08}, + {0x97, 0x19}, + {0x97, 0x02}, + {0x97, 0x0c}, + {0x97, 0x24}, + {0x97, 0x30}, + {0x97, 0x28}, + {0x97, 0x26}, + {0x97, 0x02}, + {0x97, 0x98}, + {0x97, 0x80}, + {0x97, 0x00}, + {0x97, 0x00}, + {0xc3, 0xed}, + {0xa4, 0x00}, + {0xa8, 0x00}, + {0xc5, 0x11}, + {0xc6, 0x51}, + {0xbf, 0x80}, + {0xc7, 0x10}, + {0xb6, 0x66}, + {0xb8, 0xa5}, + {0xb7, 0x64}, + {0xb9, 0x7c}, + {0xb3, 0xaf}, + {0xb4, 0x97}, + {0xb5, 0xff}, + {0xb0, 0xc5}, + {0xb1, 0x94}, + {0xb2, 0x0f}, + {0xc4, 0x5c}, + {0xc0, 0x64}, + {0xc1, 0x4b}, + {0x8c, 0x00}, + {0x86, 0x3d}, + {0x50, 0x00}, + {0x51, 0xc8}, + {0x52, 0x96}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x00}, + {0x5a, 0xc8}, + {0x5b, 0x96}, + {0x5c, 0x00}, + {0xd3, 0x02}, + {0xc3, 0xed}, + {0x7f, 0x00}, + {0xda, 0x08}, + {0xe5, 0x1f}, + {0xe1, 0x67}, + {0xe0, 0x00}, + {0xdd, 0x7f}, + {0x05, 0x00}, + {0xff, 0x00}, + {0xe0, 0x04}, + {0x5a, 0x50}, + {0x5b, 0x3c}, + {0x5c, 0x00}, + {0xe0, 0x00}, + {0x00, 0x00} +}; +#elif defined UXGA_15FPS_MODE +const uint8_t ov2640_config[][2]= +{ + {0xFF, 0x00}, + {0x2C, 0xFF}, + {0x2E, 0xDF}, + {0xFF, 0x01}, + {0x3C, 0x32}, + {0x11, 0x00}, + {0x09, 0x02}, + {0x04, 0x28}, + {0x13, 0xE5}, + {0x14, 0x48}, + {0x2C, 0x0C}, + {0x33, 0x78}, + {0x3A, 0x33}, + {0x3B, 0xFB}, + {0x3E, 0x00}, + {0x43, 0x11}, + {0x16, 0x10}, + {0x39, 0x92}, + {0x35, 0xDA}, + {0x22, 0x1A}, + {0x37, 0xC3}, + {0x23, 0x00}, + {0x34, 0xC0}, + {0x36, 0x1A}, + {0x06, 0x88}, + {0x07, 0xC0}, + {0x0D, 0x87}, + {0x0E, 0x41}, + {0x4C, 0x00}, + {0x48, 0x00}, + {0x5B, 0x00}, + {0x42, 0x03}, + {0x4A, 0x81}, + {0x21, 0x99}, + {0x24, 0x40}, + {0x25, 0x38}, + {0x26, 0x82}, + {0x5C, 0x00}, + {0x63, 0x00}, + {0x46, 0x00}, + {0x0C, 0x3C}, + {0x61, 0x70}, + {0x62, 0x80}, + {0x7C, 0x05}, + {0x20, 0x80}, + {0x28, 0x30}, + {0x6C, 0x00}, + {0x6D, 0x80}, + {0x6E, 0x00}, + {0x70, 0x02}, + {0x71, 0x94}, + {0x73, 0xC1}, + {0x3D, 0x34}, + {0x5A, 0x57}, + {0x12, 0x00}, + {0x17, 0x11}, + {0x18, 0x75}, + {0x19, 0x01}, + {0x1A, 0x97}, + {0x32, 0x36}, + {0x03, 0x0F}, + {0x37, 0x40}, + {0x4F, 0xCA}, + {0x50, 0xA8}, + {0x5A, 0x23}, + {0x6D, 0x00}, + {0x6D, 0x38}, + {0xFF, 0x00}, + {0xE5, 0x7F}, + {0xF9, 0xC0}, + {0x41, 0x24}, + {0xE0, 0x14}, + {0x76, 0xFF}, + {0x33, 0xA0}, + {0x42, 0x20}, + {0x43, 0x18}, + {0x4C, 0x00}, + {0x87, 0xD5}, + {0x88, 0x3F}, + {0xD7, 0x03}, + {0xD9, 0x10}, + {0xD3, 0x82}, + {0xC8, 0x08}, + {0xC9, 0x80}, + {0x7C, 0x00}, + {0x7D, 0x00}, + {0x7C, 0x03}, + {0x7D, 0x48}, + {0x7D, 0x48}, + {0x7C, 0x08}, + {0x7D, 0x20}, + {0x7D, 0x10}, + {0x7D, 0x0E}, + {0x90, 0x00}, + {0x91, 0x0E}, + {0x91, 0x1A}, + {0x91, 0x31}, + {0x91, 0x5A}, + {0x91, 0x69}, + {0x91, 0x75}, + {0x91, 0x7E}, + {0x91, 0x88}, + {0x91, 0x8F}, + {0x91, 0x96}, + {0x91, 0xA3}, + {0x91, 0xAF}, + {0x91, 0xC4}, + {0x91, 0xD7}, + {0x91, 0xE8}, + {0x91, 0x20}, + {0x92, 0x00}, + {0x93, 0x06}, + {0x93, 0xE3}, + {0x93, 0x05}, + {0x93, 0x05}, + {0x93, 0x00}, + {0x93, 0x04}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x96, 0x00}, + {0x97, 0x08}, + {0x97, 0x19}, + {0x97, 0x02}, + {0x97, 0x0C}, + {0x97, 0x24}, + {0x97, 0x30}, + {0x97, 0x28}, + {0x97, 0x26}, + {0x97, 0x02}, + {0x97, 0x98}, + {0x97, 0x80}, + {0x97, 0x00}, + {0x97, 0x00}, + {0xC3, 0xEF}, + {0xA4, 0x00}, + {0xA8, 0x00}, + {0xC5, 0x11}, + {0xC6, 0x51}, + {0xBF, 0x80}, + {0xC7, 0x10}, + {0xB6, 0x66}, + {0xB8, 0xA5}, + {0xB7, 0x64}, + {0xB9, 0x7C}, + {0xB3, 0xAF}, + {0xB4, 0x97}, + {0xB5, 0xFF}, + {0xB0, 0xC5}, + {0xB1, 0x94}, + {0xB2, 0x0F}, + {0xC4, 0x5C}, + {0xC0, 0xC8}, + {0xC1, 0x96}, + {0x8C, 0x00}, + {0x86, 0x3D}, + {0x50, 0x00}, + {0x51, 0x90}, + {0x52, 0x2C}, + {0x53, 0x00}, + {0x54, 0x00}, + {0x55, 0x88}, + {0x5A, 0x90}, + {0x5B, 0x2C}, + {0x5C, 0x05}, + {0xD3, 0x02}, + {0xC3, 0xED}, + {0x7F, 0x00}, + {0xDA, 0x08}, + {0xE5, 0x1F}, + {0xE1, 0x67}, + {0xE0, 0x00}, + {0xDD, 0x7F}, + {0x05, 0x00}, + {0xe0, 0x04}, + {0x5a, 0x50}, + {0x5b, 0x3c}, + {0x5c, 0x00}, + {0xe0, 0x00}, + {0x00, 0x00} +}; +#else +const uint8_t ov2640_config[][2]= +{ + {0x00,x00} +} +#endif + + + +int ov2640_init(void) +{ + uint16_t v_manuf_id; + uint16_t v_device_id; + ov2640_read_id(&v_manuf_id, &v_device_id); + printf("manuf_id:0x%04x,device_id:0x%04x\n", v_manuf_id, v_device_id); + uint16_t index = 0; + for (index = 0; ov2640_config[index][0]; index++) + dvp_sccb_send_data(OV2640_ADDR, ov2640_config[index][0], ov2640_config[index][1]); + return 0; +} + +int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id) +{ + dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x01); + *manuf_id = (dvp_sccb_receive_data(OV2640_ADDR, 0x1C) << 8) | dvp_sccb_receive_data(OV2640_ADDR, 0x1D); + *device_id = (dvp_sccb_receive_data(OV2640_ADDR, 0x0A) << 8) | dvp_sccb_receive_data(OV2640_ADDR, 0x0B); + return 0; +} + +int SensorConfigure(struct CameraCfg *cfg_info) +{ + uint8_t reg_tmp; + + //set reg mode to sensor + dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x00); + + //configure the window size and position + dvp_sccb_send_data(OV2640_ADDR, 0x51, cfg_info->window_w>>2); + dvp_sccb_send_data(OV2640_ADDR, 0x52, cfg_info->window_h>>2); + dvp_sccb_send_data(OV2640_ADDR, 0x53, (uint8_t)(cfg_info->window_xoffset&0xFF)); + dvp_sccb_send_data(OV2640_ADDR, 0x54, (uint8_t)(cfg_info->window_yoffset&0xFF)); + dvp_sccb_send_data(OV2640_ADDR, 0x55, (((cfg_info->window_h/4)&0x100)>>1)+ + ((cfg_info->window_yoffset&0x700)>>4)+ + (((cfg_info->window_w/4)&0x100)>>5)+ + ((cfg_info->window_xoffset&0x700)>>8)); + dvp_sccb_send_data(OV2640_ADDR, 0x57, ((cfg_info->window_w/4)&0x200)>>2); + dvp_sccb_send_data(OV2640_ADDR, 0x5A, cfg_info->output_w>>2); + dvp_sccb_send_data(OV2640_ADDR, 0x5B, cfg_info->output_h>>2); + + //set reg mode to dsp + dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x01); + + //configure dsp gain + if(cfg_info->gain_manu_enable){ + reg_tmp = dvp_sccb_receive_data(OV2640_ADDR, 0x13); + dvp_sccb_send_data(OV2640_ADDR, 0x13, reg_tmp&0xFB); + dvp_sccb_send_data(OV2640_ADDR, 0x00, cfg_info->gain); + }else{ + reg_tmp = dvp_sccb_receive_data(OV2640_ADDR, 0x13); + dvp_sccb_send_data(OV2640_ADDR, 0x13, reg_tmp|0x04); + } + + + return 1; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig new file mode 100644 index 000000000..baf59367c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig @@ -0,0 +1,15 @@ +# Kconfig file + +config BSP_USING_W5500 +bool "Using w5500 " +default y + +# if BSP_USING_W5500 + config BSP_WIZ_RST_PIN + int + default 13 + + config BSP_WIZ_INT_PIN + int + default 14 +# endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile new file mode 100644 index 000000000..1ea20caac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md new file mode 100644 index 000000000..947404f4a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md @@ -0,0 +1,25 @@ +## w5500 测试文档 + +通过board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c 可以找到内写的3个,包含ping, tcp server test, tcp client test; + + - ping 测试,测试结果包括: + - pc ping w5500 + - w5500 ping baidu.com (DNS实现暂未实现,因此使用baidu.com的ip地址进行寻址) + + + + + +- tcp server 测试:在xizi中调用wiz_server_op,指定port,之后可以在pc中向该端口发送数据 + - wiz_server 将额外启动一个线程执行server工作,server将向client返回client发来的消息 + + + + + +- client 测试:通过wiz_client_op可以向pc中打开的tcp server发送消息 + - 由于wiz_client_test函数参数接收问题,测试使用的ip地址暂时使用硬编码实现 + + + + \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c new file mode 100644 index 000000000..22803ee9e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -0,0 +1,505 @@ + +#include "connect_w5500.h" + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" +#include "socket.h" +#include "w5500.h" + +#define SPI_LORA_FREQUENCY 10000000 + +// spi operations +extern void spi_enter_cris(void); +extern void spi_exit_cris(void); +extern void spi_select_cs(void); +extern void spi_deselete_cs(void); + +// global configurations for w5500 tcp connection +const uint32_t socket_tcp = 0; +const uint32_t g_wiznet_buf_size = 2048; + +static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, + .ip = {192, 168, 31, 13}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 31, 1}, + .dns = {0, 0, 0, 0}, + .dhcp = NETINFO_STATIC}; + +int network_init() { + wiz_NetInfo check_wiz_netinfo; + check_wiz_netinfo.dhcp = NETINFO_STATIC; + ctlnetwork(CN_SET_NETINFO, (void *)&g_wiz_netinfo); + ctlnetwork(CN_GET_NETINFO, (void *)&check_wiz_netinfo); + + if (memcmp(&g_wiz_netinfo, &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { + KPrintf( + "mac: %d; ip: %d; gw: %d; sn: %d; dns: %d; dhcp: %d;\n", + memcmp(&g_wiz_netinfo.mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), + memcmp(&g_wiz_netinfo.ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); + KPrintf("WIZCHIP set network information fail.\n"); + return ERROR; + } + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", g_wiz_netinfo.mac[0], + g_wiz_netinfo.mac[1], g_wiz_netinfo.mac[2], g_wiz_netinfo.mac[3], + g_wiz_netinfo.mac[4], g_wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", g_wiz_netinfo.ip[0], g_wiz_netinfo.ip[1], + g_wiz_netinfo.ip[2], g_wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", g_wiz_netinfo.gw[0], g_wiz_netinfo.gw[1], + g_wiz_netinfo.gw[2], g_wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", g_wiz_netinfo.sn[0], g_wiz_netinfo.sn[1], + g_wiz_netinfo.sn[2], g_wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", g_wiz_netinfo.dns[0], g_wiz_netinfo.dns[1], + g_wiz_netinfo.dns[2], g_wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); + + return EOK; +} + +/****************** spi init ******************/ +static struct Bus *w5500_spi_bus; +int w5500_spi_init() { + x_err_t ret = EOK; + + w5500_spi_bus = BusFind(SPI_BUS_NAME_1); + w5500_spi_bus->owner_haldev = + BusFindDevice(w5500_spi_bus, SPI_1_DEVICE_NAME_0); + w5500_spi_bus->owner_driver = BusFindDriver(w5500_spi_bus, SPI_1_DRV_NAME); + + w5500_spi_bus->match(w5500_spi_bus->owner_driver, + w5500_spi_bus->owner_haldev); + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + spi_master_param.spi_maxfrequency = SPI_LORA_FREQUENCY; + spi_master_param.spi_data_endian = 0; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", + w5500_spi_bus->owner_driver, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", w5500_spi_bus->owner_driver); + return ERROR; + } + + return EOK; +} + +void spi_write_byte(uint8_t tx_data) { + struct BusBlockWriteParam write_param; + write_param.buffer = &tx_data; + write_param.size = 1; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +uint8_t spi_read_byte(void) { + uint8_t result = 0; + struct BusBlockReadParam read_param; + read_param.buffer = &result; + read_param.size = 1; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); + return result; +} +void spi_write_burst(uint8_t *tx_buf, uint16_t len) { + struct BusBlockWriteParam write_param; + write_param.buffer = tx_buf; + write_param.size = len; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +void spi_read_burst(uint8_t *rx_buf, uint16_t len) { + struct BusBlockReadParam read_param; + read_param.buffer = rx_buf; + read_param.size = len; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); +} + +/****************** chip init ******************/ + +void wiz_reset() { + gpiohs_set_drive_mode(WIZ_RST_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_LOW); + MdelayKTask(20); + + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_HIGH); + MdelayKTask(20); +} + +void wiz_spi_handler_reg() { + // spi ops registration +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_) || \ + (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_) + /* register SPI device CS select callback function */ + gpiohs_set_drive_mode(SPI1_CS0_PIN, GPIO_DM_OUTPUT); + reg_wizchip_cs_cbfunc(spi_select_cs, spi_deselete_cs); +#else +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_ +#error "Unknown _WIZCHIP_IO_MODE_" +#else + reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); +#endif +#endif + + reg_wizchip_spi_cbfunc(spi_read_byte, spi_write_byte); + reg_wizchip_cris_cbfunc(spi_enter_cris, spi_exit_cris); + reg_wizchip_spiburst_cbfunc(spi_read_burst, spi_write_burst); +} + +int wiz_chip_cfg_init() { + uint8_t mem_size[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; + + /* reset WIZnet chip internal PHY, configures PHY mode. */ + if (ctlwizchip(CW_INIT_WIZCHIP, (void *)mem_size) == -1) { + KPrintf("WIZCHIP initialize failed."); + return ERROR; + } + + struct wiz_NetTimeout_t net_timeout; + net_timeout.retry_cnt = 5; + net_timeout.time_100us = 20000; + ctlnetwork(CN_SET_TIMEOUT, (void *)&net_timeout); + + return EOK; +} + +/****************** interrupt handle ******************/ +void wiz_irq_handler() {} + +int wiz_interrupt_init() { + int32_t ret = -ERROR; + + struct Bus *pin_bus = PinBusInitGet(); + + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void *)&pin_param; + + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.mode = GPIO_CFG_INPUT_PULLUP; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("config pin_param %d input failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_REGISTER; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_FALLING; + pin_param.irq_set.hdr = wiz_irq_handler; + pin_param.irq_set.args = NONE; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + // 4. enable interuption + pin_param.cmd = GPIO_IRQ_ENABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("enable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + return EOK; + + return EOK; +} + +int HwWiznetInit(void) { + wiz_reset(); + + if (EOK != w5500_spi_init()) { + return ERROR; + } + + wiz_spi_handler_reg(); + + if (EOK != wiz_chip_cfg_init()) { + return ERROR; + } + + network_init(); + + return EOK; +} + +/****************** basic functions ********************/ + +enum TCP_OPTION { + SEND_DATA = 0, + RECV_DATA, +}; + +uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint8_t dst_ip[4], uint16_t dst_port, + enum TCP_OPTION opt) { + // assert(buf_size <= g_wiznet_buf_size); + int32_t ret; + switch (getSn_SR(socket_tcp)) { + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(socket_tcp); + break; + case SOCK_CLOSED: + wiz_socket(socket_tcp, Sn_MR_TCP, 5000, 0x00); + break; + case SOCK_INIT: + KPrintf("[SOCKET CLIENT] sock init.\n"); + wiz_sock_connect(socket_tcp, dst_ip, dst_port); + break; + case SOCK_ESTABLISHED: + if (getSn_IR(socket_tcp) & Sn_IR_CON) { + printf("[SOCKET CLIENT] %d:Connected\r\n", socket_tcp); + setSn_IR(socket_tcp, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + if (ret <= 0) return ret; + } + } + break; + default: + break; + } +} + +void wiz_client_op_test(char *addr, uint16_t port, char *msg) { + /* argv[1]: ip + * argv[2]: port + * argv[3]: msg + */ + uint8_t client_sock = 2; + uint8_t ip[4] = {192, 168, 31, 127}; + uint32_t tmp_ip[4]; + KPrintf("wiz client to %s", addr); + sscanf(addr, "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + for (int i = 0; i < 4; ++i) { + ip[i] = (uint8_t)tmp_ip[i]; + } + uint8_t buf[g_wiznet_buf_size]; + KPrintf("wiz_server, send to %d.%d.%d.%d %d\n", // tip info + ip[0], ip[1], ip[2], ip[3], port); + sscanf(msg, "%s", buf); + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, SEND_DATA); + MdelayKTask(10); + memset(buf, 0, g_wiznet_buf_size); + // waiting for a responding. + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, RECV_DATA); + KPrintf("received msg: %s\n", buf); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(3), + wiz_client_op, wiz_client_op_test, + wiz_sock_recv or wiz_sock_send data as tcp client); + +int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint16_t port, enum TCP_OPTION opt) { + int32_t ret = 0; + uint16_t size = 0, sentsize = 0; + switch (getSn_SR(sn)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("%d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + return ret; + } + } + break; + case SOCK_CLOSE_WAIT: + printf("%d:CloseWait\r\n", sn); + if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; + printf("%d:Closed\r\n", sn); + break; + case SOCK_INIT: + printf("%d:Listen, port [%d]\r\n", sn, port); + if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: + printf("%d:LBTStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; + printf("%d:Opened\r\n", sn); + break; + default: + break; + } + return 0; +} + +void wiz_server(void *param) { + uint16_t port = *(uint16_t *)param; + KPrintf("wiz server, listen port: %d\n", port); + uint8_t buf[g_wiznet_buf_size]; + memset(buf, 0, g_wiznet_buf_size); + int ret = 0; + while (1) { + ret = wiz_server_op(0, buf, g_wiznet_buf_size, port, RECV_DATA); + if (ret > 0) { + wiz_server_op(0, buf, g_wiznet_buf_size, port, SEND_DATA); + }; + } +} + +void wiz_server_test(uint16_t port) { + /* argv[1]: port + */ + int32 wiz_server_id = + KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); + x_err_t flag = StartupKTask(wiz_server_id); + if (flag != EOK) { + KPrintf("StartupKTask wiz_server_id failed .\n"); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(1), + wiz_server_op, wiz_server_test, + wiz_sock_recv or wiz_sock_send data as tcp server); + +int32_t loopback_udps(uint8_t sn, uint8_t *buf, uint16_t port) { + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + // uint8_t packinfo = 0; + switch (getSn_SR(sn)) { + case SOCK_UDP: + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > g_wiznet_buf_size) size = g_wiznet_buf_size; + ret = wiz_sock_recvfrom(sn, buf, size, destip, (uint16_t *)&destport); + if (ret <= 0) { + printf("%d: wiz_sock_recvfrom error. %ld\r\n", sn, ret); + return ret; + } + size = (uint16_t)ret; + sentsize = 0; + while (sentsize != size) { + ret = wiz_sock_sendto(sn, buf + sentsize, size - sentsize, destip, + destport); + if (ret < 0) { + printf("%d: wiz_sock_sendto error. %ld\r\n", sn, ret); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: + printf("%d:LBUStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_UDP, port, 0x00)) != sn) return ret; + printf("%d:Opened, port [%d]\r\n", sn, port); + break; + default: + break; + } + return 1; +} + +void ifconfig() { + wiz_NetInfo wiz_netinfo; + ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], + wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], + wiz_netinfo.mac[4], wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], + wiz_netinfo.ip[2], wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], + wiz_netinfo.gw[2], wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], + wiz_netinfo.sn[2], wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], + wiz_netinfo.dns[2], wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + ifconfig, ifconfig, printf w5500 configurations); + +void char_arr_assign(uint8_t **dst, uint32_t *src, uint32_t len) { + for (int i = 0; i < len; ++i) { + (*dst)[i] = (uint8_t)(src[i]); + } +} + +void config_w5500_network(char *mac, char *ip, char *sn, char *gw, char *dns) { + wiz_NetInfo wiz_netinfo; + uint32_t tmp_arr[4]; + // config netinfo + sscanf(mac, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.mac, tmp_arr, 4); + sscanf(ip, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.ip, tmp_arr, 4); + sscanf(sn, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.sn, tmp_arr, 4); + sscanf(gw, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.gw, tmp_arr, 4); + sscanf(dns, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.dns, tmp_arr, 4); + // set new netinfo + ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); + ifconfig(); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(5), + config_w5500_network, config_w5500_network, + set w5500 configurations); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png new file mode 100644 index 000000000..7df09b0d9 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png new file mode 100644 index 000000000..167d455b8 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png new file mode 100644 index 000000000..c79f4bb85 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png new file mode 100644 index 000000000..e453995a6 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png new file mode 100644 index 000000000..63f2d5f57 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png new file mode 100644 index 000000000..7643c9bf3 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c new file mode 100755 index 000000000..820e0631c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c @@ -0,0 +1,912 @@ + +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* +//! addr parameter is not aligned by 4byte address. Copy 4 byte addr +//! value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status +//! (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +#include "wizchip_conf.h" + +// M20150401 : Typing Error +//#define SOCK_ANY_PORT_NUM 0xC000; +#define SOCK_ANY_PORT_NUM 0xC000 + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; + +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = { + 0, + 0, +}; + +// M20150601 : For extern decleation +// static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +// + +#if _WIZCHIP_ == 5200 +static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 +uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = { + 0, +}; // set by wiz_recv_data() +#endif + +#define CHECK_SOCKNUM() \ + do { \ + if (sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + } while (0); + +#define CHECK_SOCKMODE(mode) \ + do { \ + if ((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + } while (0); + +#define CHECK_SOCKINIT() \ + do { \ + if ((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + } while (0); + +#define CHECK_SOCKDATA() \ + do { \ + if (len == 0) return SOCKERR_DATALEN; \ + } while (0); + +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) { + CHECK_SOCKNUM(); + switch (protocol) { + case Sn_MR_TCP: { + // M20150601 : Fixed the warning - taddr will never be NULL + /* + uint8_t taddr[4]; + getSIPR(taddr); + */ + uint32_t taddr; + getSIPR((uint8_t *)&taddr); + if (taddr == 0) return SOCKERR_SOCKINIT; + break; + } + case Sn_MR_UDP: + case Sn_MR_MACRAW: + case Sn_MR_IPRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + // M20150601 : For SF_TCP_ALIGN & W5300 + // if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; + if ((flag & 0x04) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if (flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if (flag != 0) { + switch (protocol) { + case Sn_MR_TCP: + // M20150601 : For SF_TCP_ALIGN & W5300 +#if _WIZCHIP_ == 5300 + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK | SF_TCP_ALIGN)) == 0) + return SOCKERR_SOCKFLAG; +#else + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK)) == 0) + return SOCKERR_SOCKFLAG; +#endif + + break; + case Sn_MR_UDP: + if (flag & SF_IGMP_VER2) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#if _WIZCHIP_ == 5500 + if (flag & SF_UNI_BLOCK) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#endif + break; + default: + break; + } + } + wiz_sock_close(sn); +// M20150601 +#if _WIZCHIP_ == 5300 + setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | + (((uint16_t)(flag & 0x02)) << 7)); +#else + setSn_MR(sn, (protocol | (flag & 0xF0))); +#endif + if (!port) { + port = sock_any_port++; + if (sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn, port); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn)) + ; + // A20150401 : For release the previous sock_io_mode + sock_io_mode &= ~(1 << sn); + // + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + // M20150601 : repalce 0 with PACK_COMPLETED + // sock_pack_info[sn] = 0; + sock_pack_info[sn] = PACK_COMPLETED; + // + while (getSn_SR(sn) == SOCK_CLOSED) + ; + return (int8_t)sn; +} + +int8_t wiz_sock_close(uint8_t sn) { + CHECK_SOCKNUM(); +// A20160426 : Applied the erratum 1 of W5300 +#if (_WIZCHIP_ == 5300) + // M20160503 : Wrong socket parameter. s -> sn + // if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != + // getSn_TxMAX(s)) ) + if (((getSn_MR(sn) & 0x0F) == Sn_MR_TCP) && + (getSn_TX_FSR(sn) != getSn_TxMAX(sn))) { + uint8_t destip[4] = {0, 0, 0, 1}; + // TODO + // You can wait for completing to sending data; + // wait about 1 second; + // if you have completed to send data, skip the code of erratum 1 + // ex> wait_1s(); + // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue; + // + // M20160503 : The socket() of close() calls close() itself again. It + // occures a infinite loop - close()->socket()->close()->socket()-> ~ + // socket(s,Sn_MR_UDP,0x3000,0); + // sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown + // destination(0.0.0.1). + setSn_MR(sn, Sn_MR_UDP); + setSn_PORTR(sn, 0x3000); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn) != 0) + ; + while (getSn_SR(sn) != SOCK_UDP) + ; + wiz_sock_sendto( + sn, destip, 1, destip, + 0x3000); // send the dummy data to an unknown destination(0.0.0.1). + }; +#endif + setSn_CR(sn, Sn_CR_CLOSE); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + // A20150401 : Release the sock_io_mode of socket n. + sock_io_mode &= ~(1 << sn); + // + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while (getSn_SR(sn) != SOCK_CLOSED) + ; + return SOCK_OK; +} + +int8_t wiz_sock_listen(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + setSn_CR(sn, Sn_CR_LISTEN); + while (getSn_CR(sn)) + ; + while (getSn_SR(sn) != SOCK_LISTEN) { + wiz_sock_close(sn); + return SOCKERR_SOCKCLOSED; + } + return SOCK_OK; +} + +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return + // SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; + } + // + + if (port == 0) return SOCKERR_PORTZERO; + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + setSn_CR(sn, Sn_CR_CONNECT); + while (getSn_CR(sn)) + ; + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_ESTABLISHED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } + } + + return SOCK_OK; +} + +int8_t wiz_sock_disconnect(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_CR(sn, Sn_CR_DISCON); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending &= ~(1 << sn); + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_CLOSED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } + } + return SOCK_OK; +} + +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t freesize = 0; + + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) + return SOCKERR_SOCKSTATUS; + if (sock_is_sending & (1 << sn)) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); +// M20150401 : Typing Error +//#if _WZICHIP_ == 5200 +#if _WIZCHIP_ == 5200 + if (getSn_TX_RD(sn) != sock_next_rd[sn]) { + setSn_CR(sn, Sn_CR_SEND); + while (getSn_CR(sn)) + ; + return SOCK_BUSY; + } +#endif + sock_is_sending &= ~(1 << sn); + } else if (tmp & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } else + return SOCK_BUSY; + } + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + } + wiz_send_data(sn, buf, len); +#if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; +#endif + +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending |= (1 << sn); + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t recvsize = 0; +// A20150601 : For integarating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t head[2]; + uint16_t mr; +#endif + // + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if (recvsize < len) len = recvsize; + +// A20150601 : For Integrating with W5300 +#if _WIZCHIP_ == 5300 + // sock_pack_info[sn] = PACK_COMPLETED; // for clear + if (sock_remained_size[sn] == 0) { +#endif + // + while (1) { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) { + if (tmp == SOCK_CLOSE_WAIT) { + if (recvsize != 0) + break; + else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } else { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if ((sock_io_mode & (1 << sn)) && (recvsize == 0)) return SOCK_BUSY; + if (recvsize != 0) break; + }; +#if _WIZCHIP_ == 5300 + } +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 + if ((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) { + mr = getMR(); + if ((getSn_MR(sn) & Sn_MR_ALIGN) == 0) { + wiz_recv_data(sn, head, 2); + if (mr & MR_FS) + recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); + else + recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); + sock_pack_info[sn] = PACK_FIRST; + } + sock_remained_size[sn] = recvsize; + } + if (len > sock_remained_size[sn]) len = sock_remained_size[sn]; + recvsize = len; + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf = sock_remained_byte[sn]; + buf++; + sock_pack_info[sn] &= ~(PACK_FIFOBYTE); + recvsize -= 1; + sock_remained_size[sn] -= 1; + } + if (recvsize != 0) { + wiz_recv_data(sn, buf, recvsize); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + } + sock_remained_size[sn] -= recvsize; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; + if (recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; + } else + sock_pack_info[sn] = PACK_COMPLETED; + if (getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; + // len = recvsize; +#else + if (recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; +#endif + + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port) { + uint8_t tmp = 0; + uint16_t freesize = 0; + uint32_t taddr; + + CHECK_SOCKNUM(); + switch (getSn_MR(sn) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + // break; + // #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + break; + // #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + //{ + // uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + //} + // + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if ((taddr == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_IPINVALID; + if ((port == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); + //#if ( _WIZCHIP_ < 5200 ) + if ((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) + return SOCKERR_SOCKSTATUS; + //#else + // if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + //#endif + + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + getSIPR((uint8_t *)&taddr); + if (taddr == 0) { + getSUBR((uint8_t *)&taddr); + setSUBR((uint8_t *)"\x00\x00\x00\x00"); + } else + taddr = 0; +#endif + +// A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + // + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + while (1) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + // M:20131104 + // else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if (tmp & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); +// M20150409 : Fixed the lost of sign bits by type casting. +// len = (uint16_t)SOCKERR_TIMEOUT; +// break; +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + return SOCKERR_TIMEOUT; + } + //////////// + } +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port) { +// M20150601 : For W5300 +#if _WIZCHIP_ == 5300 + uint16_t mr; + uint16_t mr1; +#else + uint8_t mr; +#endif + // + uint8_t head[8]; + uint16_t pack_len = 0; + + CHECK_SOCKNUM(); + // CHECK_SOCKMODE(Sn_MR_UDP); +// A20150601 +#if _WIZCHIP_ == 5300 + mr1 = getMR(); +#endif + + switch ((mr = getSn_MR(sn)) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_IPRAW: + case Sn_MR_MACRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if (sock_remained_size[sn] == 0) { + while (1) { + pack_len = getSn_RX_RSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (pack_len == 0)) return SOCK_BUSY; + if (pack_len != 0) break; + }; + } + // D20150601 : Move it to bottom + // sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) { + case Sn_MR_UDP: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 8); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + // A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + if (mr1 & MR_FS) { + addr[0] = head[1]; + addr[1] = head[0]; + addr[2] = head[3]; + addr[3] = head[2]; + *port = head[5]; + *port = (*port << 8) + head[4]; + sock_remained_size[sn] = head[7]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; + } else { +#endif + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; +#if _WIZCHIP_ == 5300 + } +#endif + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + // A20150601 : For W5300 + len = pack_len; +#if _WIZCHIP_ == 5300 + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf++ = sock_remained_byte[sn]; + pack_len -= 1; + sock_remained_size[sn] -= 1; + sock_pack_info[sn] &= ~PACK_FIFOBYTE; + } +#endif + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + case Sn_MR_MACRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 2); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2; +#if _WIZCHIP_ == W5300 + if (sock_remained_size[sn] & 0x01) + sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; + else + sock_remained_size[sn] -= 4; +#endif + if (sock_remained_size[sn] > 1514) { + wiz_sock_close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); + break; + //#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 6); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + // M20150401 : For Typing Error + // sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + //#endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn, Sn_CR_RECV); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_remained_size[sn] -= pack_len; + // M20150601 : + // if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; +#if _WIZCHIP_ == 5300 + if (pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; +#endif + } else + sock_pack_info[sn] = PACK_COMPLETED; +#if _WIZCHIP_ == 5300 + pack_len = len; +#endif + // + // M20150409 : Explicit Type Casting + // return pack_len; + return (int32_t)pack_len; +} + +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg) { + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch (cstype) { + case CS_SET_IOMODE: + tmp = *((uint8_t *)arg); + if (tmp == SOCK_IO_NONBLOCK) + sock_io_mode |= (1 << sn); + else if (tmp == SOCK_IO_BLOCK) + sock_io_mode &= ~(1 << sn); + else + return SOCKERR_ARG; + break; + case CS_GET_IOMODE: + // M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t *)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t *)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t *)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t *)arg) = getSn_IR(sn); + break; +#if _WIZCHIP_ != 5100 + case CS_SET_INTMASK: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTMASK: + *((uint8_t *)arg) = getSn_IMR(sn); + break; +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + // M20131220 : Remove warning + // uint8_t tmp; + CHECK_SOCKNUM(); + switch (sotype) { + case SO_TTL: + setSn_TTL(sn, *(uint8_t *)arg); + break; + case SO_TOS: + setSn_TOS(sn, *(uint8_t *)arg); + break; + case SO_MSS: + setSn_MSSR(sn, *(uint16_t *)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t *)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ > 5200 + if (getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; +#endif + setSn_CR(sn, Sn_CR_SEND_KEEP); + while (getSn_CR(sn) != 0) { + // M20131220 + // if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn, *(uint8_t *)arg); + break; +#endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + CHECK_SOCKNUM(); + switch (sotype) { + case SO_FLAG: + *(uint8_t *)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t *)arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t *)arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint16_t *)arg = getSn_MSSR(sn); + break; + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + *(uint16_t *)arg = getSn_DPORT(sn); + break; +#if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t *)arg = getSn_KPALVTR(sn); + break; +#endif + case SO_SENDBUF: + *(uint16_t *)arg = getSn_TX_FSR(sn); + break; + case SO_RECVBUF: + *(uint16_t *)arg = getSn_RX_RSR(sn); + break; + case SO_STATUS: + *(uint8_t *)arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if (getSn_MR(sn) & Sn_MR_TCP) + *(uint16_t *)arg = getSn_RX_RSR(sn); + else + *(uint16_t *)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + // CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ != 5300 + if ((getSn_MR(sn) == Sn_MR_TCP)) return SOCKERR_SOCKMODE; +#endif + *(uint8_t *)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c new file mode 100644 index 000000000..7dbba1b46 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c @@ -0,0 +1,35 @@ + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" + +// #define SPI1_CS_GPIONUM 24 + +static x_base g_w5500_spi_lock; +/** + * @brief 进入临界区 + * @retval None + */ +void spi_enter_cris(void) { g_w5500_spi_lock = DisableLocalInterrupt(); } +/** + * @brief 退出临界区 + * @retval None + */ +void spi_exit_cris(void) { EnableLocalInterrupt(g_w5500_spi_lock); } + +/** + * @brief 片选信号输出低电平 + * @retval None + */ +void spi_select_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_LOW); } +/** + * @brief 片选信号输出高电平 + * @retval None + */ +void spi_deselete_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_HIGH); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c new file mode 100755 index 000000000..e98739488 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c @@ -0,0 +1,255 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to +//! M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case +//! _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include +#include "w5500.h" + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +#if (_WIZCHIP_ == 5500) +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) { + uint8_t ret; + uint8_t spi_data[3]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + // if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte + // operation + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint16_t getSn_TX_FSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + } + } while (val != val1); + return val; +} + +uint16_t getSn_RX_RSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + } + } while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_TX_WR(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel, wizdata, len); + + ptr += len; + setSn_TX_WR(sn, ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_RX_RD(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) { + uint16_t ptr = 0; + + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn, ptr); +} + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c new file mode 100644 index 000000000..c424ed177 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c @@ -0,0 +1,250 @@ + +#include "wiz_ping.h" + +#include +#include +#include +#include +#include + +#define Sn_PROTO(ch) (0x001408 + (ch << 5)) + +#define PING_BIND_PORT 3000 + +PINGMSGR PingRequest = {0}; +PINGMSGR PingReply = {0}; + +static uint16_t ping_RandomID = 0x1234; +static uint16_t ping_RandomSeqNum = 0x4321; +uint8_t ping_reply_received = 0; +uint8_t ping_req = 0; +uint8_t ping_rep = 0; +uint8_t ping_cnt = 0; +uint8_t ping_rep_buf[150] = {0}; + +// ping状态机 +#define PING_STA_FREE 0 +#define PING_STA_OPEN 1 +#define PING_STA_SEND 2 +#define PING_STA_WAIT 3 +#define PING_STA_CLOSE 4 + +uint8_t ping_sta = PING_STA_FREE; + +//当前ping的设备的序号 +uint8_t ping_socket = 0; + +#define bswap_16(A) ((((uint16)(A)&0xff00) >> 8) | (((uint16)(A)&0x00ff) << 8)) + +uint16_t htons(uint16_t n) { + union { + int i; + char c; + } u = {1}; + return u.c ? bswap_16(n) : n; +} + +uint16_t checksum(uint8_t *src, uint32_t len) { + uint16_t sum, tsum, i, j; + uint32_t lsum; + + j = len >> 1; + lsum = 0; + + for (i = 0; i < j; i++) { + tsum = src[i * 2]; + tsum = tsum << 8; + tsum += src[i * 2 + 1]; + lsum += tsum; + } + + if (len % 2) { + tsum = src[i * 2]; + lsum += (tsum << 8); + } + + sum = lsum; + sum = ~(sum + (lsum >> 16)); + return (uint16_t)sum; +} + +/** + *@brief 设定次数ping外网IP函数 + *@param sn- socket number + *@param addr- 外网IP地址 + *@param pCount- ping的次数 + *@return ping成功次数 + */ +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr) { + uint16_t rlen, cnt, i; + + ping_reply_received = 0; + ping_req = 0; + ping_rep = 0; + KPrintf("Ping:%d.%d.%d.%d\r\n", (addr[0]), (addr[1]), (addr[2]), (addr[3])); + + for (i = 0; i < pCount + 1; i++) /*循环ping pCount次*/ + { + switch (getSn_SR(sn)) /*获取socket状态*/ + { + case SOCK_CLOSED: /*socket关闭状态*/ + { + wiz_sock_close(sn); + /* Create Socket */ + IINCHIP_WRITE(Sn_PROTO(sn), IPPROTO_ICMP); /*设置ICMP 协议*/ + if (wiz_socket(sn, Sn_MR_IPRAW, PING_BIND_PORT, 0) != + 0) /*判断ip raw模式socket是否开启*/ + { + } + /* Check socket register */ + while (getSn_SR(sn) != SOCK_IPRAW) { + MdelayKTask(50); + }; + break; + } + case SOCK_IPRAW: /*ip raw模式*/ + { + cnt = 0; + ping_request(sn, addr); /*发送Ping请求*/ + ping_req++; + while (1) { + if ((rlen = getSn_RX_RSR(sn)) > 0) { + rlen = ping_reply(sn, addr, rlen); /*获取回复信息*/ + ping_rep++; + if (ping_reply_received) { + break; + } + } + if ((cnt > 300)) { + cnt = 0; + break; + } else { + cnt++; + MdelayKTask(10); + } + } + break; + } + default: + break; + } + if (ping_req >= pCount) { + wiz_sock_close(sn); + } + } + return ping_rep; +} + +/** + *@brief ping请求函数 + *@param sn- socket number + *@param addr- P地址 + *@return 无 + */ +uint8_t ping_request(uint8_t sn, uint8_t *addr) { + uint8_t *buffer; + uint16_t i, temp_len = 0; + ping_reply_received = 0; /*ping 回复初始化标志位*/ + PingRequest.Type = PING_REQUEST; /*Ping-Request*/ + PingRequest.Code = CODE_ZERO; /*总是 '0'*/ + PingRequest.ID = htons(ping_RandomID++); /*设置ping响应ID为随机的整型变量*/ + PingRequest.SeqNum = + htons(ping_RandomSeqNum++); /*设置ping响应的序列号为随机整形变量*/ + for (i = 0; i < PING_BUF_LEN; i++) { + PingRequest.Data[i] = (i) % 8; /*ping相应的数在'0'~'8‘*/ + } + PingRequest.CheckSum = 0; + /* 计算响应次数*/ + PingRequest.CheckSum = + htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest))); + + /*发送ping响应到目的方 */ + if (wiz_sock_sendto(sn, (uint8_t *)&PingRequest, sizeof(PingRequest), addr, + PING_BIND_PORT) == 0) { + KPrintf("Fail to send ping-reply packet\r\n"); + } else { + KPrintf("ping send\n"); + } + return 0; +} + +/** + *@brief 解析Ping回复 + *@param sn- socket number + *@param addr- Ping地址 + *@return 无 + */ +uint8_t ping_reply(uint8_t sn, uint8_t *addr, uint16_t rlen) { + uint16_t tmp_checksum; + uint16_t len; + uint16_t i; + + uint16_t port = PING_BIND_PORT; + PINGMSGR PingReply; + + memset(ping_rep_buf, 0, sizeof(ping_rep_buf)); + len = wiz_sock_recvfrom(sn, ping_rep_buf, rlen, addr, + &port); /*从目的端接收数据*/ + + if (ping_rep_buf[0] == PING_REPLY) { + PingReply.Type = ping_rep_buf[0]; + PingReply.Code = ping_rep_buf[1]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = ~checksum(ping_rep_buf, len); /*检查ping回复的次数*/ + if (tmp_checksum != 0xffff) { + KPrintf("tmp_checksum = %x\r\n", tmp_checksum); + } else { + KPrintf("Reply from %3d.%3d.%3d.%3d ID=%x Byte=%d\r\n\r\n", (addr[0]), + (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), (rlen + 6)); + ping_reply_received = 1; /*当退出ping回复循环时,设置ping回复标志为1*/ + } + } else if (ping_rep_buf[0] == PING_REQUEST) { + PingReply.Code = ping_rep_buf[1]; + PingReply.Type = ping_rep_buf[2]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = PingReply.CheckSum; /*检查ping回复次数*/ + PingReply.CheckSum = 0; + if (tmp_checksum != PingReply.CheckSum) { + KPrintf(" \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), + htons(PingReply.CheckSum)); + } else { + } + KPrintf( + " Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n", + (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), + (PingReply.SeqNum), (rlen + 6)); + ping_reply_received = 1; /* 当退出ping回复循环时,设置ping回复标志为1 + */ + } else { + KPrintf(" Unkonwn msg. \n"); + } + return 0; +} + +void wiz_ping_test(int argc, char *argv[]) { + uint32_t tmp_ip[4]; + uint8_t target_ip[4]; + if (argc >= 2) { + KPrintf("This is a Ping test: %s\n", argv[1]); + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], + &tmp_ip[3]); + target_ip[0] = (uint8_t)tmp_ip[0]; + target_ip[1] = (uint8_t)tmp_ip[1]; + target_ip[2] = (uint8_t)tmp_ip[2]; + target_ip[3] = (uint8_t)tmp_ip[3]; + ping_count(ping_socket, 5, target_ip); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + ping, wiz_ping_test, ping to given addr); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h new file mode 100644 index 000000000..3ead801b8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h @@ -0,0 +1,35 @@ +#ifndef _WIZ_PING_H_ +#define _WIZ_PING_H_ + +#include "socket.h" +#include "w5500.h" + +#define PING_BUF_LEN 32 +#define PING_REQUEST 8 +#define PING_REPLY 0 +#define CODE_ZERO 0 + +#define SOCKET_ERROR 1 +#define TIMEOUT_ERROR 2 +#define SUCCESS 3 +#define REPLY_ERROR 4 + +typedef struct pingmsg { + uint8_t Type; // 0 - Ping Reply, 8 - Ping Request + uint8_t Code; // Always 0 + uint16_t CheckSum; // Check sum + uint16_t ID; // Identification + uint16_t SeqNum; // Sequence Number + int8_t Data[PING_BUF_LEN]; // Ping Data : 1452 = IP RAW MTU - + // sizeof(Type+Code+CheckSum+ID+SeqNum) +} PINGMSGR; + +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr); + +uint8_t ping_request(uint8_t s, uint8_t *addr); + +uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen); + +void Ethernet_ping_service_deal(uint8_t sn); + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c new file mode 100755 index 000000000..1407c852f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c @@ -0,0 +1,862 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readdata() & +//! wizchip_bus_writedata() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting +//! it into uint8_t* For remove the warning when pointer type size is +//! not 32bit. If ptrdiff_t doesn't support in your complier, You +//! should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +// A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" + +///////////// +// M20150401 : Remove ; in the default callback function such as +// wizchip_cris_enter(), wizchip_cs_select() and etc. +///////////// + +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_enter(void) {}; +void wizchip_cris_enter(void) {} + +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_exit(void) {}; +void wizchip_cris_exit(void) {} + +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_select(void) {}; +void wizchip_cs_select(void) {} + +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_deselect(void) {}; +void wizchip_cs_deselect(void) {} + +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t +// *)((ptrdiff_t) AddrSel)); } +iodata_t wizchip_bus_readdata(uint32_t AddrSel) { + return *((volatile iodata_t *)((ptrdiff_t)AddrSel)); +} + +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile +// uint8_t*)((ptrdiff_t)AddrSel)) = wb; } +void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { + *((volatile iodata_t *)((ptrdiff_t)AddrSel)) = wb; +} + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// uint8_t wizchip_spi_readbyte(void) {return 0;}; +uint8_t wizchip_spi_readbyte(void) { return 0; } + +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writebyte(uint8_t wb) {}; +void wizchip_spi_writebyte(uint8_t wb) {} + +/** + * @brief Default function to burst read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_readburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @brief Default function to burst write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_writeburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @\ref _WIZCHIP instance + */ +// +// M20150401 : For a compiler didnot support a member of structure +// Replace the assignment of struct members with the assingment of +// array +// +/* +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; +*/ +_WIZCHIP WIZCHIP = {_WIZCHIP_IO_MODE_, + _WIZCHIP_ID_, + {wizchip_cris_enter, wizchip_cris_exit}, + {wizchip_cs_select, wizchip_cs_deselect}, + { + {// M20150601 : Rename the function + // wizchip_bus_readbyte, + // wizchip_bus_writebyte + wizchip_bus_readdata, wizchip_bus_writedata}, + + }}; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)) { + if (!cris_en || !cris_ex) { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } else { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)) { + if (!cs_sel || !cs_desel) { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } else { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +// M20150515 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)) +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)) + ; + // M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if (!bus_rb || !bus_wb) { + WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata; + WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata; + } else { + WIZCHIP.IF.BUS._read_data = bus_rb; + WIZCHIP.IF.BUS._write_data = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +// 20140626 Eric Added for SPI burst operations +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rb; + WIZCHIP.IF.SPI._write_burst = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg) { +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + uint8_t tmp = 0; +#endif + uint8_t *ptmp[2] = {0, 0}; + switch (cwtype) { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if (arg != 0) { + ptmp[0] = (uint8_t *)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind *)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind *)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind *)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind *)arg) = wizchip_getinterruptmask(); + break; +// M20150601 : This can be supported by W5200, W5500 +//#if _WIZCHIP_ > W5100 +#if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t *)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t *)arg = getINTLEVEL(); + break; +#endif + case CW_GET_ID: + ((uint8_t *)arg)[0] = WIZCHIP.id[0]; + ((uint8_t *)arg)[1] = WIZCHIP.id[1]; + ((uint8_t *)arg)[2] = WIZCHIP.id[2]; + ((uint8_t *)arg)[3] = WIZCHIP.id[3]; + ((uint8_t *)arg)[4] = WIZCHIP.id[4]; + ((uint8_t *)arg)[5] = WIZCHIP.id[5]; + ((uint8_t *)arg)[6] = 0; + break; +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t *)arg); +#endif +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; +#endif + default: + return -1; + } + return 0; +} + +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg) { + + switch (cntype) { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo *)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo *)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type *)arg); + case CN_GET_NETMODE: + *(netmode_type *)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout *)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout *)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) { + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; +// A20150601 +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + uint16_t mr = (uint16_t)getMR(); + setMR(mr | MR_IND); +#endif + // + getSHAR(mac); + getGAR(gw); + getSUBR(sn); + getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay +// A2015051 : For indirect bus mode +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + setMR(mr | MR_IND); +#endif + // + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize) { + int8_t i; +#if _WIZCHIP_ < W5200 + int8_t j; +#endif + int8_t tmp = 0; + wizchip_sw_reset(); + if (txsize) { + tmp = 0; +// M20150601 : For integrating with W5300 +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (txsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += txsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += txsize[i]; + +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 + j = 0; + while ((txsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_TXBUF_SIZE(i, j); +#else + setSn_TXBUF_SIZE(i, txsize[i]); +#endif + } + +#endif + } + + if (rxsize) { + tmp = 0; +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (rxsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += rxsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += rxsize[i]; +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // add condition for w5100 + j = 0; + while ((rxsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_RXBUF_SIZE(i, j); +#else + setSn_RXBUF_SIZE(i, rxsize[i]); +#endif + } +#endif + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) { + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + ir |= (1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ <= W5100S + ir |= sir; + setIR(ir); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIR(((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF))); +#else + setIR(ir); + // M20200227 : For clear + // setSIR(sir); + for (ir = 0; ir < 8; ir++) { + if (sir & (0x01 << ir)) + setSn_IR(ir, 0xff); + } + +#endif +} + +intr_kind wizchip_getinterrupt(void) { + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ <= W5100S + ir = getIR(); + sir = ir & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIR(); + ir = (uint8_t)(ret >> 8); + sir = (uint8_t)ret; +#else + ir = getIR(); + sir = getSIR(); +#endif + +// M20150601 : For Integrating with W5300 +//#if _WIZCHIP_ < W5500 +#if _WIZCHIP_ < W5200 + ir &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) { + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + simr &= 0x0F; + imr |= simr; + setIMR(imr); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIMR(((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF))); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) { + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ < W5200 + imr = getIMR(); + simr = imr & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIMR(); + imr = (uint8_t)(ret >> 8); + simr = (uint8_t)ret; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) { + int8_t tmp = PHY_LINK_OFF; +#if _WIZCHIP_ == W5100S + if (getPHYSR() & PHYSR_LNK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5500 + if (getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > W5100 + +int8_t wizphy_getphypmode(void) { + int8_t tmp = 0; +#if _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#elif _WIZCHIP_ == 5500 + if ((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#else + tmp = -1; +#endif + return tmp; +} +#endif + +#if _WIZCHIP_ == W5100S +void wizphy_reset(void) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + tmp |= BMCR_RESET; + wiz_mdio_write(PHYMDIO_BMCR, tmp); + while (wiz_mdio_read(PHYMDIO_BMCR) & BMCR_RESET) { + } +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= BMCR_AUTONEGO; + else { + tmp &= ~BMCR_AUTONEGO; + if (phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DUP; + } else { + tmp &= ~BMCR_DUP; + } + if (phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPEED; + } else { + tmp &= ~BMCR_SPEED; + } + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + phyconf->by = PHY_CONFBY_SW; + if (tmp & BMCR_AUTONEGO) { + phyconf->mode = PHY_MODE_AUTONEGO; + } else { + phyconf->mode = PHY_MODE_MANUAL; + if (tmp & BMCR_DUP) + phyconf->duplex = PHY_DUPLEX_FULL; + else + phyconf->duplex = PHY_DUPLEX_HALF; + if (tmp & BMCR_SPEED) + phyconf->speed = PHY_SPEED_100; + else + phyconf->speed = PHY_SPEED_10; + } +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + if (tmp & BMCR_PWDN) + return 0; + } else { + if ((tmp & BMCR_PWDN) != BMCR_PWDN) + return 0; + } + return -1; +} + +#endif +#if _WIZCHIP_ == W5500 +void wizphy_reset(void) { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + if (phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else { + if (phyconf->duplex == PHY_DUPLEX_FULL) { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } else { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf *phyconf) { + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = + (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if ((tmp & PHYCFGR_OPMD) == 0) + return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if (pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if (pmode == PHY_POWER_DOWN) { + if (tmp & PHYCFGR_OPMDC_PDOWN) + return 0; + } else { + if (tmp & PHYCFGR_OPMDC_ALLA) + return 0; + } + return -1; +} +#endif + +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo) { + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo) { + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0] = _DNS_[0]; + pnetinfo->dns[1] = _DNS_[1]; + pnetinfo->dns[2] = _DNS_[2]; + pnetinfo->dns[3] = _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) { + uint8_t tmp = 0; +#if _WIZCHIP_ != W5500 + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) + return -1; +#else + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) + return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) { return (netmode_type)getMR(); } + +void wizchip_settimeout(wiz_NetTimeout *nettime) { + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout *nettime) { + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c index defc6e6b6..0c7167441 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c @@ -72,31 +72,15 @@ static struct io_config IOCONFIG(BSP_UART2_RXD_PIN, FUNC_UART2_RX), #endif #ifdef BSP_USING_UART3 - IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_RX), - IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_TX), + IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_TX), + IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_RX), #endif #ifdef BSP_USING_I2C IOCONFIG(BSP_I2C_SDA, FUNC_GPIO3), IOCONFIG(BSP_I2C_SCL, FUNC_GPIO4), #endif #ifdef BSP_USING_TOUCH - // IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)), - IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FUNC_GPIOHS30)), -#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_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)), #endif #ifdef BSP_USING_SOFT_SPI @@ -106,6 +90,17 @@ static struct io_config IOCONFIG(BSP_SOFT_SPI_NCS_PIN, HS_GPIO(FPIOA_SOFT_SPI_NCS)), #endif +#ifdef BSP_USING_CAMERA + IOCONFIG(BSP_DVP_RST_PIN,FUNC_CMOS_RST), + IOCONFIG(BSP_DVP_PWDN_PIN, FUNC_CMOS_PWDN), + IOCONFIG(BSP_DVP_XCLK_PIN,FUNC_CMOS_XCLK), + IOCONFIG(BSP_DVP_PCLK_PIN,FUNC_CMOS_PCLK), + IOCONFIG(BSP_DVP_HSYNC_PIN,FUNC_CMOS_HREF), + IOCONFIG(BSP_DVP_VSYNC_PIN,FUNC_CMOS_VSYNC), + IOCONFIG(BSP_DVP_SCL_PIN,FUNC_SCCB_SCLK), + IOCONFIG(BSP_DVP_SDA_PIN,FUNC_SCCB_SDA), +#endif + #ifdef BSP_USING_LORA IOCONFIG(BSP_E220_M0_PIN, HS_GPIO(FUNC_GPIOHS10)), IOCONFIG(BSP_E220_M1_PIN, HS_GPIO(FUNC_GPIOHS11)), @@ -159,6 +154,11 @@ int IoConfigInit(void) sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); #endif +#ifdef BSP_USING_CAMERA + sysctl_set_power_mode(SYSCTL_POWER_BANK7,SYSCTL_POWER_V18); + // sysctl_set_power_mode(SYSCTL_POWER_BANK7,SYSCTL_POWER_V18); +#endif + for(i = 0; i < count; i++) { ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func); diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_dvp.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_dvp.h new file mode 100644 index 000000000..178fc5ddd --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_dvp.h @@ -0,0 +1,34 @@ +/* +* 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_dvp.h +* @brief define edu-riscv64-board DVP init function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-21 +*/ +#ifndef CONNECT_DVP_H +#define CONNECT_DVP_H +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwDvpInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_touch.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_touch.h index 30ed6008d..3ac99e392 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_touch.h +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_touch.h @@ -64,6 +64,10 @@ typedef enum _touch_event #define GTP_REG_CONFIG_DATA 0x8047 #define GTP_REG_VERSION 0x8140 +#define LCD_SIZE 320 +#define TOUCH_WIDTH 1000 +#define TOUCH_HEIGHT 660 + #define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0])) int HwTouchInit(void); diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h new file mode 100644 index 000000000..43359e8f4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan + * PSL v2. You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY + * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the + * Mulan PSL v2 for more details. + */ + +/** + * @file connect_w5500.h + * @brief define aiit-riscv64-board spi function and struct + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-10-16 + */ + +#ifndef _CONNECT_W5500_H_ +#define _CONNECT_W5500_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static struct Bus *spi_bus; + +int HwWiznetInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h index f48e34c0d..4c4f86972 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h @@ -9,19 +9,19 @@ */ /** -* @file drv_io_config.h -* @brief define edu-riscv64-board io configure -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2022-10-17 -*/ + * @file drv_io_config.h + * @brief define edu-riscv64-board io configure + * @version 2.0 + * @author AIIT XUOS Lab + * @date 2022-10-17 + */ /************************************************* File name: drv_io_config.h Description: define edu-riscv64-board io configure Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.h for references https://github.com/RT-Thread/rt-thread/tree/v4.0.2 -History: +History: 1. Date: 2022-10-17 Author: AIIT XUOS Lab Modification: add edu-riscv64-board io configure define @@ -30,10 +30,9 @@ Modification: add edu-riscv64-board io configure define #ifndef __DRV_IO_CONFIG_H__ #define __DRV_IO_CONFIG_H__ -enum HS_GPIO_CONFIG -{ +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, @@ -47,48 +46,42 @@ enum HS_GPIO_CONFIG #ifdef BSP_SPI1_USING_SS3 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 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 +#ifdef BSP_USING_W5500 + WIZ_RST_PIN, WIZ_INT_PIN, #endif + GPIO_ALLOC_START /* index of gpio driver start */ +} +; #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 +#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 BSP_SOFT_SPI_SCK_PIN 26 #define BSP_SOFT_SPI_MIOS_PIN 25 #define BSP_SOFT_SPI_MSOI_PIN 27 #define BSP_SOFT_SPI_NCS_PIN 28 +#endif +#ifdef BSP_USING_CAMERA +#define BSP_DVP_RST_PIN 40 +#define BSP_DVP_PWDN_PIN 41 +#define BSP_DVP_XCLK_PIN 42 +#define BSP_DVP_PCLK_PIN 43 +#define BSP_DVP_HSYNC_PIN 44 +#define BSP_DVP_VSYNC_PIN 45 +#define BSP_DVP_SCL_PIN 46 +#define BSP_DVP_SDA_PIN 47 #endif #ifdef BSP_USING_LED @@ -108,6 +101,7 @@ enum HS_GPIO_CONFIG #define BSP_485_DIR_PIN 24 #endif -extern int IoConfigInit(void); + extern int + IoConfigInit(void); #endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/ov2640.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/ov2640.h new file mode 100644 index 000000000..4f1240b73 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/ov2640.h @@ -0,0 +1,38 @@ +/* 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. + */ +#ifndef _OV2640_H +#define _OV2640_H + +#include + +#define OV2640_ADDR 0x60 + +struct CameraCfg +{ + uint16_t window_w; + uint16_t window_h; + uint16_t window_xoffset; + uint16_t window_yoffset; + uint16_t output_w; + uint16_t output_h; + uint8_t gain; + uint8_t gain_manu_enable; +}; + +int ov2640_init(void); +int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id); +int SensorConfigure(struct CameraCfg* cfg_info); + +#endif /* _OV2640_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h new file mode 100755 index 000000000..91e1a7bd9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h @@ -0,0 +1,585 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has + * much similar name and interface. But there is a little bit of difference. + * @details + * Comparison between WIZnet and Berkeley SOCKET APIs + * + * + * + * + * + * + * + * + * + * + * + * + * + *
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating + * a SOCKET but also binding a local port number, and listen() of WIZnet is not + * only listening to connection request from client but also accepting the + * connection request. \n When you program "TCP SERVER" with Berkeley SOCKET + * API, you can use only one listen port. When the listen SOCKET accepts a + * connection request from a client, it keeps listening. After accepting the + * connection request, a new SOCKET is created and the new SOCKET is used in + * communication with the client. \n Following figure shows network flow diagram + * by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as + * many as 8 listen SOCKET with same port number. \n Because there's no accept() + * in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request + * from a client, it is changed in order to communicate with the client. And the + * changed SOCKET is not listening any more and is dedicated for communicating + * with the client. \n If there're many listen SOCKET with same listen port + * number and a client requests a connection, the SOCKET which has the smallest + * SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY \ + 0 ///< Socket is busy on processing the operation. Valid only Non-block IO + ///< Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT \ + (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address + ///< when Sn_MR_TCP +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE \ + (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS \ + (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN \ + (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER \ + (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN \ + (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN \ + (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, + ///< multicast and own packet +#define SF_IGMP_VER2 \ + (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP + ///< version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE \ + (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 +#define SF_BROAD_BLOCK \ + (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast + ///< packet. Valid only in W5500 +#define SF_MULTI_BLOCK \ + (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in + ///< W5500 +#define SF_IPv6_BLOCK \ + (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in + ///< W5500 +#define SF_UNI_BLOCK \ + (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only + ///< in W5500 +#endif + +// A201505 : For W5300 +#if _WIZCHIP_ == 5300 +#define SF_TCP_ALIGN \ + 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN +#endif + +#define SF_IO_NONBLOCK \ + 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST \ + 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When + ///< W5300, This flag can be applied) +#define PACK_REMAINED \ + 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. + ///< (When W5300, This flag can be applied) +#define PACK_COMPLETED \ + 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + ///< (When W5300, This flag can be applied) +// A20150601 : For Integrating with W5300 +#define PACK_FIFOBYTE \ + 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR. +// + +#ifndef AF_WIZ +#define AF_WIZ 46 +#endif + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref + * SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n Valid + * flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref + * SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as + * TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t wiz_sock_close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is + * established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t wiz_sock_listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and + * port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediately. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request + * connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned + * immediately\n + */ +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as + parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. + \n + * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t wiz_sock_disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data + * greater than socket buffer size. \n In block io mode, It doesn't return until + * data send is completed - socket buffer size is greater than data. \n In + * non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is + * not enough. \n + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in + * the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data + * greater than socket buffer size. \n In block io mode, it doesn't return until + * data reception is completed - data is filled as len in socket buffer. + * \n In non-block io mode, it return @ref SOCK_BUSY immediately when len + * is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket + * \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port + * number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP + * address and port number passed as parameter.\n Even if the connectionless + * socket has been previously connected to a specific address, the address and + * port number parameters override the destination address for that particular + * datagram only. + * @note In block io mode, It doesn't return until data send is completed - + * socket buffer size is greater than len. In non-block io mode, It + * return @ref SOCK_BUSY immediately when socket buffer is not enough. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed + * \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to + * receive the data in other then TCP mode. \n This function is used to receive + * UDP and MAC_RAW mode, and handle the header as well. This function can divide + * to received the packet data. On the MACRAW SOCKET, the addr and port + * parameters are ignored. + * @note In block io mode, it doesn't return until data reception is + * completed - data is filled as len in socket buffer In non-block io + * mode, it return @ref SOCK_BUSY immediately when len is greater than + * data size in socket buffer. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet + * sized. When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. It is valid only when the first call recvfrom for + * receiving the packet. When it is valid, @ref packinfo[7] should be set as + * '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the + * packet. When it is valid, @ref packinfo[7] should be set as '1' after call + * @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for + * success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port); + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum { + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + // M20150410 : Remove the comma of last member + // SIK_ALL = 0x1F, ///< all interrupt + SIK_ALL = 0x1F ///< all interrupt +} sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum { + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref + ///< SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind +#if _WIZCHIP_ > 5100 + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, + ///< Not supported in W5100 + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref + ///< sockint_kind, Not supported in W5100 +#endif +} ctlsock_type; + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum { + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to + ///< flag in @ref socket(). + SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref + ///< setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref + ///< setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive + ///< packet in TCP mode, Not supported in W5100 +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP + ///< mode, Not supported in W5100, W5200 +#endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt + ///< TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in + ///< socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, + ///< @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in + ///< other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref + ///< PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in + ///< other then TCP mode. +} sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket + * buffer information. Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. + * \n + *
@b cstype @b data type@b + * value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE + * uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
+ * @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 + * ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n + * @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind + * @ref SIK_CONNECTED, etc.
+ * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref + * sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + *
@b sotype @b data type@b + * value
@ref SO_TTL uint8_t 0 ~ 255 + *
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ + * 65535
@ref SO_KEEPALIVESEND null + * null
@ref SO_KEEPALIVEAUTO uint8_t + * 0 ~ 255
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet + * \n + */ +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref + * sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + *
@b sotype @b data type@b + * value
@ref SO_FLAG uint8_t @ref + * SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t + * 0 ~ 255
@ref SO_MSS uint16_t + * 0 ~ 65535
@ref SO_DESTIP + * uint8_t[4]
@ref SO_DESTPORT + * uint16_t
@ref SO_KEEPALIVEAUTO + * uint8_t 0 ~ 255
@ref SO_SENDBUF + * uint16_t 0 ~ 65535
@ref SO_RECVBUF + * uint16_t 0 ~ 65535
@ref SO_STATUS + * uint8_t @ref SOCK_ESTABLISHED, etc..
@ref + * SO_REMAINSIZE uint16_t 0~ 65535
+ * @ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc... + *
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode + * and after call @ref recvfrom(). \n When SO_PACKINFO value is PACK_FIRST and + * the return value of recvfrom() is zero, This means the zero byte UDP data(UDP + * Header only) received. + */ +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif // _SOCKET_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h new file mode 100755 index 000000000..121baab06 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h @@ -0,0 +1,2321 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +// + +#ifndef _W5500_H_ +#define _W5500_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" +#include + + +/// @cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5500) +/// @endcond + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ \ + (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ \ + (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1 + 4 * N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2 + 4 * N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3 + 4 * N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) \ + (ADDR + (N << 8)) //< Increase offset address + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) \ + WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR, VAL) \ + WIZCHIP_WRITE(ADDR, VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR, BUF, LEN) \ + WIZCHIP_READ_BUF(ADDR, BUF, LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR, BUF, LEN) \ + WIZCHIP_WRITE(ADDR, BUF, LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref + * Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref + * Common_register_access_function and @ref Socket_register_access_function + */ + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), + * setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), + * setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), + * getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), + * setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), + * getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() getSn_MSSR(), + * setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), + * setSn_TXBUF_SIZE() \n getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data + * communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, + * Sn_RX_RD, Sn_RX_WR : Data communication + */ + +/** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or + * write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end +//-------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP +//----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + * + * + *
7 6 5 4 32 1 0
RST ReservedWOL PB PPPoE Reserved FARPReserved
+ * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be + * still until the bit will be written to by the host. If @ref IR is not equal + * to x00 INTn PIN is asserted to low until it is x00\n\n Each bit of @ref IR + * defined as follows. + * + * + * + *
7 6 5 43 2 1 0
CONFLICTUNREACH PPPoE MP ReservedReserved Reserved Reserved
+ * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ + * corresponds to each bit of @ref IR. When a bit of @ref _IMR_ is and the + * corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref _IMR_ is an interrupt will not be issued even if the + * corresponding bit of @ref IR is \n\n Each bit of @ref _IMR_ defined as the + * following. + * + * + * + *
7 6 5 43 2 1 0
IM_IR7IM_IR6 IM_IR5 IM_IR4 ReservedReserved Reserved Reserved
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is + * asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt + * will be issued. In other words, if a bit of @ref SIMR is an interrupt will + * be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref _RTR_ configures the retransmission timeout period. The unit of + * timeout period is 100us and the default of @ref _RTR_ is x07D0. And so the + * default timeout period is 200ms(100us X 2000). During the time configured by + * @ref _RTR_, W5500 waits for the peer response to the packet that is + * transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP + * command). If the peer does not respond within the @ref _RTR_ time, W5500 + * retransmits the packet or issues timeout. + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued + * (@ref Sn_IR_TIMEOUT = '1'). + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The + * unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP + * negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is + * acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during + * PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In + * addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, + * Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +//----------------------------- W5500 Socket Registers IOMAP +//----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + * + * + *
7 6 5 4 32 1 0
MULTI/MFENBCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3]Protocol[2] Protocol[1] Protocol[0]
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + * + * + *
Protocol[3] Protocol[2]Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0MACRAW
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) \ + (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, + * CONNECT, LISTEN, SEND, and RECEIVE.\n After W5500 accepts the command, the + * @ref Sn_CR register is automatically cleared to 0x00. Even though @ref Sn_CR + * is cleared to 0x00, the command is still being processed.\n To check whether + * the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server + * mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client + * mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP + * process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) \ + (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as + * establishment, termination, receiving data, timeout).\n When an interrupt + * occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes \n In order to clear the @ref Sn_IR bit, the host should + * write the bit to \n + * + * + * + *
7 6 5 43 2 1 0
ReservedReserved Reserved SEND_OK TIMEOUTRECV DISCON CON
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) \ + (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control + *packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the + *connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received + *the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) \ + (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before + * OPEN command is ordered. + */ +#define Sn_PORT(N) \ + (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n + * when using SEND_MAC command in UDP mode or it indicates that it is acquired + * in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) \ + (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP client + * mode, it configures an IP address of TCP serverbefore CONNECT command. In TCP + * server mode, it indicates an IP address of TCP clientafter successfully + * establishing connection. In UDP mode, it configures an IP address of peer to + * be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) \ + (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP + * clientmode, it configures the listen port number of TCP serverbefore CONNECT + * command. In TCP Servermode, it indicates the port number of TCP client after + * successfully establishing connection. In UDP mode, it configures the port + * number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) \ + (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) + * of Socket n. + */ +#define Sn_MSSR(N) \ + (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) + * of Socket n. It is set before OPEN command. + */ +#define Sn_TOS(N) \ + (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of + * Socket n. It is set before OPEN command. + */ +#define Sn_TTL(N) \ + (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from + * a peer. Although Socket n RX Buffer Block size is initially configured to + * 2Kbytes, user can re-configure its size using @ref Sn_RXBUF_SIZE. The total + * sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. When exceeded, the data + * reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. + * Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to + * a peer. Although Socket n TX Buffer Block size is initially configured to + * 2Kbytes, user can be re-configure its size using @ref Sn_TXBUF_SIZE. The + * total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. When exceeded, + * the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. + * It is initialized to the configured size by @ref Sn_TXBUF_SIZE. Data bigger + * than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the + * bigger data overwrites the previous saved data not yet sent. Therefore, check + * before saving the data to the Socket n TX Buffer, and if data is equal or + * smaller than its checked size, transmit the data with SEND/SEND_MAC command + * after saving the data in Socket n TX buffer. But, if data is bigger than its + * checked size, transmit the data after dividing into the checked size and + * saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) \ + (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP. After its initialization, it is auto-increased by SEND command. SEND + * command transmits the saved data from the current @ref Sn_TX_RD to the @ref + * Sn_TX_WR in the Socket n TX Buffer. After transmitting the saved data, the + * SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. If its + * increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and + * the carry bit occurs), then the carry bit is ignored and will automatically + * update with the lower 16bits value. + */ +#define Sn_TX_RD(N) \ + (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP.\n It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX + * buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased + * value as many as transmitting data size. If the increment value exceeds the + * maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), then the + * carry bit is ignored and will automatically update with the lower 16bits + * value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) \ + (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket + * n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as + * the difference between �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket + * n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) \ + (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read + * or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased + * value as many as the reading size. If the increment value exceeds the maximum + * value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) \ + (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is + * auto-increased by the data reception. If the increased value exceeds the + * maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), then + * the carry bit is ignored and will automatically update with the lower 16bits + * value. + */ +#define Sn_RX_WR(N) \ + (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is + * occurred and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref + * Sn_IR are and the n-th bit of @ref IR is Host is interrupted by asserted INTn + * PIN to low. + */ +#define Sn_IMR(N) \ + (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) \ + (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP + * ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, and ignored in + * other modes. The time unit is 5s. KA packet is transmittable after @ref Sn_SR + * is changed to SOCK_ESTABLISHED and after the data is transmitted or received + * to/from a peer at least once. In case of '@ref Sn_KPALVTR > 0', W5500 + * automatically transmits KA packet after time-period for checking the TCP + * connection (Auto-keepalive-process). In case of '@ref Sn_KPALVTR = 0', + * Auto-keep-alive-process will not operate, and KA packet can be transmitted by + * SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) \ + (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + +//(WIZCHIP_SREG_BLOCK(N) << 3)) + +//----------------------------- W5500 Register values +//----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will + * be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been + * normally processed, the Interrupt PIN (INTn) asserts to low. When using WOL + * mode, the UDP Socket should be opened with any source port number. (Refer to + * Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes + * synchronization stream (xFFFFFFFFFFFF and 16 times Target MAC address stream + * in UDP payload. The options such like password are ignored. You can use any + * UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP + * address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this + * bit is set as When this bit is Destination Information such as IP address + * and Port number may be checked with the corresponding @ref UIPR & @ref + * UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, + * this bit is set. + */ +#define IR_MP 0x10 + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1 << 7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1 << 6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7 << 3) +#define PHYCFGR_OPMDC_PDOWN (6 << 3) +#define PHYCFGR_OPMDC_NA (5 << 3) +#define PHYCFGR_OPMDC_100FA (4 << 3) +#define PHYCFGR_OPMDC_100F (3 << 3) +#define PHYCFGR_OPMDC_100H (2 << 3) +#define PHYCFGR_OPMDC_10F (1 << 3) +#define PHYCFGR_OPMDC_10H (0 << 3) +#define PHYCFGR_DPX_FULL (1 << 2) +#define PHYCFGR_DPX_HALF (0 << 2) +#define PHYCFGR_SPD_100 (1 << 1) +#define PHYCFGR_SPD_10 (0 << 1) +#define PHYCFGR_LNK_ON (1 << 0) +#define PHYCFGR_LNK_OFF (0 << 0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively + * configured with the multicast group IP address & port number before Socket n + * is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = + * 010.\m In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data + * packet is received from a peer.\n When this bit is It sends the ACK packet + * after waiting for the timeout time configured by @ref _RTR_. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and + * MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to + * itself. When this bit is W5500 can receive all packets on Ethernet. If user + * wants to implement Hybrid TCP/IP stack, it is recommended that this bit is + * set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to + * receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive + * the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol + * selected in Sn_MR(P3:P0). The table below shows the value of @ref Sn_SR + * corresponding to @ref Sn_MR.\n + * + * + * + * + *
\b Sn_MR (P[3:0])\b Sn_SR
Sn_MR_CLOSE + * (000)
Sn_MR_TCP (001) SOCK_INIT (0x13)
Sn_MR_UDP (010) SOCK_UDP (0x22)
S0_MR_MACRAW (100) SOCK_MACRAW (0x02)
+ */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP). + * In this mode, Socket n operates as a TCP serverand waits for + * connection-request (SYN packet) from any TCP client The @ref Sn_SR changes + * the state from \ref SOCK_INIT to \ref SOCKET_LISTEN. When a TCP + * clientconnection request is successfully established, the @ref Sn_SR changes + * from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes But when a + * TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status + * of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP + * serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref + * SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n The connect-request fails in + * the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware + * address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these + * cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as + * TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON + * command processes the disconnect-process (b>Active closeor Passive + * close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the + * peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet + * is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to + * @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref + * Sn_TX_FSR), Socket n, TX Write Pointer Register(@ref Sn_TX_WR), and Socket n + * TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired + * by the automatic ARP-process(Address Resolution Protocol).\n But SEND_MAC + * transmits data without the automatic ARP-process.\n In this case, the + * destination hardware address is acquired from @ref Sn_DHAR configured by + * host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive + * packet.\n If the peer can not respond to the keep-alive packet during timeout + * time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX + * Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n For more + * details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket + * n RX Write Pointer Register (@ref Sn_RX_WR), and Socket n RX Read Pointer + * Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful + * and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed + * to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN + * command is ordered.\n After @ref SOCK_INIT, user can use LISTEN /CONNECT + * command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and + * waiting for connection-request (SYN packet) from a peer TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is + * successfully accepted.\n Otherwise it will change to @ref SOCK_CLOSED after + * TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred. + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) + * to a peer.\n It is temporarily shown when @ref Sn_SR is changed from @ref + * SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n If + * connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it + * changes to @ref SOCK_ESTABLISHED.\n Otherwise, it changes to @ref SOCK_CLOSED + * after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request + * packet (SYN packet) from a peer.\n If socket n sends the response (SYN/ACK + * packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n If + * not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') + * is occurred. + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the + * SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or when the + * CONNECT command is successful.\n During @ref SOCK_ESTABLISHED, DATA packet + * can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) + * from the connected peer.\n This is half-closing status, and data can be + * transferred.\n For full-closing, DISCON command is used. But For + * just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) + * to the disconnect-request (FIN packet) by passive-close.\n It changes to @ref + * SOCK_CLOSED when Socket n received the response successfully, or when + * timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = + * '010').\n It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref + * Sn_CR_OPEN command is ordered.\n Unlike TCP mode, data can be transfered + * without the connection-process. + */ +#define SOCK_UDP 0x22 + +#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = + * 100and is valid only in Socket 0.\n It changes to SOCK_MACRAW when + * S0_MR(P[3:0] = 100and OPEN command is ordered.\n Like UDP mode socket, MACRAW + * mode Socket 0 can transfer a MAC packet (Ethernet frame) without the + * connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt.\n In OS environment, You can replace it to critical section api + * supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt. \n In OS environment, You can replace it to critical section api + * supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ(uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) WIZCHIP_WRITE(MR, mr) + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be + * allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) WIZCHIP_WRITE_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be + * allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) WIZCHIP_READ_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should + * be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) WIZCHIP_WRITE_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should + * be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be + * allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be + * allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be + * allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be + * allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) \ + { \ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL, 1), (uint8_t)intlevel); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +// M20150401 : Type explict declaration +/* +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) +*/ +#define getINTLEVEL() \ + (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) \ + { \ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_, 1), (uint8_t)rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +// M20150401 : Type explict declaration +/* +#define getRTR() \ + ((WIZCHIP_READ(_RTR_) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) +*/ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() WIZCHIP_READ(_RCR_) + +//================================================== test done +//=========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHAR address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) \ + { \ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID, 1), (uint8_t)psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +// uint16_t getPSID(void); +// M20150401 : Type explict declaration +/* +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) +*/ +#define getPSID() \ + (((uint16_t)WIZCHIP_READ(PSID) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) \ + { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU, 1), (uint8_t)pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +// M20150401 : Type explict declaration +/* +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) +*/ +#define getPMRU() \ + (((uint16_t)WIZCHIP_READ(PMRU) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It + * should be allocated 4 bytes. + */ +// M20150401 : Size Error of UIPR (6 -> 4) +/* +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) +*/ +#define getUIPR(uipr) WIZCHIP_READ_BUF(UIPR, uipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +// M20150401 : Type explict declaration +/* +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) +*/ +#define getUPORTR() \ + (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) WIZCHIP_WRITE(Sn_MR(sn), mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) \ + { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1), (uint8_t)port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) +*/ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP + * address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP + * address. It should be allocated 4 bytes. + * @sa setSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) \ + { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t)(dport >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1), (uint8_t)dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) +*/ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) \ + { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1), (uint8_t)mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) +*/ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn), rxbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) +*/ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) \ + { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1), (uint8_t)txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) +*/ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) \ + { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1), (uint8_t)rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) +*/ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) +*/ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) \ + { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1), (uint8_t)frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +// M20150401 : Type explict declaration +/* +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) +*/ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) +*/ +#define getSn_RxMAX(sn) (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10) + +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) +*/ +#define getSn_TxMAX(sn) (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of + * len(variable) bytes to internal TX memory and updates the Tx write + * pointer register. This function is being called by send() and sendto() + * function also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) + * bytes. This function is being called by recv() also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in + * internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif // _W5500_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h new file mode 100755 index 000000000..a58da3a19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h @@ -0,0 +1,704 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP + * I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, + * network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b + * W5500 or etc. \n\n ex> #define \_WIZCHIP_ W5500 + */ + +#define W5100 5100 +#define W5100S 5100 + 5 +#define W5200 5200 +#define W5300 5300 +#define W5500 5500 + +#ifndef _WIZCHIP_ +#define _WIZCHIP_ W5500 // W5100, W5100S, W5200, W5300, W5500 +#endif + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length \ \ \ + data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 2) /**< SPI interface mode for fixed length data mode*/ +#define _WIZCHIP_IO_MODE_SPI_5500_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 3) /**< SPI interface mode for fixed length data mode*/ + +#if (_WIZCHIP_ == W5100) +#define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100/w5100.h" + +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_ID_ "W5100S\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_5500_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100S/w5100s.h" +#elif (_WIZCHIP_ == W5200) +#define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ or @ref \ _WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "W5200/w5200.h" +#elif (_WIZCHIP_ == W5500) +#define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + * + * + */ +#ifndef _WIZCHIP_IO_MODE_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "w5500.h" +#elif (_WIZCHIP_ == W5300) +#define _WIZCHIP_ID_ "W5300\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#endif + +// A20150601 : Define the unit and bus width of IO DATA. +/** + * @brief Select the data width 8 or 16 bits. + * @todo you should select the bus width. Select one of 8 or 16. + */ +#ifndef _WIZCHIP_IO_BUS_WIDTH_ +#define _WIZCHIP_IO_BUS_WIDTH_ 16 // 8 +#endif +#if _WIZCHIP_IO_BUS_WIDTH_ == 8 +typedef uint8_t iodata_t; +#elif _WIZCHIP_IO_BUS_WIDTH_ == 16 +typedef uint16_t iodata_t; +#else +#error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16." +#endif +// +#include "W5300/w5300.h" +#else +#error \ + "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ +#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref + * \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). + * \n\n ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 + */ +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +// #define _WIZCHIP_IO_BASE_ 0x60000000 +//// for 5100S IND +#define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 +#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // for 5100S SPI +#endif + +#ifndef _WIZCHIP_IO_BASE_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000 +#endif + +// M20150401 : Typing Error +//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +#ifndef _WIZCHIP_IO_BASE_ +#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." +#endif +#endif + +#if _WIZCHIP_ >= W5200 +#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else +#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + +/******************************************************** + * WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. + *********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions + * W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP { + uint16_t if_mode; ///< host interface mode + uint8_t id[8]; ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b + ///< 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS { + void (*_enter)(void); ///< crtical section enter + void (*_exit)(void); ///< critial section exit + } CRIS; + /** + * The set of @ref \_WIZCHIP_ select control callback func. + */ + struct _CS { + void (*_select)(void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + } CS; + /** + * The set of interface IO callback func. + */ + union _IF { + /** + * For BUS interface IO + */ + // M20156501 : Modify the function name for integrating with W5300 + // struct + //{ + // uint8_t (*_read_byte) (uint32_t AddrSel); + // void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + //}BUS; + struct { + iodata_t (*_read_data)(uint32_t AddrSel); + void (*_write_data)(uint32_t AddrSel, iodata_t wb); + } BUS; + + /** + * For SPI interface IO + */ + struct { + uint8_t (*_read_byte)(void); + void (*_write_byte)(uint8_t wb); + void (*_read_burst)(uint8_t *pBuf, uint16_t len); + void (*_write_burst)(uint8_t *pBuf, uint16_t len); + } SPI; + // To be added + // + } IF; +} _WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum { + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 + ///< dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500 + CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation + ///< mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only + ///< W5500 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when + ///< PHYSTATUS.OPMD == 1. Valid Only W5500 + //#endif + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only + ///< W5100, W5200 + CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200 + //#endif +} ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum { + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +} ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum { +#if _WIZCHIP_ == W5500 + IK_WOL = + (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#elif _WIZCHIP_ == W5300 + IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU) +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != W5200 + IK_DEST_UNREACH = + (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > W5100S + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > W5100S + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt +#endif +} intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO \ + 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in + * W5500, and it indicates the real PHY status configured by HW or SW in all + * WIZCHIP. \n Valid only in W5500. + */ +typedef struct wiz_PhyConf_t { + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + // uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + // uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref + // PHY_LINK_ON or PHY_DUPLEX_OFF +} wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum { + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +} dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t { + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +} wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum { +#if _WIZCHIP_ == W5500 + NM_FORCEARP = (1 << 1), ///< Force to APP send whenever udp data is sent. + ///< Valid only in W5500 +#endif + NM_WAKEONLAN = (1 << 5), ///< Wake On Lan + NM_PINGBLOCK = (1 << 4), ///< Block ping-request + NM_PPPOE = (1 << 3), ///< PPPoE mode +} netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout + * configruation. + */ +typedef struct wiz_NetTimeout_t { + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +} wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such + *as \ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref + *WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT + *marco or register your functions. + *@note If you do not describe or register, default functions(@ref + *wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)); + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or + *register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +// M20150601 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)); +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte using SPI + *@param spi_wb : callback function to write byte using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to burst read using SPI + *@param spi_wb : callback function to burst write using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor + * PHY(Link,Speed,Half/Full/Auto), controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref + * ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref + * ctlnetwork_type in WIZCHIP \n 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg); + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of + * ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size + * 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size + * 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to + * uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +// todo +#if _WIZCHIP_ > W5100 +int8_t wizphy_getphylink( + void); ///< get the link status of phy in WIZCHIP. No use in W5100 +int8_t wizphy_getphypmode( + void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 + /** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_setphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphystat(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in + * W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ +int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** + * @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout *nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout *nettime); +#ifdef __cplusplus +} +#endif + +#endif // _WIZCHIP_CONF_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/connect_lcd.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/connect_lcd.c index 8595bca05..dd43ac2d0 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/connect_lcd.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/connect_lcd.c @@ -342,7 +342,7 @@ static void DrvLcdRectUpdate(uint16_t x1, uint16_t y1, uint16_t width, uint16_t } } -x_err_t DrvLcdInit(Lcd8080DeviceType dev) +static x_err_t DrvLcdInit(Lcd8080DeviceType dev) { x_err_t ret = EOK; aiit_lcd = (Lcd8080DeviceType)dev; @@ -366,6 +366,8 @@ x_err_t DrvLcdInit(Lcd8080DeviceType dev) data = 0x55; DrvLcdDataByte(&data, 1); + DrvLcdCmd(INVERSION_DISPALY_ON); + /* set direction */ DrvLcdSetDirection(DIR_YX_RLUD); @@ -476,7 +478,6 @@ static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param) } else if(1 == show->type) //output dot { - // DrvLcdSetPixel(show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color); DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color); return EOK; } @@ -549,7 +550,7 @@ static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, co return ret; } - +static int flag = 1; int HwLcdInit(void) { x_err_t ret = EOK; @@ -613,7 +614,11 @@ int HwLcdInit(void) KPrintf("LCD driver inited ...\r\n"); - DrvLcdInit(lcd_dev); + if(flag){ + DrvLcdInit(lcd_dev); + flag = 0; + } + return ret; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c index 9cf961d40..b3a11b572 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c @@ -12,7 +12,7 @@ #include #include -static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg) +static x_err_t SoftSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg) { NULL_PARAM_CHECK(spi_drv); NULL_PARAM_CHECK(cfg); @@ -29,7 +29,7 @@ static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *c return EOK; } -static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +static uint32 SoftSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) { NULL_PARAM_CHECK(drv); NULL_PARAM_CHECK(configure_info); @@ -41,7 +41,7 @@ static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_ switch (configure_info->configure_cmd) { case OPE_INT: - softSPIinit(spi_drv, configure_info); + SoftSPIinit(spi_drv, configure_info); break; case OPE_CFG: @@ -54,7 +54,7 @@ static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_ return ret; } -static void soft_spi_writebyte(struct SpiHardwareDevice *spi_dev, uint8_t data) +static void SoftSpiWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data) { int8_t i = 0; uint8_t temp = 0; @@ -79,7 +79,7 @@ static void soft_spi_writebyte(struct SpiHardwareDevice *spi_dev, uint8_t data) } /* 读一个字节 */ -static uint8_t soft_spi_readbyte(struct SpiHardwareDevice *spi_dev) +static uint8_t SoftSpiReadbyte(struct SpiHardwareDevice *spi_dev) { uint8_t i = 0; uint8_t read_data = 0xFF; @@ -100,7 +100,7 @@ static uint8_t soft_spi_readbyte(struct SpiHardwareDevice *spi_dev) /* 读写一个字节 */ // this funcition is unverify until now! -static uint8_t soft_spi_readwritebyte(struct SpiHardwareDevice *spi_dev, uint8_t data) +static uint8_t SoftSpiReadWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data) { uint8_t i = 0; uint8_t temp = 0; @@ -129,7 +129,7 @@ static uint8_t soft_spi_readwritebyte(struct SpiHardwareDevice *spi_dev, uint8_t return read_data; } -static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +static uint32 SoftSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); @@ -148,7 +148,7 @@ static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiData for (size_t i = 0; i < data_length; i++) { - soft_spi_writebyte(spi_dev, data_buff[i]); + SoftSpiWriteByte(spi_dev, data_buff[i]); } if (spi_datacfg->spi_cs_release) @@ -160,7 +160,7 @@ static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiData return EOK; } -static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +static uint32 SoftSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) { SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; @@ -179,7 +179,7 @@ static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataS for (size_t i = 0; i < recv_length; i++) { - recv_buff[i] = soft_spi_readbyte(spi_dev); + recv_buff[i] = SoftSpiReadbyte(spi_dev); } if (spi_datacfg->spi_cs_release) @@ -195,8 +195,8 @@ static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataS const struct SpiDevDone soft_spi_dev_done = { .dev_close = NONE, .dev_open = NONE, - .dev_read = softSpiReadData, - .dev_write = softSpiWriteData}; + .dev_read = SoftSpiReadData, + .dev_write = SoftSpiWriteData}; static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver) { @@ -275,7 +275,7 @@ int HwSoftSPIInit(void) static struct SpiDriver spi_driver; memset(&spi_driver, 0, sizeof(struct SpiDriver)); - spi_driver.configure = &(softSpiDrvConfigure); + spi_driver.configure = &(SoftSpiDrvConfigure); ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver); if (EOK != ret) diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c index 2f95c371e..54efb4a73 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c @@ -38,7 +38,7 @@ struct Touch_event { }; #define DEFAULT_NUM 0x0D -#define TOUCH_ADDRESS 0x44 +#define TOUCH_ADDRESS 0x40 volatile bool SemReleaseFlag = 0; static struct Bus* i2c_bus = NONE; @@ -77,7 +77,7 @@ static x_err_t ReadRegs(struct HardwareDev* dev, uint8 len, uint8* buf) // not used in polling mode static void touch_pin_irqhandler(void* arg) { - // KPrintf("int hdr working.\n"); + KPrintf("int hdr working.\n"); if (!SemReleaseFlag) { KSemaphoreAbandon(touch_sem); @@ -277,8 +277,8 @@ static uint32 TouchRead(void* dev, struct BusBlockReadParam* read_param) char status_reg = 0x80; struct TouchDataStandard* data = (struct TouchDataStandard*)read_param->buffer; - read_param->read_length = 0; - result = KSemaphoreObtain(touch_sem, 1000); + + result = KSemaphoreObtain(touch_sem, 100); // if (EOK == result) // { memset(TOUCHRECDATA, 0, 24); @@ -292,13 +292,16 @@ static uint32 TouchRead(void* dev, struct BusBlockReadParam* read_param) { ts_event.fingers[i].x = ((((uint32_t)TOUCHRECDATA[(i * 4) + 5]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 4]) & 0x00000FFF; // 12 bits of X coord ts_event.fingers[i].y = ((((uint32_t)TOUCHRECDATA[(i * 4) + 7]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 6]) & 0x00000FFF; + uint32_t pos_y = 320 > ts_event.fingers[i].x *LCD_SIZE/TOUCH_WIDTH?320 - ts_event.fingers[i].x *LCD_SIZE/TOUCH_WIDTH:0; + ts_event.fingers[i].x = ts_event.fingers[i].y *LCD_SIZE/TOUCH_HEIGHT>6?ts_event.fingers[i].y *LCD_SIZE/TOUCH_HEIGHT-6:0; + ts_event.fingers[i].y = pos_y; ts_event.fingers[i].fingerID = (uint32_t)TOUCHRECDATA[(i * 4) + 7] >> 4; // finger that did the touch - printf("fingers[%d] x %d y %d id %d\n",i,ts_event.fingers[i].x,ts_event.fingers[i].y,ts_event.fingers[i].fingerID); + // printf("fingers[%d] x %d y %d id %d\n",i,ts_event.fingers[i].x,ts_event.fingers[i].y,ts_event.fingers[i].fingerID); } data->x = ts_event.fingers[ts_event.NBfingers - 1].x; data->y = ts_event.fingers[ts_event.NBfingers - 1].y; - + read_param->read_length = ts_event.NBfingers; SemReleaseFlag = 0; // } diff --git a/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/.defconfig b/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/.defconfig index 9511edeb5..8280d8f01 100644 --- a/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/.defconfig +++ b/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/.defconfig @@ -140,7 +140,7 @@ CONFIG_SHELL_HELP_SHOW_PERMISSION=y # CONFIG_SHELL_HELP_LIST_VAR is not set # CONFIG_SHELL_HELP_LIST_KEY is not set #CONFIG_KERNEL_QUEUEMANAGE=y -# CONFIG_KERNEL_WORKQUEUE is not set +CONFIG_KERNEL_WORKQUEUE=y CONFIG_WORKQUEUE_KTASK_STACKSIZE=256 CONFIG_WORKQUEUE_KTASK_PRIORITY=2 CONFIG_QUEUE_MAX=2 diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link.lds b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link.lds index 9c0fec187..1940e5b81 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link.lds +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link.lds @@ -48,8 +48,7 @@ Modification: /* Entry Point */ ENTRY(Reset_Handler) -HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; +STACK_SIZE = 0x4000; /* Specify the memory areas */ MEMORY diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/Kconfig index 223f5e966..72eef20d3 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/Kconfig @@ -49,6 +49,7 @@ menuconfig BSP_USING_SDIO if BSP_USING_SDIO source "$BSP_DIR/third_party_driver/sdio/Kconfig" endif + menuconfig BSP_USING_LCD bool "Using LCD device" default n @@ -56,6 +57,7 @@ menuconfig BSP_USING_LCD if BSP_USING_LCD source "$BSP_DIR/third_party_driver/lcd/Kconfig" endif + menuconfig BSP_USING_TOUCH bool "Using TOUCH device" default n diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c index 2912af879..3df2f6e40 100755 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c @@ -85,7 +85,7 @@ void enet_delay(void) { volatile uint32_t i = 0; - for (i = 0; i < 1000000; ++i) + for (i = 0; i < 10000000; ++i) { __asm("NOP"); /* delay */ } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/semc/semc_externsdram_test.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/semc/semc_externsdram_test.c index c09b6dc27..ba18eca61 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/semc/semc_externsdram_test.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/semc/semc_externsdram_test.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ #include "board.h" +#include #define EXAMPLE_SEMC_START_ADDRESS (0x80000000U) diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/touch/connect_touch.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/touch/connect_touch.c index 8fd57894b..05b6d2ade 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/touch/connect_touch.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/touch/connect_touch.c @@ -359,7 +359,8 @@ static uint32 TouchRead(void *dev, struct BusBlockReadParam *read_param) result = KSemaphoreObtain(touch_sem, 1000); if (EOK == result) { - if(GetTouchEvent(&touch_point, &touch_event)) + ret = GetTouchEvent(&touch_point, &touch_event); + if(ret > 0) { data->x = abs(LCD_WIDTH - touch_point.X); data->y = abs(LCD_HEIGHT - touch_point.Y); @@ -369,6 +370,11 @@ static uint32 TouchRead(void *dev, struct BusBlockReadParam *read_param) read_param->read_length = read_param->size; ret = EOK; + } + else + { + ret = -ERROR; + read_param->read_length = -ERROR; } SemReleaseFlag = 0; } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c index 42ee200ce..44d11dd3a 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/board.c @@ -14,49 +14,54 @@ */ /** -* @file board.c -* @brief support kd233-board init configure and start-up -* @version 1.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file board.c + * @brief support kd233-board init configure and start-up + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: board.c -Description: support xidatong-riscv64-board init configure and driver/task/... init -Others: https://canaan-creative.com/developer -History: +Description: support xidatong-riscv64-board init configure and driver/task/... +init Others: https://canaan-creative.com/developer History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab -Modification: +Modification: 1. support xidatong-riscv64-board InitBoardHardware 2. support xidatong-riscv64-board Kd233Start 3. support xidatong-riscv64-board shell cmd, include reboot, shutdown *************************************************/ -#include +#include "board.h" + #include #include -#include "board.h" -#include "tick.h" +#include + +#include "connect_gpio.h" +#include "connect_spi.h" #include "connect_uart.h" +#include "connect_w5500.h" +#include "dmac.h" #include "encoding.h" #include "fpioa.h" -#include "dmac.h" -#include "connect_gpio.h" +#include "tick.h" #if defined(FS_VFS) #include #endif -#define CPU0 (0) -#define CPU1 (1) +#define CPU0 (0) +#define CPU1 (1) extern x_base cpu2_boot_flag; extern void entry(void); extern void SecondaryCpuCStart(void); extern int IoConfigInit(void); extern int HwI2cInit(void); extern int HwTouchInit(void); +extern int HwSpiInit(void); +extern int HwWiznetInit(void); extern int HwCh438Init(void); extern int HwCh376Init(void); extern int HwTimerInit(void); @@ -70,14 +75,14 @@ extern int HwWdtInit(void); * @description: Mount USB * @return 0 */ -int MountUsb(void) -{ - if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_CH376, "/") == 0) - KPrintf("usb mount to '/'\n"); - else - KPrintf("usb mount to '/' failed!\n"); - - return 0; +int MountUsb(void) { + if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, + FSTYPE_CH376, "/") == 0) + KPrintf("usb mount to '/'\n"); + else + KPrintf("usb mount to '/' failed!\n"); + + return 0; } #endif #ifdef MOUNT_SDCARD @@ -86,168 +91,183 @@ int MountUsb(void) * @return 0 */ -int MountSDCard(void) -{ - if (MountFilesystem(SDIO_BUS_NAME,SDIO_DEVICE_NAME ,SDIO_DRIVER_NAME , FSTYPE_CH376, "/") == 0) - KPrintf("sd card mount to '/'\n"); - else - KPrintf("sd card mount to '/' failed!\n"); - - return 0; +int MountSDCard(void) { + if (MountFilesystem(SDIO_BUS_NAME, SDIO_DEVICE_NAME, SDIO_DRIVER_NAME, + FSTYPE_CH376, "/") == 0) + KPrintf("sd card mount to '/'\n"); + else + KPrintf("sd card mount to '/' failed!\n"); + + return 0; +} + +if (EOK == MountFilesystem(SPI_BUS_NAME_1, SPI_SD_NAME, SPI_1_DRV_NAME, + FSTYPE_FATFS, "/")) + KPrintf("SPI SD card fatfs mounted\n"); + +return 0; } #endif #endif -void InitBss(void) -{ - unsigned int *dst; +void InitBss(void) { + unsigned int *dst; - dst = &__bss_start; - while (dst < &__bss_end){ - *dst++ = 0; - } + dst = &__bss_start; + while (dst < &__bss_end) { + *dst++ = 0; + } } -void Kd233Start(uint32_t mhartid) -{ - switch(mhartid) { - case CPU0: - InitBss(); +void Kd233Start(uint32_t mhartid) { + switch (mhartid) { + case CPU0: + InitBss(); - /*kernel start entry*/ - entry(); - break; - case CPU1: - while(0x2018050420191010 != cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core + /*kernel start entry*/ + entry(); + break; + case CPU1: + while (0x2018050420191010 != + cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core #ifndef ARCH_SMP - asm volatile("wfi"); + asm volatile("wfi"); #endif - } + } #ifdef ARCH_SMP - SecondaryCpuCStart(); + SecondaryCpuCStart(); #endif - break; + break; - default: - break; - } + default: + break; + } } -int Freq(void) -{ - uint64 value = 0; +int Freq(void) { + uint64 value = 0; - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); - KPrintf("PLL0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); - KPrintf("PLL1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); - KPrintf("PLL2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); - KPrintf("CPU : %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); - KPrintf("APB0: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); - KPrintf("APB1: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); - KPrintf("APB2: %d\n", value); - value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); - KPrintf("HCLK: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); + KPrintf("PLL0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); + KPrintf("PLL1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); + KPrintf("PLL2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + KPrintf("CPU : %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + KPrintf("APB0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + KPrintf("APB1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); + KPrintf("APB2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); + KPrintf("HCLK: %d\n", value); - value = clint_get_time(); - KPrintf("mtime: %d\n", value); + value = clint_get_time(); + KPrintf("mtime: %d\n", value); - return 0; + return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Freq, Freq, show frequency information ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Freq, Freq, show frequency information); #ifdef ARCH_SMP extern int EnableHwclintIpi(void); #endif -struct InitSequenceDesc _board_init[] = -{ +struct InitSequenceDesc _board_init[] = { #ifdef BSP_USING_GPIO - { "hw_pin", HwGpioInit }, - { "io_config", IoConfigInit }, + {"hw_pin", HwGpioInit}, + {"io_config", IoConfigInit}, #endif #ifdef BSP_USING_CH438 - { "hw_extuart", HwCh438Init }, + {"hw_extuart", HwCh438Init}, #endif #ifdef BSP_USING_I2C - { "hw_i2c", HwI2cInit }, + {"hw_i2c", HwI2cInit}, #endif #ifdef BSP_USING_RTC - { "hw_rtc", HwRtcInit }, + {"hw_rtc", HwRtcInit}, #endif #ifdef BSP_USING_HWTIMER - { "hw_timer" , HwTimerInit }, + {"hw_timer", HwTimerInit}, #endif #ifdef BSP_USING_WDT - { "hw_wdt", HwWdtInit }, + {"hw_wdt", HwWdtInit}, #endif #ifdef BSP_USING_SDIO - { "hw_sdio", HwCh376Init}, + {"hw_sdio", HwCh376Init}, #endif #ifdef BSP_USING_USB - { "hw_usb", HwCh376Init}, + {"hw_usb", HwCh376Init}, #endif #ifdef BSP_USING_TOUCH - {"touch", HwTouchInit }, + {"touch", HwTouchInit}, #endif - { " NONE ",NONE }, +#ifdef BSP_USING_SPI + {"spi", HwSpiInit}, +#endif +#ifdef BSP_USING_WIZCHIP + {"w5500", HwWiznetInit}, +#endif + {" NONE ", NONE}, }; -void InitBoardHardware(void) -{ - int i = 0; - int ret = 0; - - SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); - SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); +void InitBoardHardware(void) { + int i = 0; + int ret = 0; + + SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); + SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); #ifdef BSP_USING_GPIO - /* Init FPIOA */ - FpioaInit(); + /* Init FPIOA */ + FpioaInit(); #endif #ifdef BSP_USING_DMA - /* Dmac init */ - DmacInit(); + /* Dmac init */ + DmacInit(); #endif - /* initalize interrupt */ - InitHwinterrupt(); -#ifdef BSP_USING_UART - HwUartInit(); + /* initalize interrupt */ + InitHwinterrupt(); +#ifdef BSP_USING_UART + HwUartInit(); #endif - /* initialize memory system */ - InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); #ifdef KERNEL_CONSOLE - /* set console device */ - InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME); - KPrintf("\nconsole init completed.\n"); - KPrintf("board initialization......\n"); + /* set console device */ + InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, + KERNEL_CONSOLE_DEVICE_NAME); + KPrintf("\nconsole init completed.\n"); + KPrintf("board initialization......\n"); #endif /* KERNEL_CONSOLE */ - InitHwTick(); + InitHwTick(); #ifdef ARCH_SMP - EnableHwclintIpi(); + EnableHwclintIpi(); #endif #ifdef KERNEL_COMPONENTS_INIT - for(i = 0; _board_init[i].fn != NONE; i++) { - ret = _board_init[i].fn(); - KPrintf("initialize %s %s\n",_board_init[i].fn_name, ret == 0 ? "success" : "failed"); - } + for (i = 0; _board_init[i].fn != NONE; i++) { + ret = _board_init[i].fn(); + KPrintf("initialize %s %s\n", _board_init[i].fn_name, + ret == 0 ? "success" : "failed"); + } #endif - KPrintf("board init done.\n"); - KPrintf("start kernel...\n"); + KPrintf("board init done.\n"); + KPrintf("start kernel...\n"); } -void HwCpuReset(void) -{ - sysctl->soft_reset.soft_reset = 1; - while(RET_TRUE); +void HwCpuReset(void) { + sysctl->soft_reset.soft_reset = 1; + while (RET_TRUE) + ; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),Reboot, HwCpuReset, reset machine ); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Reboot, HwCpuReset, reset machine); diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig index 812afe099..1d7cac909 100755 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Kconfig @@ -29,6 +29,22 @@ if BSP_USING_GPIO source "$BSP_DIR/third_party_driver/gpio/Kconfig" endif +menuconfig BSP_USING_SPI +bool "Using SPI device" +default n +select RESOURCES_SPI +if BSP_USING_SPI +source "$BSP_DIR/third_party_driver/spi/Kconfig" +endif + +menuconfig BSP_USING_WIZCHIP +bool "Using w5500 as network device" +default n +select RESOURCES_WIZCHIP +if BSP_USING_WIZCHIP +source "$BSP_DIR/third_party_driver/ethernet/Kconfig" +endif + menuconfig BSP_USING_I2C bool "Using I2C device" default n @@ -91,3 +107,19 @@ select RESOURCES_WDT if BSP_USING_WDT source "$BSP_DIR/third_party_driver/watchdog/Kconfig" endif + +menuconfig BSP_USING_WDT +bool "Using WATCHDOG device" +default n +select RESOURCES_WDT +if BSP_USING_WDT +source "$BSP_DIR/third_party_driver/watchdog/Kconfig" +endif + +menuconfig BSP_USING_SOFT_SPI +bool "Using SOFT_SPI device" +default n +select RESOURCES_SOFT_SPI +if BSP_USING_SOFT_SPI +source "$BSP_DIR/third_party_driver/soft_spi/Kconfig" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile index acb338501..faf386b9c 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/Makefile @@ -20,6 +20,14 @@ ifeq ($(CONFIG_BSP_USING_I2C),y) SRC_DIR += i2c endif +ifeq ($(CONFIG_BSP_USING_SPI),y) + SRC_DIR += spi +endif + +ifeq ($(CONFIG_BSP_USING_WIZCHIP),y) + SRC_DIR += ethernet +endif + ifeq ($(CONFIG_BSP_USING_TOUCH),y) SRC_DIR += touch endif @@ -48,4 +56,8 @@ ifeq ($(CONFIG_BSP_USING_WDT),y) SRC_DIR += watchdog endif +ifeq ($(CONFIG_BSP_USING_SOFT_SPI),y) + SRC_DIR += soft_spi +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Kconfig new file mode 100644 index 000000000..baf59367c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Kconfig @@ -0,0 +1,15 @@ +# Kconfig file + +config BSP_USING_W5500 +bool "Using w5500 " +default y + +# if BSP_USING_W5500 + config BSP_WIZ_RST_PIN + int + default 13 + + config BSP_WIZ_INT_PIN + int + default 14 +# endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Makefile new file mode 100644 index 000000000..1ea20caac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/ReadMe.md b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/ReadMe.md new file mode 100644 index 000000000..947404f4a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/ReadMe.md @@ -0,0 +1,25 @@ +## w5500 测试文档 + +通过board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c 可以找到内写的3个,包含ping, tcp server test, tcp client test; + + - ping 测试,测试结果包括: + - pc ping w5500 + - w5500 ping baidu.com (DNS实现暂未实现,因此使用baidu.com的ip地址进行寻址) + + + + + +- tcp server 测试:在xizi中调用wiz_server_op,指定port,之后可以在pc中向该端口发送数据 + - wiz_server 将额外启动一个线程执行server工作,server将向client返回client发来的消息 + + + + + +- client 测试:通过wiz_client_op可以向pc中打开的tcp server发送消息 + - 由于wiz_client_test函数参数接收问题,测试使用的ip地址暂时使用硬编码实现 + + + + \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c new file mode 100644 index 000000000..22803ee9e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -0,0 +1,505 @@ + +#include "connect_w5500.h" + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" +#include "socket.h" +#include "w5500.h" + +#define SPI_LORA_FREQUENCY 10000000 + +// spi operations +extern void spi_enter_cris(void); +extern void spi_exit_cris(void); +extern void spi_select_cs(void); +extern void spi_deselete_cs(void); + +// global configurations for w5500 tcp connection +const uint32_t socket_tcp = 0; +const uint32_t g_wiznet_buf_size = 2048; + +static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, + .ip = {192, 168, 31, 13}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 31, 1}, + .dns = {0, 0, 0, 0}, + .dhcp = NETINFO_STATIC}; + +int network_init() { + wiz_NetInfo check_wiz_netinfo; + check_wiz_netinfo.dhcp = NETINFO_STATIC; + ctlnetwork(CN_SET_NETINFO, (void *)&g_wiz_netinfo); + ctlnetwork(CN_GET_NETINFO, (void *)&check_wiz_netinfo); + + if (memcmp(&g_wiz_netinfo, &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { + KPrintf( + "mac: %d; ip: %d; gw: %d; sn: %d; dns: %d; dhcp: %d;\n", + memcmp(&g_wiz_netinfo.mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), + memcmp(&g_wiz_netinfo.ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); + KPrintf("WIZCHIP set network information fail.\n"); + return ERROR; + } + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", g_wiz_netinfo.mac[0], + g_wiz_netinfo.mac[1], g_wiz_netinfo.mac[2], g_wiz_netinfo.mac[3], + g_wiz_netinfo.mac[4], g_wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", g_wiz_netinfo.ip[0], g_wiz_netinfo.ip[1], + g_wiz_netinfo.ip[2], g_wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", g_wiz_netinfo.gw[0], g_wiz_netinfo.gw[1], + g_wiz_netinfo.gw[2], g_wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", g_wiz_netinfo.sn[0], g_wiz_netinfo.sn[1], + g_wiz_netinfo.sn[2], g_wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", g_wiz_netinfo.dns[0], g_wiz_netinfo.dns[1], + g_wiz_netinfo.dns[2], g_wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); + + return EOK; +} + +/****************** spi init ******************/ +static struct Bus *w5500_spi_bus; +int w5500_spi_init() { + x_err_t ret = EOK; + + w5500_spi_bus = BusFind(SPI_BUS_NAME_1); + w5500_spi_bus->owner_haldev = + BusFindDevice(w5500_spi_bus, SPI_1_DEVICE_NAME_0); + w5500_spi_bus->owner_driver = BusFindDriver(w5500_spi_bus, SPI_1_DRV_NAME); + + w5500_spi_bus->match(w5500_spi_bus->owner_driver, + w5500_spi_bus->owner_haldev); + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + spi_master_param.spi_maxfrequency = SPI_LORA_FREQUENCY; + spi_master_param.spi_data_endian = 0; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", + w5500_spi_bus->owner_driver, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", w5500_spi_bus->owner_driver); + return ERROR; + } + + return EOK; +} + +void spi_write_byte(uint8_t tx_data) { + struct BusBlockWriteParam write_param; + write_param.buffer = &tx_data; + write_param.size = 1; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +uint8_t spi_read_byte(void) { + uint8_t result = 0; + struct BusBlockReadParam read_param; + read_param.buffer = &result; + read_param.size = 1; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); + return result; +} +void spi_write_burst(uint8_t *tx_buf, uint16_t len) { + struct BusBlockWriteParam write_param; + write_param.buffer = tx_buf; + write_param.size = len; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +void spi_read_burst(uint8_t *rx_buf, uint16_t len) { + struct BusBlockReadParam read_param; + read_param.buffer = rx_buf; + read_param.size = len; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); +} + +/****************** chip init ******************/ + +void wiz_reset() { + gpiohs_set_drive_mode(WIZ_RST_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_LOW); + MdelayKTask(20); + + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_HIGH); + MdelayKTask(20); +} + +void wiz_spi_handler_reg() { + // spi ops registration +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_) || \ + (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_) + /* register SPI device CS select callback function */ + gpiohs_set_drive_mode(SPI1_CS0_PIN, GPIO_DM_OUTPUT); + reg_wizchip_cs_cbfunc(spi_select_cs, spi_deselete_cs); +#else +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_ +#error "Unknown _WIZCHIP_IO_MODE_" +#else + reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); +#endif +#endif + + reg_wizchip_spi_cbfunc(spi_read_byte, spi_write_byte); + reg_wizchip_cris_cbfunc(spi_enter_cris, spi_exit_cris); + reg_wizchip_spiburst_cbfunc(spi_read_burst, spi_write_burst); +} + +int wiz_chip_cfg_init() { + uint8_t mem_size[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; + + /* reset WIZnet chip internal PHY, configures PHY mode. */ + if (ctlwizchip(CW_INIT_WIZCHIP, (void *)mem_size) == -1) { + KPrintf("WIZCHIP initialize failed."); + return ERROR; + } + + struct wiz_NetTimeout_t net_timeout; + net_timeout.retry_cnt = 5; + net_timeout.time_100us = 20000; + ctlnetwork(CN_SET_TIMEOUT, (void *)&net_timeout); + + return EOK; +} + +/****************** interrupt handle ******************/ +void wiz_irq_handler() {} + +int wiz_interrupt_init() { + int32_t ret = -ERROR; + + struct Bus *pin_bus = PinBusInitGet(); + + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void *)&pin_param; + + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.mode = GPIO_CFG_INPUT_PULLUP; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("config pin_param %d input failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_REGISTER; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_FALLING; + pin_param.irq_set.hdr = wiz_irq_handler; + pin_param.irq_set.args = NONE; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + // 4. enable interuption + pin_param.cmd = GPIO_IRQ_ENABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("enable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + return EOK; + + return EOK; +} + +int HwWiznetInit(void) { + wiz_reset(); + + if (EOK != w5500_spi_init()) { + return ERROR; + } + + wiz_spi_handler_reg(); + + if (EOK != wiz_chip_cfg_init()) { + return ERROR; + } + + network_init(); + + return EOK; +} + +/****************** basic functions ********************/ + +enum TCP_OPTION { + SEND_DATA = 0, + RECV_DATA, +}; + +uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint8_t dst_ip[4], uint16_t dst_port, + enum TCP_OPTION opt) { + // assert(buf_size <= g_wiznet_buf_size); + int32_t ret; + switch (getSn_SR(socket_tcp)) { + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(socket_tcp); + break; + case SOCK_CLOSED: + wiz_socket(socket_tcp, Sn_MR_TCP, 5000, 0x00); + break; + case SOCK_INIT: + KPrintf("[SOCKET CLIENT] sock init.\n"); + wiz_sock_connect(socket_tcp, dst_ip, dst_port); + break; + case SOCK_ESTABLISHED: + if (getSn_IR(socket_tcp) & Sn_IR_CON) { + printf("[SOCKET CLIENT] %d:Connected\r\n", socket_tcp); + setSn_IR(socket_tcp, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + if (ret <= 0) return ret; + } + } + break; + default: + break; + } +} + +void wiz_client_op_test(char *addr, uint16_t port, char *msg) { + /* argv[1]: ip + * argv[2]: port + * argv[3]: msg + */ + uint8_t client_sock = 2; + uint8_t ip[4] = {192, 168, 31, 127}; + uint32_t tmp_ip[4]; + KPrintf("wiz client to %s", addr); + sscanf(addr, "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + for (int i = 0; i < 4; ++i) { + ip[i] = (uint8_t)tmp_ip[i]; + } + uint8_t buf[g_wiznet_buf_size]; + KPrintf("wiz_server, send to %d.%d.%d.%d %d\n", // tip info + ip[0], ip[1], ip[2], ip[3], port); + sscanf(msg, "%s", buf); + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, SEND_DATA); + MdelayKTask(10); + memset(buf, 0, g_wiznet_buf_size); + // waiting for a responding. + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, RECV_DATA); + KPrintf("received msg: %s\n", buf); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(3), + wiz_client_op, wiz_client_op_test, + wiz_sock_recv or wiz_sock_send data as tcp client); + +int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint16_t port, enum TCP_OPTION opt) { + int32_t ret = 0; + uint16_t size = 0, sentsize = 0; + switch (getSn_SR(sn)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("%d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + return ret; + } + } + break; + case SOCK_CLOSE_WAIT: + printf("%d:CloseWait\r\n", sn); + if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; + printf("%d:Closed\r\n", sn); + break; + case SOCK_INIT: + printf("%d:Listen, port [%d]\r\n", sn, port); + if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: + printf("%d:LBTStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; + printf("%d:Opened\r\n", sn); + break; + default: + break; + } + return 0; +} + +void wiz_server(void *param) { + uint16_t port = *(uint16_t *)param; + KPrintf("wiz server, listen port: %d\n", port); + uint8_t buf[g_wiznet_buf_size]; + memset(buf, 0, g_wiznet_buf_size); + int ret = 0; + while (1) { + ret = wiz_server_op(0, buf, g_wiznet_buf_size, port, RECV_DATA); + if (ret > 0) { + wiz_server_op(0, buf, g_wiznet_buf_size, port, SEND_DATA); + }; + } +} + +void wiz_server_test(uint16_t port) { + /* argv[1]: port + */ + int32 wiz_server_id = + KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); + x_err_t flag = StartupKTask(wiz_server_id); + if (flag != EOK) { + KPrintf("StartupKTask wiz_server_id failed .\n"); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(1), + wiz_server_op, wiz_server_test, + wiz_sock_recv or wiz_sock_send data as tcp server); + +int32_t loopback_udps(uint8_t sn, uint8_t *buf, uint16_t port) { + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + // uint8_t packinfo = 0; + switch (getSn_SR(sn)) { + case SOCK_UDP: + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > g_wiznet_buf_size) size = g_wiznet_buf_size; + ret = wiz_sock_recvfrom(sn, buf, size, destip, (uint16_t *)&destport); + if (ret <= 0) { + printf("%d: wiz_sock_recvfrom error. %ld\r\n", sn, ret); + return ret; + } + size = (uint16_t)ret; + sentsize = 0; + while (sentsize != size) { + ret = wiz_sock_sendto(sn, buf + sentsize, size - sentsize, destip, + destport); + if (ret < 0) { + printf("%d: wiz_sock_sendto error. %ld\r\n", sn, ret); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: + printf("%d:LBUStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_UDP, port, 0x00)) != sn) return ret; + printf("%d:Opened, port [%d]\r\n", sn, port); + break; + default: + break; + } + return 1; +} + +void ifconfig() { + wiz_NetInfo wiz_netinfo; + ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], + wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], + wiz_netinfo.mac[4], wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], + wiz_netinfo.ip[2], wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], + wiz_netinfo.gw[2], wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], + wiz_netinfo.sn[2], wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], + wiz_netinfo.dns[2], wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + ifconfig, ifconfig, printf w5500 configurations); + +void char_arr_assign(uint8_t **dst, uint32_t *src, uint32_t len) { + for (int i = 0; i < len; ++i) { + (*dst)[i] = (uint8_t)(src[i]); + } +} + +void config_w5500_network(char *mac, char *ip, char *sn, char *gw, char *dns) { + wiz_NetInfo wiz_netinfo; + uint32_t tmp_arr[4]; + // config netinfo + sscanf(mac, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.mac, tmp_arr, 4); + sscanf(ip, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.ip, tmp_arr, 4); + sscanf(sn, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.sn, tmp_arr, 4); + sscanf(gw, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.gw, tmp_arr, 4); + sscanf(dns, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.dns, tmp_arr, 4); + // set new netinfo + ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); + ifconfig(); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(5), + config_w5500_network, config_w5500_network, + set w5500 configurations); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client0.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client0.png new file mode 100644 index 000000000..7df09b0d9 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client1.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client1.png new file mode 100644 index 000000000..167d455b8 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/client1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping baidu.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping baidu.png new file mode 100644 index 000000000..c79f4bb85 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping baidu.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping w5500.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping w5500.png new file mode 100644 index 000000000..e453995a6 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/ping w5500.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server0.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server0.png new file mode 100644 index 000000000..63f2d5f57 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server1.png b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server1.png new file mode 100644 index 000000000..7643c9bf3 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/imgs/server1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/socket.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/socket.c new file mode 100755 index 000000000..820e0631c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/socket.c @@ -0,0 +1,912 @@ + +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* +//! addr parameter is not aligned by 4byte address. Copy 4 byte addr +//! value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status +//! (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +#include "wizchip_conf.h" + +// M20150401 : Typing Error +//#define SOCK_ANY_PORT_NUM 0xC000; +#define SOCK_ANY_PORT_NUM 0xC000 + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; + +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = { + 0, + 0, +}; + +// M20150601 : For extern decleation +// static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +// + +#if _WIZCHIP_ == 5200 +static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 +uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = { + 0, +}; // set by wiz_recv_data() +#endif + +#define CHECK_SOCKNUM() \ + do { \ + if (sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + } while (0); + +#define CHECK_SOCKMODE(mode) \ + do { \ + if ((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + } while (0); + +#define CHECK_SOCKINIT() \ + do { \ + if ((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + } while (0); + +#define CHECK_SOCKDATA() \ + do { \ + if (len == 0) return SOCKERR_DATALEN; \ + } while (0); + +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) { + CHECK_SOCKNUM(); + switch (protocol) { + case Sn_MR_TCP: { + // M20150601 : Fixed the warning - taddr will never be NULL + /* + uint8_t taddr[4]; + getSIPR(taddr); + */ + uint32_t taddr; + getSIPR((uint8_t *)&taddr); + if (taddr == 0) return SOCKERR_SOCKINIT; + break; + } + case Sn_MR_UDP: + case Sn_MR_MACRAW: + case Sn_MR_IPRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + // M20150601 : For SF_TCP_ALIGN & W5300 + // if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; + if ((flag & 0x04) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if (flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if (flag != 0) { + switch (protocol) { + case Sn_MR_TCP: + // M20150601 : For SF_TCP_ALIGN & W5300 +#if _WIZCHIP_ == 5300 + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK | SF_TCP_ALIGN)) == 0) + return SOCKERR_SOCKFLAG; +#else + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK)) == 0) + return SOCKERR_SOCKFLAG; +#endif + + break; + case Sn_MR_UDP: + if (flag & SF_IGMP_VER2) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#if _WIZCHIP_ == 5500 + if (flag & SF_UNI_BLOCK) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#endif + break; + default: + break; + } + } + wiz_sock_close(sn); +// M20150601 +#if _WIZCHIP_ == 5300 + setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | + (((uint16_t)(flag & 0x02)) << 7)); +#else + setSn_MR(sn, (protocol | (flag & 0xF0))); +#endif + if (!port) { + port = sock_any_port++; + if (sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn, port); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn)) + ; + // A20150401 : For release the previous sock_io_mode + sock_io_mode &= ~(1 << sn); + // + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + // M20150601 : repalce 0 with PACK_COMPLETED + // sock_pack_info[sn] = 0; + sock_pack_info[sn] = PACK_COMPLETED; + // + while (getSn_SR(sn) == SOCK_CLOSED) + ; + return (int8_t)sn; +} + +int8_t wiz_sock_close(uint8_t sn) { + CHECK_SOCKNUM(); +// A20160426 : Applied the erratum 1 of W5300 +#if (_WIZCHIP_ == 5300) + // M20160503 : Wrong socket parameter. s -> sn + // if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != + // getSn_TxMAX(s)) ) + if (((getSn_MR(sn) & 0x0F) == Sn_MR_TCP) && + (getSn_TX_FSR(sn) != getSn_TxMAX(sn))) { + uint8_t destip[4] = {0, 0, 0, 1}; + // TODO + // You can wait for completing to sending data; + // wait about 1 second; + // if you have completed to send data, skip the code of erratum 1 + // ex> wait_1s(); + // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue; + // + // M20160503 : The socket() of close() calls close() itself again. It + // occures a infinite loop - close()->socket()->close()->socket()-> ~ + // socket(s,Sn_MR_UDP,0x3000,0); + // sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown + // destination(0.0.0.1). + setSn_MR(sn, Sn_MR_UDP); + setSn_PORTR(sn, 0x3000); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn) != 0) + ; + while (getSn_SR(sn) != SOCK_UDP) + ; + wiz_sock_sendto( + sn, destip, 1, destip, + 0x3000); // send the dummy data to an unknown destination(0.0.0.1). + }; +#endif + setSn_CR(sn, Sn_CR_CLOSE); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + // A20150401 : Release the sock_io_mode of socket n. + sock_io_mode &= ~(1 << sn); + // + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while (getSn_SR(sn) != SOCK_CLOSED) + ; + return SOCK_OK; +} + +int8_t wiz_sock_listen(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + setSn_CR(sn, Sn_CR_LISTEN); + while (getSn_CR(sn)) + ; + while (getSn_SR(sn) != SOCK_LISTEN) { + wiz_sock_close(sn); + return SOCKERR_SOCKCLOSED; + } + return SOCK_OK; +} + +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return + // SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; + } + // + + if (port == 0) return SOCKERR_PORTZERO; + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + setSn_CR(sn, Sn_CR_CONNECT); + while (getSn_CR(sn)) + ; + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_ESTABLISHED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } + } + + return SOCK_OK; +} + +int8_t wiz_sock_disconnect(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_CR(sn, Sn_CR_DISCON); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending &= ~(1 << sn); + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_CLOSED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } + } + return SOCK_OK; +} + +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t freesize = 0; + + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) + return SOCKERR_SOCKSTATUS; + if (sock_is_sending & (1 << sn)) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); +// M20150401 : Typing Error +//#if _WZICHIP_ == 5200 +#if _WIZCHIP_ == 5200 + if (getSn_TX_RD(sn) != sock_next_rd[sn]) { + setSn_CR(sn, Sn_CR_SEND); + while (getSn_CR(sn)) + ; + return SOCK_BUSY; + } +#endif + sock_is_sending &= ~(1 << sn); + } else if (tmp & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } else + return SOCK_BUSY; + } + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + } + wiz_send_data(sn, buf, len); +#if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; +#endif + +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending |= (1 << sn); + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t recvsize = 0; +// A20150601 : For integarating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t head[2]; + uint16_t mr; +#endif + // + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if (recvsize < len) len = recvsize; + +// A20150601 : For Integrating with W5300 +#if _WIZCHIP_ == 5300 + // sock_pack_info[sn] = PACK_COMPLETED; // for clear + if (sock_remained_size[sn] == 0) { +#endif + // + while (1) { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) { + if (tmp == SOCK_CLOSE_WAIT) { + if (recvsize != 0) + break; + else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } else { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if ((sock_io_mode & (1 << sn)) && (recvsize == 0)) return SOCK_BUSY; + if (recvsize != 0) break; + }; +#if _WIZCHIP_ == 5300 + } +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 + if ((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) { + mr = getMR(); + if ((getSn_MR(sn) & Sn_MR_ALIGN) == 0) { + wiz_recv_data(sn, head, 2); + if (mr & MR_FS) + recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); + else + recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); + sock_pack_info[sn] = PACK_FIRST; + } + sock_remained_size[sn] = recvsize; + } + if (len > sock_remained_size[sn]) len = sock_remained_size[sn]; + recvsize = len; + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf = sock_remained_byte[sn]; + buf++; + sock_pack_info[sn] &= ~(PACK_FIFOBYTE); + recvsize -= 1; + sock_remained_size[sn] -= 1; + } + if (recvsize != 0) { + wiz_recv_data(sn, buf, recvsize); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + } + sock_remained_size[sn] -= recvsize; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; + if (recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; + } else + sock_pack_info[sn] = PACK_COMPLETED; + if (getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; + // len = recvsize; +#else + if (recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; +#endif + + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port) { + uint8_t tmp = 0; + uint16_t freesize = 0; + uint32_t taddr; + + CHECK_SOCKNUM(); + switch (getSn_MR(sn) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + // break; + // #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + break; + // #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + //{ + // uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + //} + // + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if ((taddr == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_IPINVALID; + if ((port == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); + //#if ( _WIZCHIP_ < 5200 ) + if ((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) + return SOCKERR_SOCKSTATUS; + //#else + // if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + //#endif + + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + getSIPR((uint8_t *)&taddr); + if (taddr == 0) { + getSUBR((uint8_t *)&taddr); + setSUBR((uint8_t *)"\x00\x00\x00\x00"); + } else + taddr = 0; +#endif + +// A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + // + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + while (1) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + // M:20131104 + // else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if (tmp & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); +// M20150409 : Fixed the lost of sign bits by type casting. +// len = (uint16_t)SOCKERR_TIMEOUT; +// break; +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + return SOCKERR_TIMEOUT; + } + //////////// + } +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port) { +// M20150601 : For W5300 +#if _WIZCHIP_ == 5300 + uint16_t mr; + uint16_t mr1; +#else + uint8_t mr; +#endif + // + uint8_t head[8]; + uint16_t pack_len = 0; + + CHECK_SOCKNUM(); + // CHECK_SOCKMODE(Sn_MR_UDP); +// A20150601 +#if _WIZCHIP_ == 5300 + mr1 = getMR(); +#endif + + switch ((mr = getSn_MR(sn)) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_IPRAW: + case Sn_MR_MACRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if (sock_remained_size[sn] == 0) { + while (1) { + pack_len = getSn_RX_RSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (pack_len == 0)) return SOCK_BUSY; + if (pack_len != 0) break; + }; + } + // D20150601 : Move it to bottom + // sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) { + case Sn_MR_UDP: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 8); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + // A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + if (mr1 & MR_FS) { + addr[0] = head[1]; + addr[1] = head[0]; + addr[2] = head[3]; + addr[3] = head[2]; + *port = head[5]; + *port = (*port << 8) + head[4]; + sock_remained_size[sn] = head[7]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; + } else { +#endif + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; +#if _WIZCHIP_ == 5300 + } +#endif + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + // A20150601 : For W5300 + len = pack_len; +#if _WIZCHIP_ == 5300 + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf++ = sock_remained_byte[sn]; + pack_len -= 1; + sock_remained_size[sn] -= 1; + sock_pack_info[sn] &= ~PACK_FIFOBYTE; + } +#endif + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + case Sn_MR_MACRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 2); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2; +#if _WIZCHIP_ == W5300 + if (sock_remained_size[sn] & 0x01) + sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; + else + sock_remained_size[sn] -= 4; +#endif + if (sock_remained_size[sn] > 1514) { + wiz_sock_close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); + break; + //#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 6); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + // M20150401 : For Typing Error + // sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + //#endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn, Sn_CR_RECV); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_remained_size[sn] -= pack_len; + // M20150601 : + // if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; +#if _WIZCHIP_ == 5300 + if (pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; +#endif + } else + sock_pack_info[sn] = PACK_COMPLETED; +#if _WIZCHIP_ == 5300 + pack_len = len; +#endif + // + // M20150409 : Explicit Type Casting + // return pack_len; + return (int32_t)pack_len; +} + +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg) { + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch (cstype) { + case CS_SET_IOMODE: + tmp = *((uint8_t *)arg); + if (tmp == SOCK_IO_NONBLOCK) + sock_io_mode |= (1 << sn); + else if (tmp == SOCK_IO_BLOCK) + sock_io_mode &= ~(1 << sn); + else + return SOCKERR_ARG; + break; + case CS_GET_IOMODE: + // M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t *)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t *)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t *)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t *)arg) = getSn_IR(sn); + break; +#if _WIZCHIP_ != 5100 + case CS_SET_INTMASK: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTMASK: + *((uint8_t *)arg) = getSn_IMR(sn); + break; +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + // M20131220 : Remove warning + // uint8_t tmp; + CHECK_SOCKNUM(); + switch (sotype) { + case SO_TTL: + setSn_TTL(sn, *(uint8_t *)arg); + break; + case SO_TOS: + setSn_TOS(sn, *(uint8_t *)arg); + break; + case SO_MSS: + setSn_MSSR(sn, *(uint16_t *)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t *)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ > 5200 + if (getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; +#endif + setSn_CR(sn, Sn_CR_SEND_KEEP); + while (getSn_CR(sn) != 0) { + // M20131220 + // if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn, *(uint8_t *)arg); + break; +#endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + CHECK_SOCKNUM(); + switch (sotype) { + case SO_FLAG: + *(uint8_t *)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t *)arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t *)arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint16_t *)arg = getSn_MSSR(sn); + break; + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + *(uint16_t *)arg = getSn_DPORT(sn); + break; +#if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t *)arg = getSn_KPALVTR(sn); + break; +#endif + case SO_SENDBUF: + *(uint16_t *)arg = getSn_TX_FSR(sn); + break; + case SO_RECVBUF: + *(uint16_t *)arg = getSn_RX_RSR(sn); + break; + case SO_STATUS: + *(uint8_t *)arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if (getSn_MR(sn) & Sn_MR_TCP) + *(uint16_t *)arg = getSn_RX_RSR(sn); + else + *(uint16_t *)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + // CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ != 5300 + if ((getSn_MR(sn) == Sn_MR_TCP)) return SOCKERR_SOCKMODE; +#endif + *(uint8_t *)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/spi_interface.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/spi_interface.c new file mode 100644 index 000000000..7dbba1b46 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/spi_interface.c @@ -0,0 +1,35 @@ + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" + +// #define SPI1_CS_GPIONUM 24 + +static x_base g_w5500_spi_lock; +/** + * @brief 进入临界区 + * @retval None + */ +void spi_enter_cris(void) { g_w5500_spi_lock = DisableLocalInterrupt(); } +/** + * @brief 退出临界区 + * @retval None + */ +void spi_exit_cris(void) { EnableLocalInterrupt(g_w5500_spi_lock); } + +/** + * @brief 片选信号输出低电平 + * @retval None + */ +void spi_select_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_LOW); } +/** + * @brief 片选信号输出高电平 + * @retval None + */ +void spi_deselete_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_HIGH); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/w5500.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/w5500.c new file mode 100755 index 000000000..e98739488 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/w5500.c @@ -0,0 +1,255 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to +//! M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case +//! _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include +#include "w5500.h" + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +#if (_WIZCHIP_ == 5500) +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) { + uint8_t ret; + uint8_t spi_data[3]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + // if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte + // operation + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint16_t getSn_TX_FSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + } + } while (val != val1); + return val; +} + +uint16_t getSn_RX_RSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + } + } while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_TX_WR(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel, wizdata, len); + + ptr += len; + setSn_TX_WR(sn, ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_RX_RD(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) { + uint16_t ptr = 0; + + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn, ptr); +} + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.c new file mode 100644 index 000000000..c424ed177 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.c @@ -0,0 +1,250 @@ + +#include "wiz_ping.h" + +#include +#include +#include +#include +#include + +#define Sn_PROTO(ch) (0x001408 + (ch << 5)) + +#define PING_BIND_PORT 3000 + +PINGMSGR PingRequest = {0}; +PINGMSGR PingReply = {0}; + +static uint16_t ping_RandomID = 0x1234; +static uint16_t ping_RandomSeqNum = 0x4321; +uint8_t ping_reply_received = 0; +uint8_t ping_req = 0; +uint8_t ping_rep = 0; +uint8_t ping_cnt = 0; +uint8_t ping_rep_buf[150] = {0}; + +// ping状态机 +#define PING_STA_FREE 0 +#define PING_STA_OPEN 1 +#define PING_STA_SEND 2 +#define PING_STA_WAIT 3 +#define PING_STA_CLOSE 4 + +uint8_t ping_sta = PING_STA_FREE; + +//当前ping的设备的序号 +uint8_t ping_socket = 0; + +#define bswap_16(A) ((((uint16)(A)&0xff00) >> 8) | (((uint16)(A)&0x00ff) << 8)) + +uint16_t htons(uint16_t n) { + union { + int i; + char c; + } u = {1}; + return u.c ? bswap_16(n) : n; +} + +uint16_t checksum(uint8_t *src, uint32_t len) { + uint16_t sum, tsum, i, j; + uint32_t lsum; + + j = len >> 1; + lsum = 0; + + for (i = 0; i < j; i++) { + tsum = src[i * 2]; + tsum = tsum << 8; + tsum += src[i * 2 + 1]; + lsum += tsum; + } + + if (len % 2) { + tsum = src[i * 2]; + lsum += (tsum << 8); + } + + sum = lsum; + sum = ~(sum + (lsum >> 16)); + return (uint16_t)sum; +} + +/** + *@brief 设定次数ping外网IP函数 + *@param sn- socket number + *@param addr- 外网IP地址 + *@param pCount- ping的次数 + *@return ping成功次数 + */ +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr) { + uint16_t rlen, cnt, i; + + ping_reply_received = 0; + ping_req = 0; + ping_rep = 0; + KPrintf("Ping:%d.%d.%d.%d\r\n", (addr[0]), (addr[1]), (addr[2]), (addr[3])); + + for (i = 0; i < pCount + 1; i++) /*循环ping pCount次*/ + { + switch (getSn_SR(sn)) /*获取socket状态*/ + { + case SOCK_CLOSED: /*socket关闭状态*/ + { + wiz_sock_close(sn); + /* Create Socket */ + IINCHIP_WRITE(Sn_PROTO(sn), IPPROTO_ICMP); /*设置ICMP 协议*/ + if (wiz_socket(sn, Sn_MR_IPRAW, PING_BIND_PORT, 0) != + 0) /*判断ip raw模式socket是否开启*/ + { + } + /* Check socket register */ + while (getSn_SR(sn) != SOCK_IPRAW) { + MdelayKTask(50); + }; + break; + } + case SOCK_IPRAW: /*ip raw模式*/ + { + cnt = 0; + ping_request(sn, addr); /*发送Ping请求*/ + ping_req++; + while (1) { + if ((rlen = getSn_RX_RSR(sn)) > 0) { + rlen = ping_reply(sn, addr, rlen); /*获取回复信息*/ + ping_rep++; + if (ping_reply_received) { + break; + } + } + if ((cnt > 300)) { + cnt = 0; + break; + } else { + cnt++; + MdelayKTask(10); + } + } + break; + } + default: + break; + } + if (ping_req >= pCount) { + wiz_sock_close(sn); + } + } + return ping_rep; +} + +/** + *@brief ping请求函数 + *@param sn- socket number + *@param addr- P地址 + *@return 无 + */ +uint8_t ping_request(uint8_t sn, uint8_t *addr) { + uint8_t *buffer; + uint16_t i, temp_len = 0; + ping_reply_received = 0; /*ping 回复初始化标志位*/ + PingRequest.Type = PING_REQUEST; /*Ping-Request*/ + PingRequest.Code = CODE_ZERO; /*总是 '0'*/ + PingRequest.ID = htons(ping_RandomID++); /*设置ping响应ID为随机的整型变量*/ + PingRequest.SeqNum = + htons(ping_RandomSeqNum++); /*设置ping响应的序列号为随机整形变量*/ + for (i = 0; i < PING_BUF_LEN; i++) { + PingRequest.Data[i] = (i) % 8; /*ping相应的数在'0'~'8‘*/ + } + PingRequest.CheckSum = 0; + /* 计算响应次数*/ + PingRequest.CheckSum = + htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest))); + + /*发送ping响应到目的方 */ + if (wiz_sock_sendto(sn, (uint8_t *)&PingRequest, sizeof(PingRequest), addr, + PING_BIND_PORT) == 0) { + KPrintf("Fail to send ping-reply packet\r\n"); + } else { + KPrintf("ping send\n"); + } + return 0; +} + +/** + *@brief 解析Ping回复 + *@param sn- socket number + *@param addr- Ping地址 + *@return 无 + */ +uint8_t ping_reply(uint8_t sn, uint8_t *addr, uint16_t rlen) { + uint16_t tmp_checksum; + uint16_t len; + uint16_t i; + + uint16_t port = PING_BIND_PORT; + PINGMSGR PingReply; + + memset(ping_rep_buf, 0, sizeof(ping_rep_buf)); + len = wiz_sock_recvfrom(sn, ping_rep_buf, rlen, addr, + &port); /*从目的端接收数据*/ + + if (ping_rep_buf[0] == PING_REPLY) { + PingReply.Type = ping_rep_buf[0]; + PingReply.Code = ping_rep_buf[1]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = ~checksum(ping_rep_buf, len); /*检查ping回复的次数*/ + if (tmp_checksum != 0xffff) { + KPrintf("tmp_checksum = %x\r\n", tmp_checksum); + } else { + KPrintf("Reply from %3d.%3d.%3d.%3d ID=%x Byte=%d\r\n\r\n", (addr[0]), + (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), (rlen + 6)); + ping_reply_received = 1; /*当退出ping回复循环时,设置ping回复标志为1*/ + } + } else if (ping_rep_buf[0] == PING_REQUEST) { + PingReply.Code = ping_rep_buf[1]; + PingReply.Type = ping_rep_buf[2]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = PingReply.CheckSum; /*检查ping回复次数*/ + PingReply.CheckSum = 0; + if (tmp_checksum != PingReply.CheckSum) { + KPrintf(" \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), + htons(PingReply.CheckSum)); + } else { + } + KPrintf( + " Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n", + (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), + (PingReply.SeqNum), (rlen + 6)); + ping_reply_received = 1; /* 当退出ping回复循环时,设置ping回复标志为1 + */ + } else { + KPrintf(" Unkonwn msg. \n"); + } + return 0; +} + +void wiz_ping_test(int argc, char *argv[]) { + uint32_t tmp_ip[4]; + uint8_t target_ip[4]; + if (argc >= 2) { + KPrintf("This is a Ping test: %s\n", argv[1]); + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], + &tmp_ip[3]); + target_ip[0] = (uint8_t)tmp_ip[0]; + target_ip[1] = (uint8_t)tmp_ip[1]; + target_ip[2] = (uint8_t)tmp_ip[2]; + target_ip[3] = (uint8_t)tmp_ip[3]; + ping_count(ping_socket, 5, target_ip); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + ping, wiz_ping_test, ping to given addr); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.h new file mode 100644 index 000000000..3ead801b8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wiz_ping.h @@ -0,0 +1,35 @@ +#ifndef _WIZ_PING_H_ +#define _WIZ_PING_H_ + +#include "socket.h" +#include "w5500.h" + +#define PING_BUF_LEN 32 +#define PING_REQUEST 8 +#define PING_REPLY 0 +#define CODE_ZERO 0 + +#define SOCKET_ERROR 1 +#define TIMEOUT_ERROR 2 +#define SUCCESS 3 +#define REPLY_ERROR 4 + +typedef struct pingmsg { + uint8_t Type; // 0 - Ping Reply, 8 - Ping Request + uint8_t Code; // Always 0 + uint16_t CheckSum; // Check sum + uint16_t ID; // Identification + uint16_t SeqNum; // Sequence Number + int8_t Data[PING_BUF_LEN]; // Ping Data : 1452 = IP RAW MTU - + // sizeof(Type+Code+CheckSum+ID+SeqNum) +} PINGMSGR; + +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr); + +uint8_t ping_request(uint8_t s, uint8_t *addr); + +uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen); + +void Ethernet_ping_service_deal(uint8_t sn); + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wizchip_conf.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wizchip_conf.c new file mode 100755 index 000000000..1407c852f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/ethernet/wizchip_conf.c @@ -0,0 +1,862 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readdata() & +//! wizchip_bus_writedata() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting +//! it into uint8_t* For remove the warning when pointer type size is +//! not 32bit. If ptrdiff_t doesn't support in your complier, You +//! should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +// A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" + +///////////// +// M20150401 : Remove ; in the default callback function such as +// wizchip_cris_enter(), wizchip_cs_select() and etc. +///////////// + +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_enter(void) {}; +void wizchip_cris_enter(void) {} + +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_exit(void) {}; +void wizchip_cris_exit(void) {} + +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_select(void) {}; +void wizchip_cs_select(void) {} + +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_deselect(void) {}; +void wizchip_cs_deselect(void) {} + +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t +// *)((ptrdiff_t) AddrSel)); } +iodata_t wizchip_bus_readdata(uint32_t AddrSel) { + return *((volatile iodata_t *)((ptrdiff_t)AddrSel)); +} + +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile +// uint8_t*)((ptrdiff_t)AddrSel)) = wb; } +void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { + *((volatile iodata_t *)((ptrdiff_t)AddrSel)) = wb; +} + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// uint8_t wizchip_spi_readbyte(void) {return 0;}; +uint8_t wizchip_spi_readbyte(void) { return 0; } + +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writebyte(uint8_t wb) {}; +void wizchip_spi_writebyte(uint8_t wb) {} + +/** + * @brief Default function to burst read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_readburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @brief Default function to burst write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_writeburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @\ref _WIZCHIP instance + */ +// +// M20150401 : For a compiler didnot support a member of structure +// Replace the assignment of struct members with the assingment of +// array +// +/* +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; +*/ +_WIZCHIP WIZCHIP = {_WIZCHIP_IO_MODE_, + _WIZCHIP_ID_, + {wizchip_cris_enter, wizchip_cris_exit}, + {wizchip_cs_select, wizchip_cs_deselect}, + { + {// M20150601 : Rename the function + // wizchip_bus_readbyte, + // wizchip_bus_writebyte + wizchip_bus_readdata, wizchip_bus_writedata}, + + }}; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)) { + if (!cris_en || !cris_ex) { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } else { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)) { + if (!cs_sel || !cs_desel) { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } else { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +// M20150515 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)) +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)) + ; + // M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if (!bus_rb || !bus_wb) { + WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata; + WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata; + } else { + WIZCHIP.IF.BUS._read_data = bus_rb; + WIZCHIP.IF.BUS._write_data = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +// 20140626 Eric Added for SPI burst operations +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rb; + WIZCHIP.IF.SPI._write_burst = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg) { +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + uint8_t tmp = 0; +#endif + uint8_t *ptmp[2] = {0, 0}; + switch (cwtype) { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if (arg != 0) { + ptmp[0] = (uint8_t *)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind *)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind *)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind *)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind *)arg) = wizchip_getinterruptmask(); + break; +// M20150601 : This can be supported by W5200, W5500 +//#if _WIZCHIP_ > W5100 +#if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t *)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t *)arg = getINTLEVEL(); + break; +#endif + case CW_GET_ID: + ((uint8_t *)arg)[0] = WIZCHIP.id[0]; + ((uint8_t *)arg)[1] = WIZCHIP.id[1]; + ((uint8_t *)arg)[2] = WIZCHIP.id[2]; + ((uint8_t *)arg)[3] = WIZCHIP.id[3]; + ((uint8_t *)arg)[4] = WIZCHIP.id[4]; + ((uint8_t *)arg)[5] = WIZCHIP.id[5]; + ((uint8_t *)arg)[6] = 0; + break; +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t *)arg); +#endif +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; +#endif + default: + return -1; + } + return 0; +} + +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg) { + + switch (cntype) { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo *)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo *)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type *)arg); + case CN_GET_NETMODE: + *(netmode_type *)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout *)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout *)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) { + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; +// A20150601 +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + uint16_t mr = (uint16_t)getMR(); + setMR(mr | MR_IND); +#endif + // + getSHAR(mac); + getGAR(gw); + getSUBR(sn); + getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay +// A2015051 : For indirect bus mode +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + setMR(mr | MR_IND); +#endif + // + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize) { + int8_t i; +#if _WIZCHIP_ < W5200 + int8_t j; +#endif + int8_t tmp = 0; + wizchip_sw_reset(); + if (txsize) { + tmp = 0; +// M20150601 : For integrating with W5300 +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (txsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += txsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += txsize[i]; + +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 + j = 0; + while ((txsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_TXBUF_SIZE(i, j); +#else + setSn_TXBUF_SIZE(i, txsize[i]); +#endif + } + +#endif + } + + if (rxsize) { + tmp = 0; +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (rxsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += rxsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += rxsize[i]; +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // add condition for w5100 + j = 0; + while ((rxsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_RXBUF_SIZE(i, j); +#else + setSn_RXBUF_SIZE(i, rxsize[i]); +#endif + } +#endif + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) { + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + ir |= (1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ <= W5100S + ir |= sir; + setIR(ir); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIR(((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF))); +#else + setIR(ir); + // M20200227 : For clear + // setSIR(sir); + for (ir = 0; ir < 8; ir++) { + if (sir & (0x01 << ir)) + setSn_IR(ir, 0xff); + } + +#endif +} + +intr_kind wizchip_getinterrupt(void) { + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ <= W5100S + ir = getIR(); + sir = ir & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIR(); + ir = (uint8_t)(ret >> 8); + sir = (uint8_t)ret; +#else + ir = getIR(); + sir = getSIR(); +#endif + +// M20150601 : For Integrating with W5300 +//#if _WIZCHIP_ < W5500 +#if _WIZCHIP_ < W5200 + ir &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) { + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + simr &= 0x0F; + imr |= simr; + setIMR(imr); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIMR(((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF))); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) { + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ < W5200 + imr = getIMR(); + simr = imr & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIMR(); + imr = (uint8_t)(ret >> 8); + simr = (uint8_t)ret; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) { + int8_t tmp = PHY_LINK_OFF; +#if _WIZCHIP_ == W5100S + if (getPHYSR() & PHYSR_LNK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5500 + if (getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > W5100 + +int8_t wizphy_getphypmode(void) { + int8_t tmp = 0; +#if _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#elif _WIZCHIP_ == 5500 + if ((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#else + tmp = -1; +#endif + return tmp; +} +#endif + +#if _WIZCHIP_ == W5100S +void wizphy_reset(void) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + tmp |= BMCR_RESET; + wiz_mdio_write(PHYMDIO_BMCR, tmp); + while (wiz_mdio_read(PHYMDIO_BMCR) & BMCR_RESET) { + } +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= BMCR_AUTONEGO; + else { + tmp &= ~BMCR_AUTONEGO; + if (phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DUP; + } else { + tmp &= ~BMCR_DUP; + } + if (phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPEED; + } else { + tmp &= ~BMCR_SPEED; + } + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + phyconf->by = PHY_CONFBY_SW; + if (tmp & BMCR_AUTONEGO) { + phyconf->mode = PHY_MODE_AUTONEGO; + } else { + phyconf->mode = PHY_MODE_MANUAL; + if (tmp & BMCR_DUP) + phyconf->duplex = PHY_DUPLEX_FULL; + else + phyconf->duplex = PHY_DUPLEX_HALF; + if (tmp & BMCR_SPEED) + phyconf->speed = PHY_SPEED_100; + else + phyconf->speed = PHY_SPEED_10; + } +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + if (tmp & BMCR_PWDN) + return 0; + } else { + if ((tmp & BMCR_PWDN) != BMCR_PWDN) + return 0; + } + return -1; +} + +#endif +#if _WIZCHIP_ == W5500 +void wizphy_reset(void) { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + if (phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else { + if (phyconf->duplex == PHY_DUPLEX_FULL) { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } else { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf *phyconf) { + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = + (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if ((tmp & PHYCFGR_OPMD) == 0) + return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if (pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if (pmode == PHY_POWER_DOWN) { + if (tmp & PHYCFGR_OPMDC_PDOWN) + return 0; + } else { + if (tmp & PHYCFGR_OPMDC_ALLA) + return 0; + } + return -1; +} +#endif + +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo) { + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo) { + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0] = _DNS_[0]; + pnetinfo->dns[1] = _DNS_[1]; + pnetinfo->dns[2] = _DNS_[2]; + pnetinfo->dns[3] = _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) { + uint8_t tmp = 0; +#if _WIZCHIP_ != W5500 + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) + return -1; +#else + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) + return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) { return (netmode_type)getMR(); } + +void wizchip_settimeout(wiz_NetTimeout *nettime) { + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout *nettime) { + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c index 78793b8aa..3b344e47d 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/drv_io_config.c @@ -9,44 +9,49 @@ */ /** -* @file drv_io_config.c -* @brief support xidatong-riscv64-board io configure -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file drv_io_config.c + * @brief support xidatong-riscv64-board io configure + * @version 2.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: drv_io_config.c Description: support kd233-board io configure Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.c for references https://github.com/RT-Thread/rt-thread/tree/v4.0.2 -History: +History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab Modification: support kd233-board io configure *************************************************/ -#include -#include #include "drv_io_config.h" -#include + +#include +#include +#include #define HS_GPIO(n) (FUNC_GPIOHS0 + n) -#define IOCONFIG(pin,func) {pin, func, #func} +#define IOCONFIG(pin, func) \ + { pin, func, #func } -static struct io_config -{ - int io_num; - fpioa_function_t func; - const char * FuncName; -} io_config[] = -{ +static struct io_config { + int io_num; + fpioa_function_t func; + const char* FuncName; +} io_config[] = { #ifdef BSP_USING_LCD - IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0), - IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK), - IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(LCD_DC_PIN)), + IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0), + IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK), + IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(LCD_DC_PIN)), +#endif + +#ifdef BSP_USING_W5500 + IOCONFIG(BSP_WIZ_RST_PIN, HS_GPIO(WIZ_RST_PIN)), + IOCONFIG(BSP_WIZ_INT_PIN, HS_GPIO(WIZ_INT_PIN)), #endif #ifdef BSP_USING_SPI1 @@ -83,63 +88,59 @@ static struct io_config #endif #ifdef BSP_USING_CH438 - IOCONFIG(BSP_CH438_ALE_PIN, HS_GPIO(FPIOA_CH438_ALE)), - IOCONFIG(BSP_CH438_NWR_PIN, HS_GPIO(FPIOA_CH438_NWR)), - IOCONFIG(BSP_CH438_NRD_PIN, HS_GPIO(FPIOA_CH438_NRD)), - IOCONFIG(BSP_CH438_INT_PIN, HS_GPIO(FPIOA_CH438_INT)), - IOCONFIG(BSP_CH438_D0_PIN, HS_GPIO(FPIOA_CH438_D0)), - IOCONFIG(BSP_CH438_D1_PIN, HS_GPIO(FPIOA_CH438_D1)), - IOCONFIG(BSP_CH438_D2_PIN, HS_GPIO(FPIOA_CH438_D2)), - IOCONFIG(BSP_CH438_D3_PIN, HS_GPIO(FPIOA_CH438_D3)), - IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)), - IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)), - IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)), - IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)) + IOCONFIG(BSP_CH438_ALE_PIN, HS_GPIO(FPIOA_CH438_ALE)), + IOCONFIG(BSP_CH438_NWR_PIN, HS_GPIO(FPIOA_CH438_NWR)), + IOCONFIG(BSP_CH438_NRD_PIN, HS_GPIO(FPIOA_CH438_NRD)), + IOCONFIG(BSP_CH438_INT_PIN, HS_GPIO(FPIOA_CH438_INT)), + IOCONFIG(BSP_CH438_D0_PIN, HS_GPIO(FPIOA_CH438_D0)), + IOCONFIG(BSP_CH438_D1_PIN, HS_GPIO(FPIOA_CH438_D1)), + IOCONFIG(BSP_CH438_D2_PIN, HS_GPIO(FPIOA_CH438_D2)), + IOCONFIG(BSP_CH438_D3_PIN, HS_GPIO(FPIOA_CH438_D3)), + IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)), + IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)), + IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)), + IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)) #endif }; -static int PrintIoConfig() -{ - int i; - KPrintf("IO Configuration Table\n"); - KPrintf("┌───────┬────────────────────────┐\n"); - KPrintf("│Pin │Function │\n"); - KPrintf("├───────┼────────────────────────┤\n"); - for(i = 0; i < sizeof io_config / sizeof io_config[0]; i++) - { - KPrintf("│%-2d │%-24.24s│\n", io_config[i].io_num, io_config[i].FuncName); - } - KPrintf("└───────┴────────────────────────┘\n"); - return 0; +static int PrintIoConfig() { + int i; + KPrintf("IO Configuration Table\n"); + KPrintf("┌───────┬────────────────────────┐\n"); + KPrintf("│Pin │Function │\n"); + KPrintf("├───────┼────────────────────────┤\n"); + for (i = 0; i < sizeof io_config / sizeof io_config[0]; i++) { + KPrintf("│%-2d │%-24.24s│\n", io_config[i].io_num, + io_config[i].FuncName); + } + KPrintf("└───────┴────────────────────────┘\n"); + return 0; } -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), - io,PrintIoConfig,print io config); +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + io, PrintIoConfig, print io config); -int IoConfigInit(void) -{ - int count = sizeof(io_config) / sizeof(io_config[0]); - int i; - int ret = 0; +int IoConfigInit(void) { + int count = sizeof(io_config) / sizeof(io_config[0]); + int i; + int ret = 0; - sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); - sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); - sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); #ifdef BSP_USING_UART2 - // for IO-27/28 - sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33); + // for IO-27/28 + sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33); #endif -#if defined(BSP_USING_UART1) || defined(BSP_USING_UART3) - // for IO-20~23 - sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); +#if defined(BSP_USING_UART1) || defined(BSP_USING_UART3) + // for IO-20~23 + sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); #endif - for(i = 0; i < count; i++) - { - ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func); - if(ret != 0) - return ret; - } + for (i = 0; i < count; i++) { + ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func); + if (ret != 0) return ret; + } - return ret; + return ret; } - diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c index 9802b69f7..6e71be831 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/gpio/gpio.c @@ -26,6 +26,7 @@ #include "utils.h" #include "fpioa.h" #include "sysctl.h" +#include #define GPIO_MAX_PINNO 8 volatile gpio_t* const gpio = (volatile gpio_t*)GPIO_BASE_ADDR; diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_soft_spi.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_soft_spi.h new file mode 100644 index 000000000..687c1383d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_soft_spi.h @@ -0,0 +1,14 @@ +#ifndef CONNECT_TF_H +#define CONNECT_TF_H + +#ifdef __cplusplus +extern "C" { +#endif + +int HwSoftSPIInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_spi.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_spi.h new file mode 100644 index 000000000..cd746d016 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_spi.h @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_spi.h +* @brief define aiit-riscv64-board spi function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_SPI_H +#define CONNECT_SPI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwSpiInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_w5500.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_w5500.h new file mode 100644 index 000000000..43359e8f4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/connect_w5500.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan + * PSL v2. You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY + * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the + * Mulan PSL v2 for more details. + */ + +/** + * @file connect_w5500.h + * @brief define aiit-riscv64-board spi function and struct + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-10-16 + */ + +#ifndef _CONNECT_W5500_H_ +#define _CONNECT_W5500_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static struct Bus *spi_bus; + +int HwWiznetInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h index 4e247e955..7b2dfadca 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/drv_io_config.h @@ -9,19 +9,19 @@ */ /** -* @file drv_io_config.h -* @brief define xidatong-riscv64-board io configure -* @version 2.0 -* @author AIIT XUOS Lab -* @date 2022-07-25 -*/ + * @file drv_io_config.h + * @brief define xidatong-riscv64-board io configure + * @version 2.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ /************************************************* File name: drv_io_config.h Description: define xidatong-riscv64-board io configure Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.h for references https://github.com/RT-Thread/rt-thread/tree/v4.0.2 -History: +History: 1. Date: 2022-07-25 Author: AIIT XUOS Lab Modification: add xidatong-riscv64-board io configure define @@ -30,52 +30,57 @@ Modification: add xidatong-riscv64-board io configure define #ifndef __DRV_IO_CONFIG_H__ #define __DRV_IO_CONFIG_H__ -enum HS_GPIO_CONFIG -{ +#include + +enum HS_GPIO_CONFIG { #ifdef BSP_USING_LCD - LCD_DC_PIN = 0, /* LCD DC PIN */ + LCD_DC_PIN = 0, /* LCD DC PIN */ #endif #ifdef BSP_SPI1_USING_SS0 - SPI1_CS0_PIN, + SPI1_CS0_PIN, #endif #ifdef BSP_SPI1_USING_SS1 - SPI1_CS1_PIN, + SPI1_CS1_PIN, #endif #ifdef BSP_SPI1_USING_SS2 - SPI1_CS2_PIN, + SPI1_CS2_PIN, #endif #ifdef BSP_SPI1_USING_SS3 - SPI1_CS3_PIN, + SPI1_CS3_PIN, #endif - GPIO_ALLOC_START /* index of gpio driver start */ +#ifdef BSP_USING_W5500 + WIZ_RST_PIN, + WIZ_INT_PIN, +#endif + GPIO_ALLOC_START /* index of gpio driver start */ }; #ifdef BSP_USING_CH438 -#define FPIOA_CH438_ALE 12 -#define FPIOA_CH438_NWR 13 -#define FPIOA_CH438_NRD 14 -#define FPIOA_CH438_D0 15 -#define FPIOA_CH438_D1 16 -#define FPIOA_CH438_D2 17 -#define FPIOA_CH438_D3 18 -#define FPIOA_CH438_D4 19 -#define FPIOA_CH438_D5 20 -#define FPIOA_CH438_D6 21 -#define FPIOA_CH438_D7 22 -#define FPIOA_CH438_INT 23 +#define FPIOA_CH438_ALE 12 +#define FPIOA_CH438_NWR 13 +#define FPIOA_CH438_NRD 14 +#define FPIOA_CH438_D0 15 +#define FPIOA_CH438_D1 16 +#define FPIOA_CH438_D2 17 +#define FPIOA_CH438_D3 18 +#define FPIOA_CH438_D4 19 +#define FPIOA_CH438_D5 20 +#define FPIOA_CH438_D6 21 +#define FPIOA_CH438_D7 22 +#define FPIOA_CH438_INT 23 -#define BSP_CH438_ALE_PIN 24 -#define BSP_CH438_NWR_PIN 25 -#define BSP_CH438_NRD_PIN 26 -#define BSP_CH438_D0_PIN 27 -#define BSP_CH438_D1_PIN 28 -#define BSP_CH438_D2_PIN 29 -#define BSP_CH438_D3_PIN 30 -#define BSP_CH438_D4_PIN 31 -#define BSP_CH438_D5_PIN 32 -#define BSP_CH438_D6_PIN 33 -#define BSP_CH438_D7_PIN 34 -#define BSP_CH438_INT_PIN 35 +#define BSP_CH438_ALE_PIN 24 +#define BSP_CH438_NWR_PIN 25 +#define BSP_CH438_NRD_PIN 26 +#define BSP_CH438_D0_PIN 27 +#define BSP_CH438_D1_PIN 28 +#define BSP_CH438_D2_PIN 29 +#define BSP_CH438_D3_PIN 30 +#define BSP_CH438_D4_PIN 31 +#define BSP_CH438_D5_PIN 32 +#define BSP_CH438_D6_PIN 33 +#define BSP_CH438_D7_PIN 34 +#define BSP_CH438_INT_PIN 35 #endif extern int IoConfigInit(void); diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/hardware_spi.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/hardware_spi.h new file mode 100644 index 000000000..4d3fd3599 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/hardware_spi.h @@ -0,0 +1,494 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_spi.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __HARDWARE_SPI_H__ +#define __HARDWARE_SPI_H__ + +#include "dmac.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +typedef struct _spi +{ + /* SPI Control Register 0 (0x00)*/ + volatile uint32_t ctrlr0; + /* SPI Control Register 1 (0x04)*/ + volatile uint32_t ctrlr1; + /* SPI Enable Register (0x08)*/ + volatile uint32_t ssienr; + /* SPI Microwire Control Register (0x0c)*/ + volatile uint32_t mwcr; + /* SPI Slave Enable Register (0x10)*/ + volatile uint32_t ser; + /* SPI Baud Rate Select (0x14)*/ + volatile uint32_t baudr; + /* SPI Transmit FIFO Threshold Level (0x18)*/ + volatile uint32_t txftlr; + /* SPI Receive FIFO Threshold Level (0x1c)*/ + volatile uint32_t rxftlr; + /* SPI Transmit FIFO Level Register (0x20)*/ + volatile uint32_t txflr; + /* SPI Receive FIFO Level Register (0x24)*/ + volatile uint32_t rxflr; + /* SPI Status Register (0x28)*/ + volatile uint32_t sr; + /* SPI Interrupt Mask Register (0x2c)*/ + volatile uint32_t imr; + /* SPI Interrupt Status Register (0x30)*/ + volatile uint32_t isr; + /* SPI Raw Interrupt Status Register (0x34)*/ + volatile uint32_t risr; + /* SPI Transmit FIFO Overflow Interrupt Clear Register (0x38)*/ + volatile uint32_t txoicr; + /* SPI Receive FIFO Overflow Interrupt Clear Register (0x3c)*/ + volatile uint32_t rxoicr; + /* SPI Receive FIFO Underflow Interrupt Clear Register (0x40)*/ + volatile uint32_t rxuicr; + /* SPI Multi-Master Interrupt Clear Register (0x44)*/ + volatile uint32_t msticr; + /* SPI Interrupt Clear Register (0x48)*/ + volatile uint32_t icr; + /* SPI DMA Control Register (0x4c)*/ + volatile uint32_t dmacr; + /* SPI DMA Transmit Data Level (0x50)*/ + volatile uint32_t dmatdlr; + /* SPI DMA Receive Data Level (0x54)*/ + volatile uint32_t dmardlr; + /* SPI Identification Register (0x58)*/ + volatile uint32_t idr; + /* SPI DWC_ssi component version (0x5c)*/ + volatile uint32_t ssic_version_id; + /* SPI Data Register 0-36 (0x60 -- 0xec)*/ + volatile uint32_t dr[36]; + /* SPI RX Sample Delay Register (0xf0)*/ + volatile uint32_t rx_sample_delay; + /* SPI SPI Control Register (0xf4)*/ + volatile uint32_t spi_ctrlr0; + /* reserved (0xf8)*/ + volatile uint32_t resv; + /* SPI XIP Mode bits (0xfc)*/ + volatile uint32_t xip_mode_bits; + /* SPI XIP INCR transfer opcode (0x100)*/ + volatile uint32_t xip_incr_inst; + /* SPI XIP WRAP transfer opcode (0x104)*/ + volatile uint32_t xip_wrap_inst; + /* SPI XIP Control Register (0x108)*/ + volatile uint32_t xip_ctrl; + /* SPI XIP Slave Enable Register (0x10c)*/ + volatile uint32_t xip_ser; + /* SPI XIP Receive FIFO Overflow Interrupt Clear Register (0x110)*/ + volatile uint32_t xrxoicr; + /* SPI XIP time out register for continuous transfers (0x114)*/ + volatile uint32_t xip_cnt_time_out; + volatile uint32_t endian; +} __attribute__((packed, aligned(4))) spi_t; +/* clang-format on */ + +typedef enum _spi_device_num +{ + SPI_DEVICE_0, + SPI_DEVICE_1, + SPI_DEVICE_2, + SPI_DEVICE_3, + SPI_DEVICE_MAX, +} spi_device_num_t; + +typedef enum _spi_work_mode +{ + SPI_WORK_MODE_0, + SPI_WORK_MODE_1, + SPI_WORK_MODE_2, + SPI_WORK_MODE_3, +} spi_work_mode_t; + +typedef enum _spi_frame_format +{ + SPI_FF_STANDARD, + SPI_FF_DUAL, + SPI_FF_QUAD, + SPI_FF_OCTAL +} spi_frame_format_t; + +typedef enum _spi_instruction_address_trans_mode +{ + SPI_AITM_STANDARD, + SPI_AITM_ADDR_STANDARD, + SPI_AITM_AS_FRAME_FORMAT +} spi_instruction_address_trans_mode_t; + +typedef enum _spi_transfer_mode +{ + SPI_TMOD_TRANS_RECV, + SPI_TMOD_TRANS, + SPI_TMOD_RECV, + SPI_TMOD_EEROM +} spi_transfer_mode_t; + + +typedef enum _spi_transfer_width +{ + SPI_TRANS_CHAR = 0x1, + SPI_TRANS_SHORT = 0x2, + SPI_TRANS_INT = 0x4, +} spi_transfer_width_t; + +typedef enum _spi_chip_select +{ + SPI_CHIP_SELECT_0, + SPI_CHIP_SELECT_1, + SPI_CHIP_SELECT_2, + SPI_CHIP_SELECT_3, + SPI_CHIP_SELECT_MAX, +} spi_chip_select_t; + +typedef enum +{ + WRITE_CONFIG, + READ_CONFIG, + WRITE_DATA_BYTE, + READ_DATA_BYTE, + WRITE_DATA_BLOCK, + READ_DATA_BLOCK, +} spi_slave_command_e; + +typedef struct +{ + uint8_t cmd; + uint8_t err; + uint32_t addr; + uint32_t len; +} spi_slave_command_t; + +typedef enum +{ + IDLE, + COMMAND, + TRANSFER, +} spi_slave_status_e; + +typedef int (*spi_slave_receive_callback_t)(void *ctx); + +typedef struct _spi_slave_instance +{ + uint8_t int_pin; + uint8_t ready_pin; + dmac_channel_number_t dmac_channel; + uint8_t dfs; + uint8_t slv_oe; + uint8_t work_mode; + size_t data_bit_length; + volatile spi_slave_status_e status; + volatile spi_slave_command_t command; + volatile uint8_t *config_ptr; + uint32_t config_len; + spi_slave_receive_callback_t callback; +} spi_slave_instance_t; + +typedef struct _spi_data_t +{ + dmac_channel_number_t tx_channel; + dmac_channel_number_t rx_channel; + uint32_t *tx_buf; + size_t tx_len; + uint32_t *rx_buf; + size_t rx_len; + spi_transfer_mode_t TransferMode; + bool fill_mode; +} spi_data_t; + +extern volatile spi_t *const spi[4]; + +/** + * @brief Set spi configuration + * + * @param[in] spi_num Spi bus number + * @param[in] mode Spi mode + * @param[in] frame_format Spi frame format + * @param[in] data_bit_length Spi data bit length + * @param[in] endian 0:little-endian 1:big-endian + * + * @return Void + */ +void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format, + size_t data_bit_length, uint32_t endian); + +/** + * @brief Set multiline configuration + * + * @param[in] spi_num Spi bus number + * @param[in] instruction_length Instruction length + * @param[in] address_length Address length + * @param[in] wait_cycles Wait cycles + * @param[in] instruction_address_trans_mode Spi transfer mode + * + */ +void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length, + uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode); + +/** + * @brief Spi send data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi receive data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special receive data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special send data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi send data by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint8_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi receive data by dma + * + * @param[in] w_channel_num Dmac write channel number + * @param[in] r_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special send data by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint32_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi special receive data by dma + * + * @param[in] dma_send_channel_num Dmac write channel number + * @param[in] dma_receive_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi fill dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buff Spi command buffer point + * @param[in] tx_len Spi command length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint32_t *tx_buff, size_t tx_len); + +/** + * @brief Spi normal send by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * @param[in] stw Spi transfer width + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width); + +/** + * @brief Spi normal send by dma + * + * @param[in] spi_num Spi bus number + * @param[in] spi_clk Spi clock rate + * + * @return The real spi clock rate + */ +uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk); + +/** + * @brief Spi full duplex send receive data by dma + * + * @param[in] dma_send_channel_num Dmac write channel number + * @param[in] dma_receive_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buf Spi send buffer + * @param[in] tx_len Spi send buffer length + * @param[in] rx_buf Spi receive buffer + * @param[in] rx_len Spi receive buffer length + * + */ +void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len); + +/** + * @brief Set spi slave configuration + * + * @param[in] int_pin SPI master starts sending data interrupt. + * @param[in] ready_pin SPI slave ready. + * @param[in] dmac_channel Dmac channel number for block. + * @param[in] data_bit_length Spi data bit length + * @param[in] data SPI slave device data buffer. + * @param[in] len The length of SPI slave device data buffer. + * @param[in] callback Callback of spi slave. + * + * @return Void + */ +void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback); + +/** + * @brief Spi handle transfer data operations + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] data Spi transfer data information + * @param[in] cb Spi DMA callback + * + */ +void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb); + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_SPI_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/socket.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/socket.h new file mode 100755 index 000000000..91e1a7bd9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/socket.h @@ -0,0 +1,585 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has + * much similar name and interface. But there is a little bit of difference. + * @details + * Comparison between WIZnet and Berkeley SOCKET APIs + * + * + * + * + * + * + * + * + * + * + * + * + * + *
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating + * a SOCKET but also binding a local port number, and listen() of WIZnet is not + * only listening to connection request from client but also accepting the + * connection request. \n When you program "TCP SERVER" with Berkeley SOCKET + * API, you can use only one listen port. When the listen SOCKET accepts a + * connection request from a client, it keeps listening. After accepting the + * connection request, a new SOCKET is created and the new SOCKET is used in + * communication with the client. \n Following figure shows network flow diagram + * by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as + * many as 8 listen SOCKET with same port number. \n Because there's no accept() + * in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request + * from a client, it is changed in order to communicate with the client. And the + * changed SOCKET is not listening any more and is dedicated for communicating + * with the client. \n If there're many listen SOCKET with same listen port + * number and a client requests a connection, the SOCKET which has the smallest + * SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY \ + 0 ///< Socket is busy on processing the operation. Valid only Non-block IO + ///< Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT \ + (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address + ///< when Sn_MR_TCP +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE \ + (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS \ + (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN \ + (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER \ + (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN \ + (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN \ + (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, + ///< multicast and own packet +#define SF_IGMP_VER2 \ + (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP + ///< version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE \ + (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 +#define SF_BROAD_BLOCK \ + (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast + ///< packet. Valid only in W5500 +#define SF_MULTI_BLOCK \ + (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in + ///< W5500 +#define SF_IPv6_BLOCK \ + (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in + ///< W5500 +#define SF_UNI_BLOCK \ + (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only + ///< in W5500 +#endif + +// A201505 : For W5300 +#if _WIZCHIP_ == 5300 +#define SF_TCP_ALIGN \ + 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN +#endif + +#define SF_IO_NONBLOCK \ + 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST \ + 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When + ///< W5300, This flag can be applied) +#define PACK_REMAINED \ + 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. + ///< (When W5300, This flag can be applied) +#define PACK_COMPLETED \ + 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + ///< (When W5300, This flag can be applied) +// A20150601 : For Integrating with W5300 +#define PACK_FIFOBYTE \ + 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR. +// + +#ifndef AF_WIZ +#define AF_WIZ 46 +#endif + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref + * SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n Valid + * flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref + * SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as + * TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t wiz_sock_close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is + * established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t wiz_sock_listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and + * port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediately. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request + * connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned + * immediately\n + */ +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as + parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. + \n + * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t wiz_sock_disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data + * greater than socket buffer size. \n In block io mode, It doesn't return until + * data send is completed - socket buffer size is greater than data. \n In + * non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is + * not enough. \n + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in + * the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data + * greater than socket buffer size. \n In block io mode, it doesn't return until + * data reception is completed - data is filled as len in socket buffer. + * \n In non-block io mode, it return @ref SOCK_BUSY immediately when len + * is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket + * \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port + * number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP + * address and port number passed as parameter.\n Even if the connectionless + * socket has been previously connected to a specific address, the address and + * port number parameters override the destination address for that particular + * datagram only. + * @note In block io mode, It doesn't return until data send is completed - + * socket buffer size is greater than len. In non-block io mode, It + * return @ref SOCK_BUSY immediately when socket buffer is not enough. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed + * \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to + * receive the data in other then TCP mode. \n This function is used to receive + * UDP and MAC_RAW mode, and handle the header as well. This function can divide + * to received the packet data. On the MACRAW SOCKET, the addr and port + * parameters are ignored. + * @note In block io mode, it doesn't return until data reception is + * completed - data is filled as len in socket buffer In non-block io + * mode, it return @ref SOCK_BUSY immediately when len is greater than + * data size in socket buffer. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet + * sized. When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. It is valid only when the first call recvfrom for + * receiving the packet. When it is valid, @ref packinfo[7] should be set as + * '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the + * packet. When it is valid, @ref packinfo[7] should be set as '1' after call + * @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for + * success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port); + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum { + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + // M20150410 : Remove the comma of last member + // SIK_ALL = 0x1F, ///< all interrupt + SIK_ALL = 0x1F ///< all interrupt +} sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum { + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref + ///< SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind +#if _WIZCHIP_ > 5100 + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, + ///< Not supported in W5100 + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref + ///< sockint_kind, Not supported in W5100 +#endif +} ctlsock_type; + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum { + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to + ///< flag in @ref socket(). + SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref + ///< setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref + ///< setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive + ///< packet in TCP mode, Not supported in W5100 +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP + ///< mode, Not supported in W5100, W5200 +#endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt + ///< TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in + ///< socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, + ///< @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in + ///< other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref + ///< PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in + ///< other then TCP mode. +} sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket + * buffer information. Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. + * \n + *
@b cstype @b data type@b + * value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE + * uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
+ * @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 + * ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n + * @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind + * @ref SIK_CONNECTED, etc.
+ * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref + * sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + *
@b sotype @b data type@b + * value
@ref SO_TTL uint8_t 0 ~ 255 + *
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ + * 65535
@ref SO_KEEPALIVESEND null + * null
@ref SO_KEEPALIVEAUTO uint8_t + * 0 ~ 255
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet + * \n + */ +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref + * sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + *
@b sotype @b data type@b + * value
@ref SO_FLAG uint8_t @ref + * SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t + * 0 ~ 255
@ref SO_MSS uint16_t + * 0 ~ 65535
@ref SO_DESTIP + * uint8_t[4]
@ref SO_DESTPORT + * uint16_t
@ref SO_KEEPALIVEAUTO + * uint8_t 0 ~ 255
@ref SO_SENDBUF + * uint16_t 0 ~ 65535
@ref SO_RECVBUF + * uint16_t 0 ~ 65535
@ref SO_STATUS + * uint8_t @ref SOCK_ESTABLISHED, etc..
@ref + * SO_REMAINSIZE uint16_t 0~ 65535
+ * @ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc... + *
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode + * and after call @ref recvfrom(). \n When SO_PACKINFO value is PACK_FIRST and + * the return value of recvfrom() is zero, This means the zero byte UDP data(UDP + * Header only) received. + */ +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif // _SOCKET_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/w5500.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/w5500.h new file mode 100755 index 000000000..121baab06 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/w5500.h @@ -0,0 +1,2321 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +// + +#ifndef _W5500_H_ +#define _W5500_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" +#include + + +/// @cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5500) +/// @endcond + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ \ + (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ \ + (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1 + 4 * N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2 + 4 * N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3 + 4 * N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) \ + (ADDR + (N << 8)) //< Increase offset address + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) \ + WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR, VAL) \ + WIZCHIP_WRITE(ADDR, VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR, BUF, LEN) \ + WIZCHIP_READ_BUF(ADDR, BUF, LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR, BUF, LEN) \ + WIZCHIP_WRITE(ADDR, BUF, LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref + * Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref + * Common_register_access_function and @ref Socket_register_access_function + */ + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), + * setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), + * setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), + * getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), + * setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), + * getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() getSn_MSSR(), + * setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), + * setSn_TXBUF_SIZE() \n getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data + * communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, + * Sn_RX_RD, Sn_RX_WR : Data communication + */ + +/** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or + * write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end +//-------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP +//----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + * + * + *
7 6 5 4 32 1 0
RST ReservedWOL PB PPPoE Reserved FARPReserved
+ * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be + * still until the bit will be written to by the host. If @ref IR is not equal + * to x00 INTn PIN is asserted to low until it is x00\n\n Each bit of @ref IR + * defined as follows. + * + * + * + *
7 6 5 43 2 1 0
CONFLICTUNREACH PPPoE MP ReservedReserved Reserved Reserved
+ * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ + * corresponds to each bit of @ref IR. When a bit of @ref _IMR_ is and the + * corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref _IMR_ is an interrupt will not be issued even if the + * corresponding bit of @ref IR is \n\n Each bit of @ref _IMR_ defined as the + * following. + * + * + * + *
7 6 5 43 2 1 0
IM_IR7IM_IR6 IM_IR5 IM_IR4 ReservedReserved Reserved Reserved
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is + * asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt + * will be issued. In other words, if a bit of @ref SIMR is an interrupt will + * be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref _RTR_ configures the retransmission timeout period. The unit of + * timeout period is 100us and the default of @ref _RTR_ is x07D0. And so the + * default timeout period is 200ms(100us X 2000). During the time configured by + * @ref _RTR_, W5500 waits for the peer response to the packet that is + * transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP + * command). If the peer does not respond within the @ref _RTR_ time, W5500 + * retransmits the packet or issues timeout. + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued + * (@ref Sn_IR_TIMEOUT = '1'). + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The + * unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP + * negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is + * acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during + * PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In + * addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, + * Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +//----------------------------- W5500 Socket Registers IOMAP +//----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + * + * + *
7 6 5 4 32 1 0
MULTI/MFENBCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3]Protocol[2] Protocol[1] Protocol[0]
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + * + * + *
Protocol[3] Protocol[2]Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0MACRAW
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) \ + (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, + * CONNECT, LISTEN, SEND, and RECEIVE.\n After W5500 accepts the command, the + * @ref Sn_CR register is automatically cleared to 0x00. Even though @ref Sn_CR + * is cleared to 0x00, the command is still being processed.\n To check whether + * the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server + * mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client + * mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP + * process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) \ + (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as + * establishment, termination, receiving data, timeout).\n When an interrupt + * occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes \n In order to clear the @ref Sn_IR bit, the host should + * write the bit to \n + * + * + * + *
7 6 5 43 2 1 0
ReservedReserved Reserved SEND_OK TIMEOUTRECV DISCON CON
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) \ + (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control + *packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the + *connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received + *the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) \ + (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before + * OPEN command is ordered. + */ +#define Sn_PORT(N) \ + (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n + * when using SEND_MAC command in UDP mode or it indicates that it is acquired + * in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) \ + (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP client + * mode, it configures an IP address of TCP serverbefore CONNECT command. In TCP + * server mode, it indicates an IP address of TCP clientafter successfully + * establishing connection. In UDP mode, it configures an IP address of peer to + * be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) \ + (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP + * clientmode, it configures the listen port number of TCP serverbefore CONNECT + * command. In TCP Servermode, it indicates the port number of TCP client after + * successfully establishing connection. In UDP mode, it configures the port + * number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) \ + (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) + * of Socket n. + */ +#define Sn_MSSR(N) \ + (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) + * of Socket n. It is set before OPEN command. + */ +#define Sn_TOS(N) \ + (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of + * Socket n. It is set before OPEN command. + */ +#define Sn_TTL(N) \ + (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from + * a peer. Although Socket n RX Buffer Block size is initially configured to + * 2Kbytes, user can re-configure its size using @ref Sn_RXBUF_SIZE. The total + * sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. When exceeded, the data + * reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. + * Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to + * a peer. Although Socket n TX Buffer Block size is initially configured to + * 2Kbytes, user can be re-configure its size using @ref Sn_TXBUF_SIZE. The + * total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. When exceeded, + * the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. + * It is initialized to the configured size by @ref Sn_TXBUF_SIZE. Data bigger + * than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the + * bigger data overwrites the previous saved data not yet sent. Therefore, check + * before saving the data to the Socket n TX Buffer, and if data is equal or + * smaller than its checked size, transmit the data with SEND/SEND_MAC command + * after saving the data in Socket n TX buffer. But, if data is bigger than its + * checked size, transmit the data after dividing into the checked size and + * saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) \ + (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP. After its initialization, it is auto-increased by SEND command. SEND + * command transmits the saved data from the current @ref Sn_TX_RD to the @ref + * Sn_TX_WR in the Socket n TX Buffer. After transmitting the saved data, the + * SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. If its + * increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and + * the carry bit occurs), then the carry bit is ignored and will automatically + * update with the lower 16bits value. + */ +#define Sn_TX_RD(N) \ + (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP.\n It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX + * buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased + * value as many as transmitting data size. If the increment value exceeds the + * maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), then the + * carry bit is ignored and will automatically update with the lower 16bits + * value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) \ + (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket + * n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as + * the difference between �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket + * n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) \ + (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read + * or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased + * value as many as the reading size. If the increment value exceeds the maximum + * value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) \ + (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is + * auto-increased by the data reception. If the increased value exceeds the + * maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), then + * the carry bit is ignored and will automatically update with the lower 16bits + * value. + */ +#define Sn_RX_WR(N) \ + (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is + * occurred and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref + * Sn_IR are and the n-th bit of @ref IR is Host is interrupted by asserted INTn + * PIN to low. + */ +#define Sn_IMR(N) \ + (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) \ + (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP + * ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, and ignored in + * other modes. The time unit is 5s. KA packet is transmittable after @ref Sn_SR + * is changed to SOCK_ESTABLISHED and after the data is transmitted or received + * to/from a peer at least once. In case of '@ref Sn_KPALVTR > 0', W5500 + * automatically transmits KA packet after time-period for checking the TCP + * connection (Auto-keepalive-process). In case of '@ref Sn_KPALVTR = 0', + * Auto-keep-alive-process will not operate, and KA packet can be transmitted by + * SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) \ + (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + +//(WIZCHIP_SREG_BLOCK(N) << 3)) + +//----------------------------- W5500 Register values +//----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will + * be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been + * normally processed, the Interrupt PIN (INTn) asserts to low. When using WOL + * mode, the UDP Socket should be opened with any source port number. (Refer to + * Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes + * synchronization stream (xFFFFFFFFFFFF and 16 times Target MAC address stream + * in UDP payload. The options such like password are ignored. You can use any + * UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP + * address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this + * bit is set as When this bit is Destination Information such as IP address + * and Port number may be checked with the corresponding @ref UIPR & @ref + * UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, + * this bit is set. + */ +#define IR_MP 0x10 + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1 << 7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1 << 6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7 << 3) +#define PHYCFGR_OPMDC_PDOWN (6 << 3) +#define PHYCFGR_OPMDC_NA (5 << 3) +#define PHYCFGR_OPMDC_100FA (4 << 3) +#define PHYCFGR_OPMDC_100F (3 << 3) +#define PHYCFGR_OPMDC_100H (2 << 3) +#define PHYCFGR_OPMDC_10F (1 << 3) +#define PHYCFGR_OPMDC_10H (0 << 3) +#define PHYCFGR_DPX_FULL (1 << 2) +#define PHYCFGR_DPX_HALF (0 << 2) +#define PHYCFGR_SPD_100 (1 << 1) +#define PHYCFGR_SPD_10 (0 << 1) +#define PHYCFGR_LNK_ON (1 << 0) +#define PHYCFGR_LNK_OFF (0 << 0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively + * configured with the multicast group IP address & port number before Socket n + * is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = + * 010.\m In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data + * packet is received from a peer.\n When this bit is It sends the ACK packet + * after waiting for the timeout time configured by @ref _RTR_. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and + * MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to + * itself. When this bit is W5500 can receive all packets on Ethernet. If user + * wants to implement Hybrid TCP/IP stack, it is recommended that this bit is + * set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to + * receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive + * the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol + * selected in Sn_MR(P3:P0). The table below shows the value of @ref Sn_SR + * corresponding to @ref Sn_MR.\n + * + * + * + * + *
\b Sn_MR (P[3:0])\b Sn_SR
Sn_MR_CLOSE + * (000)
Sn_MR_TCP (001) SOCK_INIT (0x13)
Sn_MR_UDP (010) SOCK_UDP (0x22)
S0_MR_MACRAW (100) SOCK_MACRAW (0x02)
+ */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP). + * In this mode, Socket n operates as a TCP serverand waits for + * connection-request (SYN packet) from any TCP client The @ref Sn_SR changes + * the state from \ref SOCK_INIT to \ref SOCKET_LISTEN. When a TCP + * clientconnection request is successfully established, the @ref Sn_SR changes + * from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes But when a + * TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status + * of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP + * serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref + * SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n The connect-request fails in + * the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware + * address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these + * cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as + * TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON + * command processes the disconnect-process (b>Active closeor Passive + * close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the + * peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet + * is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to + * @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref + * Sn_TX_FSR), Socket n, TX Write Pointer Register(@ref Sn_TX_WR), and Socket n + * TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired + * by the automatic ARP-process(Address Resolution Protocol).\n But SEND_MAC + * transmits data without the automatic ARP-process.\n In this case, the + * destination hardware address is acquired from @ref Sn_DHAR configured by + * host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive + * packet.\n If the peer can not respond to the keep-alive packet during timeout + * time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX + * Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n For more + * details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket + * n RX Write Pointer Register (@ref Sn_RX_WR), and Socket n RX Read Pointer + * Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful + * and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed + * to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN + * command is ordered.\n After @ref SOCK_INIT, user can use LISTEN /CONNECT + * command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and + * waiting for connection-request (SYN packet) from a peer TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is + * successfully accepted.\n Otherwise it will change to @ref SOCK_CLOSED after + * TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred. + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) + * to a peer.\n It is temporarily shown when @ref Sn_SR is changed from @ref + * SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n If + * connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it + * changes to @ref SOCK_ESTABLISHED.\n Otherwise, it changes to @ref SOCK_CLOSED + * after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request + * packet (SYN packet) from a peer.\n If socket n sends the response (SYN/ACK + * packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n If + * not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') + * is occurred. + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the + * SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or when the + * CONNECT command is successful.\n During @ref SOCK_ESTABLISHED, DATA packet + * can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) + * from the connected peer.\n This is half-closing status, and data can be + * transferred.\n For full-closing, DISCON command is used. But For + * just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) + * to the disconnect-request (FIN packet) by passive-close.\n It changes to @ref + * SOCK_CLOSED when Socket n received the response successfully, or when + * timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = + * '010').\n It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref + * Sn_CR_OPEN command is ordered.\n Unlike TCP mode, data can be transfered + * without the connection-process. + */ +#define SOCK_UDP 0x22 + +#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = + * 100and is valid only in Socket 0.\n It changes to SOCK_MACRAW when + * S0_MR(P[3:0] = 100and OPEN command is ordered.\n Like UDP mode socket, MACRAW + * mode Socket 0 can transfer a MAC packet (Ethernet frame) without the + * connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt.\n In OS environment, You can replace it to critical section api + * supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt. \n In OS environment, You can replace it to critical section api + * supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ(uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) WIZCHIP_WRITE(MR, mr) + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be + * allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) WIZCHIP_WRITE_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be + * allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) WIZCHIP_READ_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should + * be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) WIZCHIP_WRITE_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should + * be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be + * allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be + * allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be + * allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be + * allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) \ + { \ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL, 1), (uint8_t)intlevel); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +// M20150401 : Type explict declaration +/* +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) +*/ +#define getINTLEVEL() \ + (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) \ + { \ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_, 1), (uint8_t)rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +// M20150401 : Type explict declaration +/* +#define getRTR() \ + ((WIZCHIP_READ(_RTR_) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) +*/ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() WIZCHIP_READ(_RCR_) + +//================================================== test done +//=========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHAR address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) \ + { \ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID, 1), (uint8_t)psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +// uint16_t getPSID(void); +// M20150401 : Type explict declaration +/* +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) +*/ +#define getPSID() \ + (((uint16_t)WIZCHIP_READ(PSID) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) \ + { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU, 1), (uint8_t)pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +// M20150401 : Type explict declaration +/* +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) +*/ +#define getPMRU() \ + (((uint16_t)WIZCHIP_READ(PMRU) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It + * should be allocated 4 bytes. + */ +// M20150401 : Size Error of UIPR (6 -> 4) +/* +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) +*/ +#define getUIPR(uipr) WIZCHIP_READ_BUF(UIPR, uipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +// M20150401 : Type explict declaration +/* +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) +*/ +#define getUPORTR() \ + (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) WIZCHIP_WRITE(Sn_MR(sn), mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) \ + { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1), (uint8_t)port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) +*/ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP + * address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP + * address. It should be allocated 4 bytes. + * @sa setSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) \ + { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t)(dport >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1), (uint8_t)dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) +*/ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) \ + { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1), (uint8_t)mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) +*/ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn), rxbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) +*/ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) \ + { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1), (uint8_t)txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) +*/ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) \ + { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1), (uint8_t)rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) +*/ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) +*/ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) \ + { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1), (uint8_t)frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +// M20150401 : Type explict declaration +/* +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) +*/ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) +*/ +#define getSn_RxMAX(sn) (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10) + +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) +*/ +#define getSn_TxMAX(sn) (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of + * len(variable) bytes to internal TX memory and updates the Tx write + * pointer register. This function is being called by send() and sendto() + * function also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) + * bytes. This function is being called by recv() also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in + * internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif // _W5500_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/wizchip_conf.h b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/wizchip_conf.h new file mode 100755 index 000000000..a58da3a19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/include/wizchip_conf.h @@ -0,0 +1,704 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP + * I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, + * network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b + * W5500 or etc. \n\n ex> #define \_WIZCHIP_ W5500 + */ + +#define W5100 5100 +#define W5100S 5100 + 5 +#define W5200 5200 +#define W5300 5300 +#define W5500 5500 + +#ifndef _WIZCHIP_ +#define _WIZCHIP_ W5500 // W5100, W5100S, W5200, W5300, W5500 +#endif + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length \ \ \ + data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 2) /**< SPI interface mode for fixed length data mode*/ +#define _WIZCHIP_IO_MODE_SPI_5500_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 3) /**< SPI interface mode for fixed length data mode*/ + +#if (_WIZCHIP_ == W5100) +#define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100/w5100.h" + +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_ID_ "W5100S\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_5500_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100S/w5100s.h" +#elif (_WIZCHIP_ == W5200) +#define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ or @ref \ _WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "W5200/w5200.h" +#elif (_WIZCHIP_ == W5500) +#define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + * + * + */ +#ifndef _WIZCHIP_IO_MODE_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "w5500.h" +#elif (_WIZCHIP_ == W5300) +#define _WIZCHIP_ID_ "W5300\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#endif + +// A20150601 : Define the unit and bus width of IO DATA. +/** + * @brief Select the data width 8 or 16 bits. + * @todo you should select the bus width. Select one of 8 or 16. + */ +#ifndef _WIZCHIP_IO_BUS_WIDTH_ +#define _WIZCHIP_IO_BUS_WIDTH_ 16 // 8 +#endif +#if _WIZCHIP_IO_BUS_WIDTH_ == 8 +typedef uint8_t iodata_t; +#elif _WIZCHIP_IO_BUS_WIDTH_ == 16 +typedef uint16_t iodata_t; +#else +#error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16." +#endif +// +#include "W5300/w5300.h" +#else +#error \ + "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ +#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref + * \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). + * \n\n ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 + */ +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +// #define _WIZCHIP_IO_BASE_ 0x60000000 +//// for 5100S IND +#define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 +#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // for 5100S SPI +#endif + +#ifndef _WIZCHIP_IO_BASE_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000 +#endif + +// M20150401 : Typing Error +//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +#ifndef _WIZCHIP_IO_BASE_ +#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." +#endif +#endif + +#if _WIZCHIP_ >= W5200 +#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else +#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + +/******************************************************** + * WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. + *********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions + * W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP { + uint16_t if_mode; ///< host interface mode + uint8_t id[8]; ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b + ///< 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS { + void (*_enter)(void); ///< crtical section enter + void (*_exit)(void); ///< critial section exit + } CRIS; + /** + * The set of @ref \_WIZCHIP_ select control callback func. + */ + struct _CS { + void (*_select)(void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + } CS; + /** + * The set of interface IO callback func. + */ + union _IF { + /** + * For BUS interface IO + */ + // M20156501 : Modify the function name for integrating with W5300 + // struct + //{ + // uint8_t (*_read_byte) (uint32_t AddrSel); + // void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + //}BUS; + struct { + iodata_t (*_read_data)(uint32_t AddrSel); + void (*_write_data)(uint32_t AddrSel, iodata_t wb); + } BUS; + + /** + * For SPI interface IO + */ + struct { + uint8_t (*_read_byte)(void); + void (*_write_byte)(uint8_t wb); + void (*_read_burst)(uint8_t *pBuf, uint16_t len); + void (*_write_burst)(uint8_t *pBuf, uint16_t len); + } SPI; + // To be added + // + } IF; +} _WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum { + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 + ///< dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500 + CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation + ///< mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only + ///< W5500 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when + ///< PHYSTATUS.OPMD == 1. Valid Only W5500 + //#endif + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only + ///< W5100, W5200 + CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200 + //#endif +} ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum { + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +} ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum { +#if _WIZCHIP_ == W5500 + IK_WOL = + (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#elif _WIZCHIP_ == W5300 + IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU) +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != W5200 + IK_DEST_UNREACH = + (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > W5100S + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > W5100S + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt +#endif +} intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO \ + 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in + * W5500, and it indicates the real PHY status configured by HW or SW in all + * WIZCHIP. \n Valid only in W5500. + */ +typedef struct wiz_PhyConf_t { + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + // uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + // uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref + // PHY_LINK_ON or PHY_DUPLEX_OFF +} wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum { + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +} dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t { + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +} wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum { +#if _WIZCHIP_ == W5500 + NM_FORCEARP = (1 << 1), ///< Force to APP send whenever udp data is sent. + ///< Valid only in W5500 +#endif + NM_WAKEONLAN = (1 << 5), ///< Wake On Lan + NM_PINGBLOCK = (1 << 4), ///< Block ping-request + NM_PPPOE = (1 << 3), ///< PPPoE mode +} netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout + * configruation. + */ +typedef struct wiz_NetTimeout_t { + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +} wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such + *as \ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref + *WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT + *marco or register your functions. + *@note If you do not describe or register, default functions(@ref + *wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)); + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or + *register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +// M20150601 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)); +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte using SPI + *@param spi_wb : callback function to write byte using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to burst read using SPI + *@param spi_wb : callback function to burst write using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor + * PHY(Link,Speed,Half/Full/Auto), controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref + * ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref + * ctlnetwork_type in WIZCHIP \n 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg); + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of + * ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size + * 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size + * 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to + * uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +// todo +#if _WIZCHIP_ > W5100 +int8_t wizphy_getphylink( + void); ///< get the link status of phy in WIZCHIP. No use in W5100 +int8_t wizphy_getphypmode( + void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 + /** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_setphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphystat(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in + * W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ +int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** + * @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout *nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout *nettime); +#ifdef __cplusplus +} +#endif + +#endif // _WIZCHIP_CONF_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/Kconfig new file mode 100644 index 000000000..73b7f7c4f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/Kconfig @@ -0,0 +1,43 @@ +if BSP_USING_SOFT_SPI + config SOFT_SPI_BUS_NAME + string "soft spi bus 1 name" + default "soft_spi1_bus1" + + config SOFT_SPI_DEVICE_NAME + string "soft spi dev 1 name" + default "soft_spi1_dev1" + + config SOFT_SPI_DRV_NAME + string "soft spi drv 1 name" + default "soft_spi1_drv1" + + config SOFT_SPI_SCK + int "soft spi sck pin" + default 26 + + config SOFT_SPI_MOSI + int "soft spi mosi pin" + default 27 + + config SOFT_SPI_MISO + int "soft spi miso pin" + default 25 + + config SOFT_SPI_CS0_PIN + int "soft spi cs pin" + default 28 + + config SOFT_SPI_DEVICE_SLAVE_ID + int "soft spi slave id" + default 0 + + config SOFT_SPI_CHIP_SELECT + int "soft spi chip selected" + default 0 + + config SOFT_SPI_CLK_DELAY + int "clk in microsecond" + default 0 + +endif + diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/Makefile new file mode 100644 index 000000000..8ccf2895c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_soft_spi.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/connect_soft_spi.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/connect_soft_spi.c new file mode 100644 index 000000000..68a01db87 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/soft_spi/connect_soft_spi.c @@ -0,0 +1,295 @@ +#include +#include +#include +#include +#include "drv_io_config.h" +#include +#include +#include +#include + +#include +#include +#include + +static x_err_t SoftSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg) +{ + NULL_PARAM_CHECK(spi_drv); + NULL_PARAM_CHECK(cfg); + + // mode CPOL = 0 CPHA = 0 + gpiohs_set_drive_mode(SOFT_SPI_CS0_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(SOFT_SPI_CS0_PIN, GPIO_PV_HIGH); // set the cs gpio high + gpiohs_set_drive_mode(SOFT_SPI_SCK, GPIO_DM_OUTPUT); + gpiohs_set_drive_mode(SOFT_SPI_MOSI, GPIO_DM_OUTPUT); + gpiohs_set_drive_mode(SOFT_SPI_MISO, GPIO_DM_INPUT); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + KPrintf("%s init done\n", SOFT_SPI_BUS_NAME); + + return EOK; +} + +static uint32 SoftSpiDrvConfigure(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: + SoftSPIinit(spi_drv, configure_info); + break; + + case OPE_CFG: + break; + default: + + break; + } + + return ret; +} + +static void SoftSpiWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data) +{ + int8_t i = 0; + uint8_t temp = 0; + for (i = 0; i < 8; i++) + { + temp = ((data & 0x80) == 0x80) ? 1 : 0; + data = data << 1; + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + usleep(SOFT_SPI_CLK_DELAY); + if (0 == temp) + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); + } + else + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH); + } + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + } + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); +} + +/* 读一个字节 */ +static uint8_t SoftSpiReadByte(struct SpiHardwareDevice *spi_dev) +{ + uint8_t i = 0; + uint8_t read_data = 0xFF; + for (i = 0; i < 8; i++) + { + read_data = read_data << 1; + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + usleep(SOFT_SPI_CLK_DELAY); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + if (1 == gpiohs_get_pin(SOFT_SPI_MISO)) + { + read_data = read_data | 0x01; + } + } + return read_data; +} + +/* 读写一个字节 */ +// this funcition is unverify until now! +static uint8_t SoftSpiReadWriteByte(struct SpiHardwareDevice *spi_dev, uint8_t data) +{ + uint8_t i = 0; + uint8_t temp = 0; + uint8_t read_data = 0xFF; + for (i = 0; i < 8; i++) + { + temp = ((data & 0x80) == 0x80) ? 1 : 0; + data = data << 1; + read_data = read_data << 1; + if (temp == 0) + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); + } + else + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH); + } + usleep(SOFT_SPI_CLK_DELAY); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + if (gpiohs_get_pin(SOFT_SPI_MISO) == 1) + { + read_data = read_data + 1; + } + } + return read_data; +} + +static uint32 SoftSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + const uint8_t *data_buff = spi_datacfg->tx_buff; + int data_length = spi_datacfg->length; + if (NONE == spi_datacfg->tx_buff) + { + data_length = 0; + } + + if (spi_datacfg->spi_chip_select) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + for (size_t i = 0; i < data_length; i++) + { + SoftSpiWriteByte(spi_dev, data_buff[i]); + } + + if (spi_datacfg->spi_cs_release) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + spi_datacfg = spi_datacfg->next; + + return EOK; +} + +static uint32 SoftSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + uint8_t *recv_buff = spi_datacfg->rx_buff; + int recv_length = spi_datacfg->length; + + if (NONE == spi_datacfg->rx_buff) + { + recv_length = 0; + } + + if (spi_datacfg->spi_chip_select) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + for (size_t i = 0; i < recv_length; i++) + { + recv_buff[i] = SoftSpiReadByte(spi_dev); + } + + if (spi_datacfg->spi_cs_release) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_datacfg = spi_datacfg->next; + + return spi_datacfg->length; +} + +const struct SpiDevDone soft_spi_dev_done = { + .dev_close = NONE, + .dev_open = NONE, + .dev_read = SoftSpiReadData, + .dev_write = SoftSpiWriteData}; + +static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver) +{ + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, SOFT_SPI_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(SOFT_SPI_DRV_NAME, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +static int BoardSoftSpiDevBend(void) +{ + x_err_t ret = EOK; + + 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 = SOFT_SPI_DEVICE_SLAVE_ID; + spi_slaveparam0.spi_cs_gpio_pin = SOFT_SPI_CS0_PIN; + spi_slaveparam0.spi_cs_select_id = SOFT_SPI_CHIP_SELECT; + + spi_device0.spi_param.spi_dma_param = NONE; + spi_device0.spi_param.spi_slave_param = &spi_slaveparam0; + + spi_device0.spi_dev_done = &(soft_spi_dev_done); + + ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), SOFT_SPI_DEVICE_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SOFT_SPI_DEVICE_NAME, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwSoftSPIInit(void) +{ + x_err_t ret = EOK; + + 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_driver.configure = &(SoftSpiDrvConfigure); + + ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver); + if (EOK != ret) + { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardSoftSpiDevBend(); + if (EOK != ret) + { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Kconfig new file mode 100644 index 000000000..9eb26b6a3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Kconfig @@ -0,0 +1,66 @@ +config BSP_USING_SPI1 +bool "Using spi1 " +default y + + +if BSP_USING_SPI1 + config SPI_BUS_NAME_1 + string "spi bus 1 name" + default "spi1" + config SPI_1_DRV_NAME + string "spi bus 1 driver name" + default "spi1_drv" + config BSP_SPI1_CLK_PIN + int "spi1 clk pin number" + default 9 + config BSP_SPI1_D0_PIN + int "spi1 d0 pin number" + default 11 + config BSP_SPI1_D1_PIN + int "spi1 d1 pin number" + default 10 + menuconfig BSP_SPI1_USING_SS0 + bool "SPI1 Enable SS0" + default y + if BSP_SPI1_USING_SS0 + config SPI_1_DEVICE_NAME_0 + string "spi bus 1 device 0 name" + default "spi1_dev0" + config BSP_SPI1_SS0_PIN + int "spi1 ss0 pin number" + default 12 + menuconfig BSP_SPI1_USING_SS1 + bool "SPI1 Enable SS1" + default n + endif + if BSP_SPI1_USING_SS1 + config SPI_1_DEVICE_NAME_1 + string "spi bus 1 device 1 name" + default "spi1_dev1" + config BSP_SPI1_SS1_PIN + int "spi1 ss1 pin number" + default 13 + endif + menuconfig BSP_SPI1_USING_SS2 + bool "SPI1 Enable SS2" + default n + if BSP_SPI1_USING_SS2 + config SPI_1_DEVICE_NAME_2 + string "spi bus 1 device 2 name" + default "spi1_dev2" + config BSP_SPI1_SS2_PIN + int "spi1 ss2 pin number" + default 26 + endif + menuconfig BSP_SPI1_USING_SS3 + bool "SPI1 Enable SS3" + default n + if BSP_SPI1_USING_SS3 + config SPI_1_DEVICE_NAME_3 + string "spi bus 1 device 3 name" + default "spi1_dev3" + config BSP_SPI1_SS3_PIN + int "spi1 ss3 pin number" + default 27 + endif +endif diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Makefile b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Makefile new file mode 100644 index 000000000..945c415a4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_spi.c hardware_spi.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/connect_spi.c new file mode 100644 index 000000000..4191b4e6b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/connect_spi.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2020 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-18 ZYH first version + */ + +/** + * @file connect_spi.c + * @brief support aiit-riscv64-board spi function and register to bus framework + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2021-04-25 + */ + +/************************************************* +File name: connect_spi.c +Description: support aiit-riscv64-board spi configure and spi bus register +function Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_spi.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. support aiit-riscv64-board spi configure, write and read +2. support aiit-riscv64-board spi bus device and driver register +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BSP_SPI1_USING_SS0 +#define SPI_DEVICE_SLAVE_ID_0 0 +#endif + +#ifdef BSP_SPI1_USING_SS1 +#define SPI_DEVICE_SLAVE_ID_1 1 +#endif + +#ifdef BSP_SPI1_USING_SS2 +#define SPI_DEVICE_SLAVE_ID_2 2 +#endif + +#ifdef BSP_SPI1_USING_SS3 +#define SPI_DEVICE_SLAVE_ID_3 3 +#endif + +static volatile spi_t *const spi_instance[4] = { + (volatile spi_t *)SPI0_BASE_ADDR, (volatile spi_t *)SPI1_BASE_ADDR, + (volatile spi_t *)SPI_SLAVE_BASE_ADDR, (volatile spi_t *)SPI3_BASE_ADDR}; + +void __spi_set_tmod(uint8_t spi_num, uint32_t tmod) { + CHECK(spi_num < SPI_DEVICE_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + uint8_t tmod_offset = 0; + switch (spi_num) { + case 0: + case 1: + case 2: + tmod_offset = 8; + break; + case 3: + default: + tmod_offset = 10; + break; + } + set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset); +} + +/*Init the spi sdk intetface */ +static uint32 SpiSdkInit(struct SpiDriver *spi_drv) { + NULL_PARAM_CHECK(spi_drv); + uint8 cs_gpio_pin, cs_select_id; + uint32 max_frequency; + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + + cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + cs_select_id = dev_param->spi_slave_param->spi_cs_select_id; + + gpiohs_set_drive_mode(cs_select_id, + GPIO_DM_OUTPUT); // Set the cs pin as output + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); // set the cs gpio high + + spi_init(dev_param->spi_dma_param->spi_master_id, + dev_param->spi_master_param->spi_work_mode & SPI_MODE_3, + dev_param->spi_master_param->spi_frame_format, + dev_param->spi_master_param->spi_data_bit_width, + dev_param->spi_master_param->spi_data_endian); + + max_frequency = + (dev_param->spi_master_param->spi_maxfrequency < SPI_MAX_CLOCK) + ? dev_param->spi_master_param->spi_maxfrequency + : SPI_MAX_CLOCK; + + uint32 real_freq = + spi_set_clk_rate(dev_param->spi_dma_param->spi_master_id, max_frequency); + + return EOK; +} + +static uint32 SpiSdkCfg(struct SpiDriver *spi_drv, + struct SpiMasterParam *spi_param) { + NULL_PARAM_CHECK(spi_drv); + NULL_PARAM_CHECK(spi_param); + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + + dev_param->spi_master_param = spi_param; + dev_param->spi_master_param->spi_work_mode = + dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK; + dev_param->spi_master_param->spi_frame_format = SPI_FF_STANDARD; + + return EOK; +} + +/*Configure the spi device param, make sure struct + * (configure_info->private_data) = (SpiMasterParam)*/ +static uint32 SpiDrvConfigure(void *drv, + struct BusConfigureInfo *configure_info) { + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct SpiDriver *spi_drv = (struct SpiDriver *)drv; + struct SpiMasterParam *spi_param; + + switch (configure_info->configure_cmd) { + case OPE_INT: + ret = SpiSdkInit(spi_drv); + break; + case OPE_CFG: + spi_param = (struct SpiMasterParam *)configure_info->private_data; + ret = SpiSdkCfg(spi_drv, spi_param); + break; + default: + break; + } + + return ret; +} + +static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, + struct SpiDataStandard *spi_datacfg) { + DEBUG_PRINT + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 device_id = dev_param->spi_slave_param->spi_slave_id; + uint8 device_master_id = dev_param->spi_dma_param->spi_master_id; + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + + while (NONE != spi_datacfg) { + uint32_t *tx_buff = NONE; + int i; + x_ubase dummy = 0xFFFFFFFFU; + + __spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV); + + if (spi_datacfg->spi_chip_select) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + if (spi_datacfg->length) { + DEBUG_PRINT + spi_instance[device_master_id]->dmacr = 0x3; + spi_instance[device_master_id]->ssienr = 0x01; + + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, + SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2); + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, + SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id * 2); + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, + (void *)(&spi_instance[device_master_id]->dr[0]), + &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, + spi_datacfg->length); + + if (!spi_datacfg->tx_buff) { + dmac_set_single_mode( + dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, + (void *)(&spi_instance[device_master_id]->dr[0]), + DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, + DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } else { + tx_buff = x_malloc(spi_datacfg->length * 4); + if (!tx_buff) { + goto transfer_done; + } + for (i = 0; i < spi_datacfg->length; i++) { + tx_buff[i] = ((uint8_t *)spi_datacfg->tx_buff)[i]; + } + dmac_set_single_mode( + dev_param->spi_dma_param->spi_dmac_txchannel, tx_buff, + (void *)(&spi_instance[device_master_id]->dr[0]), + DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, + DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } + + spi_instance[device_master_id]->ser = + 1U << dev_param->spi_slave_param->spi_cs_select_id; + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel); + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel); + spi_instance[device_master_id]->ser = 0x00; + spi_instance[device_master_id]->ssienr = 0x00; + + transfer_done: + if (tx_buff) { + x_free(tx_buff); + } + } + + if (spi_datacfg->spi_cs_release) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_datacfg = spi_datacfg->next; + } + + DEBUG_PRINT + return EOK; +} + +static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, + struct SpiDataStandard *spi_datacfg) { + DEBUG_PRINT + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint32 spi_read_length = 0; + ; + uint8 device_id = dev_param->spi_slave_param->spi_slave_id; + uint8 device_master_id = dev_param->spi_dma_param->spi_master_id; + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + + DEBUG_PRINT + while (NONE != spi_datacfg) { + uint32_t *rx_buff = NONE; + int i; + x_ubase dummy = 0xFFFFFFFFU; + + __spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV); + + if (spi_datacfg->spi_chip_select) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + if (spi_datacfg->length) { + spi_instance[device_master_id]->dmacr = 0x3; + spi_instance[device_master_id]->ssienr = 0x01; + + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, + SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2); + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, + SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id * 2); + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, + (void *)(&spi_instance[device_master_id]->dr[0]), + DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, DMAC_MSIZE_4, + DMAC_TRANS_WIDTH_32, spi_datacfg->length); + + if (!spi_datacfg->rx_buff) { + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, + (void *)(&spi_instance[device_master_id]->dr[0]), + &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, + spi_datacfg->length); + } else { + rx_buff = x_calloc(spi_datacfg->length * 4, 1); + if (!rx_buff) { + goto transfer_done; + } + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, + (void *)(&spi_instance[device_master_id]->dr[0]), + rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, + spi_datacfg->length); + } + + spi_instance[device_master_id]->ser = + 1U << dev_param->spi_slave_param->spi_cs_select_id; + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel); + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel); + spi_instance[device_master_id]->ser = 0x00; + spi_instance[device_master_id]->ssienr = 0x00; + + DEBUG_PRINT + if (spi_datacfg->rx_buff) { + for (i = 0; i < spi_datacfg->length; i++) { + ((uint8_t *)spi_datacfg->rx_buff)[i] = (uint8_t)rx_buff[i]; + } + } + + transfer_done: + if (rx_buff) { + x_free(rx_buff); + } + } + + if (spi_datacfg->spi_cs_release) { + DEBUG_PRINT + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_read_length += spi_datacfg->length; + spi_datacfg = spi_datacfg->next; + } + + DEBUG_PRINT + return spi_read_length; +} + +/*manage the spi device operations*/ +static const struct SpiDevDone spi_dev_done = { + .dev_open = NONE, + .dev_close = NONE, + .dev_write = SpiWriteData, + .dev_read = SpiReadData, +}; + +static int BoardSpiBusInit(struct SpiBus *spi_bus, + struct SpiDriver *spi_driver) { + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, SPI_1_DRV_NAME); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the spi driver to the spi bus*/ + ret = SpiDriverAttachToBus(SPI_1_DRV_NAME, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the spi device to the spi bus*/ +static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) { + x_err_t ret = EOK; + +#ifdef BSP_SPI1_USING_SS0 + static struct SpiHardwareDevice spi_device0; + memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam0; + memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam0.spi_slave_id = SPI_DEVICE_SLAVE_ID_0; + spi_slaveparam0.spi_cs_gpio_pin = SPI1_CS0_PIN; + spi_slaveparam0.spi_cs_select_id = SPI_CHIP_SELECT_0; + + spi_device0.spi_param.spi_dma_param = spi_initparam; + spi_device0.spi_param.spi_slave_param = &spi_slaveparam0; + + spi_device0.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), + SPI_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_0, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS1 + static struct SpiHardwareDevice spi_device1; + memset(&spi_device1, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam1; + memset(&spi_slaveparam1, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam1.spi_slave_id = SPI_DEVICE_SLAVE_ID_1; + spi_slaveparam1.spi_cs_gpio_pin = SPI1_CS1_PIN; + spi_slaveparam1.spi_cs_select_id = SPI_CHIP_SELECT_1; + + spi_device1.spi_param.spi_dma_param = spi_initparam; + spi_device1.spi_param.spi_slave_param = &spi_slaveparam1; + + spi_device1.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device1, (void *)(&spi_device1.spi_param), + SPI_1_DEVICE_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_1, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_1, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_1, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS2 + static struct SpiHardwareDevice spi_device2; + memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice)); + + spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2; + spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN; + spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2; + + spi_device2.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device2, (void *)(&spi_device2.spi_param), + SPI_1_DEVICE_NAME_2); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_2, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_2, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_2, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS3 + static struct SpiHardwareDevice spi_device3; + memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice)); + + spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3; + spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN; + spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3; + + spi_device3.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device3, (void *)(&spi_device3.spi_param), + SPI_1_DEVICE_NAME_3); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", + SPI_1_DEVICE_NAME_3, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_3, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", + SPI_1_DEVICE_NAME_3, ret); + return ERROR; + } +#endif + return ret; +} + +/*RISC-V 64 BOARD SPI INIT*/ +int HwSpiInit(void) { + x_err_t ret = EOK; + static struct SpiDmaParam spi_initparam; + memset(&spi_initparam, 0, sizeof(struct SpiDmaParam)); + +#ifdef BSP_USING_SPI1 + + static struct SpiBus spi_bus; + memset(&spi_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver spi_driver; + memset(&spi_driver, 0, sizeof(struct SpiDriver)); + + spi_initparam.spi_master_id = SPI_DEVICE_1; + spi_initparam.spi_dmac_txchannel = DMAC_CHANNEL1; + spi_initparam.spi_dmac_rxchannel = DMAC_CHANNEL2; + + spi_driver.configure = &(SpiDrvConfigure); + + ret = BoardSpiBusInit(&spi_bus, &spi_driver); + if (EOK != ret) { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardSpiDevBend(&spi_initparam); + if (EOK != ret) { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/hardware_spi.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/hardware_spi.c new file mode 100644 index 000000000..2947682d3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/spi/hardware_spi.c @@ -0,0 +1,1523 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_spi.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +volatile spi_t *const spi[4] = +{ + (volatile spi_t *)SPI0_BASE_ADDR, + (volatile spi_t *)SPI1_BASE_ADDR, + (volatile spi_t *)SPI_SLAVE_BASE_ADDR, + (volatile spi_t *)SPI3_BASE_ADDR +}; + +typedef struct _spi_dma_context +{ + uint8_t *buffer; + size_t BufLen; + uint32_t *MallocBuffer; + spi_transfer_mode_t IntMode; + dmac_channel_number_t dmac_channel; + spi_device_num_t spi_num; + plic_instance_t spi_int_instance; +} spi_dma_context_t; + +spi_dma_context_t spi_dma_context[4]; + +typedef struct _spi_instance_t +{ + spi_device_num_t spi_num; + spi_transfer_mode_t TransferMode; + dmac_channel_number_t dmac_channel; + plic_instance_t spi_int_instance; + spinlock_t lock; +} spi_instance_t; + +static spi_instance_t g_spi_instance[4]; + +static spi_slave_instance_t g_instance; + +static spi_frame_format_t spi_get_frame_format(spi_device_num_t spi_num) +{ + uint8_t frf_offset; + switch(spi_num) + { + case 0: + case 1: + frf_offset = 21; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + frf_offset = 22; + break; + } + volatile spi_t *spi_adapter = spi[spi_num]; + return ((spi_adapter->ctrlr0 >> frf_offset) & 0x3); +} + +static spi_transfer_width_t spi_get_frame_size(size_t data_bit_length) +{ + if (data_bit_length < 8) + return SPI_TRANS_CHAR; + else if (data_bit_length < 16) + return SPI_TRANS_SHORT; + return SPI_TRANS_INT; +} + +static int spi_dma_irq(void *ctx) +{ + spi_instance_t *v_instance = (spi_instance_t *)ctx; + volatile spi_t *spi_handle = spi[v_instance->spi_num]; + dmac_irq_unregister(v_instance->dmac_channel); + while ((spi_handle->sr & 0x05) != 0x04); + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + spinlock_unlock(&v_instance->lock); + if(v_instance->spi_int_instance.callback) + { + v_instance->spi_int_instance.callback(v_instance->spi_int_instance.ctx); + } + return 0; +} + +static int spi_clk_init(uint8_t spi_num) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + if(spi_num == 3) + sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_SPI3, 1); + sysctl_clock_enable(SYSCTL_CLOCK_SPI0 + spi_num); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI0 + spi_num, 0); + return 0; +} + +static void spi_set_tmod(uint8_t spi_num, uint32_t tmod) +{ + configASSERT(spi_num < SPI_DEVICE_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + uint8_t tmod_offset = 0; + switch(spi_num) + { + case 0: + case 1: + case 2: + tmod_offset = 8; + break; + case 3: + default: + tmod_offset = 10; + break; + } + set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset); +} + +void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format, + size_t data_bit_length, uint32_t endian) +{ + configASSERT(data_bit_length >= 4 && data_bit_length <= 32); + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + spi_clk_init(spi_num); + + uint8_t dfs_offset, frf_offset, work_mode_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + frf_offset = 21; + work_mode_offset = 6; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + frf_offset = 22; + work_mode_offset = 8; + break; + } + + switch (frame_format) + { + case SPI_FF_DUAL: + configASSERT(data_bit_length % 2 == 0); + break; + case SPI_FF_QUAD: + configASSERT(data_bit_length % 4 == 0); + break; + case SPI_FF_OCTAL: + configASSERT(data_bit_length % 8 == 0); + break; + default: + break; + } + volatile spi_t *spi_adapter = spi[spi_num]; + if(spi_adapter->baudr == 0) + spi_adapter->baudr = 0x14; + spi_adapter->imr = 0x00; + spi_adapter->dmacr = 0x00; + spi_adapter->dmatdlr = 0x10; + spi_adapter->dmardlr = 0x00; + spi_adapter->ser = 0x00; + spi_adapter->ssienr = 0x00; + spi_adapter->ctrlr0 = (work_mode << work_mode_offset) | (frame_format << frf_offset) | ((data_bit_length - 1) << dfs_offset); + spi_adapter->spi_ctrlr0 = 0; + spi_adapter->endian = endian; +} + +void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length, + uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode) +{ + configASSERT(wait_cycles < (1 << 5)); + configASSERT(instruction_address_trans_mode < 3); + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + uint32_t inst_l = 0; + switch (instruction_length) + { + case 0: + inst_l = 0; + break; + case 4: + inst_l = 1; + break; + case 8: + inst_l = 2; + break; + case 16: + inst_l = 3; + break; + default: + configASSERT(!"Invalid instruction length"); + break; + } + + configASSERT(address_length % 4 == 0 && address_length <= 60); + uint32_t addr_l = address_length / 4; + + spi_handle->spi_ctrlr0 = (wait_cycles << 11) | (inst_l << 8) | (addr_l << 2) | instruction_address_trans_mode; +} + +uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk) +{ + uint32_t spi_baudr = SysctlClockGetFreq(SYSCTL_CLOCK_SPI0 + spi_num) / spi_clk; + if(spi_baudr < 2 ) + { + spi_baudr = 2; + } + else if(spi_baudr > 65534) + { + spi_baudr = 65534; + } + volatile spi_t *spi_adapter = spi[spi_num]; + spi_adapter->baudr = spi_baudr; + return SysctlClockGetFreq(SYSCTL_CLOCK_SPI0 + spi_num) / spi_baudr; +} + +void spi_send_data_normal(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint8_t v_misalign_flag = 0; + uint32_t v_send_data; + if((uintptr_t)tx_buff % frame_width) + v_misalign_flag = 1; + + spi_handle->ssienr = 0x01; + spi_handle->ser = 1U << chip_select; + uint32_t i = 0; + while (tx_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < tx_len ? fifo_len : tx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + fifo_len = fifo_len / 4 * 4; + if(v_misalign_flag) + { + for(index = 0; index < fifo_len; index +=4) + { + memcpy(&v_send_data, tx_buff + i , 4); + spi_handle->dr[0] = v_send_data; + i += 4; + } + } + else + { + for (index = 0; index < fifo_len / 4; index++) + spi_handle->dr[0] = ((uint32_t *)tx_buff)[i++]; + } + break; + case SPI_TRANS_SHORT: + fifo_len = fifo_len / 2 * 2; + if(v_misalign_flag) + { + for(index = 0; index < fifo_len; index +=2) + { + memcpy(&v_send_data, tx_buff + i, 2); + spi_handle->dr[0] = v_send_data; + i += 2; + } + } + else + { + for (index = 0; index < fifo_len / 2; index++) + spi_handle->dr[0] = ((uint16_t *)tx_buff)[i++]; + } + break; + default: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = tx_buff[i++]; + break; + } + tx_len -= fifo_len; + } + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + +} + +void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + uint8_t *v_buf = malloc(CmdLen + tx_len); + size_t i; + for(i = 0; i < CmdLen; i++) + v_buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + v_buf[CmdLen + i] = tx_buff[i]; + + spi_send_data_normal(spi_num, chip_select, v_buf, CmdLen + tx_len); + free((void *)v_buf); +} + +void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint8_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t *buf; + size_t v_send_len; + int i; + switch(frame_width) + { + case SPI_TRANS_INT: + buf = malloc(CmdLen + tx_len); + for(i = 0; i < CmdLen / 4; i++) + buf[i] = ((uint32_t *)CmdBuff)[i]; + for(i = 0; i < tx_len / 4; i++) + buf[CmdLen / 4 + i] = ((uint32_t *)tx_buff)[i]; + v_send_len = (CmdLen + tx_len) / 4; + break; + case SPI_TRANS_SHORT: + buf = malloc((CmdLen + tx_len) / 2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen / 2; i++) + buf[i] = ((uint16_t *)CmdBuff)[i]; + for(i = 0; i < tx_len / 2; i++) + buf[CmdLen / 2 + i] = ((uint16_t *)tx_buff)[i]; + v_send_len = (CmdLen + tx_len) / 2; + break; + default: + buf = malloc((CmdLen + tx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + buf[CmdLen + i] = tx_buff[i]; + v_send_len = CmdLen + tx_len; + break; + } + + spi_send_data_normal_dma(channel_num, spi_num, chip_select, buf, v_send_len, SPI_TRANS_INT); + + free((void *)buf); +} + +void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + uint32_t *buf; + int i; + switch(spi_transfer_width) + { + case SPI_TRANS_SHORT: + buf = malloc((tx_len) * sizeof(uint32_t)); + for(i = 0; i < tx_len; i++) + buf[i] = ((uint16_t *)tx_buff)[i]; + break; + case SPI_TRANS_INT: + buf = (uint32_t *)tx_buff; + break; + case SPI_TRANS_CHAR: + default: + buf = malloc((tx_len) * sizeof(uint32_t)); + for(i = 0; i < tx_len; i++) + buf[i] = ((uint8_t *)tx_buff)[i]; + break; + } + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t) channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(channel_num, buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, tx_len); + spi_handle->ser = 1U << chip_select; + dmac_wait_done(channel_num); + if(spi_transfer_width != SPI_TRANS_INT) + free((void *)buf); + + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) +{ + spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + size_t v_tx_len = tx_len / frame_width; + size_t v_rx_len = rx_len / frame_width; + + size_t v_max_len = v_tx_len > v_rx_len ? v_tx_len : v_rx_len; + + uint32_t *v_tx_buf = malloc(v_max_len * 4); + uint32_t *v_rx_buf = malloc(v_max_len * 4); + uint32_t i = 0; + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = ((uint32_t *)tx_buf)[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = ((uint16_t *)tx_buf)[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + default: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = tx_buf[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + } + + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(dma_receive_channel_num, (void *)(&spi_handle->dr[0]), v_rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, v_max_len); + + dmac_set_single_mode(dma_send_channel_num, v_tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, v_max_len); + + spi_handle->ser = 1U << chip_select; + dmac_wait_done(dma_send_channel_num); + dmac_wait_done(dma_receive_channel_num); + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_rx_len; i++) + ((uint32_t *)rx_buf)[i] = v_rx_buf[i]; + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_rx_len; i++) + ((uint16_t *)rx_buf)[i] = v_rx_buf[i]; + break; + default: + for(i = 0; i < v_rx_len; i++) + rx_buf[i] = v_rx_buf[i]; + break; + } + free(v_tx_buf); + free(v_rx_buf); +} + +void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + size_t index, fifo_len; + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t i = 0; + size_t v_cmd_len = CmdLen / frame_width; + uint32_t v_rx_len = rx_len / frame_width; + + spi_handle->ctrlr1 = (uint32_t)(v_rx_len - 1); + spi_handle->ssienr = 0x01; + + while (v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = ((uint32_t *)CmdBuff)[i++]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = ((uint16_t *)CmdBuff)[i++]; + break; + default: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = CmdBuff[i++]; + break; + } + spi_handle->ser = 1U << chip_select; + v_cmd_len -= fifo_len; + } + + if(CmdLen == 0) + { + spi_handle->dr[0] = 0xffffffff; + spi_handle->ser = 1U << chip_select; + } + + i = 0; + while (v_rx_len) + { + fifo_len = spi_handle->rxflr; + fifo_len = fifo_len < v_rx_len ? fifo_len : v_rx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; + break; + default: + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + break; + } + + v_rx_len -= fifo_len; + } + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +void spi_receive_data_normal_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const void *CmdBuff, + size_t CmdLen, void *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + + volatile spi_t *spi_handle = spi[spi_num]; + + spi_handle->ctrlr1 = (uint32_t)(rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + if(CmdLen) + sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(dma_receive_channel_num, (void *)(&spi_handle->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, rx_len); + if(CmdLen) + dmac_set_single_mode(dma_send_channel_num, CmdBuff, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, CmdLen); + if(CmdLen == 0 && spi_get_frame_format(spi_num) == SPI_FF_STANDARD) + spi[spi_num]->dr[0] = 0xffffffff; + spi_handle->ser = 1U << chip_select; + if(CmdLen) + dmac_wait_done(dma_send_channel_num); + dmac_wait_done(dma_receive_channel_num); + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + + +void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + size_t i; + + uint32_t *write_cmd; + uint32_t *ReadBuf; + size_t v_recv_len; + size_t v_cmd_len; + switch(frame_width) + { + case SPI_TRANS_INT: + write_cmd = malloc(CmdLen + rx_len); + for(i = 0; i < CmdLen / 4; i++) + write_cmd[i] = ((uint32_t *)CmdBuff)[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 4; + v_cmd_len = CmdLen / 4; + break; + case SPI_TRANS_SHORT: + write_cmd = malloc((CmdLen + rx_len) /2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen / 2; i++) + write_cmd[i] = ((uint16_t *)CmdBuff)[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 2; + v_cmd_len = CmdLen / 2; + break; + default: + write_cmd = malloc((CmdLen + rx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len; + v_cmd_len = CmdLen; + break; + } + + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, v_cmd_len, ReadBuf, v_recv_len); + + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_recv_len; i++) + ((uint32_t *)rx_buff)[i] = ReadBuf[i]; + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_recv_len; i++) + ((uint16_t *)rx_buff)[i] = ReadBuf[i]; + break; + default: + for(i = 0; i < v_recv_len; i++) + rx_buff[i] = ReadBuf[i]; + break; + } + + free(write_cmd); +} + +void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t v_cmd_len = CmdLen; + uint32_t i = 0; + + uint32_t v_rx_len = rx_len / frame_width; + + spi_handle->ctrlr1 = (uint32_t)(v_rx_len - 1); + spi_handle->ssienr = 0x01; + + while (v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = *CmdBuff++; + + spi_handle->ser = 1U << chip_select; + v_cmd_len -= fifo_len; + } + + if(CmdLen == 0) + { + spi_handle->ser = 1U << chip_select; + } + + while (v_rx_len) + { + fifo_len = spi_handle->rxflr; + fifo_len = fifo_len < v_rx_len ? fifo_len : v_rx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; + break; + default: + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + break; + } + + v_rx_len -= fifo_len; + } + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + +} + +void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + size_t i; + + uint32_t *write_cmd = NULL; + uint32_t *ReadBuf; + size_t v_recv_len; + switch(frame_width) + { + case SPI_TRANS_INT: + v_recv_len = rx_len / 4; + break; + case SPI_TRANS_SHORT: + write_cmd = malloc(CmdLen + rx_len /2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 2; + break; + default: + write_cmd = malloc(CmdLen + rx_len * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len; + break; + } + if(frame_width == SPI_TRANS_INT) + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, CmdBuff, CmdLen, rx_buff, v_recv_len); + else + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, CmdLen, ReadBuf, v_recv_len); + + switch(frame_width) + { + case SPI_TRANS_INT: + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_recv_len; i++) + ((uint16_t *)rx_buff)[i] = ReadBuf[i]; + break; + default: + for(i = 0; i < v_recv_len; i++) + rx_buff[i] = ReadBuf[i]; + break; + } + + if(frame_width != SPI_TRANS_INT) + free(write_cmd); +} + +void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + spi_handle->ssienr = 0x01; + spi_handle->ser = 1U << chip_select; + + size_t v_cmd_len = CmdLen * 4; + while(v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + fifo_len = fifo_len / 4 * 4; + for (index = 0; index < fifo_len / 4; index++) + spi_handle->dr[0] = *CmdBuff++; + v_cmd_len -= fifo_len; + } + spi_send_data_normal(spi_num, chip_select, tx_buff, tx_len); +} + +void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint32_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t *buf; + size_t v_send_len; + int i; + switch(frame_width) + { + case SPI_TRANS_INT: + buf = malloc(CmdLen * sizeof(uint32_t) + tx_len); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len / 4; i++) + buf[CmdLen + i] = ((uint32_t *)tx_buff)[i]; + v_send_len = CmdLen + tx_len / 4; + break; + case SPI_TRANS_SHORT: + buf = malloc(CmdLen * sizeof(uint32_t) + tx_len / 2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len / 2; i++) + buf[CmdLen + i] = ((uint16_t *)tx_buff)[i]; + v_send_len = CmdLen + tx_len / 2; + break; + default: + buf = malloc((CmdLen + tx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + buf[CmdLen + i] = tx_buff[i]; + v_send_len = CmdLen + tx_len; + break; + } + + spi_send_data_normal_dma(channel_num, spi_num, chip_select, buf, v_send_len, SPI_TRANS_INT); + + free((void *)buf); +} + +void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint32_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t)channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(channel_num, tx_buff, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, tx_len); + spi_handle->ser = 1U << chip_select; + dmac_wait_done(channel_num); + + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +static int spi_slave_irq(void *ctx) +{ + volatile spi_t *spi_handle = spi[2]; + + spi_handle->imr = 0x00; + *(volatile uint32_t *)((uintptr_t)spi_handle->icr); + if (g_instance.status == IDLE) + g_instance.status = COMMAND; + return 0; +} + +static void spi_slave_idle_mode(void) +{ + volatile spi_t *spi_handle = spi[2]; + uint32_t DataWidth = g_instance.data_bit_length / 8; + g_instance.status = IDLE; + spi_handle->ssienr = 0x00; + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_handle->rxftlr = 0x08 / DataWidth - 1; + + spi_handle->dmacr = 0x00; + spi_handle->imr = 0x10; + spi_handle->ssienr = 0x01; + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH); +} + +static void spi_slave_command_mode(void) +{ + volatile spi_t *spi_handle = spi[2]; + uint8_t CmdData[8], sum = 0; + + spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1); + uint32_t DataWidth = g_instance.data_bit_length / 8; + spi_device_num_t spi_num = SPI_DEVICE_2; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < 8 / 4; i++) + ((uint32_t *)CmdData)[i] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < 8 / 2; i++) + ((uint16_t *)CmdData)[i] = spi_handle->dr[0]; + break; + default: + for (uint32_t i = 0; i < 8; i++) + CmdData[i] = spi_handle->dr[0]; + break; + } + + for (uint32_t i = 0; i < 7; i++) + { + sum += CmdData[i]; + } + if (CmdData[7] != sum) + { + spi_slave_idle_mode(); + return; + } + g_instance.command.cmd = CmdData[0]; + g_instance.command.addr = CmdData[1] | (CmdData[2] << 8) | (CmdData[3] << 16) | (CmdData[4] << 24); + g_instance.command.len = CmdData[5] | (CmdData[6] << 8); + if (g_instance.command.len == 0) + g_instance.command.len = 65536; + if ((g_instance.command.cmd < WRITE_DATA_BLOCK) && (g_instance.command.len > 8)) + { + spi_slave_idle_mode(); + return; + } + g_instance.status = TRANSFER; + spi_handle->ssienr = 0x00; + if (g_instance.command.cmd == WRITE_CONFIG) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi[2]->rxftlr = g_instance.command.len / DataWidth - 1; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + } + else if (g_instance.command.cmd == READ_CONFIG) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->txftlr = 0x00; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < g_instance.command.len / 4; i++) + { + spi_handle->dr[0] = ((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < g_instance.command.len / 2; i++) + { + spi_handle->dr[0] = ((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + default: + for (uint32_t i = 0; i < g_instance.command.len; i++) + { + spi_handle->dr[0] = ((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BYTE) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi[2]->rxftlr = g_instance.command.len / DataWidth - 1; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + } + else if (g_instance.command.cmd == READ_DATA_BYTE) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->txftlr = 0x00; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < g_instance.command.len / 4; i++) + { + spi_handle->dr[0] = ((uint32_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < g_instance.command.len / 2; i++) + { + spi_handle->dr[0] = ((uint16_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + default: + for (uint32_t i = 0; i < g_instance.command.len; i++) + { + spi_handle->dr[0] = ((uint8_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BLOCK) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs); + + spi_handle->dmacr = 0x01; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + + sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(g_instance.dmac_channel, (void *)(&spi_handle->dr[0]), (void *)((uintptr_t)g_instance.command.addr & 0xFFFFFFF0), DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4); + } + else if (g_instance.command.cmd == READ_DATA_BLOCK) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->dmacr = 0x02; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + + sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(g_instance.dmac_channel, (void *)((uintptr_t)g_instance.command.addr & 0xFFFFFFF0), (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4); + } + else + { + spi_slave_idle_mode(); + return; + } + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_LOW); +} + +static void spi_slave_transfer_mode(void) +{ + spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1); + uint32_t command_len = 0; + + switch(frame_width) + { + case SPI_TRANS_INT: + command_len = g_instance.command.len / 4; + break; + case SPI_TRANS_SHORT: + command_len = g_instance.command.len / 2; + break; + default: + command_len = g_instance.command.len; + break; + } + volatile spi_t *spi_handle = spi[2]; + g_instance.command.err = 0; + if (g_instance.command.cmd == WRITE_CONFIG || g_instance.command.cmd == WRITE_DATA_BYTE) + { + if (spi_handle->rxflr < command_len - 1) + g_instance.command.err = 1; + } + else if (g_instance.command.cmd == READ_CONFIG || g_instance.command.cmd == READ_DATA_BYTE) + { + if (spi_handle->txflr != 0) + g_instance.command.err = 2; + } else if (g_instance.command.cmd == WRITE_DATA_BLOCK || g_instance.command.cmd == READ_DATA_BLOCK) + { + if (dmac->channel[g_instance.dmac_channel].intstatus != 0x02) + g_instance.command.err = 3; + } + else + { + spi_slave_idle_mode(); + return; + } + + if (g_instance.command.err == 0) + { + if (g_instance.command.cmd == WRITE_CONFIG) + { + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + default: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BYTE) + { + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint32_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint16_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + default: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint8_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + } + } + } + if(g_instance.callback != NULL) + { + g_instance.callback((void *)&g_instance.command); + } + spi_slave_idle_mode(); +} + +static void spi_slave_cs_irq(void) +{ + if (g_instance.status == IDLE) + spi_slave_idle_mode(); + else if (g_instance.status == COMMAND) + spi_slave_command_mode(); + else if (g_instance.status == TRANSFER) + spi_slave_transfer_mode(); +} + +void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback) +{ + g_instance.status = IDLE; + g_instance.config_ptr = data; + g_instance.config_len = len; + g_instance.work_mode = 6; + g_instance.slv_oe = 10; + g_instance.dfs = 16; + g_instance.data_bit_length = data_bit_length; + g_instance.ready_pin = ready_pin; + g_instance.int_pin = int_pin; + g_instance.callback = callback; + g_instance.dmac_channel = dmac_channel; + sysctl_reset(SYSCTL_RESET_SPI2); + sysctl_clock_enable(SYSCTL_CLOCK_SPI2); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI2, 9); + + uint32_t DataWidth = data_bit_length / 8; + volatile spi_t *spi_handle = spi[2]; + spi_handle->ssienr = 0x00; + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((data_bit_length - 1) << g_instance.dfs); + spi_handle->dmatdlr = 0x04; + spi_handle->dmardlr = 0x03; + spi_handle->dmacr = 0x00; + spi_handle->txftlr = 0x00; + spi_handle->rxftlr = 0x08 / DataWidth - 1; + spi_handle->imr = 0x10; + spi_handle->ssienr = 0x01; + + gpiohs_set_drive_mode(g_instance.ready_pin, GPIO_DM_OUTPUT); + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH); + + gpiohs_set_drive_mode(g_instance.int_pin, GPIO_DM_INPUT_PULL_UP); + gpiohs_set_pin_edge(g_instance.int_pin, GPIO_PE_RISING); + gpiohs_set_irq(g_instance.int_pin, 3, spi_slave_cs_irq); + + plic_set_priority(IRQN_SPI_SLAVE_INTERRUPT, 4); + plic_irq_enable(IRQN_SPI_SLAVE_INTERRUPT); + plic_irq_register(IRQN_SPI_SLAVE_INTERRUPT, spi_slave_irq, NULL); +} + +void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + configASSERT(chip_select < SPI_CHIP_SELECT_MAX); + switch(data.TransferMode) + { + case SPI_TMOD_TRANS_RECV: + case SPI_TMOD_EEROM: + configASSERT(data.tx_buf && data.tx_len && data.rx_buf && data.rx_len); + break; + case SPI_TMOD_TRANS: + configASSERT(data.tx_buf && data.tx_len); + break; + case SPI_TMOD_RECV: + configASSERT(data.rx_buf && data.rx_len); + break; + default: + configASSERT(!"Transfer Mode ERR"); + break; + } + configASSERT(data.tx_channel < DMAC_CHANNEL_MAX && data.rx_channel < DMAC_CHANNEL_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + + spinlock_lock(&g_spi_instance[spi_num].lock); + if(cb) + { + g_spi_instance[spi_num].spi_int_instance.callback = cb->callback; + g_spi_instance[spi_num].spi_int_instance.ctx = cb->ctx; + } + switch(data.TransferMode) + { + case SPI_TMOD_RECV: + spi_set_tmod(spi_num, SPI_TMOD_RECV); + if(data.rx_len > 65536) + data.rx_len = 65536; + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x03; + spi_handle->ssienr = 0x01; + if(spi_get_frame_format(spi_num) == SPI_FF_STANDARD) + spi_handle->dr[0] = 0xffffffff; + if(cb) + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + sysctl_dma_select((sysctl_dma_channel_t)data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + dmac_wait_idle(data.rx_channel); + break; + case SPI_TMOD_TRANS: + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + if(cb) + { + dmac_irq_register(data.tx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.tx_channel; + } + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + { + dmac_wait_idle(data.tx_channel); + while ((spi_handle->sr & 0x05) != 0x04) + ; + } + break; + case SPI_TMOD_EEROM: + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + if(data.rx_len > 65536) + data.rx_len = 65536; + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + if(cb) + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + sysctl_dma_select(data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + dmac_wait_idle(data.rx_channel); + break; + case SPI_TMOD_TRANS_RECV: + spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV); + if(data.rx_len > 65536) + data.rx_len = 65536; + + if(cb) + { + if(data.tx_len > data.rx_len) + { + dmac_irq_register(data.tx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.tx_channel; + } + else + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + } + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + sysctl_dma_select(data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + { + dmac_wait_idle(data.tx_channel); + dmac_wait_idle(data.rx_channel); + } + break; + } + if(!cb) + { + spinlock_unlock(&g_spi_instance[spi_num].lock); + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + } +} + diff --git a/Ubiquitous/XiZi_IIoT/path_kernel.mk b/Ubiquitous/XiZi_IIoT/path_kernel.mk index 3bdb39df7..ea096bda6 100755 --- a/Ubiquitous/XiZi_IIoT/path_kernel.mk +++ b/Ubiquitous/XiZi_IIoT/path_kernel.mk @@ -446,6 +446,7 @@ endif endif +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Applications/general_functions/circular_area # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Applications/general_functions/list # ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK), y) @@ -478,9 +479,11 @@ ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK), y) KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/shared # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol # +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/include # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/modbus_tcp # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/modbus_uart # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol # +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/include # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/fins # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/melsec # KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/opcua # diff --git a/Ubiquitous/XiZi_IIoT/resources/Kconfig b/Ubiquitous/XiZi_IIoT/resources/Kconfig index e41b96df9..c8119869a 100644 --- a/Ubiquitous/XiZi_IIoT/resources/Kconfig +++ b/Ubiquitous/XiZi_IIoT/resources/Kconfig @@ -163,3 +163,9 @@ if BSP_USING_DAC bool "Using DAC bus drivers" default n endif + +if BSP_USING_CAMERA + config RESOURCES_CAMERA + bool "Using Camera bus drivers" + default n +endif diff --git a/Ubiquitous/XiZi_IIoT/resources/Makefile b/Ubiquitous/XiZi_IIoT/resources/Makefile index 3c10a79f9..833c982f2 100644 --- a/Ubiquitous/XiZi_IIoT/resources/Makefile +++ b/Ubiquitous/XiZi_IIoT/resources/Makefile @@ -65,4 +65,8 @@ ifeq ($(CONFIG_RESOURCES_DAC),y) SRC_DIR += dac endif +ifeq ($(CONFIG_RESOURCES_CAMERA),y) + SRC_DIR += camera +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/camera/Makefile b/Ubiquitous/XiZi_IIoT/resources/camera/Makefile new file mode 100644 index 000000000..747de5b1b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/camera/Makefile @@ -0,0 +1,5 @@ +SRC_FILES += dev_camera.c drv_camera.c bus_camera.c + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/camera/bus_camera.c b/Ubiquitous/XiZi_IIoT/resources/camera/bus_camera.c new file mode 100644 index 000000000..6bb77fe0d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/camera/bus_camera.c @@ -0,0 +1,123 @@ +/* +* 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 bus_camera.c +* @brief register camera bus function using bus driver framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-24 +*/ + +#include +#include + +/*Register the CAMERA BUS*/ +int CameraBusInit(struct CameraBus *camera_bus, const char *bus_name) +{ + NULL_PARAM_CHECK(camera_bus); + NULL_PARAM_CHECK(bus_name); + + x_err_t ret = EOK; + + if (BUS_INSTALL != camera_bus->bus.bus_state) { + strncpy(camera_bus->bus.bus_name, bus_name, NAME_NUM_MAX); + + camera_bus->bus.bus_type = TYPE_CAMERA_BUS; + camera_bus->bus.bus_state = BUS_INSTALL; + camera_bus->bus.private_data = camera_bus->private_data; + + ret = BusRegister(&camera_bus->bus); + if (EOK != ret) { + KPrintf("CameraBusInit BusRegister error %u\n", ret); + return ret; + } + } else { + KPrintf("CameraBusInit BusRegister bus has been register state%u\n", camera_bus->bus.bus_state); + } + + return ret; +} + +/*Register the CAMERA Driver*/ +int CameraDriverInit(struct CameraDriver *camera_driver, const char *driver_name) +{ + NULL_PARAM_CHECK(camera_driver); + NULL_PARAM_CHECK(driver_name); + + x_err_t ret = EOK; + + if (DRV_INSTALL != camera_driver->driver.driver_state) { + camera_driver->driver.driver_type = TYPE_CAMERA_DRV; + camera_driver->driver.driver_state = DRV_INSTALL; + + strncpy(camera_driver->driver.drv_name, driver_name, NAME_NUM_MAX); + + camera_driver->driver.private_data = camera_driver->private_data; + + camera_driver->driver.configure = camera_driver->configure; + + ret = CameraDriverRegister(&camera_driver->driver); + if (EOK != ret) { + KPrintf("CameraDriverInit DriverRegister error %u\n", ret); + return ret; + } + } else { + KPrintf("CameraDriverInit DriverRegister driver has been register state%u\n", camera_driver->driver.driver_state); + } + + return ret; +} + +/*Release the CAMERA device*/ +int CameraReleaseBus(struct CameraBus *camera_bus) +{ + NULL_PARAM_CHECK(camera_bus); + + return BusRelease(&camera_bus->bus); +} + +/*Register the CAMERA Driver to the CAMERA BUS*/ +int CameraDriverAttachToBus(const char *drv_name, const char *bus_name) +{ + NULL_PARAM_CHECK(drv_name); + NULL_PARAM_CHECK(bus_name); + + x_err_t ret = EOK; + + struct Bus *bus; + struct Driver *driver; + + bus = BusFind(bus_name); + if (NONE == bus) { + KPrintf("CameraDriverAttachToBus find camera bus error!name %s\n", bus_name); + return ERROR; + } + + if (TYPE_CAMERA_BUS == bus->bus_type) { + driver = CameraDriverFind(drv_name, TYPE_CAMERA_DRV); + if (NONE == driver) { + KPrintf("CameraDriverAttachToBus find camera driver error!name %s\n", drv_name); + return ERROR; + } + + if (TYPE_CAMERA_DRV == driver->driver_type) { + ret = DriverRegisterToBus(bus, driver); + if (EOK != ret) { + KPrintf("CameraDriverAttachToBus DriverRegisterToBus error %u\n", ret); + return ERROR; + } + } + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/resources/camera/dev_camera.c b/Ubiquitous/XiZi_IIoT/resources/camera/dev_camera.c new file mode 100644 index 000000000..3ada2191c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/camera/dev_camera.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2006-03-13 bernard first version + * 2012-05-15 lgnq modified according bernard's implementation. + * 2012-05-28 bernard code cleanup + * 2012-11-23 bernard fix compiler warning. + * 2013-02-20 bernard use RT_CAMERA_RB_BUFSZ to define + * the size of ring buffer. + * 2014-07-10 bernard rewrite camera framework + * 2014-12-31 bernard use open_flag for poll_tx stream mode. + * 2015-05-19 Quintin fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG + * in open function. + * 2015-11-10 bernard fix the poll rx issue when there is no data. + * 2016-05-10 armink add fifo mode to DMA rx when camera->config.bufsz != 0. + * 2017-01-19 aubr.cool prevent change camera rx bufsz when camera is opened. + * 2017-11-07 JasonJia fix data bits error issue when using tcsetattr. + * 2017-11-15 JasonJia fix poll rx issue when data is full. + * add TCFLSH and FIONREAD support. + * 2018-12-08 Ernest Chen add DMA choice + * 2020-09-14 WillianChan add a line feed to the carriage return character + * when using interrupt tx + */ + +/** +* @file dev_camera.c +* @brief register camera dev function using bus driver framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-24 +*/ + +/************************************************* +File name: dev_camera.c +Description: support camera dev INT and DMA configure、transfer data +Others: take RT-Thread v4.0.2/components/driver/camera/camera.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2021-04-24 +Author: AIIT XUOS Lab +Modification: +1. support camera dev register, configure, write and read +2. add bus driver framework support, include INT and DMA mode +*************************************************/ + +#include +#include + +static DoubleLinklistType cameradev_linklist; + +static uint32 CameraDevOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + x_err_t ret = EOK; + struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev; + + ret = camera_dev->camera_dev_done->dev_open(dev); + + return EOK; +} + +static uint32 CameraDevClose(void *dev) +{ + NULL_PARAM_CHECK(dev); + + x_err_t ret = EOK; + struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev; + + ret = camera_dev->camera_dev_done->dev_close(dev); + return EOK; +} + +static uint32 CameraDevWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(write_param); + + x_err_t ret = EOK; + + struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev; + ret = camera_dev->camera_dev_done->dev_write(dev,write_param); + + return ret; +} + +static uint32 CameraDevRead(void *dev, struct BusBlockReadParam *read_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(read_param); + + x_err_t ret = EOK; + + struct CameraHardwareDevice *camera_dev = (struct CameraHardwareDevice *)dev; + ret = camera_dev->camera_dev_done->dev_read(dev,read_param); + + return EOK; +} + + +static const struct HalDevDone dev_done = +{ + .open = CameraDevOpen, + .close = CameraDevClose, + .write = CameraDevWrite, + .read = CameraDevRead, +}; + +/*Create the camera device linklist*/ +static void CameraDeviceLinkInit() +{ + InitDoubleLinkList(&cameradev_linklist); +} + +HardwareDevType CameraDeviceFind(const char *dev_name, enum DevType dev_type) +{ + NULL_PARAM_CHECK(dev_name); + + struct HardwareDev *device = NONE; + + DoubleLinklistType *node = NONE; + DoubleLinklistType *head = &cameradev_linklist; + + for (node = head->node_next; node != head; node = node->node_next) { + device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link); + if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) { + return device; + } + } + + KPrintf("CameraDeviceFind cannot find the %s device.return NULL\n", dev_name); + return NONE; +} + +int CameraDeviceRegister(struct CameraHardwareDevice *camera_device, void *camera_param, const char *device_name) +{ + NULL_PARAM_CHECK(camera_device); + NULL_PARAM_CHECK(device_name); + + x_err_t ret = EOK; + static x_bool dev_link_flag = RET_FALSE; + + if (!dev_link_flag) { + CameraDeviceLinkInit(); + dev_link_flag = RET_TRUE; + } + + if (DEV_INSTALL != camera_device->haldev.dev_state) { + strncpy(camera_device->haldev.dev_name, device_name, NAME_NUM_MAX); + camera_device->haldev.dev_type = TYPE_CAMERA_DEV; + camera_device->haldev.dev_state = DEV_INSTALL; + camera_device->haldev.dev_done = (struct HalDevDone *)&dev_done; + + + DoubleLinkListInsertNodeAfter(&cameradev_linklist, &(camera_device->haldev.dev_link)); + } else { + KPrintf("CameraDeviceRegister device has been register state%u\n", camera_device->haldev.dev_state); + } + + return ret; +} + +int CameraDeviceAttachToBus(const char *dev_name, const char *bus_name) +{ + NULL_PARAM_CHECK(dev_name); + NULL_PARAM_CHECK(bus_name); + + x_err_t ret = EOK; + + struct Bus *bus; + struct HardwareDev *device; + + bus = BusFind(bus_name); + if (NONE == bus) { + KPrintf("CameraDeviceAttachToBus find camera bus error!name %s\n", bus_name); + return ERROR; + } + + if (TYPE_CAMERA_BUS == bus->bus_type) { + device = CameraDeviceFind(dev_name, TYPE_CAMERA_DEV); + if (NONE == device) { + KPrintf("CameraDeviceAttachToBus find camera device error!name %s\n", dev_name); + return ERROR; + } + + if (TYPE_CAMERA_DEV == device->dev_type) { + ret = DeviceRegisterToBus(bus, device); + if (EOK != ret) { + KPrintf("CameraDeviceAttachToBus DeviceRegisterToBus error %u\n", ret); + return ERROR; + } + } + } + + return EOK; +} diff --git a/Ubiquitous/XiZi_IIoT/resources/camera/drv_camera.c b/Ubiquitous/XiZi_IIoT/resources/camera/drv_camera.c new file mode 100644 index 000000000..258c373a4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/camera/drv_camera.c @@ -0,0 +1,68 @@ +/* +* 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 drv_camera.c +* @brief register camera drv function using bus driver framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-24 +*/ + +#include +#include + +static DoubleLinklistType camera_drv_linklist; + +/*Create the driver linklist*/ +static void CameraDrvLinkInit() +{ + InitDoubleLinkList(&camera_drv_linklist); +} + +DriverType CameraDriverFind(const char *drv_name, enum DriverType_e drv_type) +{ + NULL_PARAM_CHECK(drv_name); + + struct Driver *driver = NONE; + + DoubleLinklistType *node = NONE; + DoubleLinklistType *head = &camera_drv_linklist; + + for (node = head->node_next; node != head; node = node->node_next) { + driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link); + + if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) { + return driver; + } + } + + KPrintf("CameraDriverFind cannot find the %s driver.return NULL\n", drv_name); + return NONE; +} + +int CameraDriverRegister(struct Driver *driver) +{ + NULL_PARAM_CHECK(driver); + + x_err_t ret = EOK; + static x_bool driver_link_flag = RET_FALSE; + + if (!driver_link_flag) { + CameraDrvLinkInit(); + driver_link_flag = RET_TRUE; + } + + DoubleLinkListInsertNodeAfter(&camera_drv_linklist, &(driver->driver_link)); + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h index 392168382..698afb121 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/lwipopts.h @@ -269,7 +269,7 @@ typedef unsigned int nfds_t; #define MEMP_LIB_MALLOC 1 #define MEMP_MEM_MALLOC 1 -#define lw_print //KPrintf +#define lw_print KPrintf #define lw_error KPrintf #define lw_notice KPrintf diff --git a/Ubiquitous/XiZi_IIoT/resources/include/bus.h b/Ubiquitous/XiZi_IIoT/resources/include/bus.h index b9d0f4ad7..c0f65c4a7 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/bus.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/bus.h @@ -54,6 +54,7 @@ enum BusType_e TYPE_SERIAL_BUS, TYPE_ADC_BUS, TYPE_DAC_BUS, + TYPE_CAMERA_BUS, TYPE_BUS_END, }; @@ -80,6 +81,7 @@ enum DevType TYPE_SERIAL_DEV, TYPE_ADC_DEV, TYPE_DAC_DEV, + TYPE_CAMERA_DEV, TYPE_DEV_END, }; @@ -106,6 +108,7 @@ enum DriverType_e TYPE_SERIAL_DRV, TYPE_ADC_DRV, TYPE_DAC_DRV, + TYPE_CAMERA_DRV, TYPE_DRV_END, }; diff --git a/Ubiquitous/XiZi_IIoT/resources/include/bus_camera.h b/Ubiquitous/XiZi_IIoT/resources/include/bus_camera.h new file mode 100644 index 000000000..3e6a30f4f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/include/bus_camera.h @@ -0,0 +1,69 @@ +/* +* 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 bus_camera.h +* @brief define camera bus and drv function using bus driver framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-11-15 +*/ + +#ifndef BUS_CAMERA_H +#define BUS_CAMERA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +struct CameraDriver +{ + struct Driver driver; + + uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info); + + void *private_data; +}; + +struct CameraBus +{ + struct Bus bus; + + void *private_data; +}; + +/*Register the CAMERA bus*/ +int CameraBusInit(struct CameraBus *camera_bus, const char *bus_name); + +/*Register the CAMERA driver*/ +int CameraDriverInit(struct CameraDriver *camera_driver, const char *driver_name); + +/*Release the CAMERA device*/ +int CameraReleaseBus(struct CameraBus *camera_bus); + +/*Register the CAMERA driver to the CAMERA bus*/ +int CameraDriverAttachToBus(const char *drv_name, const char *bus_name); + +/*Register the driver, manage with the double linklist*/ +int CameraDriverRegister(struct Driver *driver); + +/*Find the register driver*/ +DriverType CameraDriverFind(const char *drv_name, enum DriverType_e drv_type); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/resources/include/dev_camera.h b/Ubiquitous/XiZi_IIoT/resources/include/dev_camera.h new file mode 100644 index 000000000..4077c3254 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/resources/include/dev_camera.h @@ -0,0 +1,69 @@ +/* +* 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 dev_camera.h +* @brief define camera dev function using bus driver framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-11-15 +*/ + +#ifndef DEV_CAMERA_H +#define DEV_CAMERA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +struct CameraDataStandard +{ + uint16 addr; + uint16 flags; + uint16 len; + uint16 retries; + uint8 *buf; + + struct CameraDataStandard *next; +}; + +struct CameraDevDone +{ + uint32 (*dev_open) (void *camera_device); + uint32 (*dev_close) (void *camera_device); + uint32 (*dev_write) (void *camera_device, struct BusBlockWriteParam *msg); + uint32 (*dev_read) (void *camera_device, struct BusBlockReadParam *msg); +}; + +struct CameraHardwareDevice +{ + struct HardwareDev haldev; + const struct CameraDevDone *camera_dev_done; +}; + +/*Register the CAMERA device*/ +int CameraDeviceRegister(struct CameraHardwareDevice *camera_device, void *camera_param, const char *device_name); + +/*Register the CAMERA device to the CAMERA bus*/ +int CameraDeviceAttachToBus(const char *dev_name, const char *bus_name); + +/*Find the register CAMERA device*/ +HardwareDevType CameraDeviceFind(const char *dev_name, enum DevType dev_type); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/resources/include/device.h b/Ubiquitous/XiZi_IIoT/resources/include/device.h index cf0e0a2ed..fc4540f75 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/device.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/device.h @@ -106,4 +106,9 @@ HardwareDevType ObtainConsole(void); #include #endif +#ifdef RESOURCES_CAMERA +#include +#include +#endif + #endif diff --git a/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/cmd.c b/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/cmd.c index f3a4b60f0..82fd4eb6f 100644 --- a/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/cmd.c +++ b/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/cmd.c @@ -384,6 +384,7 @@ static char *const bus_type_str[] = "SERIAL_BUS", "ADC_BUS", "DAC_BUS", + "CAMERA_BUS", "Unknown" };