forked from xuos/xiuos
				
			add 4g、ch376、w5500、gt911 driver for xidatong-riscv64 on nuttx from Wang_guozhu
it is OK
This commit is contained in:
		
						commit
						de947e0942
					
				| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 ****************************************************************************/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 );	
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,6 @@
 | 
			
		|||
#include <nuttx/config.h>
 | 
			
		||||
 | 
			
		||||
#include <nuttx/board.h>
 | 
			
		||||
 | 
			
		||||
#include <arch/board/board.h>
 | 
			
		||||
 | 
			
		||||
#include "k210_fpioa.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
 * 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
											
										
									
								
							| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@
 | 
			
		|||
 ****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "fpioa.h"
 | 
			
		||||
 | 
			
		||||
/****************************************************************************
 | 
			
		||||
 * Pre-processor Definitions
 | 
			
		||||
| 
						 | 
				
			
			@ -44,8 +45,30 @@
 | 
			
		|||
#define K210_GPIOHS_MAX_PINNO  32
 | 
			
		||||
#define K210_GPIO_MAX_PINNO    8
 | 
			
		||||
 | 
			
		||||
#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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +109,199 @@
 | 
			
		|||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,36 +39,72 @@
 | 
			
		|||
#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);
 | 
			
		||||
    uint32_t org = (*bits) & ~mask;
 | 
			
		||||
    *bits = org | (value & mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    set_bit(bits, mask << offset, value << offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    set_bit_offset(bits, 1, offset, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 = FPIOA_PULL_NONE;
 | 
			
		||||
  uint32_t dir = 0;
 | 
			
		||||
    fpioa_pull_t pull;
 | 
			
		||||
    uint32_t dir;
 | 
			
		||||
 | 
			
		||||
  switch (mode)
 | 
			
		||||
    switch(mode)
 | 
			
		||||
    {
 | 
			
		||||
        case GPIO_DM_INPUT:
 | 
			
		||||
            pull = FPIOA_PULL_NONE;
 | 
			
		||||
| 
						 | 
				
			
			@ -87,34 +123,26 @@ void k210_gpio_set_direction(uint32_t io, gpio_drive_mode_t mode)
 | 
			
		|||
            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);
 | 
			
		||||
    set_gpio_bit(gpio->direction.u32, pin, dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void k210_gpio_set_value(uint32_t io, bool val)
 | 
			
		||||
gpio_pin_value_t gpio_get_pin(uint8_t pin)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t setbit = val << io;
 | 
			
		||||
  uint32_t clrbit  = (!val) << io;
 | 
			
		||||
  modifyreg32(GPIO_OUTPUT, clrbit, setbit);
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool k210_gpio_get_value(uint32_t io)
 | 
			
		||||
void gpio_set_pin(uint8_t pin, gpio_pin_value_t value)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t reg = getreg32(GPIO_INPUT);
 | 
			
		||||
 | 
			
		||||
  if (reg & (1 << io))
 | 
			
		||||
    {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
 * 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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
		Loading…
	
		Reference in New Issue