diff --git a/APP_Framework/Framework/connection/wifi/Kconfig b/APP_Framework/Framework/connection/wifi/Kconfig index 9afa7bf28..fcc6b31d2 100644 --- a/APP_Framework/Framework/connection/wifi/Kconfig +++ b/APP_Framework/Framework/connection/wifi/Kconfig @@ -8,6 +8,14 @@ if ADAPTER_HFA21_WIFI source "$APP_DIR/Framework/connection/wifi/hfa21_wifi/Kconfig" endif +config ADAPTER_ESP8285_WIFI + bool "Using wifi adapter device esp8285" + default n + +if ADAPTER_ESP8285_WIFI + source "$APP_DIR/Framework/connection/wifi/esp8285_wifi/Kconfig" +endif + config ADAPTER_ESP07S_WIFI bool "Using wifi adapter device esp07s" default n diff --git a/APP_Framework/Framework/connection/wifi/adapter_wifi.c b/APP_Framework/Framework/connection/wifi/adapter_wifi.c index 53f46603f..f3622ade5 100644 --- a/APP_Framework/Framework/connection/wifi/adapter_wifi.c +++ b/APP_Framework/Framework/connection/wifi/adapter_wifi.c @@ -28,6 +28,10 @@ extern AdapterProductInfoType Hfa21WifiAttach(struct Adapter *adapter); extern AdapterProductInfoType Esp07sWifiAttach(struct Adapter *adapter); #endif +#ifdef ADAPTER_ESP8285_WIFI +extern AdapterProductInfoType Esp8285WifiAttach(struct Adapter *adapter); +#endif + static int AdapterWifiRegister(struct Adapter *adapter) { int ret = 0; @@ -91,11 +95,27 @@ int AdapterWifiInit(void) adapter->info = product_info; adapter->done = product_info->model_done; +#endif + + +#ifdef ADAPTER_ESP8285_WIFI + AdapterProductInfoType product_info = Esp8285WifiAttach(adapter); + if (!product_info) { + printf("AdapterWifiInit ESP8285 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; + #endif return ret; } + /******************wifi TEST*********************/ int AdapterWifiTest(void) { diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig new file mode 100644 index 000000000..f44e5d47a --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig @@ -0,0 +1,10 @@ +config ADAPTER_WIFI_ESP8285 + string "ESP8285 WIFI adapter name" + default "esp8285_wifi" + +if ADD_NUTTX_FETURES + config ADAPTER_ESP8285_DRIVER + string "ESP8285 device uart driver path" + default "/dev/ttyS1" +endif + diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Make.defs b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Make.defs new file mode 100644 index 000000000..2c5d833a3 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Make.defs @@ -0,0 +1,6 @@ +############################################################################ +# APP_Framework/Framework/connection/wifi/esp8285/Make.defs +############################################################################ +ifneq ($(CONFIG_ADAPTER_ESP8285_WIFI),) +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/wifi/esp8285_wifi +endif diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile new file mode 100644 index 000000000..c1ee6bd29 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile @@ -0,0 +1,7 @@ +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += esp8285_wifi.c + include $(APPDIR)/Application.mk + +endif diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c b/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c new file mode 100644 index 000000000..07a050333 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c @@ -0,0 +1,589 @@ +/* +* 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 esp07_wifi.c + * @brief Implement the connection wifi adapter function, using ESP8285 device + * @version 1.1 + * @author AIIT XUOS Lab + * @date 2022.04.08 + */ + +#include +#include +#include "../adapter_wifi.h" +#include + +#define LEN_PARA_BUF 128 + +static int Esp8285WifiSetDown(struct Adapter *adapter_at); + +/** + * @description: check AT startup status + * @param at_agent - wifi device agent pointer + * @return success: EOK + */ +static int Esp8285WifiTestAtCmd(ATAgentType at_agent) +{ + int ret = 0; + + ret = AtCmdConfigAndCheck(at_agent, "ATE0\r\n", "OK"); ///< close echo function + if(ret < 0) { + printf("%s %d cmd[ATE0] config failed!\n",__func__,__LINE__); + ret = -1; + } + + PrivTaskDelay(2000); + ret = AtCmdConfigAndCheck(at_agent, "AT\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd[AT] config failed!\n",__func__,__LINE__); + ret = -1; + } + return ret; +} + +static int Esp8285UartOpen(struct Adapter *adapter) +{ + if (NULL == adapter) { + return -1; + } + + /* Open device in read-write mode */ + adapter->fd = PrivOpen(ADAPTER_ESP8285_DRIVER, O_RDWR); + if (adapter->fd < 0) { + printf("Esp8285WifiOpen get serial %s fd error\n", ADAPTER_ESP8285_DRIVER); + return -1; + } + /* set serial config, serial_baud_rate = 115200 */ + + struct SerialDataCfg cfg; + memset(&cfg, 0 ,sizeof(struct SerialDataCfg)); + + cfg.serial_baud_rate = BAUD_RATE_115200; + cfg.serial_data_bits = DATA_BITS_8; + cfg.serial_stop_bits = STOP_BITS_1; + cfg.serial_parity_mode = PARITY_NONE; + cfg.serial_bit_order = BIT_ORDER_LSB; + cfg.serial_invert_mode = NRZ_NORMAL; + cfg.serial_buffer_size = SERIAL_RB_BUFSZ; + cfg.is_ext_uart = 0; +#ifdef ADAPTER_ESP8285_DRIVER_EXT_PORT + cfg.is_ext_uart = 1; + cfg.ext_uart_no = ADAPTER_ESP8285_DRIVER_EXT_PORT; + cfg.port_configure = PORT_CFG_INIT; +#endif + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; + ioctl_cfg.args = &cfg; + + PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg); + PrivTaskDelay(1000); + + printf("esp8285 uart config ready\n"); + return 0; +} + +/** + * @description: Open wifi + * @param adapter - wifi device pointer + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiOpen(struct Adapter *adapter) +{ + /*step1: open esp8285 serial port*/ + Esp8285UartOpen(adapter); + + /*step2: init AT agent*/ + if (!adapter->agent) { + char *agent_name = "wifi_uart_client"; + if (EOK != InitATAgent(agent_name, adapter->fd, 512)) { + printf("at agent init failed !\n"); + return -1; + } + ATAgentType at_agent = GetATAgent(agent_name); + + adapter->agent = at_agent; + } + + AtSetReplyEndChar(adapter->agent,'O','K'); + + ADAPTER_DEBUG("Esp8285Wifi open done\n"); + + return 0; +} + +/** + * @description: Close wifi + * @param adapter - wifi device pointer + * @return success: EOK + */ +static int Esp8285WifiClose(struct Adapter *adapter) +{ + Esp8285WifiSetDown(adapter); + PrivClose(adapter->fd); + return 0; +} + +/** + * @description: send data to adapter + * @param adapter - wifi device pointer + * @param data - data buffer + * @param data - data length + * @return success: EOK + */ +static int Esp8285WifiSend(struct Adapter *adapter, const void *data, size_t len) +{ + x_err_t result = EOK; + if (adapter->agent) { + EntmSend(adapter->agent, (const char *)data, len); + }else { + printf("Esp8285WifiSend can not find agent!\n"); + } + + return result; +} + +/** + * @description: receive data from adapter + * @param adapter - wifi device pointer + * @param data - data buffer + * @param data - data length + * @return success: EOK + */ +static int Esp8285WifiReceive(struct Adapter *adapter, void *rev_buffer, size_t buffer_len) +{ + x_err_t result = EOK; + printf("esp8285 receive waiting ... \n"); + + if (adapter->agent) { + return EntmRecv(adapter->agent, (char *)rev_buffer, buffer_len, 40); + } else { + printf("Esp8285WifiReceive can not find agent!\n"); + } + + return result; +} + +/** + * @description: connnect wifi to internet + * @param adapter - wifi device pointer + * @return success: EOK + */ +static int Esp8285WifiSetUp(struct Adapter *adapter) +{ + char cmd[LEN_PARA_BUF]; + int ret = 0; + char *result = NULL; + + struct WifiParam *param = (struct WifiParam *)adapter->adapter_param; + struct ATAgent *agent = adapter->agent; + + PrivTaskDelay(2000); + + if(Esp8285WifiTestAtCmd(agent) < 0) + { + printf("wifi at cmd startup failed.\n"); + return -1; + } + PrivTaskDelay(2000); + /* config as softAP+station mode */ + ret = AtCmdConfigAndCheck(agent, "AT+CWMODE=3\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd[AT+CWMODE=3] config failed!\n",__func__,__LINE__); + return -1; + } + 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)); + + strncat(cmd,"\"",1); + strncat(cmd,",",1); + strncat(cmd,"\"",1); + strncat(cmd,param->wifi_pwd,strlen(param->wifi_pwd)); + + strncat(cmd,"\"",1); + strcat(cmd,"\r\n"); + + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d cmd[%s] connect[%s] failed!\n",__func__,__LINE__,cmd,param->wifi_ssid); + return -1; + } + + /* check the wifi ip address */ + ATReplyType reply = CreateATReply(256); + if (NULL == reply) { + printf("%s %d at_create_resp failed!\n",__func__,__LINE__); + return -1; + } + ret = ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+CIFSR\r\n"); + if(ret < 0){ + printf("%s %d ATOrderSend AT+CIFSR failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + + result = GetReplyText(reply); + if (!result) { + printf("%s %n get reply failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + printf("[%s]\n", result); + +__exit: + DeleteATReply(reply); + + return ret; +} + +/** + * @description: disconnnect wifi from internet + * @param adapter - wifi device pointer + * @return success: EOK + */ +static int Esp8285WifiSetDown(struct Adapter *adapter) +{ + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+RESTORE\r\n"); + PrivTaskDelay(2000); + + return 0; +} + +/** + * @description: set wifi ip/gateway/netmask address(in sta mode) + * @param adapter - wifi device pointer + * @param ip - ip address + * @param gateway - gateway address + * @param netmask - netmask address + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiSetAddr(struct Adapter *adapter, const char *ip, const char *gateway, const char *netmask) +{ + int ret = 0; + char cmd[LEN_PARA_BUF]; + + /* 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,"\r\n"); + + ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d cmd[%s] config ip failed!\n",__func__,__LINE__,cmd); + return -1; + } + + return 0; +} + +/** + * @description: wifi ping function + * @param adapter - wifi device pointer + * @param destination - domain name or ip address + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiPing(struct Adapter *adapter, const char *destination) +{ + char cmd[LEN_PARA_BUF]; + int ret = 0; + + 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,"\r\n"); + + ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); ///< config as softAP+station mode + if(ret < 0) { + printf("%s %d ping [%s] failed!\n",__func__,__LINE__,destination); + return -1; + } + + printf("ping [%s] ok\n", destination); + + return 0; +} + +/** + * @description: display wifi network configuration + * @param adapter - wifi device pointer + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiNetstat(struct Adapter *adapter) +{ + int ret = 0; + char *result = NULL; + + /* check the wifi ip address */ + ATReplyType reply = CreateATReply(256); + if (NULL == reply) { + printf("%s %d at_create_resp failed!\n",__func__,__LINE__); + return -1; + } + ret = ATOrderSend(adapter->agent, REPLY_TIME_OUT, reply, "AT+CIFSR\r\n"); + if(ret < 0){ + printf("%s %d ATOrderSend AT+CIFSR failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + + result = GetReplyText(reply); + if (!result) { + printf("%s %n get reply failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + printf("[%s]\n", result); + +__exit: + DeleteATReply(reply); + + return ret; +} + +/** + * @description: wifi connect function + * @param adapter - wifi device pointer + * @param net_role - net role, CLIENT or SERVER + * @param ip - ip address + * @param port - port num + * @param ip_type - ip type, IPV4 or IPV6 + * @return success: 0, failure: -1 + */ +static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role, const char *ip, const char *port, enum IpType ip_type) +{ + int ret = EOK; + char cmd[LEN_PARA_BUF]; + struct ATAgent *agent = adapter->agent; + + memset(cmd,0,sizeof(cmd)); + if(adapter->socket.protocal == SOCKET_PROTOCOL_TCP && net_role == CLIENT) //esp8285 as tcp client to connect server + { + //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,"\r\n"); + + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d tcp connect [%s] failed!\n",__func__,__LINE__,ip); + return -1; + } + } + else if(adapter->socket.protocal == SOCKET_PROTOCOL_UDP) + { + //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,"\r\n"); + + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d udp connect [%s] failed!\n",__func__,__LINE__,ip); + return -1; + } + } + + ret = AtCmdConfigAndCheck(agent, "AT+CIPMODE=1\r\n", "OK"); ///< config as transparent transmission + if(ret < 0) { + printf("%s %d cmd[%s] config as transparent transmission failed!\n",__func__,__LINE__,cmd); + return -1; + } + ATOrderSend(agent, REPLY_TIME_OUT, NULL, "AT+CIPSEND\r\n"); + + printf("[%s] connection config as transparent transmission\n",adapter->socket.protocal == SOCKET_PROTOCOL_UDP ? "udp" : "tcp"); + adapter->net_role = net_role; + + return 0; +} + +/** + * @description: wifi disconnect function + * @param adapter - wifi device pointer + * @return success: 0, failure: -1 + */ +static int Esp8285WifiDisconnect(struct Adapter *adapter) +{ + int ret = EOK; + char cmd[LEN_PARA_BUF]; + struct ATAgent *agent = adapter->agent; + memset(cmd,0,sizeof(cmd)); + + /* step1: stop transparent transmission mode */ + ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++\r\n"); + + /* step2: exit transparent transmission mode */ + ret = AtCmdConfigAndCheck(agent, "AT+CIPMODE=0\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd[AT+CIPMODE=0] exit failed!\n",__func__,__LINE__); + return -1; + } + + /* step3: disconnect */ + ret = AtCmdConfigAndCheck(agent, "AT+CIPCLOSE\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd [AT+CIPCLOSE] disconnect failed!\n",__func__,__LINE__); + return -1; + } + + return 0; +} + +static int Esp8285WifiIoctl(struct Adapter *adapter, int cmd, void *args) +{ + int32_t ret = 0; + char baud_str[LEN_PARA_BUF]; + struct SerialDataCfg cfg; + char at_cmd[LEN_PARA_BUF]; + uint32_t baud_rate = 0 ; + + switch (cmd) + { + case CONFIG_WIFI_RESET: /* reset wifi */ + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+RST\r\n"); + break; + case CONFIG_WIFI_RESTORE: /* resore wifi */ + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+RESTORE\r\n"); + break; + case CONFIG_WIFI_BAUDRATE: + /* step1: config mcu uart*/ + baud_rate = *((uint32_t *)args); + + memset(at_cmd, 0, sizeof(at_cmd)); + memset(baud_str, 0, sizeof(baud_str)); + memset(&cfg, 0 ,sizeof(struct SerialDataCfg)); + + cfg.serial_baud_rate = baud_rate; + cfg.serial_data_bits = DATA_BITS_8; + cfg.serial_stop_bits = STOP_BITS_1; + cfg.serial_parity_mode = PARITY_NONE; + cfg.serial_bit_order = BIT_ORDER_LSB; + cfg.serial_invert_mode = NRZ_NORMAL; + cfg.serial_buffer_size = SERIAL_RB_BUFSZ; + cfg.is_ext_uart = 0; +#ifdef ADAPTER_ESP8285_DRIVER_EXT_PORT + cfg.is_ext_uart = 1; + cfg.ext_uart_no = ADAPTER_ESP8285_DRIVER_EXT_PORT; + cfg.port_configure = PORT_CFG_INIT; +#endif + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; + ioctl_cfg.args = &cfg; + + PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg); + + /* step2: config wifi uart*/ + 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,"\r\n"); + + ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK"); + if(ret < 0) { + printf("%s %d cmd [%s] config uart failed!\n",__func__,__LINE__,at_cmd); + ret = -1; + } + + break; + default: + ret = -1; + break; + } + + return ret; +} + +static const struct IpProtocolDone esp8285_wifi_done = +{ + .open = Esp8285WifiOpen, + .close = Esp8285WifiClose, + .ioctl = Esp8285WifiIoctl, + .setup = Esp8285WifiSetUp, + .setdown = Esp8285WifiSetDown, + .setaddr = Esp8285WifiSetAddr, + .setdns = NULL, + .setdhcp = NULL, + .ping = Esp8285WifiPing, + .netstat = Esp8285WifiNetstat, + .connect = Esp8285WifiConnect, + .send = Esp8285WifiSend, + .recv = Esp8285WifiReceive, + .disconnect = Esp8285WifiDisconnect, +}; + +/** + * @description: Register wifi device esp8285 + * @return success: EOK, failure: ERROR + */ +AdapterProductInfoType Esp8285WifiAttach(struct Adapter *adapter) +{ + struct AdapterProductInfo *product_info = PrivMalloc(sizeof(struct AdapterProductInfo)); + if (!product_info) + { + printf("Esp8285WifiAttach Attach malloc product_info error\n"); + PrivFree(product_info); + return NULL; + } + + strncpy(product_info->model_name, ADAPTER_WIFI_ESP8285, strlen(ADAPTER_WIFI_ESP8285)); + + product_info->model_done = (void *)&esp8285_wifi_done; + + return product_info; +} diff --git a/APP_Framework/Framework/transform_layer/nuttx/transform.c b/APP_Framework/Framework/transform_layer/nuttx/transform.c index 878aa0f93..35e3a599d 100644 --- a/APP_Framework/Framework/transform_layer/nuttx/transform.c +++ b/APP_Framework/Framework/transform_layer/nuttx/transform.c @@ -139,10 +139,30 @@ static int PrivSerialIoctl(int fd, int cmd, void *args) { struct SerialDataCfg *serial_cfg = (struct SerialDataCfg *)args; unsigned long serial_baud_rate = (unsigned long)serial_cfg->serial_baud_rate; + struct termios term; + + /* Extended serial port */ if(serial_cfg->is_ext_uart == 1) { return ioctl(fd, OPE_INT, serial_baud_rate); } + + /* Standard serial port,only the baud rate is set */ + else if(serial_cfg->is_ext_uart == 0) + { + if(ioctl(fd, TCGETS, (unsigned long)&term) < 0) + { + return -1; + } + if ((cfsetispeed(&term, serial_baud_rate) < 0) ||(cfsetospeed(&term, serial_baud_rate) < 0)) + { + return -1; + } + if(ioctl(fd, TCSETS, (unsigned long)&term) < 0) + { + return -1; + } + } return 0; } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig index 56405367b..a4a4dac80 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig @@ -5,6 +5,40 @@ if ARCH_BOARD_XIDATONG_RISCV64 +menuconfig BSP_USING_CH376 + bool "Using CH376 device" + default n + select K210_16550_UART + select K210_16550_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 + menuconfig BSP_USING_CH438 bool "Using CH438 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 new file mode 100644 index 000000000..88480a614 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig @@ -0,0 +1,77 @@ +# +# 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_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_SUPPORT_CONNECTION_FRAMEWORK=y +CONFIG_CONNECTION_FRAMEWORK_DEBUG=y +CONFIG_CONNECTION_ADAPTER_4G=y +CONFIG_ADAPTER_EC200T=y +CONFIG_ADAPTER_4G_EC200T="ec200t" +CONFIG_ADAPTER_EC200T_DRIVER="/dev/ttyS2" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/ch376nsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/ch376nsh/defconfig new file mode 100644 index 000000000..b9aefbaa3 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/ch376nsh/defconfig @@ -0,0 +1,63 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="xidatong-riscv64" +CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y +CONFIG_ARCH_CHIP="k210" +CONFIG_ARCH_CHIP_K210=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=46000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=2097152 +CONFIG_RAM_START=0x80400000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=28 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_SCHED_HPWORK=y +CONFIG_DEV_GPIO=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BSP_USING_CH376=y +CONFIG_CH376_USB_FUNCTION=y +CONFIG_CH376_WORK_MODE=0x06 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 new file mode 100644 index 000000000..67f5f8c4a --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig @@ -0,0 +1,63 @@ +# +# 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_16550_UART=y +CONFIG_K210_16550_UART3=y +CONFIG_BSP_USING_TOUCH=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/w5500nsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/w5500nsh/defconfig new file mode 100644 index 000000000..6075ce1b8 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/w5500nsh/defconfig @@ -0,0 +1,61 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ADD_NUTTX_FETURES=y +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="xidatong-riscv64" +CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y +CONFIG_ARCH_CHIP="k210" +CONFIG_ARCH_CHIP_K210=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=46000 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INIT_STACKSIZE=3072 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_READLINE=y +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=2097152 +CONFIG_RAM_START=0x80400000 +CONFIG_RAW_BINARY=y +CONFIG_READLINE_CMD_HISTORY=y +CONFIG_READLINE_CMD_HISTORY_LEN=100 +CONFIG_READLINE_CMD_HISTORY_LINELEN=120 +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=28 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2019 +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=20 +CONFIG_TESTING_GETPRIME=y +CONFIG_UART0_SERIAL_CONSOLE=y +CONFIG_READLINE_TABCOMPLETION=y +CONFIG_SCHED_HPWORK=y +CONFIG_DEV_GPIO=y +CONFIG_BOARDCTL_RESET=y +CONFIG_BSP_USING_ENET=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index 9435e91c8..5757d2b3f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -39,12 +39,10 @@ * Pre-processor Definitions ****************************************************************************/ -#define BOARD_LED_PAD 14 /* Connected to red led */ + /* Map pad 14 to gpiohs io 0 */ - #define BOARD_LED_IO_FUNC K210_IO_FUNC_GPIOHS0 -#define BOARD_LED_IO 0 #define LED_STARTED 0 /* N/C */ #define LED_HEAPALLOCATE 1 /* N/C */ @@ -57,7 +55,7 @@ /* GPIO pins used by the GPIO Subsystem */ -#define BOARD_NGPIOOUT 3 /* Amount of GPIO Output pins */ +#define BOARD_NGPIOOUT 4 /* Amount of GPIO Output pins */ #define BOARD_NGPIOINT 0 /* Amount of GPIO Input */ /**************************************************************************** @@ -79,6 +77,99 @@ extern "C" #define EXTERN extern #endif +/*************************** GPIO define ***************************/ +/* Connected to red led */ +#define BOARD_LED_PAD 14 + +/* UART IO */ +#define GPIO_WIFI_RXD 7 +#define GPIO_WIFI_TXD 6 +#define GPIO_EC200T_RXD 21 +#define GPIO_EC200T_TXD 20 +#define GPIO_CH376T_RXD 22 +#define GPIO_CH376T_TXD 23 + +/* ch438 IO */ +#define CH438_ALE_PIN 24 +#define CH438_NWR_PIN 25 +#define CH438_NRD_PIN 26 +#define CH438_D0_PIN 27 +#define CH438_D1_PIN 28 +#define CH438_D2_PIN 29 +#define CH438_D3_PIN 30 +#define CH438_D4_PIN 31 +#define CH438_D5_PIN 32 +#define CH438_D6_PIN 33 +#define CH438_D7_PIN 34 +#define CH438_INT_PIN 35 + +/* 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 + +/* I2C */ +#define BSP_IIC_SDA 15 +#define BSP_IIC_SCL 17 + +/* other mode io */ +#define GPIO_E220_M0 44 +#define GPIO_E220_M1 45 +#define GPIO_E18_MODE 46 +#define GPIO_WIFI_EN 8 + +/************************** end GPIO define **************************/ + + +/*************************** FPIOA define ***************************/ +#define BOARD_LED_IO 0 + +/* 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 + +/* ch438 FPIOA */ +#define FPIOA_CH438_ALE 11 +#define FPIOA_CH438_NWR 12 +#define FPIOA_CH438_NRD 13 +#define FPIOA_CH438_D0 14 +#define FPIOA_CH438_D1 15 +#define FPIOA_CH438_D2 16 +#define FPIOA_CH438_D3 17 +#define FPIOA_CH438_D4 18 +#define FPIOA_CH438_D5 29 +#define FPIOA_CH438_D6 20 +#define FPIOA_CH438_D7 31 +#define FPIOA_CH438_INT 22 + +/* 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 + +/* 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 + +/************************** end FPIOA define **************************/ + + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile index d6fa521c7..04afe7e33 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile @@ -46,4 +46,16 @@ ifeq ($(CONFIG_BSP_USING_CH438),y) CSRCS += k210_ch438.c ch438_demo.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/xidatong-riscv64/src/ch376_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c new file mode 100644 index 000000000..f8d439e52 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-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 xidatong-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 演示数据\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/xidatong-riscv64/src/ch376inc.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h new file mode 100644 index 000000000..ec8a4d08f --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-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 xidatong-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/xidatong-riscv64/src/k210_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c index bc90e372b..1fed3801b 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 @@ -36,6 +36,8 @@ #include "k210.h" #include "k210_clockconfig.h" #include "xidatong-riscv64.h" +#include +#include "k210_sysctl.h" #ifdef CONFIG_BSP_USING_CH438 # include "k210_ch438.h" @@ -85,5 +87,26 @@ int k210_bringup(void) } #endif +#ifdef CONFIG_K210_16550_UART1 + sysctl_clock_enable(SYSCTL_CLOCK_UART1); + sysctl_reset(SYSCTL_RESET_UART1); + fpioa_set_function(GPIO_WIFI_RXD, FPOA_USART1_RX); + fpioa_set_function(GPIO_WIFI_TXD, FPOA_USART1_TX); +#endif + +#ifdef CONFIG_K210_16550_UART2 + sysctl_clock_enable(SYSCTL_CLOCK_UART2); + sysctl_reset(SYSCTL_RESET_UART2); + fpioa_set_function(GPIO_EC200T_RXD, FPOA_USART2_RX); + fpioa_set_function(GPIO_EC200T_TXD, FPOA_USART2_TX); +#endif + +#ifdef CONFIG_K210_16550_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/xidatong-riscv64/src/k210_ch376.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c new file mode 100644 index 000000000..e1223e086 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-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 xidatong-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/xidatong-riscv64/src/k210_ch376.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h new file mode 100644 index 000000000..23f6b7838 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-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 xidatong-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_16550.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/xidatong-riscv64/src/k210_ch438.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h index f952320e8..510e5757b 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h @@ -53,6 +53,7 @@ #include #include +#include #include #include "riscv_internal.h" @@ -289,39 +290,6 @@ #define Fpclk 1843200 /* Define the internal clock frequency*/ - -/* Define CH438 PIN NUM */ -#define CH438_ALE_PIN 24 -#define CH438_NWR_PIN 25 -#define CH438_NRD_PIN 26 - -#define CH438_D0_PIN 27 -#define CH438_D1_PIN 28 -#define CH438_D2_PIN 29 -#define CH438_D3_PIN 30 -#define CH438_D4_PIN 31 -#define CH438_D5_PIN 32 -#define CH438_D6_PIN 33 -#define CH438_D7_PIN 34 - -#define CH438_INT_PIN 35 - -/* Define ch438 FPIOA NUMBER */ -#define FPIOA_CH438_ALE 11 -#define FPIOA_CH438_NWR 12 -#define FPIOA_CH438_NRD 13 - -#define FPIOA_CH438_D0 14 -#define FPIOA_CH438_D1 15 -#define FPIOA_CH438_D2 16 -#define FPIOA_CH438_D3 17 -#define FPIOA_CH438_D4 18 -#define FPIOA_CH438_D5 29 -#define FPIOA_CH438_D6 20 -#define FPIOA_CH438_D7 31 - -#define FPIOA_CH438_INT 22 - /* ch438 debug */ #ifdef CONFIG_DEBUG_CH438_ERROR # define ch438err _err diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c index 12c88622b..ab1b880a7 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c @@ -34,7 +34,7 @@ #include #include - +#include #include #include "k210_fpioa.h" @@ -48,13 +48,7 @@ /* Pin 1 and 2 are used for this example as GPIO outputs. */ -#define GPIO_E220_M0 44 -#define GPIO_E220_M1 45 -#define GPIO_E18_MODE 46 -#define FPIOA_E220_M0 1 -#define FPIOA_E220_M1 2 -#define FPIOA_E18_MODE 3 /**************************************************************************** * Private Types @@ -94,14 +88,16 @@ static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = { GPIO_E220_M0, GPIO_E220_M1, - GPIO_E18_MODE + GPIO_E18_MODE, + GPIO_WIFI_EN }; static const uint32_t g_fpioa[BOARD_NGPIOOUT] = { FPIOA_E220_M0, FPIOA_E220_M1, - FPIOA_E18_MODE + FPIOA_E18_MODE, + FPIOA_WIFI_EN }; static struct k210gpio_dev_s g_gpout[BOARD_NGPIOOUT]; diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c index 709d74107..5d255a6f4 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c @@ -25,7 +25,6 @@ #include #include - #include #include "k210_fpioa.h" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c new file mode 100644 index 000000000..4649cf1d4 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c @@ -0,0 +1,409 @@ +/* +* 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" + +/**************************************************************************** + * Name: IIC_Init + * Description: i2c pin mode configure + * input: None + * output: None + * return:none + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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. +********************************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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: GT911_test + * Description: gt911 test code + * input: None + * output: None + * return: Returns true for touch, false for no touch + ***********************************************************************************/ +void GT911_test(void) +{ + uint16_t res; + POINT point = {0, 0}; + IIC_Init(); + res = GT911_ReadFirmwareVersion(); + printf("FirmwareVersion:%2x\n",res); + while(1) + { + if(GT911_Scan(&point)) + { + printf("Now touch point:(%d,%d)\n",point.X,point.Y); + } + } +} \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h new file mode 100644 index 000000000..26ad5ed32 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h @@ -0,0 +1,88 @@ +/* +* 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; +}POINT; + +void IIC_Init(void); +void SDA_IN(void); +void SDA_OUT(void); +uint8_t READ_SDA(void); +void IIC_SCL(uint8_t val); +void IIC_SDA(uint8_t val); +void IIC_Start(void); +void IIC_Stop(void); +uint8_t IIC_Wait_Ack(void); +void IIC_Ack(void); +void IIC_NAck(void); +void IIC_Send_Byte(uint8_t txd); +uint8_t IIC_Read_Byte(uint8_t ack); +bool GT911_Scan(POINT* point); +void GT911_test(void); + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c new file mode 100644 index 000000000..755404f91 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-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/xidatong-riscv64/src/k210_w5500.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h new file mode 100644 index 000000000..86e238b03 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-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/app_match_nuttx/apps/nshlib/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig index df719b23e..fcffc9750 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig @@ -547,6 +547,18 @@ config NSH_DISABLE_XD bool "Disable xd" default DEFAULT_SMALL +config NSH_DISABLE_CH376 + bool "Disable the ch376 demo." + default n + +config NSH_DISABLE_W5500 + bool "Disable the w5500 demo." + default n + +config NSH_DISABLE_TOUCH + bool "Disable the gt911 touch screen demo." + default n + config NSH_DISABLE_CH438 bool "Disable the ch438 demo." default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h index 1aba1a1ff..918ba31a7 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h @@ -1450,6 +1450,18 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, FAR void *arg); #endif +#if defined(CONFIG_BSP_USING_CH376) && !defined(CONFIG_NSH_DISABLE_CH376) + int cmd_Ch376(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + +#if defined(CONFIG_BSP_USING_ENET) && !defined(CONFIG_NSH_DISABLE_W5500) + int cmd_w5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + +#if defined(CONFIG_BSP_USING_TOUCH) && !defined(CONFIG_NSH_DISABLE_TOUCH) + int cmd_Touch(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif @@ -1567,7 +1579,7 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, int cmd_AdapterBlueToothTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif -#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index f19fdc9d4..820d3360d 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -38,6 +38,45 @@ extern int FrameworkInit(void); +/**************************************************************************** + * Name: cmd_Ch376 + ****************************************************************************/ +#if defined(CONFIG_BSP_USING_CH376) && !defined(CONFIG_NSH_DISABLE_CH376) +extern void CH376Demo(void); +int cmd_Ch376(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + CH376Demo(); + return OK; +} +#endif + +/**************************************************************************** + * Name: cmd_w5500 + ****************************************************************************/ +#if defined(CONFIG_BSP_USING_ENET) && !defined(CONFIG_NSH_DISABLE_W5500) +extern void w5500_test(void); +int cmd_w5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + w5500_test(); + return OK; +} +#endif + +/**************************************************************************** + * Name: cmd_Touch + ****************************************************************************/ +#if defined(CONFIG_BSP_USING_TOUCH) && !defined(CONFIG_NSH_DISABLE_TOUCH) +extern void GT911_test(void); +int cmd_Touch(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + GT911_test(); + return OK; +} +#endif + /**************************************************************************** * Name: cmd_Ch438 ****************************************************************************/ @@ -363,7 +402,7 @@ int cmd_recvzigbee(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif -#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) extern int AdapterWifiTestWithParam(int argc, char *argv[]); int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c index e040899fa..1b03f5cc9 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c @@ -596,6 +596,18 @@ static const struct cmdmap_s g_cmdmap[] = { "xd", cmd_xd, 3, 3, " " }, #endif +#if defined(CONFIG_BSP_USING_CH376) && !defined(CONFIG_NSH_DISABLE_CH376) + { "ch376", cmd_Ch376, 1, 1, "[ch376 demo cmd.]" }, +#endif + +#if defined(CONFIG_BSP_USING_ENET) && !defined(CONFIG_NSH_DISABLE_W5500) + { "w5500", cmd_w5500, 1, 1, "[w5500 demo cmd.]" }, +#endif + +#if defined(CONFIG_BSP_USING_TOUCH) && !defined(CONFIG_NSH_DISABLE_TOUCH) + { "touch", cmd_Touch, 1, 1, "[gt911 touch screen demo cmd.]" }, +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) { "ch438", cmd_Ch438, 1, 1, "[ch438 demo cmd.]" }, #endif @@ -712,7 +724,7 @@ static const struct cmdmap_s g_cmdmap[] = { "AdapterBlueToothTest", cmd_AdapterBlueToothTest, 1, 1, "[BlueTooth hc08 test.]" }, #endif -#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) { "wifitest", cmd_AdapterWifiTest, 1, 8, "[WIFI test.]" }, #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/include/k210/irq.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/include/k210/irq.h new file mode 100644 index 000000000..a800588bb --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/include/k210/irq.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/risc-v/include/k210/irq.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_K210_IRQ_H +#define __ARCH_RISCV_INCLUDE_K210_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Map RISC-V exception code to NuttX IRQ */ + +#ifdef CONFIG_K210_WITH_QEMU +#define K210_IRQ_UART0 (RISCV_IRQ_MEXT + 4) +#else +#define K210_IRQ_UART0 (RISCV_IRQ_MEXT + 33) +#define K210_IRQ_UART1 (RISCV_IRQ_MEXT + 11) +#define K210_IRQ_UART2 (RISCV_IRQ_MEXT + 12) +#define K210_IRQ_UART3 (RISCV_IRQ_MEXT + 13) +#endif + +/* Total number of IRQs */ + +#define NR_IRQS (64 + 16 +16) + +#endif /* __ARCH_RISCV_INCLUDE_K210_IRQ_H */ 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 0502d2b18..bc34095b5 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,6 +40,273 @@ config K210_LCD_BACKLIGHT endmenu +menuconfig K210_16550_UART + bool "K210 16550 UART Chip support" + select ARCH_HAVE_SERIAL_TERMIOS + default n + +if K210_16550_UART + config K210_16550_SERIAL_DISABLE_REORDERING + bool "Disable reordering of ttySx devices." + default n + ---help--- + NuttX per default reorders the serial ports (/dev/ttySx) so that the + 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. + + config K210_16550_UART1 + bool "K210 16550 UART1" + default n + + if K210_16550_UART1 + + config K210_16550_UART1_BASE + hex "K210 16550 UART1 base address" + default 0x50210000 + + config K210_16550_UART1_CLOCK + int "K210 16550 UART1 clock" + default 195000000 + + + config K210_16550_UART1_IRQ + int "K210 16550 UART1 IRQ number" + default 38 + + config K210_16550_UART1_BAUD + int "K210 16550 UART1 BAUD" + default 115200 + + config K210_16550_UART1_PARITY + int "K210 16550 UART1 parity" + default 0 + range 0 2 + ---help--- + K210 16550 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None + + config K210_16550_UART1_BITS + int "K210 16550 UART1 number of bits" + default 8 + ---help--- + K210 16550 UART1 number of bits. Default: 8 + + config K210_16550_UART1_2STOP + int "K210 16550 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" + default 256 + ---help--- + K210 16550 UART1 Rx buffer size. Default: 128 + + config K210_16550_UART1_TXBUFSIZE + int "K210 16550 UART1 Tx buffer size" + default 256 + ---help--- + K210 16550 UART1 Tx buffer size. Default: 128 + + config K210_16550_UART1_IFLOWCONTROL + bool "K210 16550 UART1 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable K210 16550 UART1 RTS flow control + + config K210_16550_UART1_OFLOWCONTROL + bool "K210 16550 UART1 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable K210 16550 UART1 CTS flow control + + endif # K210_16550_UART1 + + config K210_16550_UART2 + bool "K210 16550 UART2" + default n + + if K210_16550_UART2 + + config K210_16550_UART2_BASE + hex "K210 16550 UART2 base address" + default 0x50220000 + + config K210_16550_UART2_CLOCK + int "K210 16550 UART2 clock" + default 195000000 + + config K210_16550_UART2_IRQ + int "K210 16550 UART2 IRQ number" + default 39 + + config K210_16550_UART2_BAUD + int "K210 16550 UART2 BAUD" + default 115200 + + config K210_16550_UART2_PARITY + int "K210 16550 UART2 parity" + default 0 + range 0 2 + ---help--- + K210 16550 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None + + config K210_16550_UART2_BITS + int "K210 16550 UART2 number of bits" + default 8 + ---help--- + K210 16550 UART2 number of bits. Default: 8 + + config K210_16550_UART2_2STOP + int "K210 16550 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" + default 256 + ---help--- + K210 16550 UART2 Rx buffer size. Default: 128 + + config K210_16550_UART2_TXBUFSIZE + int "K210 16550 UART2 Tx buffer size" + default 256 + ---help--- + K210 16550 UART2 Tx buffer size. Default: 128 + + config K210_16550_UART2_IFLOWCONTROL + bool "K210 16550 UART2 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable K210 16550 UART2 RTS flow control + + config K210_16550_UART2_OFLOWCONTROL + bool "K210 16550 UART2 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable K210 16550 UART2 CTS flow control + + endif # K210_16550_UART2 + + config K210_16550_UART3 + bool "K210 16550 UART3" + default n + + if K210_16550_UART3 + + config K210_16550_UART3_BASE + hex "K210 16550 UART3 base address" + default 0x50230000 + + config K210_16550_UART3_CLOCK + int "K210 16550 UART3 clock" + default 195000000 + + config K210_16550_UART3_IRQ + int "K210 16550 UART3 IRQ number" + default 40 + + config K210_16550_UART3_BAUD + int "K210 16550 UART3 BAUD" + default 115200 + + config K210_16550_UART3_PARITY + int "K210 16550 UART3 parity" + default 0 + range 0 2 + ---help--- + K210 16550 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None + + config K210_16550_UART3_BITS + int "K210 16550 UART3 number of bits" + default 8 + ---help--- + K210 16550 UART3 number of bits. Default: 8 + + config K210_16550_UART3_2STOP + int "K210 16550 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" + default 256 + ---help--- + K210 16550 UART3 Rx buffer size. Default: 128 + + config K210_16550_UART3_TXBUFSIZE + int "K210 16550 UART3 Tx buffer size" + default 256 + ---help--- + K210 16550 UART3 Tx buffer size. Default: 128 + + config K210_16550_UART3_IFLOWCONTROL + bool "K210 16550 UART3 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable K210 16550 UART3 RTS flow control + + config K210_16550_UART3_OFLOWCONTROL + bool "K210 16550 UART3 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable K210 16550 UART3 CTS flow control + + endif # K210_16550_UART3 + + config K210_16550_SUPRESS_CONFIG + bool "Suppress K210 16550 configuration" + default n + + config K210_16550_SUPRESS_INITIAL_CONFIG + bool "Suppress initial K210 16550 configuration" + depends on !K210_16550_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 + just leave the existing console configuration in place. Default: n + + config SERIAL_UART_ARCH_MMIO + bool "Platform access register through the memory mapping" + default y + + config SERIAL_UART_ARCH_IOCTL + bool "Platform has own custom IOCTL" + default n + + config K210_16550_REGINCR + int "Address increment between K210 16550 registers" + default 4 + ---help--- + The address increment between K210 16550 registers. Options are 1, 2, or 4. + Default: 1 + + config K210_16550_REGWIDTH + int "Bit width of K210 16550 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" + default 32 + ---help--- + The bit width of registers. Options are 0, 8, 16, or 32. + Default: 32 + Note: 0 means auto detect address size (uintptr_t) +endif + menu "K210 Others" config K210_WITH_QEMU 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 63dbba19a..4089b0be4 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 @@ -55,9 +55,9 @@ endif # Specify our C code within this directory to be included 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 +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 +CHIP_CSRCS += k210_sysctl.c k210_uart_16550.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/encoding.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/encoding.h index 980e36f4c..a9a5e0353 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/encoding.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/encoding.h @@ -1,17 +1,32 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/encoding.h * - * 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 + * 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 + * 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. - */ + * 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 encoding.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #ifndef RISCV_CSR_ENCODING_H #define RISCV_CSR_ENCODING_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c new file mode 100644 index 000000000..67a93b161 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c @@ -0,0 +1,4947 @@ +/**************************************************************************** + * arch/risc-v/src/k210/fpioa.c + * + * 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. + * + ****************************************************************************/ + +/** +* @file fpioa.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + +#include +#include +#include "fpioa.h" +#include "k210_fpioa.h" +#include "k210_sysctl.h" +#include "k210_memorymap.h" + +volatile fpioa_t *const fpioa = (volatile fpioa_t *)K210_FPIOA_BASE; + +/** + * @brief Internal used FPIOA function initialize cell + * + * This is NOT fpioa_io_config_t, can't assign directly + * + */ +typedef struct _fpioa_assign_t +{ + uint32_t ch_sel : 8; + /* Channel select from 256 input. */ + uint32_t ds : 4; + /* Driving selector. */ + uint32_t oe_en : 1; + /* Static output enable, will AND with OE_INV. */ + uint32_t oe_inv : 1; + /* Invert output enable. */ + uint32_t do_sel : 1; + /* Data output select: 0 for DO, 1 for OE. */ + uint32_t do_inv : 1; + /* Invert the result of data output select (DO_SEL). */ + uint32_t pu : 1; + /* Pull up enable. 0 for nothing, 1 for pull up. */ + uint32_t pd : 1; + /* Pull down enable. 0 for nothing, 1 for pull down. */ + uint32_t resv0 : 1; + /* Reserved bits. */ + uint32_t sl : 1; + /* Slew rate control enable. */ + uint32_t ie_en : 1; + /* Static input enable, will AND with IE_INV. */ + uint32_t ie_inv : 1; + /* Invert input enable. */ + uint32_t di_inv : 1; + /* Invert Data input. */ + uint32_t st : 1; + /* Schmitt trigger. */ + uint32_t tie_en : 1; + /* Input tie enable, 1 for enable, 0 for disable. */ + uint32_t tie_val : 1; + /* Input tie value, 1 for high, 0 for low. */ + uint32_t resv1 : 5; + /* Reserved bits. */ + uint32_t pad_di : 1; + /* Read current PAD's data input. */ +} __attribute__((packed, aligned(4))) fpioa_assign_t; + +/* Function list */ +static const fpioa_assign_t function_config[FUNC_MAX] = + { + {.ch_sel = FUNC_JTAG_TCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_JTAG_TDI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_JTAG_TMS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_JTAG_TDO, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_ARB, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 1, + .tie_val = 1, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UARTHS_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UARTHS_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV6, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV7, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_SPI1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_I2C1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS9, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS10, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS11, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS12, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS13, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS15, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS16, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS17, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS18, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS19, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS20, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS21, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS22, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS23, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS24, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS25, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS26, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS27, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS28, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS29, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS30, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS31, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_ARB, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 1, + .tie_val = 1, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI_SLAVE_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI_SLAVE_SS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI_SLAVE_SCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV4, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV5, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C0_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C0_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C1_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C1_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C2_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C2_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_XCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_RST, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_PWDN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_VSYNC, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_HREF, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_PCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D4, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D5, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D6, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D7, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SCCB_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SCCB_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_SPI2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_I2C2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL9, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL10, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL11, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL12, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL13, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL15, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL16, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL17, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CONSTANT, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL18, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG9, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG10, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG11, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG12, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG13, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG15, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG16, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG17, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG18, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG19, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG20, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG21, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG22, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG23, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG24, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG25, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG26, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG27, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG28, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG29, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG30, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG31, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, +}; + +int fpioa_init(void) +{ + int i = 0; + + /* Enable fpioa clock in system controller */ + sysctl_clock_enable(SYSCTL_CLOCK_FPIOA); + + /* Initialize tie */ + fpioa_tie_t tie = {0}; + + /* Set tie enable and tie value */ + for(i = 0; i < FUNC_MAX; i++) + { + tie.en[i / 32] |= (function_config[i].tie_en << (i % 32)); + tie.val[i / 32] |= (function_config[i].tie_val << (i % 32)); + } + + /* Atomic write every 32bit register to fpioa function */ + for(i = 0; i < FUNC_MAX / 32; i++) + { + /* Set value before enable */ + fpioa->tie.val[i] = tie.val[i]; + fpioa->tie.en[i] = tie.en[i]; + } + + return 0; +} + +int fpioa_get_io(int number, fpioa_io_config_t *cfg) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || cfg == NULL) + return -1; + /* Atomic read register */ + *cfg = fpioa->io[number]; + return 0; +} + +int fpioa_set_io(int number, fpioa_io_config_t *cfg) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || cfg == NULL) + return -1; + /* Atomic write register */ + fpioa->io[number] = *cfg; + return 0; +} + +int fpioa_set_io_pull(int number, fpioa_pull_t pull) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || pull >= FPIOA_PULL_MAX) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + + switch(pull) + { + case FPIOA_PULL_NONE: + cfg.pu = 0; + cfg.pd = 0; + break; + case FPIOA_PULL_DOWN: + cfg.pu = 0; + cfg.pd = 1; + break; + case FPIOA_PULL_UP: + cfg.pu = 1; + cfg.pd = 0; + break; + default: + break; + } + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_get_io_pull(int number) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + fpioa_pull_t pull; + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + + if(cfg.pu == 0 && cfg.pd == 1) + pull = FPIOA_PULL_DOWN; + else if(cfg.pu == 1 && cfg.pd == 0) + pull = FPIOA_PULL_UP; + else + pull = FPIOA_PULL_NONE; + return pull; +} + +int fpioa_set_io_driving(int number, fpioa_driving_t driving) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || driving >= FPIOA_DRIVING_MAX) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO driving */ + cfg.ds = driving; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_sl(int number, uint8_t sl_enable) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO slew rate */ + cfg.sl = sl_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_st(int number, uint8_t st_enable) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO schmitt trigger */ + cfg.st = st_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_oe_inv(int number, uint8_t inv_enable) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO schmitt trigger */ + cfg.oe_inv = inv_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_get_io_driving(int number) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + return fpioa->io[number].ds; +} + +int fpioa_set_function_raw(int number, fpioa_function_t function) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || function < 0 || function >= FUNC_MAX) + return -1; + /* Atomic write register */ + fpioa->io[number] = (const fpioa_io_config_t){ + .ch_sel = function_config[function].ch_sel, + .ds = function_config[function].ds, + .oe_en = function_config[function].oe_en, + .oe_inv = function_config[function].oe_inv, + .do_sel = function_config[function].do_sel, + .do_inv = function_config[function].do_inv, + .pu = function_config[function].pu, + .pd = function_config[function].pd, + .sl = function_config[function].sl, + .ie_en = function_config[function].ie_en, + .ie_inv = function_config[function].ie_inv, + .di_inv = function_config[function].di_inv, + .st = function_config[function].st, + /* resv and pad_di do not need initialization */ + }; + return 0; +} + +int fpioa_set_function(int number, fpioa_function_t function) +{ + uint8_t index = 0; + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || function < 0 || function >= FUNC_MAX) + return -1; + if(function == FUNC_RESV0) + { + fpioa_set_function_raw(number, FUNC_RESV0); + return 0; + } + /* Compare all IO */ + for(index = 0; index < FPIOA_NUM_IO; index++) + { + if((fpioa->io[index].ch_sel == function) && (index != number)) + fpioa_set_function_raw(index, FUNC_RESV0); + } + fpioa_set_function_raw(number, function); + return 0; +} + +int fpioa_set_tie_enable(fpioa_function_t function, int enable) +{ + /* Check parameters */ + if(function < 0 || function >= FUNC_MAX) + return -1; + /* Set tie enable */ + if(enable) + fpioa->tie.en[function / 32] |= (1UL << (function % 32)); + else + fpioa->tie.en[function / 32] &= (~(1UL << (function % 32))); + return 0; +} + +int fpioa_set_tie_value(fpioa_function_t function, int value) +{ + /* Check parameters */ + if(function < 0 || function >= FUNC_MAX) + return -1; + /* Set tie value */ + if(value) + fpioa->tie.val[function / 32] |= (1UL << (function % 32)); + else + fpioa->tie.val[function / 32] &= (~(1UL << (function % 32))); + return 0; +} + +int fpioa_get_io_by_function(fpioa_function_t function) +{ + int index = 0; + for(index = 0; index < FPIOA_NUM_IO; index++) + { + if(fpioa->io[index].ch_sel == function) + return index; + } + + return -1; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h new file mode 100644 index 000000000..5b465556e --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h @@ -0,0 +1,756 @@ +/**************************************************************************** + * arch/risc-v/src/k210/fpioa.h + * + * 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. + * + ****************************************************************************/ + +/** +* @file fpioa.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + +#ifndef _DRIVER_FPIOA_H +#define _DRIVER_FPIOA_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FPIOA_NUM_IO (48) + +typedef enum _fpioa_function +{ + FUNC_JTAG_TCLK = 0, /*!< JTAG Test Clock */ + FUNC_JTAG_TDI = 1, /*!< JTAG Test Data In */ + FUNC_JTAG_TMS = 2, /*!< JTAG Test Mode Select */ + FUNC_JTAG_TDO = 3, /*!< JTAG Test Data Out */ + FUNC_SPI0_D0 = 4, /*!< SPI0 Data 0 */ + FUNC_SPI0_D1 = 5, /*!< SPI0 Data 1 */ + FUNC_SPI0_D2 = 6, /*!< SPI0 Data 2 */ + FUNC_SPI0_D3 = 7, /*!< SPI0 Data 3 */ + FUNC_SPI0_D4 = 8, /*!< SPI0 Data 4 */ + FUNC_SPI0_D5 = 9, /*!< SPI0 Data 5 */ + FUNC_SPI0_D6 = 10, /*!< SPI0 Data 6 */ + FUNC_SPI0_D7 = 11, /*!< SPI0 Data 7 */ + FUNC_SPI0_SS0 = 12, /*!< SPI0 Chip Select 0 */ + FUNC_SPI0_SS1 = 13, /*!< SPI0 Chip Select 1 */ + FUNC_SPI0_SS2 = 14, /*!< SPI0 Chip Select 2 */ + FUNC_SPI0_SS3 = 15, /*!< SPI0 Chip Select 3 */ + FUNC_SPI0_ARB = 16, /*!< SPI0 Arbitration */ + FUNC_SPI0_SCLK = 17, /*!< SPI0 Serial Clock */ + FUNC_UARTHS_RX = 18, /*!< UART High speed Receiver */ + FUNC_UARTHS_TX = 19, /*!< UART High speed Transmitter */ + FUNC_RESV6 = 20, /*!< Reserved function */ + FUNC_RESV7 = 21, /*!< Reserved function */ + FUNC_CLK_SPI1 = 22, /*!< Clock SPI1 */ + FUNC_CLK_I2C1 = 23, /*!< Clock I2C1 */ + FUNC_GPIOHS0 = 24, /*!< GPIO High speed 0 */ + FUNC_GPIOHS1 = 25, /*!< GPIO High speed 1 */ + FUNC_GPIOHS2 = 26, /*!< GPIO High speed 2 */ + FUNC_GPIOHS3 = 27, /*!< GPIO High speed 3 */ + FUNC_GPIOHS4 = 28, /*!< GPIO High speed 4 */ + FUNC_GPIOHS5 = 29, /*!< GPIO High speed 5 */ + FUNC_GPIOHS6 = 30, /*!< GPIO High speed 6 */ + FUNC_GPIOHS7 = 31, /*!< GPIO High speed 7 */ + FUNC_GPIOHS8 = 32, /*!< GPIO High speed 8 */ + FUNC_GPIOHS9 = 33, /*!< GPIO High speed 9 */ + FUNC_GPIOHS10 = 34, /*!< GPIO High speed 10 */ + FUNC_GPIOHS11 = 35, /*!< GPIO High speed 11 */ + FUNC_GPIOHS12 = 36, /*!< GPIO High speed 12 */ + FUNC_GPIOHS13 = 37, /*!< GPIO High speed 13 */ + FUNC_GPIOHS14 = 38, /*!< GPIO High speed 14 */ + FUNC_GPIOHS15 = 39, /*!< GPIO High speed 15 */ + FUNC_GPIOHS16 = 40, /*!< GPIO High speed 16 */ + FUNC_GPIOHS17 = 41, /*!< GPIO High speed 17 */ + FUNC_GPIOHS18 = 42, /*!< GPIO High speed 18 */ + FUNC_GPIOHS19 = 43, /*!< GPIO High speed 19 */ + FUNC_GPIOHS20 = 44, /*!< GPIO High speed 20 */ + FUNC_GPIOHS21 = 45, /*!< GPIO High speed 21 */ + FUNC_GPIOHS22 = 46, /*!< GPIO High speed 22 */ + FUNC_GPIOHS23 = 47, /*!< GPIO High speed 23 */ + FUNC_GPIOHS24 = 48, /*!< GPIO High speed 24 */ + FUNC_GPIOHS25 = 49, /*!< GPIO High speed 25 */ + FUNC_GPIOHS26 = 50, /*!< GPIO High speed 26 */ + FUNC_GPIOHS27 = 51, /*!< GPIO High speed 27 */ + FUNC_GPIOHS28 = 52, /*!< GPIO High speed 28 */ + FUNC_GPIOHS29 = 53, /*!< GPIO High speed 29 */ + FUNC_GPIOHS30 = 54, /*!< GPIO High speed 30 */ + FUNC_GPIOHS31 = 55, /*!< GPIO High speed 31 */ + FUNC_GPIO0 = 56, /*!< GPIO pin 0 */ + FUNC_GPIO1 = 57, /*!< GPIO pin 1 */ + FUNC_GPIO2 = 58, /*!< GPIO pin 2 */ + FUNC_GPIO3 = 59, /*!< GPIO pin 3 */ + FUNC_GPIO4 = 60, /*!< GPIO pin 4 */ + FUNC_GPIO5 = 61, /*!< GPIO pin 5 */ + FUNC_GPIO6 = 62, /*!< GPIO pin 6 */ + FUNC_GPIO7 = 63, /*!< GPIO pin 7 */ + FUNC_UART1_RX = 64, /*!< UART1 Receiver */ + FUNC_UART1_TX = 65, /*!< UART1 Transmitter */ + FUNC_UART2_RX = 66, /*!< UART2 Receiver */ + FUNC_UART2_TX = 67, /*!< UART2 Transmitter */ + FUNC_UART3_RX = 68, /*!< UART3 Receiver */ + FUNC_UART3_TX = 69, /*!< UART3 Transmitter */ + FUNC_SPI1_D0 = 70, /*!< SPI1 Data 0 */ + FUNC_SPI1_D1 = 71, /*!< SPI1 Data 1 */ + FUNC_SPI1_D2 = 72, /*!< SPI1 Data 2 */ + FUNC_SPI1_D3 = 73, /*!< SPI1 Data 3 */ + FUNC_SPI1_D4 = 74, /*!< SPI1 Data 4 */ + FUNC_SPI1_D5 = 75, /*!< SPI1 Data 5 */ + FUNC_SPI1_D6 = 76, /*!< SPI1 Data 6 */ + FUNC_SPI1_D7 = 77, /*!< SPI1 Data 7 */ + FUNC_SPI1_SS0 = 78, /*!< SPI1 Chip Select 0 */ + FUNC_SPI1_SS1 = 79, /*!< SPI1 Chip Select 1 */ + FUNC_SPI1_SS2 = 80, /*!< SPI1 Chip Select 2 */ + FUNC_SPI1_SS3 = 81, /*!< SPI1 Chip Select 3 */ + FUNC_SPI1_ARB = 82, /*!< SPI1 Arbitration */ + FUNC_SPI1_SCLK = 83, /*!< SPI1 Serial Clock */ + FUNC_SPI_SLAVE_D0 = 84, /*!< SPI Slave Data 0 */ + FUNC_SPI_SLAVE_SS = 85, /*!< SPI Slave Select */ + FUNC_SPI_SLAVE_SCLK = 86, /*!< SPI Slave Serial Clock */ + FUNC_I2S0_MCLK = 87, /*!< I2S0 Master Clock */ + FUNC_I2S0_SCLK = 88, /*!< I2S0 Serial Clock(BCLK) */ + FUNC_I2S0_WS = 89, /*!< I2S0 Word Select(LRCLK) */ + FUNC_I2S0_IN_D0 = 90, /*!< I2S0 Serial Data Input 0 */ + FUNC_I2S0_IN_D1 = 91, /*!< I2S0 Serial Data Input 1 */ + FUNC_I2S0_IN_D2 = 92, /*!< I2S0 Serial Data Input 2 */ + FUNC_I2S0_IN_D3 = 93, /*!< I2S0 Serial Data Input 3 */ + FUNC_I2S0_OUT_D0 = 94, /*!< I2S0 Serial Data Output 0 */ + FUNC_I2S0_OUT_D1 = 95, /*!< I2S0 Serial Data Output 1 */ + FUNC_I2S0_OUT_D2 = 96, /*!< I2S0 Serial Data Output 2 */ + FUNC_I2S0_OUT_D3 = 97, /*!< I2S0 Serial Data Output 3 */ + FUNC_I2S1_MCLK = 98, /*!< I2S1 Master Clock */ + FUNC_I2S1_SCLK = 99, /*!< I2S1 Serial Clock(BCLK) */ + FUNC_I2S1_WS = 100, /*!< I2S1 Word Select(LRCLK) */ + FUNC_I2S1_IN_D0 = 101, /*!< I2S1 Serial Data Input 0 */ + FUNC_I2S1_IN_D1 = 102, /*!< I2S1 Serial Data Input 1 */ + FUNC_I2S1_IN_D2 = 103, /*!< I2S1 Serial Data Input 2 */ + FUNC_I2S1_IN_D3 = 104, /*!< I2S1 Serial Data Input 3 */ + FUNC_I2S1_OUT_D0 = 105, /*!< I2S1 Serial Data Output 0 */ + FUNC_I2S1_OUT_D1 = 106, /*!< I2S1 Serial Data Output 1 */ + FUNC_I2S1_OUT_D2 = 107, /*!< I2S1 Serial Data Output 2 */ + FUNC_I2S1_OUT_D3 = 108, /*!< I2S1 Serial Data Output 3 */ + FUNC_I2S2_MCLK = 109, /*!< I2S2 Master Clock */ + FUNC_I2S2_SCLK = 110, /*!< I2S2 Serial Clock(BCLK) */ + FUNC_I2S2_WS = 111, /*!< I2S2 Word Select(LRCLK) */ + FUNC_I2S2_IN_D0 = 112, /*!< I2S2 Serial Data Input 0 */ + FUNC_I2S2_IN_D1 = 113, /*!< I2S2 Serial Data Input 1 */ + FUNC_I2S2_IN_D2 = 114, /*!< I2S2 Serial Data Input 2 */ + FUNC_I2S2_IN_D3 = 115, /*!< I2S2 Serial Data Input 3 */ + FUNC_I2S2_OUT_D0 = 116, /*!< I2S2 Serial Data Output 0 */ + FUNC_I2S2_OUT_D1 = 117, /*!< I2S2 Serial Data Output 1 */ + FUNC_I2S2_OUT_D2 = 118, /*!< I2S2 Serial Data Output 2 */ + FUNC_I2S2_OUT_D3 = 119, /*!< I2S2 Serial Data Output 3 */ + FUNC_RESV0 = 120, /*!< Reserved function */ + FUNC_RESV1 = 121, /*!< Reserved function */ + FUNC_RESV2 = 122, /*!< Reserved function */ + FUNC_RESV3 = 123, /*!< Reserved function */ + FUNC_RESV4 = 124, /*!< Reserved function */ + FUNC_RESV5 = 125, /*!< Reserved function */ + FUNC_I2C0_SCLK = 126, /*!< I2C0 Serial Clock */ + FUNC_I2C0_SDA = 127, /*!< I2C0 Serial Data */ + FUNC_I2C1_SCLK = 128, /*!< I2C1 Serial Clock */ + FUNC_I2C1_SDA = 129, /*!< I2C1 Serial Data */ + FUNC_I2C2_SCLK = 130, /*!< I2C2 Serial Clock */ + FUNC_I2C2_SDA = 131, /*!< I2C2 Serial Data */ + FUNC_CMOS_XCLK = 132, /*!< DVP System Clock */ + FUNC_CMOS_RST = 133, /*!< DVP System Reset */ + FUNC_CMOS_PWDN = 134, /*!< DVP Power Down Mode */ + FUNC_CMOS_VSYNC = 135, /*!< DVP Vertical Sync */ + FUNC_CMOS_HREF = 136, /*!< DVP Horizontal Reference output */ + FUNC_CMOS_PCLK = 137, /*!< Pixel Clock */ + FUNC_CMOS_D0 = 138, /*!< Data Bit 0 */ + FUNC_CMOS_D1 = 139, /*!< Data Bit 1 */ + FUNC_CMOS_D2 = 140, /*!< Data Bit 2 */ + FUNC_CMOS_D3 = 141, /*!< Data Bit 3 */ + FUNC_CMOS_D4 = 142, /*!< Data Bit 4 */ + FUNC_CMOS_D5 = 143, /*!< Data Bit 5 */ + FUNC_CMOS_D6 = 144, /*!< Data Bit 6 */ + FUNC_CMOS_D7 = 145, /*!< Data Bit 7 */ + FUNC_SCCB_SCLK = 146, /*!< SCCB Serial Clock */ + FUNC_SCCB_SDA = 147, /*!< SCCB Serial Data */ + FUNC_UART1_CTS = 148, /*!< UART1 Clear To Send */ + FUNC_UART1_DSR = 149, /*!< UART1 Data Set Ready */ + FUNC_UART1_DCD = 150, /*!< UART1 Data Carrier Detect */ + FUNC_UART1_RI = 151, /*!< UART1 Ring Indicator */ + FUNC_UART1_SIR_IN = 152, /*!< UART1 Serial Infrared Input */ + FUNC_UART1_DTR = 153, /*!< UART1 Data Terminal Ready */ + FUNC_UART1_RTS = 154, /*!< UART1 Request To Send */ + FUNC_UART1_OUT2 = 155, /*!< UART1 User-designated Output 2 */ + FUNC_UART1_OUT1 = 156, /*!< UART1 User-designated Output 1 */ + FUNC_UART1_SIR_OUT = 157, /*!< UART1 Serial Infrared Output */ + FUNC_UART1_BAUD = 158, /*!< UART1 Transmit Clock Output */ + FUNC_UART1_RE = 159, /*!< UART1 Receiver Output Enable */ + FUNC_UART1_DE = 160, /*!< UART1 Driver Output Enable */ + FUNC_UART1_RS485_EN = 161, /*!< UART1 RS485 Enable */ + FUNC_UART2_CTS = 162, /*!< UART2 Clear To Send */ + FUNC_UART2_DSR = 163, /*!< UART2 Data Set Ready */ + FUNC_UART2_DCD = 164, /*!< UART2 Data Carrier Detect */ + FUNC_UART2_RI = 165, /*!< UART2 Ring Indicator */ + FUNC_UART2_SIR_IN = 166, /*!< UART2 Serial Infrared Input */ + FUNC_UART2_DTR = 167, /*!< UART2 Data Terminal Ready */ + FUNC_UART2_RTS = 168, /*!< UART2 Request To Send */ + FUNC_UART2_OUT2 = 169, /*!< UART2 User-designated Output 2 */ + FUNC_UART2_OUT1 = 170, /*!< UART2 User-designated Output 1 */ + FUNC_UART2_SIR_OUT = 171, /*!< UART2 Serial Infrared Output */ + FUNC_UART2_BAUD = 172, /*!< UART2 Transmit Clock Output */ + FUNC_UART2_RE = 173, /*!< UART2 Receiver Output Enable */ + FUNC_UART2_DE = 174, /*!< UART2 Driver Output Enable */ + FUNC_UART2_RS485_EN = 175, /*!< UART2 RS485 Enable */ + FUNC_UART3_CTS = 176, /*!< UART3 Clear To Send */ + FUNC_UART3_DSR = 177, /*!< UART3 Data Set Ready */ + FUNC_UART3_DCD = 178, /*!< UART3 Data Carrier Detect */ + FUNC_UART3_RI = 179, /*!< UART3 Ring Indicator */ + FUNC_UART3_SIR_IN = 180, /*!< UART3 Serial Infrared Input */ + FUNC_UART3_DTR = 181, /*!< UART3 Data Terminal Ready */ + FUNC_UART3_RTS = 182, /*!< UART3 Request To Send */ + FUNC_UART3_OUT2 = 183, /*!< UART3 User-designated Output 2 */ + FUNC_UART3_OUT1 = 184, /*!< UART3 User-designated Output 1 */ + FUNC_UART3_SIR_OUT = 185, /*!< UART3 Serial Infrared Output */ + FUNC_UART3_BAUD = 186, /*!< UART3 Transmit Clock Output */ + FUNC_UART3_RE = 187, /*!< UART3 Receiver Output Enable */ + FUNC_UART3_DE = 188, /*!< UART3 Driver Output Enable */ + FUNC_UART3_RS485_EN = 189, /*!< UART3 RS485 Enable */ + FUNC_TIMER0_TOGGLE1 = 190, /*!< TIMER0 Toggle Output 1 */ + FUNC_TIMER0_TOGGLE2 = 191, /*!< TIMER0 Toggle Output 2 */ + FUNC_TIMER0_TOGGLE3 = 192, /*!< TIMER0 Toggle Output 3 */ + FUNC_TIMER0_TOGGLE4 = 193, /*!< TIMER0 Toggle Output 4 */ + FUNC_TIMER1_TOGGLE1 = 194, /*!< TIMER1 Toggle Output 1 */ + FUNC_TIMER1_TOGGLE2 = 195, /*!< TIMER1 Toggle Output 2 */ + FUNC_TIMER1_TOGGLE3 = 196, /*!< TIMER1 Toggle Output 3 */ + FUNC_TIMER1_TOGGLE4 = 197, /*!< TIMER1 Toggle Output 4 */ + FUNC_TIMER2_TOGGLE1 = 198, /*!< TIMER2 Toggle Output 1 */ + FUNC_TIMER2_TOGGLE2 = 199, /*!< TIMER2 Toggle Output 2 */ + FUNC_TIMER2_TOGGLE3 = 200, /*!< TIMER2 Toggle Output 3 */ + FUNC_TIMER2_TOGGLE4 = 201, /*!< TIMER2 Toggle Output 4 */ + FUNC_CLK_SPI2 = 202, /*!< Clock SPI2 */ + FUNC_CLK_I2C2 = 203, /*!< Clock I2C2 */ + FUNC_INTERNAL0 = 204, /*!< Internal function signal 0 */ + FUNC_INTERNAL1 = 205, /*!< Internal function signal 1 */ + FUNC_INTERNAL2 = 206, /*!< Internal function signal 2 */ + FUNC_INTERNAL3 = 207, /*!< Internal function signal 3 */ + FUNC_INTERNAL4 = 208, /*!< Internal function signal 4 */ + FUNC_INTERNAL5 = 209, /*!< Internal function signal 5 */ + FUNC_INTERNAL6 = 210, /*!< Internal function signal 6 */ + FUNC_INTERNAL7 = 211, /*!< Internal function signal 7 */ + FUNC_INTERNAL8 = 212, /*!< Internal function signal 8 */ + FUNC_INTERNAL9 = 213, /*!< Internal function signal 9 */ + FUNC_INTERNAL10 = 214, /*!< Internal function signal 10 */ + FUNC_INTERNAL11 = 215, /*!< Internal function signal 11 */ + FUNC_INTERNAL12 = 216, /*!< Internal function signal 12 */ + FUNC_INTERNAL13 = 217, /*!< Internal function signal 13 */ + FUNC_INTERNAL14 = 218, /*!< Internal function signal 14 */ + FUNC_INTERNAL15 = 219, /*!< Internal function signal 15 */ + FUNC_INTERNAL16 = 220, /*!< Internal function signal 16 */ + FUNC_INTERNAL17 = 221, /*!< Internal function signal 17 */ + FUNC_CONSTANT = 222, /*!< Constant function */ + FUNC_INTERNAL18 = 223, /*!< Internal function signal 18 */ + FUNC_DEBUG0 = 224, /*!< Debug function 0 */ + FUNC_DEBUG1 = 225, /*!< Debug function 1 */ + FUNC_DEBUG2 = 226, /*!< Debug function 2 */ + FUNC_DEBUG3 = 227, /*!< Debug function 3 */ + FUNC_DEBUG4 = 228, /*!< Debug function 4 */ + FUNC_DEBUG5 = 229, /*!< Debug function 5 */ + FUNC_DEBUG6 = 230, /*!< Debug function 6 */ + FUNC_DEBUG7 = 231, /*!< Debug function 7 */ + FUNC_DEBUG8 = 232, /*!< Debug function 8 */ + FUNC_DEBUG9 = 233, /*!< Debug function 9 */ + FUNC_DEBUG10 = 234, /*!< Debug function 10 */ + FUNC_DEBUG11 = 235, /*!< Debug function 11 */ + FUNC_DEBUG12 = 236, /*!< Debug function 12 */ + FUNC_DEBUG13 = 237, /*!< Debug function 13 */ + FUNC_DEBUG14 = 238, /*!< Debug function 14 */ + FUNC_DEBUG15 = 239, /*!< Debug function 15 */ + FUNC_DEBUG16 = 240, /*!< Debug function 16 */ + FUNC_DEBUG17 = 241, /*!< Debug function 17 */ + FUNC_DEBUG18 = 242, /*!< Debug function 18 */ + FUNC_DEBUG19 = 243, /*!< Debug function 19 */ + FUNC_DEBUG20 = 244, /*!< Debug function 20 */ + FUNC_DEBUG21 = 245, /*!< Debug function 21 */ + FUNC_DEBUG22 = 246, /*!< Debug function 22 */ + FUNC_DEBUG23 = 247, /*!< Debug function 23 */ + FUNC_DEBUG24 = 248, /*!< Debug function 24 */ + FUNC_DEBUG25 = 249, /*!< Debug function 25 */ + FUNC_DEBUG26 = 250, /*!< Debug function 26 */ + FUNC_DEBUG27 = 251, /*!< Debug function 27 */ + FUNC_DEBUG28 = 252, /*!< Debug function 28 */ + FUNC_DEBUG29 = 253, /*!< Debug function 29 */ + FUNC_DEBUG30 = 254, /*!< Debug function 30 */ + FUNC_DEBUG31 = 255, /*!< Debug function 31 */ + FUNC_MAX = 256, /*!< Function numbers */ +} fpioa_function_t; +/* clang-format on */ + +/** + * @brief FPIOA pull settings + * + * @note FPIOA pull settings description + * + * | PU | PD | Description | + * |-----|-----|-----------------------------------| + * | 0 | 0 | No Pull | + * | 0 | 1 | Pull Down | + * | 1 | 0 | Pull Up | + * | 1 | 1 | Undefined | + * + */ + +/* clang-format off */ +typedef enum _fpioa_pull +{ + FPIOA_PULL_NONE, /*!< No Pull */ + FPIOA_PULL_DOWN, /*!< Pull Down */ + FPIOA_PULL_UP, /*!< Pull Up */ + FPIOA_PULL_MAX /*!< Count of pull settings */ +} fpioa_pull_t; +/* clang-format on */ + +/** + * @brief FPIOA driving settings + * + * @note FPIOA driving settings description + * There are 16 kinds of driving settings + * + * @note Low Level Output Current + * + * |DS[3:0] |Min(mA)|Typ(mA)|Max(mA)| + * |--------|-------|-------|-------| + * |0000 |3.2 |5.4 |8.3 | + * |0001 |4.7 |8.0 |12.3 | + * |0010 |6.3 |10.7 |16.4 | + * |0011 |7.8 |13.2 |20.2 | + * |0100 |9.4 |15.9 |24.2 | + * |0101 |10.9 |18.4 |28.1 | + * |0110 |12.4 |20.9 |31.8 | + * |0111 |13.9 |23.4 |35.5 | + * + * @note High Level Output Current + * + * |DS[3:0] |Min(mA)|Typ(mA)|Max(mA)| + * |--------|-------|-------|-------| + * |0000 |5.0 |7.6 |11.2 | + * |0001 |7.5 |11.4 |16.8 | + * |0010 |10.0 |15.2 |22.3 | + * |0011 |12.4 |18.9 |27.8 | + * |0100 |14.9 |22.6 |33.3 | + * |0101 |17.4 |26.3 |38.7 | + * |0110 |19.8 |30.0 |44.1 | + * |0111 |22.3 |33.7 |49.5 | + * + */ + +/* clang-format off */ +typedef enum _fpioa_driving +{ + FPIOA_DRIVING_0, /*!< 0000 */ + FPIOA_DRIVING_1, /*!< 0001 */ + FPIOA_DRIVING_2, /*!< 0010 */ + FPIOA_DRIVING_3, /*!< 0011 */ + FPIOA_DRIVING_4, /*!< 0100 */ + FPIOA_DRIVING_5, /*!< 0101 */ + FPIOA_DRIVING_6, /*!< 0110 */ + FPIOA_DRIVING_7, /*!< 0111 */ + FPIOA_DRIVING_8, /*!< 1000 */ + FPIOA_DRIVING_9, /*!< 1001 */ + FPIOA_DRIVING_10, /*!< 1010 */ + FPIOA_DRIVING_11, /*!< 1011 */ + FPIOA_DRIVING_12, /*!< 1100 */ + FPIOA_DRIVING_13, /*!< 1101 */ + FPIOA_DRIVING_14, /*!< 1110 */ + FPIOA_DRIVING_15, /*!< 1111 */ + FPIOA_DRIVING_MAX /*!< Count of driving settings */ +} fpioa_driving_t; +/* clang-format on */ + +/** + * @brief FPIOA IO + * + * FPIOA IO is the specific pin of the chip package. Every IO + * has a 32bit width register that can independently implement + * schmitt trigger, invert input, invert output, strong pull + * up, driving selector, static input and static output. And more, + * it can implement any pin of any peripheral devices. + * + * @note FPIOA IO's register bits Layout + * + * | Bits | Name |Description | + * |-----------|----------|---------------------------------------------------| + * | 31 | PAD_DI | Read current IO's data input. | + * | 30:24 | NA | Reserved bits. | + * | 23 | ST | Schmitt trigger. | + * | 22 | DI_INV | Invert Data input. | + * | 21 | IE_INV | Invert the input enable signal. | + * | 20 | IE_EN | Input enable. It can disable or enable IO input. | + * | 19 | SL | Slew rate control enable. | + * | 18 | SPU | Strong pull up. | + * | 17 | PD | Pull select: 0 for pull down, 1 for pull up. | + * | 16 | PU | Pull enable. | + * | 15 | DO_INV | Invert the result of data output select (DO_SEL). | + * | 14 | DO_SEL | Data output select: 0 for DO, 1 for OE. | + * | 13 | OE_INV | Invert the output enable signal. | + * | 12 | OE_EN | Output enable.It can disable or enable IO output. | + * | 11:8 | DS | Driving selector. | + * | 7:0 | CH_SEL | Channel select from 256 input. | + * + */ +typedef struct _fpioa_io_config +{ + uint32_t ch_sel : 8; + /*!< Channel select from 256 input. */ + uint32_t ds : 4; + /*!< Driving selector. */ + uint32_t oe_en : 1; + /*!< Static output enable, will AND with OE_INV. */ + uint32_t oe_inv : 1; + /*!< Invert output enable. */ + uint32_t do_sel : 1; + /*!< Data output select: 0 for DO, 1 for OE. */ + uint32_t do_inv : 1; + /*!< Invert the result of data output select (DO_SEL). */ + uint32_t pu : 1; + /*!< Pull up enable. 0 for nothing, 1 for pull up. */ + uint32_t pd : 1; + /*!< Pull down enable. 0 for nothing, 1 for pull down. */ + uint32_t resv0 : 1; + /*!< Reserved bits. */ + uint32_t sl : 1; + /*!< Slew rate control enable. */ + uint32_t ie_en : 1; + /*!< Static input enable, will AND with IE_INV. */ + uint32_t ie_inv : 1; + /*!< Invert input enable. */ + uint32_t di_inv : 1; + /*!< Invert Data input. */ + uint32_t st : 1; + /*!< Schmitt trigger. */ + uint32_t resv1 : 7; + /*!< Reserved bits. */ + uint32_t pad_di : 1; + /*!< Read current IO's data input. */ +} __attribute__((packed, aligned(4))) fpioa_io_config_t; + +/** + * @brief FPIOA tie setting + * + * FPIOA Object have 48 IO pin object and 256 bit input tie bits. + * All SPI arbitration signal will tie high by default. + * + * @note FPIOA function tie bits RAM Layout + * + * | Address | Name |Description | + * |-----------|------------------|----------------------------------| + * | 0x000 | TIE_EN[31:0] | Input tie enable bits [31:0] | + * | 0x004 | TIE_EN[63:32] | Input tie enable bits [63:32] | + * | 0x008 | TIE_EN[95:64] | Input tie enable bits [95:64] | + * | 0x00C | TIE_EN[127:96] | Input tie enable bits [127:96] | + * | 0x010 | TIE_EN[159:128] | Input tie enable bits [159:128] | + * | 0x014 | TIE_EN[191:160] | Input tie enable bits [191:160] | + * | 0x018 | TIE_EN[223:192] | Input tie enable bits [223:192] | + * | 0x01C | TIE_EN[255:224] | Input tie enable bits [255:224] | + * | 0x020 | TIE_VAL[31:0] | Input tie value bits [31:0] | + * | 0x024 | TIE_VAL[63:32] | Input tie value bits [63:32] | + * | 0x028 | TIE_VAL[95:64] | Input tie value bits [95:64] | + * | 0x02C | TIE_VAL[127:96] | Input tie value bits [127:96] | + * | 0x030 | TIE_VAL[159:128] | Input tie value bits [159:128] | + * | 0x034 | TIE_VAL[191:160] | Input tie value bits [191:160] | + * | 0x038 | TIE_VAL[223:192] | Input tie value bits [223:192] | + * | 0x03C | TIE_VAL[255:224] | Input tie value bits [255:224] | + * + * @note Function which input tie high by default + * + * | Name |Description | + * |---------------|---------------------------------------| + * | SPI0_ARB | Arbitration function of SPI master 0 | + * | SPI1_ARB | Arbitration function of SPI master 1 | + * + * Tie high means the SPI Arbitration input is 1 + * + */ +typedef struct _fpioa_tie +{ + uint32_t en[FUNC_MAX / 32]; + /*!< FPIOA GPIO multiplexer tie enable array */ + uint32_t val[FUNC_MAX / 32]; + /*!< FPIOA GPIO multiplexer tie value array */ +} __attribute__((packed, aligned(4))) fpioa_tie_t; + +/** + * @brief FPIOA Object + * + * FPIOA Object have 48 IO pin object and 256 bit input tie bits. + * All SPI arbitration signal will tie high by default. + * + * @note FPIOA IO Pin RAM Layout + * + * | Address | Name |Description | + * |-----------|----------|--------------------------------| + * | 0x000 | PAD0 | FPIOA GPIO multiplexer io 0 | + * | 0x004 | PAD1 | FPIOA GPIO multiplexer io 1 | + * | 0x008 | PAD2 | FPIOA GPIO multiplexer io 2 | + * | 0x00C | PAD3 | FPIOA GPIO multiplexer io 3 | + * | 0x010 | PAD4 | FPIOA GPIO multiplexer io 4 | + * | 0x014 | PAD5 | FPIOA GPIO multiplexer io 5 | + * | 0x018 | PAD6 | FPIOA GPIO multiplexer io 6 | + * | 0x01C | PAD7 | FPIOA GPIO multiplexer io 7 | + * | 0x020 | PAD8 | FPIOA GPIO multiplexer io 8 | + * | 0x024 | PAD9 | FPIOA GPIO multiplexer io 9 | + * | 0x028 | PAD10 | FPIOA GPIO multiplexer io 10 | + * | 0x02C | PAD11 | FPIOA GPIO multiplexer io 11 | + * | 0x030 | PAD12 | FPIOA GPIO multiplexer io 12 | + * | 0x034 | PAD13 | FPIOA GPIO multiplexer io 13 | + * | 0x038 | PAD14 | FPIOA GPIO multiplexer io 14 | + * | 0x03C | PAD15 | FPIOA GPIO multiplexer io 15 | + * | 0x040 | PAD16 | FPIOA GPIO multiplexer io 16 | + * | 0x044 | PAD17 | FPIOA GPIO multiplexer io 17 | + * | 0x048 | PAD18 | FPIOA GPIO multiplexer io 18 | + * | 0x04C | PAD19 | FPIOA GPIO multiplexer io 19 | + * | 0x050 | PAD20 | FPIOA GPIO multiplexer io 20 | + * | 0x054 | PAD21 | FPIOA GPIO multiplexer io 21 | + * | 0x058 | PAD22 | FPIOA GPIO multiplexer io 22 | + * | 0x05C | PAD23 | FPIOA GPIO multiplexer io 23 | + * | 0x060 | PAD24 | FPIOA GPIO multiplexer io 24 | + * | 0x064 | PAD25 | FPIOA GPIO multiplexer io 25 | + * | 0x068 | PAD26 | FPIOA GPIO multiplexer io 26 | + * | 0x06C | PAD27 | FPIOA GPIO multiplexer io 27 | + * | 0x070 | PAD28 | FPIOA GPIO multiplexer io 28 | + * | 0x074 | PAD29 | FPIOA GPIO multiplexer io 29 | + * | 0x078 | PAD30 | FPIOA GPIO multiplexer io 30 | + * | 0x07C | PAD31 | FPIOA GPIO multiplexer io 31 | + * | 0x080 | PAD32 | FPIOA GPIO multiplexer io 32 | + * | 0x084 | PAD33 | FPIOA GPIO multiplexer io 33 | + * | 0x088 | PAD34 | FPIOA GPIO multiplexer io 34 | + * | 0x08C | PAD35 | FPIOA GPIO multiplexer io 35 | + * | 0x090 | PAD36 | FPIOA GPIO multiplexer io 36 | + * | 0x094 | PAD37 | FPIOA GPIO multiplexer io 37 | + * | 0x098 | PAD38 | FPIOA GPIO multiplexer io 38 | + * | 0x09C | PAD39 | FPIOA GPIO multiplexer io 39 | + * | 0x0A0 | PAD40 | FPIOA GPIO multiplexer io 40 | + * | 0x0A4 | PAD41 | FPIOA GPIO multiplexer io 41 | + * | 0x0A8 | PAD42 | FPIOA GPIO multiplexer io 42 | + * | 0x0AC | PAD43 | FPIOA GPIO multiplexer io 43 | + * | 0x0B0 | PAD44 | FPIOA GPIO multiplexer io 44 | + * | 0x0B4 | PAD45 | FPIOA GPIO multiplexer io 45 | + * | 0x0B8 | PAD46 | FPIOA GPIO multiplexer io 46 | + * | 0x0BC | PAD47 | FPIOA GPIO multiplexer io 47 | + * + */ +typedef struct _fpioa +{ + fpioa_io_config_t io[FPIOA_NUM_IO]; + /*!< FPIOA GPIO multiplexer io array */ + fpioa_tie_t tie; + /*!< FPIOA GPIO multiplexer tie */ +} __attribute__((packed, aligned(4))) fpioa_t; + +/** + * @brief FPIOA object instanse + */ +extern volatile fpioa_t *const fpioa; + +/** + * @brief Initialize FPIOA user custom default settings + * + * @note This function will set all FPIOA pad registers to user-defined + * values from kconfig + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_init(void); + +/** + * @brief Get IO configuration + * + * @param[in] number The IO number + * @param cfg Pointer to struct of IO configuration for specified IO + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_get_io(int number, fpioa_io_config_t *cfg); + +/** + * @brief Set IO configuration + * + * @param[in] number The IO number + * @param[in] cfg Pointer to struct of IO configuration for specified IO + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io(int number, fpioa_io_config_t *cfg); + +/** + * @brief Set IO configuration with function number + * + * @note The default IO configuration which bind to function number will + * set automatically + * + * @param[in] number The IO number + * @param[in] function The function enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_function_raw(int number, fpioa_function_t function); + +/** + * @brief Set only IO configuration with function number + * + * @note The default IO configuration which bind to function number will + * set automatically + * + * @param[in] number The IO number + * @param[in] function The function enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_function(int number, fpioa_function_t function); + +/** + * @brief Set tie enable to function + * + * @param[in] function The function enum number + * @param[in] enable Tie enable to set, 1 is enable, 0 is disable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_tie_enable(fpioa_function_t function, int enable); + +/** + * @brief Set tie value to function + * + * @param[in] function The function enum number + * @param[in] value Tie value to set, 1 is HIGH, 0 is LOW + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_tie_value(fpioa_function_t function, int value); + +/** + * @brief Set IO pull function + * + * @param[in] number The IO number + * @param[in] pull The pull enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io_pull(int number, fpioa_pull_t pull); + +/** + * @brief Get IO pull function + * + * @param[in] number The IO number + * + * @return result + * - -1 Fail + * - Other The pull enum number + */ +int fpioa_get_io_pull(int number); + +/** + * @brief Set IO driving + * + * @param[in] number The IO number + * @param[in] driving The driving enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io_driving(int number, fpioa_driving_t driving); + +/** + * @brief Get IO driving + * + * @param[in] number The IO number + * + * @return result + * - -1 Fail + * - Other The driving enum number + */ +int fpioa_get_io_driving(int number); + +/** + * @brief Get IO by function + * + * @param[in] function The function enum number + * + * @return result + * - -1 Fail + * - Other The IO number + */ +int fpioa_get_io_by_function(fpioa_function_t function); + +/** + * @brief Set IO slew rate control + * + * @param[in] number The IO number + * @param[in] sl_value Enable slew rate. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_sl(int number, uint8_t sl_enable); + +/** + * @brief Set IO schmitt trigger + * + * @param[in] number The IO number + * @param[in] st_enable Enable schmitt trigger. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_st(int number, uint8_t st_enable); + +/** + * @brief Set IO output invert enable + * + * @param[in] number The IO number + * @param[in] inv_enable Enable output invert. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_oe_inv(int number, uint8_t inv_enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRIVER_FPIOA_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c index 616348bf6..cf900b832 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c @@ -18,6 +18,15 @@ * ****************************************************************************/ +/** +* @file k210_clockconfig.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + /**************************************************************************** * Included Files ****************************************************************************/ @@ -128,8 +137,6 @@ void k210_clockconfig(void) { /* PLL0 selected */ g_cpu_clock = k210_get_pll0clk() / 2; - - syslog(LOG_NOTICE, "g_cpu clock = %d sel %#x\r\n", g_cpu_clock, clksel0); } else { @@ -142,12 +149,18 @@ void k210_clockconfig(void) void k210_sysctl_init(void) { -// sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); -// sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL); -// sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL); + sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); + sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL); + sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_APB1, 2); -// 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); + + // for IO-27/28 + sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33); + // for IO-20~23 + sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c index 267011ec3..0adcee8db 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c @@ -47,55 +47,21 @@ int k210_fpioa_get_io_by_function(uint8_t function) { int index = 0; uint32_t RegValue = 0x0000; - uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; + uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE; for (index = 0; index < K210_IO_NUMBER; index++) { - RegValue = getreg32(&fpioa[index]); + RegValue = getreg32(&fpioa_base[index]); if ((RegValue & 0xFF) == function) return index; } return -1; } -int fpioa_set_io_pull(int number, fpioa_pull_t pull) -{ - /* Check parameters */ - if (number < 0 || number >= K210_IO_NUMBER || pull >= FPIOA_PULL_MAX) - return -1; - - /* read register */ - uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; - fpioa_io_config_t cfg = *(fpioa_io_config_t *)(&fpioa[number]); - uint32_t ioflags = 0x0000; - - switch (pull) - { - case FPIOA_PULL_NONE: - cfg.pu = 0; - cfg.pd = 0; - break; - case FPIOA_PULL_DOWN: - cfg.pu = 0; - cfg.pd = 1; - break; - case FPIOA_PULL_UP: - cfg.pu = 1; - cfg.pd = 0; - break; - default: - break; - } - - /* write register */ - ioflags = *(uint32_t*)(&cfg); - putreg32(ioflags, &fpioa[number]); - return 0; -} void k210_fpioa_config(uint32_t io, uint32_t ioflags) { - uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; + uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE; DEBUGASSERT(io < K210_IO_NUMBER); - putreg32(ioflags, &fpioa[io]); + putreg32(ioflags, &fpioa_base[io]); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h index cc122c3b8..6c4a472ea 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h @@ -22,7 +22,7 @@ * @file k210_fpioa.h * @brief nuttx source code * https://github.com/apache/incubator-nuttx.git -* @version 10.3.0 +* @version 10.3.0 * @author AIIT XUOS Lab * @date 2022-03-23 */ @@ -35,6 +35,7 @@ ****************************************************************************/ #include +#include "fpioa.h" /**************************************************************************** * Pre-processor Definitions @@ -44,48 +45,263 @@ #define K210_GPIOHS_MAX_PINNO 32 #define K210_GPIO_MAX_PINNO 8 -#define K210_IO_FUNC_UARTHS_RX 18 /* UART High speed Receiver */ -#define K210_IO_FUNC_UARTHS_TX 19 /* UART High speed Transmitter */ -#define K210_IO_FUNC_GPIOHS0 24 /* GPIO High speed 0 */ -#define K210_IO_FUNC_GPIOHS1 25 /* GPIO High speed 1 */ -#define K210_IO_FUNC_GPIOHS2 26 /* GPIO High speed 2 */ -#define K210_IO_FUNC_GPIOHS3 27 /* GPIO High speed 3 */ -#define K210_IO_FUNC_GPIOHS4 28 /* GPIO High speed 4 */ -#define K210_IO_FUNC_GPIOHS5 29 /* GPIO High speed 5 */ -#define K210_IO_FUNC_GPIOHS6 30 /* GPIO High speed 6 */ -#define K210_IO_FUNC_GPIOHS7 31 /* GPIO High speed 7 */ -#define K210_IO_FUNC_GPIOHS8 32 /* GPIO High speed 8 */ -#define K210_IO_FUNC_GPIOHS9 33 /* GPIO High speed 9 */ -#define K210_IO_FUNC_GPIOHS10 34 /* GPIO High speed 10 */ -#define K210_IO_FUNC_GPIOHS11 35 /* GPIO High speed 11 */ -#define K210_IO_FUNC_GPIOHS12 36 /* GPIO High speed 12 */ -#define K210_IO_FUNC_GPIOHS13 37 /* GPIO High speed 13 */ -#define K210_IO_FUNC_GPIOHS14 38 /* GPIO High speed 14 */ -#define K210_IO_FUNC_GPIOHS15 39 /* GPIO High speed 15 */ -#define K210_IO_FUNC_GPIOHS16 40 /* GPIO High speed 16 */ -#define K210_IO_FUNC_GPIOHS17 41 /* GPIO High speed 17 */ -#define K210_IO_FUNC_GPIOHS18 42 /* GPIO High speed 18 */ -#define K210_IO_FUNC_GPIOHS19 43 /* GPIO High speed 19 */ -#define K210_IO_FUNC_GPIOHS20 44 /* GPIO High speed 20 */ -#define K210_IO_FUNC_GPIOHS21 45 /* GPIO High speed 21 */ -#define K210_IO_FUNC_GPIOHS22 46 /* GPIO High speed 22 */ -#define K210_IO_FUNC_GPIOHS23 47 /* GPIO High speed 23 */ -#define K210_IO_FUNC_GPIOHS24 48 /* GPIO High speed 24 */ -#define K210_IO_FUNC_GPIOHS25 49 /* GPIO High speed 25 */ -#define K210_IO_FUNC_GPIOHS26 50 /* GPIO High speed 26 */ -#define K210_IO_FUNC_GPIOHS27 51 /* GPIO High speed 27 */ -#define K210_IO_FUNC_GPIOHS28 52 /* GPIO High speed 28 */ -#define K210_IO_FUNC_GPIOHS29 53 /* GPIO High speed 29 */ -#define K210_IO_FUNC_GPIOHS30 54 /* GPIO High speed 30 */ -#define K210_IO_FUNC_GPIOHS31 55 /* GPIO High speed 31 */ -#define K210_IO_FUNC_GPIO0 56 /* GPIO pin 0 */ -#define K210_IO_FUNC_GPIO1 57 /* GPIO pin 1 */ -#define K210_IO_FUNC_GPIO2 58 /* GPIO pin 2 */ -#define K210_IO_FUNC_GPIO3 59 /* GPIO pin 3 */ -#define K210_IO_FUNC_GPIO4 60 /* GPIO pin 4 */ -#define K210_IO_FUNC_GPIO5 61 /* GPIO pin 5 */ -#define K210_IO_FUNC_GPIO6 62 /* GPIO pin 6 */ -#define K210_IO_FUNC_GPIO7 63 /* GPIO pin 7 */ +#define K210_IO_FUNC_JTAG_TCLK 0 /* JTAG Test Clock */ +#define K210_IO_FUNC_JTAG_TDI 1 /* JTAG Test Data In */ +#define K210_IO_FUNC_JTAG_TMS 2 /* JTAG Test Mode Select */ +#define K210_IO_FUNC_JTAG_TDO 3 /* JTAG Test Data Out */ +#define K210_IO_FUNC_SPI0_D0 4 /* SPI0 Data 0 */ +#define K210_IO_FUNC_SPI0_D1 5 /* SPI0 Data 1 */ +#define K210_IO_FUNC_SPI0_D2 6 /* SPI0 Data 2 */ +#define K210_IO_FUNC_SPI0_D3 7 /* SPI0 Data 3 */ +#define K210_IO_FUNC_SPI0_D4 8 /* SPI0 Data 4 */ +#define K210_IO_FUNC_SPI0_D5 9 /* SPI0 Data 5 */ +#define K210_IO_FUNC_SPI0_D6 10 /* SPI0 Data 6 */ +#define K210_IO_FUNC_SPI0_D7 11 /* SPI0 Data 7 */ +#define K210_IO_FUNC_SPI0_SS0 12 /* SPI0 Chip Select 0 */ +#define K210_IO_FUNC_SPI0_SS1 13 /* SPI0 Chip Select 1 */ +#define K210_IO_FUNC_SPI0_SS2 14 /* SPI0 Chip Select 2 */ +#define K210_IO_FUNC_SPI0_SS3 15 /* SPI0 Chip Select 3 */ +#define K210_IO_FUNC_SPI0_ARB 16 /* SPI0 Arbitration */ +#define K210_IO_FUNC_SPI0_SCLK 17 /* SPI0 Serial Clock */ +#define K210_IO_FUNC_UARTHS_RX 18 /* UART High speed Receiver */ +#define K210_IO_FUNC_UARTHS_TX 19 /* UART High speed Transmitter */ +#define K210_IO_FUNC_RESV6 20 /* Reserved function */ +#define K210_IO_FUNC_RESV7 21 /* Reserved function */ +#define K210_IO_FUNC_CLK_SPI1 22 /* Clock SPI1 */ +#define K210_IO_FUNC_CLK_I2C1 23 /* Clock I2C1 */ +#define K210_IO_FUNC_GPIOHS0 24 /* GPIO High speed 0 */ +#define K210_IO_FUNC_GPIOHS1 25 /* GPIO High speed 1 */ +#define K210_IO_FUNC_GPIOHS2 26 /* GPIO High speed 2 */ +#define K210_IO_FUNC_GPIOHS3 27 /* GPIO High speed 3 */ +#define K210_IO_FUNC_GPIOHS4 28 /* GPIO High speed 4 */ +#define K210_IO_FUNC_GPIOHS5 29 /* GPIO High speed 5 */ +#define K210_IO_FUNC_GPIOHS6 30 /* GPIO High speed 6 */ +#define K210_IO_FUNC_GPIOHS7 31 /* GPIO High speed 7 */ +#define K210_IO_FUNC_GPIOHS8 32 /* GPIO High speed 8 */ +#define K210_IO_FUNC_GPIOHS9 33 /* GPIO High speed 9 */ +#define K210_IO_FUNC_GPIOHS10 34 /* GPIO High speed 10 */ +#define K210_IO_FUNC_GPIOHS11 35 /* GPIO High speed 11 */ +#define K210_IO_FUNC_GPIOHS12 36 /* GPIO High speed 12 */ +#define K210_IO_FUNC_GPIOHS13 37 /* GPIO High speed 13 */ +#define K210_IO_FUNC_GPIOHS14 38 /* GPIO High speed 14 */ +#define K210_IO_FUNC_GPIOHS15 39 /* GPIO High speed 15 */ +#define K210_IO_FUNC_GPIOHS16 40 /* GPIO High speed 16 */ +#define K210_IO_FUNC_GPIOHS17 41 /* GPIO High speed 17 */ +#define K210_IO_FUNC_GPIOHS18 42 /* GPIO High speed 18 */ +#define K210_IO_FUNC_GPIOHS19 43 /* GPIO High speed 19 */ +#define K210_IO_FUNC_GPIOHS20 44 /* GPIO High speed 20 */ +#define K210_IO_FUNC_GPIOHS21 45 /* GPIO High speed 21 */ +#define K210_IO_FUNC_GPIOHS22 46 /* GPIO High speed 22 */ +#define K210_IO_FUNC_GPIOHS23 47 /* GPIO High speed 23 */ +#define K210_IO_FUNC_GPIOHS24 48 /* GPIO High speed 24 */ +#define K210_IO_FUNC_GPIOHS25 49 /* GPIO High speed 25 */ +#define K210_IO_FUNC_GPIOHS26 50 /* GPIO High speed 26 */ +#define K210_IO_FUNC_GPIOHS27 51 /* GPIO High speed 27 */ +#define K210_IO_FUNC_GPIOHS28 52 /* GPIO High speed 28 */ +#define K210_IO_FUNC_GPIOHS29 53 /* GPIO High speed 29 */ +#define K210_IO_FUNC_GPIOHS30 54 /* GPIO High speed 30 */ +#define K210_IO_FUNC_GPIOHS31 55 /* GPIO High speed 31 */ +#define K210_IO_FUNC_GPIO0 56 /* GPIO pin 0 */ +#define K210_IO_FUNC_GPIO1 57 /* GPIO pin 1 */ +#define K210_IO_FUNC_GPIO2 58 /* GPIO pin 2 */ +#define K210_IO_FUNC_GPIO3 59 /* GPIO pin 3 */ +#define K210_IO_FUNC_GPIO4 60 /* GPIO pin 4 */ +#define K210_IO_FUNC_GPIO5 61 /* GPIO pin 5 */ +#define K210_IO_FUNC_GPIO6 62 /* GPIO pin 6 */ +#define K210_IO_FUNC_GPIO7 63 /* GPIO pin 7 */ +#define K210_IO_FUNC_UART1_RX 64 /* UART1 Receiver */ +#define K210_IO_FUNC_UART1_TX 65 /* UART1 Transmitter */ +#define K210_IO_FUNC_UART2_RX 66 /* UART2 Receiver */ +#define K210_IO_FUNC_UART2_TX 67 /* UART2 Transmitter */ +#define K210_IO_FUNC_UART3_RX 68 /* UART3 Receiver */ +#define K210_IO_FUNC_UART3_TX 69 /* UART3 Transmitter */ +#define K210_IO_FUNC_SPI1_D0 70 /* SPI1 Data 0 */ +#define K210_IO_FUNC_SPI1_D1 71 /* SPI1 Data 1 */ +#define K210_IO_FUNC_SPI1_D2 72 /* SPI1 Data 2 */ +#define K210_IO_FUNC_SPI1_D3 73 /* SPI1 Data 3 */ +#define K210_IO_FUNC_SPI1_D4 74 /* SPI1 Data 4 */ +#define K210_IO_FUNC_SPI1_D5 75 /* SPI1 Data 5 */ +#define K210_IO_FUNC_SPI1_D6 76 /* SPI1 Data 6 */ +#define K210_IO_FUNC_SPI1_D7 77 /* SPI1 Data 7 */ +#define K210_IO_FUNC_SPI1_SS0 78 /* SPI1 Chip Select 0 */ +#define K210_IO_FUNC_SPI1_SS1 79 /* SPI1 Chip Select 1 */ +#define K210_IO_FUNC_SPI1_SS2 80 /* SPI1 Chip Select 2 */ +#define K210_IO_FUNC_SPI1_SS3 81 /* SPI1 Chip Select 3 */ +#define K210_IO_FUNC_SPI1_ARB 82 /* SPI1 Arbitration */ +#define K210_IO_FUNC_SPI1_SCLK 83 /* SPI1 Serial Clock */ +#define K210_IO_FUNC_SPI_SLAVE_D0 84 /* SPI Slave Data 0 */ +#define K210_IO_FUNC_SPI_SLAVE_SS 85 /* SPI Slave Select */ +#define K210_IO_FUNC_SPI_SLAVE_SCLK 86 /* SPI Slave Serial Clock */ +#define K210_IO_FUNC_I2S0_MCLK 87 /* I2S0 Master Clock */ +#define K210_IO_FUNC_I2S0_SCLK 88 /* I2S0 Serial Clock(BCLK) */ +#define K210_IO_FUNC_I2S0_WS 89 /* I2S0 Word Select(LRCLK) */ +#define K210_IO_FUNC_I2S0_IN_D0 90 /* I2S0 Serial Data Input 0 */ +#define K210_IO_FUNC_I2S0_IN_D1 91 /* I2S0 Serial Data Input 1 */ +#define K210_IO_FUNC_I2S0_IN_D2 92 /* I2S0 Serial Data Input 2 */ +#define K210_IO_FUNC_I2S0_IN_D3 93 /* I2S0 Serial Data Input 3 */ +#define K210_IO_FUNC_I2S0_OUT_D0 94 /* I2S0 Serial Data Output 0 */ +#define K210_IO_FUNC_I2S0_OUT_D1 95 /* I2S0 Serial Data Output 1 */ +#define K210_IO_FUNC_I2S0_OUT_D2 96 /* I2S0 Serial Data Output 2 */ +#define K210_IO_FUNC_I2S0_OUT_D3 97 /* I2S0 Serial Data Output 3 */ +#define K210_IO_FUNC_I2S1_MCLK 98 /* I2S1 Master Clock */ +#define K210_IO_FUNC_I2S1_SCLK 99 /* I2S1 Serial Clock(BCLK) */ +#define K210_IO_FUNC_I2S1_WS 100 /* I2S1 Word Select(LRCLK) */ +#define K210_IO_FUNC_I2S1_IN_D0 101 /* I2S1 Serial Data Input 0 */ +#define K210_IO_FUNC_I2S1_IN_D1 102 /* I2S1 Serial Data Input 1 */ +#define K210_IO_FUNC_I2S1_IN_D2 103 /* I2S1 Serial Data Input 2 */ +#define K210_IO_FUNC_I2S1_IN_D3 104 /* I2S1 Serial Data Input 3 */ +#define K210_IO_FUNC_I2S1_OUT_D0 105 /* I2S1 Serial Data Output 0 */ +#define K210_IO_FUNC_I2S1_OUT_D1 106 /* I2S1 Serial Data Output 1 */ +#define K210_IO_FUNC_I2S1_OUT_D2 107 /* I2S1 Serial Data Output 2 */ +#define K210_IO_FUNC_I2S1_OUT_D3 108 /* I2S1 Serial Data Output 3 */ +#define K210_IO_FUNC_I2S2_MCLK 109 /* I2S2 Master Clock */ +#define K210_IO_FUNC_I2S2_SCLK 110 /* I2S2 Serial Clock(BCLK) */ +#define K210_IO_FUNC_I2S2_WS 111 /* I2S2 Word Select(LRCLK) */ +#define K210_IO_FUNC_I2S2_IN_D0 112 /* I2S2 Serial Data Input 0 */ +#define K210_IO_FUNC_I2S2_IN_D1 113 /* I2S2 Serial Data Input 1 */ +#define K210_IO_FUNC_I2S2_IN_D2 114 /* I2S2 Serial Data Input 2 */ +#define K210_IO_FUNC_I2S2_IN_D3 115 /* I2S2 Serial Data Input 3 */ +#define K210_IO_FUNC_I2S2_OUT_D0 116 /* I2S2 Serial Data Output 0 */ +#define K210_IO_FUNC_I2S2_OUT_D1 117 /* I2S2 Serial Data Output 1 */ +#define K210_IO_FUNC_I2S2_OUT_D2 118 /* I2S2 Serial Data Output 2 */ +#define K210_IO_FUNC_I2S2_OUT_D3 119 /* I2S2 Serial Data Output 3 */ +#define K210_IO_FUNC_RESV0 120 /* Reserved function */ +#define K210_IO_FUNC_RESV1 121 /* Reserved function */ +#define K210_IO_FUNC_RESV2 122 /* Reserved function */ +#define K210_IO_FUNC_RESV3 123 /* Reserved function */ +#define K210_IO_FUNC_RESV4 124 /* Reserved function */ +#define K210_IO_FUNC_RESV5 125 /* Reserved function */ +#define K210_IO_FUNC_I2C0_SCLK 126 /* I2C0 Serial Clock */ +#define K210_IO_FUNC_I2C0_SDA 127 /* I2C0 Serial Data */ +#define K210_IO_FUNC_I2C1_SCLK 128 /* I2C1 Serial Clock */ +#define K210_IO_FUNC_I2C1_SDA 129 /* I2C1 Serial Data */ +#define K210_IO_FUNC_I2C2_SCLK 130 /* I2C2 Serial Clock */ +#define K210_IO_FUNC_I2C2_SDA 131 /* I2C2 Serial Data */ +#define K210_IO_FUNC_CMOS_XCLK 132 /* DVP System Clock */ +#define K210_IO_FUNC_CMOS_RST 133 /* DVP System Reset */ +#define K210_IO_FUNC_CMOS_PWDN 134 /* DVP Power Down Mode */ +#define K210_IO_FUNC_CMOS_VSYNC 135 /* DVP Vertical Sync */ +#define K210_IO_FUNC_CMOS_HREF 136 /* DVP Horizontal Reference output */ +#define K210_IO_FUNC_CMOS_PCLK 137 /* Pixel Clock */ +#define K210_IO_FUNC_CMOS_D0 138 /* Data Bit 0 */ +#define K210_IO_FUNC_CMOS_D1 139 /* Data Bit 1 */ +#define K210_IO_FUNC_CMOS_D2 140 /* Data Bit 2 */ +#define K210_IO_FUNC_CMOS_D3 141 /* Data Bit 3 */ +#define K210_IO_FUNC_CMOS_D4 142 /* Data Bit 4 */ +#define K210_IO_FUNC_CMOS_D5 143 /* Data Bit 5 */ +#define K210_IO_FUNC_CMOS_D6 144 /* Data Bit 6 */ +#define K210_IO_FUNC_CMOS_D7 145 /* Data Bit 7 */ +#define K210_IO_FUNC_SCCB_SCLK 146 /* SCCB Serial Clock */ +#define K210_IO_FUNC_SCCB_SDA 147 /* SCCB Serial Data */ +#define K210_IO_FUNC_UART1_CTS 148 /* UART1 Clear To Send */ +#define K210_IO_FUNC_UART1_DSR 149 /* UART1 Data Set Ready */ +#define K210_IO_FUNC_UART1_DCD 150 /* UART1 Data Carrier Detect */ +#define K210_IO_FUNC_UART1_RI 151 /* UART1 Ring Indicator */ +#define K210_IO_FUNC_UART1_SIR_IN 152 /* UART1 Serial Infrared Input */ +#define K210_IO_FUNC_UART1_DTR 153 /* UART1 Data Terminal Ready */ +#define K210_IO_FUNC_UART1_RTS 154 /* UART1 Request To Send */ +#define K210_IO_FUNC_UART1_OUT2 155 /* UART1 User-designated Output 2 */ +#define K210_IO_FUNC_UART1_OUT1 156 /* UART1 User-designated Output 1 */ +#define K210_IO_FUNC_UART1_SIR_OUT 157 /* UART1 Serial Infrared Output */ +#define K210_IO_FUNC_UART1_BAUD 158 /* UART1 Transmit Clock Output */ +#define K210_IO_FUNC_UART1_RE 159 /* UART1 Receiver Output Enable */ +#define K210_IO_FUNC_UART1_DE 160 /* UART1 Driver Output Enable */ +#define K210_IO_FUNC_UART1_RS485_EN 161 /* UART1 RS485 Enable */ +#define K210_IO_FUNC_UART2_CTS 162 /* UART2 Clear To Send */ +#define K210_IO_FUNC_UART2_DSR 163 /* UART2 Data Set Ready */ +#define K210_IO_FUNC_UART2_DCD 164 /* UART2 Data Carrier Detect */ +#define K210_IO_FUNC_UART2_RI 165 /* UART2 Ring Indicator */ +#define K210_IO_FUNC_UART2_SIR_IN 166 /* UART2 Serial Infrared Input */ +#define K210_IO_FUNC_UART2_DTR 167 /* UART2 Data Terminal Ready */ +#define K210_IO_FUNC_UART2_RTS 168 /* UART2 Request To Send */ +#define K210_IO_FUNC_UART2_OUT2 169 /* UART2 User-designated Output 2 */ +#define K210_IO_FUNC_UART2_OUT1 170 /* UART2 User-designated Output 1 */ +#define K210_IO_FUNC_UART2_SIR_OUT 171 /* UART2 Serial Infrared Output */ +#define K210_IO_FUNC_UART2_BAUD 172 /* UART2 Transmit Clock Output */ +#define K210_IO_FUNC_UART2_RE 173 /* UART2 Receiver Output Enable */ +#define K210_IO_FUNC_UART2_DE 174 /* UART2 Driver Output Enable */ +#define K210_IO_FUNC_UART2_RS485_EN 175 /* UART2 RS485 Enable */ +#define K210_IO_FUNC_UART3_CTS 176 /* UART3 Clear To Send */ +#define K210_IO_FUNC_UART3_DSR 177 /* UART3 Data Set Ready */ +#define K210_IO_FUNC_UART3_DCD 178 /* UART3 Data Carrier Detect */ +#define K210_IO_FUNC_UART3_RI 179 /* UART3 Ring Indicator */ +#define K210_IO_FUNC_UART3_SIR_IN 180 /* UART3 Serial Infrared Input */ +#define K210_IO_FUNC_UART3_DTR 181 /* UART3 Data Terminal Ready */ +#define K210_IO_FUNC_UART3_RTS 182 /* UART3 Request To Send */ +#define K210_IO_FUNC_UART3_OUT2 183 /* UART3 User-designated Output 2 */ +#define K210_IO_FUNC_UART3_OUT1 184 /* UART3 User-designated Output 1 */ +#define K210_IO_FUNC_UART3_SIR_OUT 185 /* UART3 Serial Infrared Output */ +#define K210_IO_FUNC_UART3_BAUD 186 /* UART3 Transmit Clock Output */ +#define K210_IO_FUNC_UART3_RE 187 /* UART3 Receiver Output Enable */ +#define K210_IO_FUNC_UART3_DE 188 /* UART3 Driver Output Enable */ +#define K210_IO_FUNC_UART3_RS485_EN 189 /* UART3 RS485 Enable */ +#define K210_IO_FUNC_TIMER0_TOGGLE1 190 /* TIMER0 Toggle Output 1 */ +#define K210_IO_FUNC_TIMER0_TOGGLE2 191 /* TIMER0 Toggle Output 2 */ +#define K210_IO_FUNC_TIMER0_TOGGLE3 192 /* TIMER0 Toggle Output 3 */ +#define K210_IO_FUNC_TIMER0_TOGGLE4 193 /* TIMER0 Toggle Output 4 */ +#define K210_IO_FUNC_TIMER1_TOGGLE1 194 /* TIMER1 Toggle Output 1 */ +#define K210_IO_FUNC_TIMER1_TOGGLE2 195 /* TIMER1 Toggle Output 2 */ +#define K210_IO_FUNC_TIMER1_TOGGLE3 196 /* TIMER1 Toggle Output 3 */ +#define K210_IO_FUNC_TIMER1_TOGGLE4 197 /* TIMER1 Toggle Output 4 */ +#define K210_IO_FUNC_TIMER2_TOGGLE1 198 /* TIMER2 Toggle Output 1 */ +#define K210_IO_FUNC_TIMER2_TOGGLE2 199 /* TIMER2 Toggle Output 2 */ +#define K210_IO_FUNC_TIMER2_TOGGLE3 200 /* TIMER2 Toggle Output 3 */ +#define K210_IO_FUNC_TIMER2_TOGGLE4 201 /* TIMER2 Toggle Output 4 */ +#define K210_IO_FUNC_CLK_SPI2 202 /* Clock SPI2 */ +#define K210_IO_FUNC_CLK_I2C2 203 /* Clock I2C2 */ +#define K210_IO_FUNC_INTERNAL0 204 /* Internal function signal 0 */ +#define K210_IO_FUNC_INTERNAL1 205 /* Internal function signal 1 */ +#define K210_IO_FUNC_INTERNAL2 206 /* Internal function signal 2 */ +#define K210_IO_FUNC_INTERNAL3 207 /* Internal function signal 3 */ +#define K210_IO_FUNC_INTERNAL4 208 /* Internal function signal 4 */ +#define K210_IO_FUNC_INTERNAL5 209 /* Internal function signal 5 */ +#define K210_IO_FUNC_INTERNAL6 210 /* Internal function signal 6 */ +#define K210_IO_FUNC_INTERNAL7 211 /* Internal function signal 7 */ +#define K210_IO_FUNC_INTERNAL8 212 /* Internal function signal 8 */ +#define K210_IO_FUNC_INTERNAL9 213 /* Internal function signal 9 */ +#define K210_IO_FUNC_INTERNAL10 214 /* Internal function signal 10 */ +#define K210_IO_FUNC_INTERNAL11 215 /* Internal function signal 11 */ +#define K210_IO_FUNC_INTERNAL12 216 /* Internal function signal 12 */ +#define K210_IO_FUNC_INTERNAL13 217 /* Internal function signal 13 */ +#define K210_IO_FUNC_INTERNAL14 218 /* Internal function signal 14 */ +#define K210_IO_FUNC_INTERNAL15 219 /* Internal function signal 15 */ +#define K210_IO_FUNC_INTERNAL16 220 /* Internal function signal 16 */ +#define K210_IO_FUNC_INTERNAL17 221 /* Internal function signal 17 */ +#define K210_IO_FUNC_CONSTANT 222 /* Constant function */ +#define K210_IO_FUNC_INTERNAL18 223 /* Internal function signal 18 */ +#define K210_IO_FUNC_DEBUG0 224 /* Debug function 0 */ +#define K210_IO_FUNC_DEBUG1 225 /* Debug function 1 */ +#define K210_IO_FUNC_DEBUG2 226 /* Debug function 2 */ +#define K210_IO_FUNC_DEBUG3 227 /* Debug function 3 */ +#define K210_IO_FUNC_DEBUG4 228 /* Debug function 4 */ +#define K210_IO_FUNC_DEBUG5 229 /* Debug function 5 */ +#define K210_IO_FUNC_DEBUG6 230 /* Debug function 6 */ +#define K210_IO_FUNC_DEBUG7 231 /* Debug function 7 */ +#define K210_IO_FUNC_DEBUG8 232 /* Debug function 8 */ +#define K210_IO_FUNC_DEBUG9 233 /* Debug function 9 */ +#define K210_IO_FUNC_DEBUG10 234 /* Debug function 10 */ +#define K210_IO_FUNC_DEBUG11 235 /* Debug function 11 */ +#define K210_IO_FUNC_DEBUG12 236 /* Debug function 12 */ +#define K210_IO_FUNC_DEBUG13 237 /* Debug function 13 */ +#define K210_IO_FUNC_DEBUG14 238 /* Debug function 14 */ +#define K210_IO_FUNC_DEBUG15 239 /* Debug function 15 */ +#define K210_IO_FUNC_DEBUG16 240 /* Debug function 16 */ +#define K210_IO_FUNC_DEBUG17 241 /* Debug function 17 */ +#define K210_IO_FUNC_DEBUG18 242 /* Debug function 18 */ +#define K210_IO_FUNC_DEBUG19 243 /* Debug function 19 */ +#define K210_IO_FUNC_DEBUG20 244 /* Debug function 20 */ +#define K210_IO_FUNC_DEBUG21 245 /* Debug function 21 */ +#define K210_IO_FUNC_DEBUG22 246 /* Debug function 22 */ +#define K210_IO_FUNC_DEBUG23 247 /* Debug function 23 */ +#define K210_IO_FUNC_DEBUG24 248 /* Debug function 24 */ +#define K210_IO_FUNC_DEBUG25 249 /* Debug function 25 */ +#define K210_IO_FUNC_DEBUG26 250 /* Debug function 26 */ +#define K210_IO_FUNC_DEBUG27 251 /* Debug function 27 */ +#define K210_IO_FUNC_DEBUG28 252 /* Debug function 28 */ +#define K210_IO_FUNC_DEBUG29 253 /* Debug function 29 */ +#define K210_IO_FUNC_DEBUG30 254 /* Debug function 30 */ +#define K210_IO_FUNC_DEBUG31 255 /* Debug function 31 */ +#define K210_IO_FUNC_MAX 256 /* Function numbers */ #define K210_IO_DS(x) (x << 8) /* Driving Selector */ @@ -102,34 +318,6 @@ #define K210_IOFLAG_GPIOHS (K210_IO_DS(0xf) | K210_IO_OUTPUT_ENABLE | \ K210_IO_INPUT_ENABLE | K210_IO_ST) -typedef struct _fpioa_io_config -{ - uint32_t ch_sel : 8; /* Channel select from 256 input. */ - uint32_t ds : 4; /* Driving selector. */ - uint32_t oe_en : 1; /* Static output enable, will AND with OE_INV. */ - uint32_t oe_inv : 1; /* Invert output enable. */ - uint32_t do_sel : 1; /* Data output select: 0 for DO, 1 for OE. */ - uint32_t do_inv : 1; /* Invert the result of data output select (DO_SEL). */ - uint32_t pu : 1; /* Pull up enable. 0 for nothing, 1 for pull up. */ - uint32_t pd : 1; /* Pull down enable. 0 for nothing, 1 for pull down. */ - uint32_t resv0 : 1; /* Reserved bits. */ - uint32_t sl : 1; /* Slew rate control enable. */ - uint32_t ie_en : 1; /* Static input enable, will AND with IE_INV. */ - uint32_t ie_inv : 1; /* Invert input enable. */ - uint32_t di_inv : 1; /* Invert Data input. */ - uint32_t st : 1; /* Schmitt trigger. */ - uint32_t resv1 : 7; /* Reserved bits. */ - uint32_t pad_di : 1; /* Read current IO's data input. */ -} __attribute__((packed, aligned(4))) fpioa_io_config_t; - -typedef enum _fpioa_pull -{ - FPIOA_PULL_NONE, /* No Pull */ - FPIOA_PULL_DOWN, /* Pull Down */ - FPIOA_PULL_UP, /* Pull Up */ - FPIOA_PULL_MAX /* Count of pull settings */ -} fpioa_pull_t; - /**************************************************************************** * Public Functions Prototypes diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c index b79966c01..eb3c0e93e 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c @@ -39,82 +39,110 @@ #include "k210_memorymap.h" #include "k210_gpio.h" #include "k210_fpioa.h" +#include "k210_sysctl.h" + +#define GPIO_MAX_PINNO 8 /**************************************************************************** - * Pre-processor Definitions + * Private Function declaration ****************************************************************************/ - -#define GPIO_INPUT_VAL_OFFSET 0x00 -#define GPIO_INPUT_EN_OFFSET 0x04 -#define GPIO_OUTPUT_EN_OFFSET 0x08 -#define GPIO_OUTPUT_VAL_OFFSET 0x0c -#define GPIO_PULLUP_EN_OFFSET 0x10 -#define GPIO_DRIVE_OFFSET 0x14 - -#define GPIO_INPUT (K210_GPIO_BASE + GPIO_INPUT_VAL_OFFSET) -#define GPIO_INPUT_EN (K210_GPIO_BASE + GPIO_INPUT_EN_OFFSET) -#define GPIO_OUTPUT (K210_GPIO_BASE + GPIO_OUTPUT_VAL_OFFSET) -#define GPIO_OUTPUT_EN (K210_GPIO_BASE + GPIO_OUTPUT_EN_OFFSET) +static void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value); +static void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value); +static void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value); +static uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset); +static uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset); /**************************************************************************** - * Public Functions + * Private Data ****************************************************************************/ -void k210_gpio_set_direction(uint32_t io, gpio_drive_mode_t mode) +volatile gpio_t *const gpio = (volatile gpio_t *)K210_GPIO_BASE; + +/**************************************************************************** + * Private Function definition + ****************************************************************************/ +static void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value) { - DEBUGASSERT(io < K210_GPIO_MAX_PINNO); - int io_number = k210_fpioa_get_io_by_function(K210_IO_FUNC_GPIO0 + io); - DEBUGASSERT(io_number >= 0); - - fpioa_pull_t pull = FPIOA_PULL_NONE; - uint32_t dir = 0; - - switch (mode) - { - case GPIO_DM_INPUT: - pull = FPIOA_PULL_NONE; - dir = 0; - break; - case GPIO_DM_INPUT_PULL_DOWN: - pull = FPIOA_PULL_DOWN; - dir = 0; - break; - case GPIO_DM_INPUT_PULL_UP: - pull = FPIOA_PULL_UP; - dir = 0; - break; - case GPIO_DM_OUTPUT: - pull = FPIOA_PULL_DOWN; - dir = 1; - break; - default: - DEBUGASSERT(!"GPIO drive mode is not supported."); - break; - } - - fpioa_set_io_pull(io_number, pull); - uint32_t outbit = dir << io; - uint32_t inbit = (!dir) << io; - modifyreg32(GPIO_OUTPUT_EN, inbit, outbit); - modifyreg32(GPIO_INPUT_EN, outbit, inbit); + uint32_t org = (*bits) & ~mask; + *bits = org | (value & mask); } -void k210_gpio_set_value(uint32_t io, bool val) +static void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value) { - uint32_t setbit = val << io; - uint32_t clrbit = (!val) << io; - modifyreg32(GPIO_OUTPUT, clrbit, setbit); + set_bit(bits, mask << offset, value << offset); } -bool k210_gpio_get_value(uint32_t io) +static void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value) { - uint32_t reg = getreg32(GPIO_INPUT); + set_bit_offset(bits, 1, offset, value); +} - if (reg & (1 << io)) +static uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset) +{ + return ((*bits) & (mask << offset)) >> offset; +} + +static uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset) +{ + return get_bit(bits, 1, offset); +} + + +/**************************************************************************** + * Public Function definition + ****************************************************************************/ +int gpio_init(void) +{ + return sysctl_clock_enable(SYSCTL_CLOCK_GPIO); +} + +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + int io_number = fpioa_get_io_by_function(K210_IO_FUNC_GPIO0 + pin); + DEBUGASSERT(io_number >= 0); + + fpioa_pull_t pull; + uint32_t dir; + + switch(mode) { - return true; - } - else - { - return false; + case GPIO_DM_INPUT: + pull = FPIOA_PULL_NONE; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_DOWN: + pull = FPIOA_PULL_DOWN; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_UP: + pull = FPIOA_PULL_UP; + dir = 0; + break; + case GPIO_DM_OUTPUT: + pull = FPIOA_PULL_DOWN; + dir = 1; + break; + default: + break; } + + fpioa_set_io_pull(io_number, pull); + set_gpio_bit(gpio->direction.u32, pin, dir); +} + +gpio_pin_value_t gpio_get_pin(uint8_t pin) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + return get_gpio_bit(reg, pin); +} + +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + DEBUGASSERT(dir == 1); + set_gpio_bit(reg, pin, value); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h index 13d98e04d..1ac4a2ef6 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h @@ -38,52 +38,127 @@ #include #include "k210_gpio_common.h" +typedef struct _gpio_bits +{ + uint32_t b0 : 1; + uint32_t b1 : 1; + uint32_t b2 : 1; + uint32_t b3 : 1; + uint32_t b4 : 1; + uint32_t b5 : 1; + uint32_t b6 : 1; + uint32_t b7 : 1; + uint32_t b8 : 1; + uint32_t b9 : 1; + uint32_t b10 : 1; + uint32_t b11 : 1; + uint32_t b12 : 1; + uint32_t b13 : 1; + uint32_t b14 : 1; + uint32_t b15 : 1; + uint32_t b16 : 1; + uint32_t b17 : 1; + uint32_t b18 : 1; + uint32_t b19 : 1; + uint32_t b20 : 1; + uint32_t b21 : 1; + uint32_t b22 : 1; + uint32_t b23 : 1; + uint32_t b24 : 1; + uint32_t b25 : 1; + uint32_t b26 : 1; + uint32_t b27 : 1; + uint32_t b28 : 1; + uint32_t b29 : 1; + uint32_t b30 : 1; + uint32_t b31 : 1; +} __attribute__((packed, aligned(4))) gpio_bits_t; + +/* Structure of templates for accessing GPIO registers */ +typedef union _gpio_access_tp +{ + /* 32x1 bit mode */ + uint32_t u32[1]; + /* 16x2 bit mode */ + uint16_t u16[2]; + /* 8x4 bit mode */ + uint8_t u8[4]; + /* 1 bit mode */ + gpio_bits_t bits; +} __attribute__((packed, aligned(4))) gpio_access_tp_t; + +/* The GPIO address map */ +typedef struct _gpio +{ + /* Offset 0x00: Data (output) registers */ + gpio_access_tp_t data_output; + /* Offset 0x04: Data direction registers */ + gpio_access_tp_t direction; + /* Offset 0x08: Data source registers */ + gpio_access_tp_t source; + /* Offset 0x10 - 0x2f: Unused registers, 9x4 bytes */ + uint32_t unused_0[9]; + /* Offset 0x30: Interrupt enable/disable registers */ + gpio_access_tp_t interrupt_enable; + /* Offset 0x34: Interrupt mask registers */ + gpio_access_tp_t interrupt_mask; + /* Offset 0x38: Interrupt level registers */ + gpio_access_tp_t interrupt_level; + /* Offset 0x3c: Interrupt polarity registers */ + gpio_access_tp_t interrupt_polarity; + /* Offset 0x40: Interrupt status registers */ + gpio_access_tp_t interrupt_status; + /* Offset 0x44: Raw interrupt status registers */ + gpio_access_tp_t interrupt_status_raw; + /* Offset 0x48: Interrupt debounce registers */ + gpio_access_tp_t interrupt_debounce; + /* Offset 0x4c: Registers for clearing interrupts */ + gpio_access_tp_t interrupt_clear; + /* Offset 0x50: External port (data input) registers */ + gpio_access_tp_t data_input; + /* Offset 0x54 - 0x5f: Unused registers, 3x4 bytes */ + uint32_t unused_1[3]; + /* Offset 0x60: Sync level registers */ + gpio_access_tp_t sync_level; + /* Offset 0x64: ID code */ + gpio_access_tp_t id_code; + /* Offset 0x68: Interrupt both edge type */ + gpio_access_tp_t interrupt_bothedge; +} __attribute__((packed, aligned(4))) gpio_t; + +/* Bus GPIO object instance */ +extern volatile gpio_t *const gpio; + /**************************************************************************** * Public Functions Prototypes ****************************************************************************/ +/** + * @brief Gpio initialize + * @return - 0:Success,Other:Fail + */ +int gpio_init(void); -/**************************************************************************** - * Name: k210_gpio_set_direction - * - * Description: - * Set gpiohs direction - * - * Input Parameters: - * io - IO number - * dir - true for output, false for input - * - ****************************************************************************/ +/** + * @brief Set Gpio drive mode + * @param[in] pin Gpio pin + * @param[in] mode Gpio pin drive mode + */ +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode); -void k210_gpio_set_direction(uint32_t io, gpio_drive_mode_t mode); +/** + * @brief Get Gpio pin value + * @param[in] pin Gpio pin + * @return Pin value + * GPIO_PV_Low Gpio pin low + * GPIO_PV_High Gpio pin high + */ +gpio_pin_value_t gpio_get_pin(uint8_t pin); -/**************************************************************************** - * Name: k210_gpio_set_value - * - * Description: - * Set gpiohs direction - * - * Input Parameters: - * io - IO number - * dir - true for high level, false for low level - * - ****************************************************************************/ - -void k210_gpio_set_value(uint32_t io, bool val); - -/**************************************************************************** - * Name: k210_gpio_get_value - * - * Description: - * Get gpiohs level - * - * Input Parameters: - * io - IO number - * - * Returned Value: - * true for high level, false for low level - * - ****************************************************************************/ - -bool k210_gpio_get_value(uint32_t io); +/** + * @brief Set Gpio pin value + * @param[in] pin Gpio pin + * @param[in] value Gpio pin value + */ +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value); #endif /* __ARCH_RISCV_SRC_K210_K210_GPIO_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h index 11f3b0634..1ef7d0ea5 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h @@ -18,6 +18,15 @@ * ****************************************************************************/ +/** +* @file k210_memorymap.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #ifndef __ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H #define __ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H 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 new file mode 100644 index 000000000..d35ba2d02 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c @@ -0,0 +1,742 @@ +/**************************************************************************** + * arch/risc-v/src/k210/k210_serial.c + * + * 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. + * + ****************************************************************************/ + +/** +* @file k210_serial.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "riscv_internal.h" +#include "k210_config.h" +#include "chip.h" +#include "k210.h" +#include "k210_uart_16550.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# error "I'm confused... Do we have a serial console or not?" +# endif +#else +# undef CONSOLE_DEV /* No console */ +# undef CONFIG_UART0_SERIAL_CONSOLE +# if defined(CONFIG_K210_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# undef TTYS0_DEV +# undef TTYS1_DEV +# endif +#endif + +/* Common initialization logic will not not know that the all of the UARTs + * have been disabled. So, as a result, we may still have to provide + * stub implementations of riscv_earlyserialinit(), riscv_serialinit(), and + * up_putc(). + */ + +#ifdef HAVE_UART_DEVICE + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t im; /* Interrupt mask state */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers */ + +static uint32_t up_serialin(struct up_dev_s *priv, int offset); +static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value); +static void up_restoreuartint(struct up_dev_s *priv, uint8_t im); +static void up_disableuartint(struct up_dev_s *priv, uint8_t *im); + +/* Serial driver methods */ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context, void *arg); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_K210_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +static uint32_t g_rxdata; +#endif + +#ifdef CONFIG_K210_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = K210_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = K210_IRQ_UART0, +}; + +static uart_dev_t g_uart0port = +{ +#if SERIAL_CONSOLE == 1 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct up_dev_s *priv, uint8_t im) +{ + irqstate_t flags = enter_critical_section(); + + priv->im = im; + up_serialout(priv, UART_IE_OFFSET, im); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct up_dev_s *priv, uint8_t *im) +{ + irqstate_t flags = enter_critical_section(); + + /* Return the current interrupt mask value */ + + if (im) + { + *im = priv->im; + } + + /* Disable all interrupts */ + + priv->im = 0; + up_serialout(priv, UART_IE_OFFSET, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#if 0 /* TODO: Setup divisor */ +#endif + + /* Enable RX */ + + up_serialout(priv, UART_RXCTL_OFFSET, 1); + + /* Set TX watermark level to 1 and enable TX */ + + up_serialout(priv, UART_TXCTL_OFFSET, 1 << 16 | 1); + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Initialize interrupt generation on the peripheral */ + + up_serialout(priv, UART_IE_OFFSET, UART_IE_TXWM | UART_IE_RXWM); + + ret = irq_attach(priv->irq, up_interrupt, dev); + + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disable_irq(priv->irq); + + /* Detach from the interrupt */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_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 uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context, void *arg) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)arg; + struct up_dev_s *priv; + uint32_t status; + int passes; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Retrieve interrupt pending status */ + + status = up_serialin(priv, UART_IP_OFFSET); + + if (status == 0) + { + break; + } + + if (status & UART_IP_RXWM) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + } + + if (status & UART_IP_TXWM) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + /* Return status information */ + + if (status) + { + *status = 0; /* We are not yet tracking serial errors */ + } + + /* Return cached data */ + + return g_rxdata; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= UART_IE_RXWM; +#endif + } + else + { + priv->im &= ~UART_IE_RXWM; + } + + up_serialout(priv, UART_IE_OFFSET, priv->im); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true is data is available in the receive data buffer */ + + uint32_t rxdata = up_serialin(priv, UART_RXDATA_OFFSET); + + /* NOTE: In K210, actual data is also retrieved */ + + g_rxdata = rxdata & 0xff; + + return (rxdata & UART_RX_EMPTY) == 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_TXDATA_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= UART_IE_TXWM; + up_serialout(priv, UART_IE_OFFSET, priv->im); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->im &= ~UART_IE_TXWM; + up_serialout(priv, UART_IE_OFFSET, priv->im); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the TX FIFO is not full */ + + return (up_serialin(priv, UART_TXDATA_OFFSET) & UART_TX_FULL) == 0; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the TX wartermak is pending */ + + return (up_serialin(priv, UART_IP_OFFSET) & UART_IP_TXWM) == 1; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT + +/**************************************************************************** + * Name: riscv_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before riscv_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock + * initialization performed in up_clkinitialize(). + * + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * k210_consoleinit(). + */ + + up_disableuartint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableuartint(TTYS1_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: riscv_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that riscv_earlyserialinit was called previously. + * + ****************************************************************************/ + +void riscv_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + uart_register("/dev/ttyS0", &TTYS0_DEV); + +#ifdef CONFIG_K210_16550_UART + /* Register UART1-UART3 */ + k210_uart_16550_register(); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint8_t imr; + + up_disableuartint(priv, &imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); + up_restoreuartint(priv, imr); +#endif + return ch; +} + +/**************************************************************************** + * Name: riscv_earlyserialinit, riscv_serialinit, and up_putc + * + * Description: + * stubs that may be needed. These stubs would be used if all UARTs are + * disabled. In that case, the logic in common/up_initialize() is not + * smart enough to know that there are not UARTs and will still expect + * these interfaces to be provided. + * + ****************************************************************************/ + +#else /* HAVE_UART_DEVICE */ +void riscv_earlyserialinit(void) +{ +} + +void riscv_serialinit(void) +{ +} + +int up_putc(int ch) +{ + return ch; +} + +#endif /* HAVE_UART_DEVICE */ +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c index 509b35c0e..39b5d8e42 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c @@ -1,17 +1,32 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/k210_sysctl.c * - * 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 + * 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 + * 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. - */ + * 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 k210_sysctl.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #include #include #include diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h index 625a3f3e3..fc4a2bbc6 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h @@ -1,17 +1,32 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/k210_sysctl.h * - * 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 + * 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 + * 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. - */ + * 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 k210_sysctl.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #ifndef _DRIVER_SYSCTL_H #define _DRIVER_SYSCTL_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c index ce7fe7fe1..d98e995ed 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c @@ -12,7 +12,7 @@ /** * @file k210_systemreset.c - * @briefk210_systemreset.c support reboot + * @brief k210 support reboot * @version 1.0 * @author AIIT XUOS Lab * @date 2022.06.27 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_16550.c new file mode 100644 index 000000000..c52c7cde9 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c @@ -0,0 +1,1000 @@ +/* +* 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_uart_16550.c + * @brief k210 uart1-uart3 support + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.09.28 + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "k210_uart_16550.h" + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#ifdef CONFIG_K210_16550_UART + + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * 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); +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool k210_16550_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); +#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); +#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); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +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, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = k210_16550_rxflowcontrol, +#endif +#ifdef CONFIG_SERIAL_TXDMA + .dmasend = k210_16550_dmasend, +#endif +#ifdef CONFIG_SERIAL_RXDMA + .dmareceive = k210_16550_dmareceive, + .dmarxfree = k210_16550_dmarxfree, +#endif +#ifdef CONFIG_SERIAL_TXDMA + .dmatxavail = k210_16550_dmatxavail, +#endif + .send = k210_16550_send, + .txint = k210_16550_txint, + .txready = k210_16550_txready, + .txempty = k210_16550_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]; +#endif +#ifdef CONFIG_K210_16550_UART2 +static char g_uart2rxbuffer[CONFIG_K210_16550_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_K210_16550_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]; +#endif + +/* This describes the state of the 16550 uart1 port. */ + +#ifdef CONFIG_K210_16550_UART1 +static struct k210_16550_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, +#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) + .flow = true, +#endif +#endif +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_K210_16550_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_K210_16550_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the 16550 uart2 port. */ + +#ifdef CONFIG_K210_16550_UART2 +static struct k210_16550_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, +#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) + .flow = true, +#endif +#endif +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_K210_16550_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_K210_16550_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; + +#endif + +/* This describes the state of the 16550 uart1 port. */ + +#ifdef CONFIG_K210_16550_UART3 +static struct k210_16550_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, +#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) + .flow = true, +#endif +#endif +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_K210_16550_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_K210_16550_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; + +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_16550_serialin + ****************************************************************************/ + +static inline uart_datawidth_t k210_16550_serialin(FAR struct k210_16550_s *priv, + int offset) +{ +#ifdef CONFIG_SERIAL_UART_ARCH_MMIO + return *((FAR volatile uart_datawidth_t *)(priv->uartbase + offset)); +#else + return uart_getreg(priv->uartbase, offset); +#endif +} + +/**************************************************************************** + * Name: k210_16550_serialout + ****************************************************************************/ + +static inline void k210_16550_serialout(FAR struct k210_16550_s *priv, int offset, + uart_datawidth_t value) +{ +#ifdef CONFIG_SERIAL_UART_ARCH_MMIO + *((FAR volatile uart_datawidth_t *)(priv->uartbase + offset)) = value; +#else + uart_putreg(priv->uartbase, offset, value); +#endif +} + +/**************************************************************************** + * Name: k210_16550_disableuartint + ****************************************************************************/ + +static inline void k210_16550_disableuartint(FAR struct k210_16550_s *priv, + FAR uart_datawidth_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLIE; + } + + priv->ier &= ~UART_IER_ALLIE; + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: k210_16550_restoreuartint + ****************************************************************************/ + +static inline void k210_16550_restoreuartint(FAR struct k210_16550_s *priv, + uint32_t ier) +{ + priv->ier |= ier & UART_IER_ALLIE; + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: k210_16550_enablebreaks + ****************************************************************************/ + +static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv, + bool enable) +{ + uint32_t lcr = k210_16550_serialin(priv, UART_LCR_OFFSET); + + if (enable) + { + lcr |= UART_LCR_BRK; + } + else + { + lcr &= ~UART_LCR_BRK; + } + + k210_16550_serialout(priv, UART_LCR_OFFSET, lcr); +} + +/**************************************************************************** + * Name: k210_16550_divisor + * + * Description: + * Select a divider to produce the BAUD from the UART_CLK. + * + * BAUD = UART_CLK / (16 * DL), or + * DIV = UART_CLK / BAUD / 16 + * + * Ignoring the fractional divider for now. + * + ****************************************************************************/ + +#ifndef CONFIG_K210_16550_SUPRESS_CONFIG +static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv) +{ + return (priv->uartclk / (uint32_t)priv->baud); +// return (priv->uartclk + (priv->baud << 3)) / (priv->baud << 4); +} +#endif + +/**************************************************************************** + * Name: k210_16550_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int k210_16550_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; + uint16_t div; + uint8_t dlh, dll, dlf; + uint32_t lcr; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + uint32_t mcr; +#endif + + /* Clear fifos */ + + k210_16550_serialout(priv, UART_FCR_OFFSET, + (UART_FCR_RXRST | UART_FCR_TXRST)); + + /* Set trigger */ + + k210_16550_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); + + /* Set up the LCR */ + + lcr = 0; + switch (priv->bits) + { + case 5 : + lcr |= UART_LCR_WLS_5BIT; + break; + + case 6 : + lcr |= UART_LCR_WLS_6BIT; + break; + + case 7 : + lcr |= UART_LCR_WLS_7BIT; + break; + + default: + case 8 : + lcr |= UART_LCR_WLS_8BIT; + break; + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STB; + } + + if (priv->parity == 1) + { + lcr |= UART_LCR_PEN; + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PEN | UART_LCR_EPS); + } + + /* Enter DLAB=1 */ + + k210_16550_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + + div = k210_16550_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); + + /* Clear DLAB */ + + k210_16550_serialout(priv, UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + k210_16550_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); + if (priv->flow) + { + mcr |= UART_MCR_AFCE; + } + else + { + mcr &= ~UART_MCR_AFCE; + } + + mcr |= UART_MCR_RTS; + + k210_16550_serialout(priv, UART_MCR_OFFSET, mcr); + + k210_16550_serialout(priv, UART_SRT_OFFSET, 0x0); + +#endif /* defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) */ + +#endif + return OK; +} + +/**************************************************************************** + * Name: k210_16550_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void k210_16550_shutdown(struct uart_dev_s *dev) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + k210_16550_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: k210_16550_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX + * and TX interrupts are not enabled until the txint() and rxint() methods + * are called. + * + ****************************************************************************/ + +static int k210_16550_attach(struct uart_dev_s *dev) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, k210_16550_interrupt, dev); +#ifndef CONFIG_ARCH_NOINTC + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } +#endif + + return ret; +} + +/**************************************************************************** + * Name: k210_16550_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. + * The exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void k210_16550_detach(FAR struct uart_dev_s *dev) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: k210_16550_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. + * + ****************************************************************************/ + +static int k210_16550_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; + uint32_t status; + int passes; + uint8_t v_int_status; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (FAR struct k210_16550_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = k210_16550_serialin(priv, UART_IIR_OFFSET); + + if (status == 0) + { + break; + } + v_int_status = status & 0xF; + + /* The UART_IIR_INTSTATUS bit should be zero if there are pending + * interrupts + */ + if(v_int_status == UART_INTERRUPT_SEND) + { + uart_xmitchars(dev); + break; + } + + else if (v_int_status == UART_INTERRUPT_RECEIVE || v_int_status == UART_INTERRUPT_CHARACTER_TIMEOUT) + { + uart_recvchars(dev); + break; + } + } + + return OK; +} + +/**************************************************************************** + * Name: k210_16550_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int k210_16550_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; + int ret; + +#ifdef CONFIG_SERIAL_UART_ARCH_IOCTL + ret = uart_ioctl(filep, cmd, arg); + + if (ret != -ENOTTY) + { + return ret; + } + +#else + ret = OK; +#endif + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + FAR struct k210_16550_s *user = (FAR struct k210_16550_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct k210_16550_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + k210_16550_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + k210_16550_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + +#if defined(CONFIG_SERIAL_TERMIOS) && !defined(CONFIG_K210_16550_SUPRESS_CONFIG) + case TCGETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + irqstate_t flags; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + flags = enter_critical_section(); + + cfsetispeed(termiosp, priv->baud); + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + termiosp->c_cflag |= priv->flow ? CRTSCTS : 0; +#endif + + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + case 8: + default: + termiosp->c_cflag |= CS8; + break; + } + + leave_critical_section(flags); + } + break; + + case TCSETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + irqstate_t flags; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + flags = enter_critical_section(); + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + priv->bits = 5; + break; + + case CS6: + priv->bits = 6; + break; + + case CS7: + priv->bits = 7; + break; + + case CS8: + default: + priv->bits = 8; + break; + } + + if ((termiosp->c_cflag & PARENB) != 0) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->baud = cfgetispeed(termiosp); + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + priv->flow = (termiosp->c_cflag & CRTSCTS) != 0; +#endif + + k210_16550_setup(dev); + leave_critical_section(flags); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: k210_16550_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int k210_16550_receive(struct uart_dev_s *dev, unsigned int *status) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + uint32_t rbr = 0; + *status = k210_16550_serialin(priv, UART_LSR_OFFSET); + rbr = k210_16550_serialin(priv, UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: k210_16550_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void k210_16550_rxint(struct uart_dev_s *dev, bool enable) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + + if (enable) + { + priv->ier |= UART_IER_ERBFI; + } + else + { + priv->ier &= ~UART_IER_ERBFI; + } + + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: k210_16550_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool k210_16550_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); +} + +/**************************************************************************** + * Name: k210_16550_dma* + * + * Description: + * Stubbed out DMA-related methods + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool k210_16550_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; + + if (priv->flow) + { + /* Disable Rx interrupt to prevent more data being from + * peripheral if the RX buffer is near full. When hardware + * RTS is enabled, this will prevent more data from coming + * in. Otherwise, enable Rx interrupt to make sure that more + * input is received. + */ + + k210_16550_rxint(dev, !upper); + return true; + } +#endif + + return false; +} +#endif + +/**************************************************************************** + * Name: k210_16550_dma* + * + * Description: + * Stub functions used when serial DMA is enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_TXDMA +static void k210_16550_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_16550_dmarxfree(FAR struct uart_dev_s *dev) +{ +} +#endif + +#ifdef CONFIG_SERIAL_TXDMA +static void k210_16550_dmatxavail(FAR struct uart_dev_s *dev) +{ +} +#endif + +/**************************************************************************** + * Name: k210_16550_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void k210_16550_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); +} + +/**************************************************************************** + * Name: k210_16550_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void k210_16550_txint(struct uart_dev_s *dev, bool enable) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_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); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + } + else + { + priv->ier &= ~UART_IER_ETBEI; + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: k210_16550_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool k210_16550_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)); +} + +/**************************************************************************** + * Name: k210_16550_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool k210_16550_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); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_uart_16550_register + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void k210_uart_16550_register(void) +{ +#if defined(CONFIG_K210_16550_UART1) + k210_16550_setup(&g_uart1port); + uart_register("/dev/ttyS1", &g_uart1port); +#endif +#if defined(CONFIG_K210_16550_UART2) + k210_16550_setup(&g_uart2port); + uart_register("/dev/ttyS2", &g_uart2port); +#endif +#if defined(CONFIG_K210_16550_UART3) + k210_16550_setup(&g_uart3port); + uart_register("/dev/ttyS3", &g_uart3port); +#endif +} + +#endif /* CONFIG_K210_16550_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_16550.h new file mode 100644 index 000000000..dbf2f4cbf --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h @@ -0,0 +1,339 @@ +/* +* 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_uart_16550.h + * @brief k210 uart1-uart3 support + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.09.28 + */ + +#ifndef __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H +#define __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_K210_16550_UART + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIGURATION ************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_K210_16550_UART1) || defined(CONFIG_K210_16550_UART2) || defined(CONFIG_K210_16550_UART3) +# define HAVE_UART 1 +#endif + +/* We need to be told the address increment between registers and the + * register bit width. + */ + +#ifndef CONFIG_K210_16550_REGINCR +# error "CONFIG_K210_16550_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" +#endif + +#ifndef CONFIG_K210_16550_REGWIDTH +# error "CONFIG_K210_16550_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" +#endif + +#ifndef CONFIG_K210_16550_ADDRWIDTH +# error "CONFIG_K210_16550_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" +#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 +# endif +# ifndef CONFIG_K210_16550_UART1_CLOCK +# error "CONFIG_K210_16550_UART1_CLOCK not provided" +# undef CONFIG_K210_16550_UART1 +# endif +# ifndef CONFIG_K210_16550_UART1_IRQ +# error "CONFIG_K210_16550_UART1_IRQ not provided" +# undef CONFIG_K210_16550_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 +# endif +# ifndef CONFIG_K210_16550_UART2_CLOCK +# error "CONFIG_K210_16550_UART2_CLOCK not provided" +# undef CONFIG_K210_16550_UART2 +# endif +# ifndef CONFIG_K210_16550_UART2_IRQ +# error "CONFIG_K210_16550_UART2_IRQ not provided" +# undef CONFIG_K210_16550_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 +# endif +# ifndef CONFIG_K210_16550_UART3_CLOCK +# error "CONFIG_K210_16550_UART3_CLOCK not provided" +# undef CONFIG_K210_16550_UART3 +# endif +# ifndef CONFIG_K210_16550_UART3_IRQ +# error "CONFIG_K210_16550_UART3_IRQ not provided" +# undef CONFIG_K210_16550_UART3 +# endif +#endif + +/* Is there a serial console? There should be at most one defined. + * It could be on any UARTn, n=0,1,2,3 + */ + +/* Register offsets *********************************************************/ + +#define UART_RBR_INCR 0 /* (DLAB =0) Receiver Buffer Register */ +#define UART_THR_INCR 0 /* (DLAB =0) Transmit Holding Register */ +#define UART_DLL_INCR 0 /* (DLAB =1) Divisor Latch LSB */ +#define UART_DLM_INCR 1 /* (DLAB =1) Divisor Latch MSB */ +#define UART_IER_INCR 1 /* (DLAB =0) Interrupt Enable Register */ +#define UART_IIR_INCR 2 /* Interrupt ID Register */ +#define UART_FCR_INCR 2 /* FIFO Control Register */ +#define UART_LCR_INCR 3 /* Line Control Register */ +#define UART_MCR_INCR 4 /* Modem Control Register */ +#define UART_LSR_INCR 5 /* Line Status Register */ +#define UART_MSR_INCR 6 /* Modem Status Register */ +#define UART_SCR_INCR 7 /* Scratch Pad Register */ +#define UART_SRT_INCR 39 /* Receive Fifo Trigger Register*/ +#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) + +/* Register bit definitions *************************************************/ + +/* RBR (DLAB =0) Receiver Buffer Register */ + +#define UART_RBR_MASK (0xff) /* Bits 0-7: Oldest received byte in RX FIFO */ + /* Bits 8-31: Reserved */ + +/* THR (DLAB =0) Transmit Holding Register */ + +#define UART_THR_MASK (0xff) /* Bits 0-7: Adds byte to TX FIFO */ + /* Bits 8-31: Reserved */ + +/* DLL (DLAB =1) Divisor Latch LSB */ + +#define UART_DLL_MASK (0xff) /* Bits 0-7: DLL */ + /* Bits 8-31: Reserved */ + +/* DLM (DLAB =1) Divisor Latch MSB */ + +#define UART_DLM_MASK (0xff) /* Bits 0-7: DLM */ + /* Bits 8-31: Reserved */ + +/* IER (DLAB =0) Interrupt Enable Register */ + +#define UART_IER_ERBFI (1 << 0) /* Bit 0: Enable received data available interrupt */ +#define UART_IER_ETBEI (1 << 1) /* Bit 1: Enable THR empty interrupt */ +#define UART_IER_ELSI (1 << 2) /* Bit 2: Enable receiver line status interrupt */ +#define UART_IER_EDSSI (1 << 3) /* Bit 3: Enable MODEM status interrupt */ + /* Bits 4-7: Reserved */ +#define UART_IER_ALLIE (0x0f) + +/* IIR Interrupt ID Register */ + +#define UART_IIR_INTSTATUS (1 << 0) /* Bit 0: Interrupt status (active low) */ +#define UART_IIR_INTID_SHIFT (1) /* Bits 1-3: Interrupt identification */ +#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT) +# define UART_IIR_INTID_MSI (0 << UART_IIR_INTID_SHIFT) /* Modem Status */ +# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* THR Empty Interrupt */ +# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* Receive Data Available (RDA) */ +# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* Receiver Line Status (RLS) */ +# define UART_IIR_INTID_CTI (6 << UART_IIR_INTID_SHIFT) /* Character Time-out Indicator (CTI) */ + + /* Bits 4-5: Reserved */ +#define UART_IIR_FIFOEN_SHIFT (6) /* Bits 6-7: RCVR FIFO interrupt */ +#define UART_IIR_FIFOEN_MASK (3 << UART_IIR_FIFOEN_SHIFT) + +/* FCR FIFO Control Register */ + +#define UART_FCR_FIFOEN (1 << 0) /* Bit 0: Enable FIFOs */ +#define UART_FCR_RXRST (1 << 1) /* Bit 1: RX FIFO Reset */ +#define UART_FCR_TXRST (1 << 2) /* Bit 2: TX FIFO Reset */ +#define UART_FCR_DMAMODE (1 << 3) /* Bit 3: DMA Mode Select */ + /* Bits 4-5: Reserved */ +#define UART_FCR_RXTRIGGER_SHIFT (6) /* Bits 6-7: RX Trigger Level */ +#define UART_FCR_RXTRIGGER_MASK (3 << UART_FCR_RXTRIGGER_SHIFT) +# define UART_FCR_RXTRIGGER_1 (0 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 0 (1 character) */ +# define UART_FCR_RXTRIGGER_4 (1 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 1 (4 characters) */ +# define UART_FCR_RXTRIGGER_8 (2 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 2 (8 characters) */ +# define UART_FCR_RXTRIGGER_14 (3 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 3 (14 characters) */ + +/* LCR Line Control Register */ + +#define UART_LCR_WLS_SHIFT (0) /* Bit 0-1: Word Length Select */ +#define UART_LCR_WLS_MASK (3 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_5BIT (0 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_6BIT (1 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_7BIT (2 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_8BIT (3 << UART_LCR_WLS_SHIFT) +#define UART_LCR_STB (1 << 2) /* Bit 2: Number of Stop Bits */ +#define UART_LCR_PEN (1 << 3) /* Bit 3: Parity Enable */ +#define UART_LCR_EPS (1 << 4) /* Bit 4: Even Parity Select */ +#define UART_LCR_STICKY (1 << 5) /* Bit 5: Stick Parity */ +#define UART_LCR_BRK (1 << 6) /* Bit 6: Break Control */ +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit (DLAB) */ + +/* MCR Modem Control Register */ + +#define UART_MCR_DTR (1 << 0) /* Bit 0: DTR Control Source for DTR output */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Control Source for RTS output */ +#define UART_MCR_OUT1 (1 << 2) /* Bit 2: Auxiliary user-defined output 1 */ +#define UART_MCR_OUT2 (1 << 3) /* Bit 3: Auxiliary user-defined output 2 */ +#define UART_MCR_LPBK (1 << 4) /* Bit 4: Loopback Mode Select */ +#define UART_MCR_AFCE (1 << 5) /* Bit 5: Auto Flow Control Enable */ + /* Bit 6-7: Reserved */ + +/* LSR Line Status Register */ + +#define UART_LSR_DR (1 << 0) /* Bit 0: Data Ready */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register Empty */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */ +#define UART_LSR_RXFE (1 << 7) /* Bit 7: Error in RX FIFO (RXFE) */ + +#define UART_INTERRUPT_SEND 0x02U +#define UART_INTERRUPT_RECEIVE 0x04U +#define UART_INTERRUPT_CHARACTER_TIMEOUT 0x0CU + +/* SCR Scratch Pad Register */ + +#define UART_SCR_MASK (0xff) /* Bits 0-7: SCR data */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#if CONFIG_K210_16550_REGWIDTH == 8 +typedef uint8_t uart_datawidth_t; +#elif CONFIG_K210_16550_REGWIDTH == 16 +typedef uint16_t uart_datawidth_t; +#elif CONFIG_K210_16550_REGWIDTH == 32 +typedef uint32_t uart_datawidth_t; +#endif + +#if CONFIG_K210_16550_ADDRWIDTH == 0 +typedef uintptr_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 8 +typedef uint8_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 16 +typedef uint16_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 32 +typedef uint32_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 64 +typedef uint64_t uart_addrwidth_t; +#endif + +struct k210_16550_s +{ + uart_addrwidth_t uartbase; /* Base address of UART registers */ +#ifndef CONFIG_K210_16550_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 + 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 */ +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flow; /* flow control (RTS/CTS) enabled */ +#endif +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: uart_getreg(), uart_putreg(), uart_ioctl() + * + * Description: + * These functions must be provided by the processor-specific code in order + * to correctly access 16550 registers + * uart_ioctl() is optional to provide custom IOCTLs + * + ****************************************************************************/ + +#ifndef CONFIG_SERIAL_UART_ARCH_MMIO +uart_datawidth_t uart_getreg(uart_addrwidth_t base, unsigned int offset); +void uart_putreg(uart_addrwidth_t base, + unsigned int offset, + uart_datawidth_t value); +#endif + +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 */ +#endif /* __INCLUDE_NUTTX_SERIAL_UART_16550_H */