add 4g、ch376、w5500、gt911 driver for xidatong-riscv64 on nuttx from Wang_guozhu

it is OK
This commit is contained in:
xuedongliang 2022-10-25 23:10:24 +08:00
commit de947e0942
48 changed files with 13243 additions and 303 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <adapter.h>
#include <at_agent.h>
#include "../adapter_wifi.h"
#include <stdlib.h>
#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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -36,6 +36,8 @@
#include "k210.h"
#include "k210_clockconfig.h"
#include "xidatong-riscv64.h"
#include <arch/board/board.h>
#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;
}

View File

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

View File

@ -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 <nuttx/config.h>
#include <sys/ioctl.h>
#include <nuttx/time.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/arch.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <debug.h>
#include <assert.h>
#include <fcntl.h>
#include <nuttx/ioexpander/gpio.h>
#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

View File

@ -53,6 +53,7 @@
#include <stdlib.h>
#include <fcntl.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#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

View File

@ -34,7 +34,7 @@
#include <arch/irq.h>
#include <nuttx/ioexpander/gpio.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#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];

View File

@ -25,7 +25,6 @@
#include <nuttx/config.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "k210_fpioa.h"

View File

@ -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<len;i++)
{
IIC_Send_Byte(buf[i]);
ret=IIC_Wait_Ack();
if(ret)break;
}
IIC_Stop();
return ret;
}
/***********************************************************************************
* Name: GT911_RD_Reg
* Description: Read data from GT911 once
* input: reg: start register address,buf: data cache area,len: read data length
* output: None
* return: None
***********************************************************************************/
static void GT911_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{
uint8_t i;
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();
IIC_Stop();
IIC_Start();
IIC_Send_Byte(CT_CMD_RD);
IIC_Wait_Ack();
for(i=0;i<len;i++)
{
buf[i]=IIC_Read_Byte(i==(len-1)?0:1);
}
IIC_Stop();
}
/***********************************************************************************
* Name: GT911_ReadFirmwareVersion
* Description: Get firmware version number
* input: None
* output: None
* return: version number
***********************************************************************************/
static uint16_t GT911_ReadFirmwareVersion(void)
{
uint8_t buf[2];
GT911_RD_Reg(GT911_FIRMWARE_VERSION_REG, buf, 2);
return ((uint16_t)buf[1] << 8) + buf[0];
}
/***********************************************************************************
* Name: GT911_Scan
* Description: point:structure to store coordinates
* input: None
* output: None
* return: Returns true for touch, false for no touch
***********************************************************************************/
bool GT911_Scan(POINT* point)
{
GT911_Dev Dev_Now;
uint8_t Clearbuf = 0;
uint8_t buf[41];
GT911_RD_Reg(GT911_READ_XY_REG, buf, 1);
if ((buf[0]&0x80) == 0x00)
{
GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1);
return false;
}
else
{
Dev_Now.TouchCount = buf[0] & 0x0f;
if((Dev_Now.TouchCount > 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);
}
}
}

View File

@ -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 <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include <nuttx/time.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <debug.h>
#include <assert.h>
#include <nuttx/time.h>
#include <nuttx/fs/fs.h>
#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

View File

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

View File

@ -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 <nuttx/config.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <debug.h>
#include <assert.h>
#include <nuttx/time.h>
#include <nuttx/fs/fs.h>
#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

View File

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

View File

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

View File

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

View File

@ -596,6 +596,18 @@ static const struct cmdmap_s g_cmdmap[] =
{ "xd", cmd_xd, 3, 3, "<hex-address> <byte-count>" },
#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

View File

@ -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 <arch/irq.h>
/****************************************************************************
* 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 */

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -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]);
}

View File

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

View File

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

View File

@ -38,52 +38,127 @@
#include <stdbool.h>
#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 */

View File

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

View File

@ -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 <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/serial/serial.h>
#include <arch/board/board.h>
#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 */

View File

@ -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 <math.h>
#include <stdint.h>
#include <stdio.h>

View File

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

View File

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

View File

@ -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 <nuttx/config.h>
#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 */