forked from xuos/xiuos
Merge branch 'prepare_for_master' of https://gitlink.org.cn/xuos/xiuos into prepare_for_master
This commit is contained in:
commit
5a64507a84
|
@ -2,7 +2,7 @@ include $(KERNEL_ROOT)/.config
|
|||
|
||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||
include $(APPDIR)/Make.defs
|
||||
CSRCS += framework_init.c
|
||||
CSRCS +=
|
||||
include $(APPDIR)/Application.mk
|
||||
endif
|
||||
|
||||
|
@ -10,7 +10,7 @@ endif
|
|||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
SRC_DIR := general_functions app_test
|
||||
|
||||
SRC_FILES := main.c framework_init.c
|
||||
SRC_FILES := main.c
|
||||
ifeq ($(CONFIG_LIB_LV),y)
|
||||
SRC_DIR += lv_app
|
||||
endif
|
||||
|
|
|
@ -164,7 +164,7 @@ void TcpSocketRecvTest(int argc, char *argv[])
|
|||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||
sys_thread_new("TcpSocketRecvTask", TcpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||
#endif
|
||||
|
||||
|
@ -231,7 +231,7 @@ void TcpSocketSendTest(int argc, char *argv[])
|
|||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip);
|
||||
sys_thread_new("Tcp Socket Send", TcpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||
#endif
|
||||
#ifdef ADD_NUTTX_FETURES
|
||||
|
|
|
@ -144,7 +144,7 @@ void UdpSocketRecvTest(int argc, char *argv[])
|
|||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||
sys_thread_new("UdpSocketRecvTask", UdpSocketRecvTask, NULL,
|
||||
LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
|
||||
#endif
|
||||
|
@ -207,7 +207,7 @@ void UdpSocketSendTest(int argc, char *argv[])
|
|||
}
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
lwip_config_tcp(lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||
lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip);
|
||||
sys_thread_new("UdpSocketSendTask", UdpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE,
|
||||
LWIP_DEMO_TASK_PRIO);
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,32 @@
|
|||
* @date 2022.9.27
|
||||
*/
|
||||
|
||||
#include <control.h>
|
||||
|
||||
void ControlOmronTest(void)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t read_data_length = 0;
|
||||
uint8_t read_data[1024] = {0};
|
||||
ControlProtocolType fins_protocol = ControlProtocolFind();
|
||||
if (NULL == fins_protocol) {
|
||||
printf("%s get fins protocol %p failed\n", __func__, fins_protocol);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s get fins protocol %p successfull\n", __func__, fins_protocol);
|
||||
|
||||
if (CONTROL_REGISTERED == fins_protocol->protocol_status) {
|
||||
ControlProtocolOpen(fins_protocol);
|
||||
|
||||
for (;;) {
|
||||
read_data_length = ControlProtocolRead(fins_protocol, read_data, sizeof(read_data));
|
||||
printf("%s read [%d] fins data %d using receipe file\n", __func__, i, read_data_length);
|
||||
i++;
|
||||
PrivTaskDelay(100000);
|
||||
}
|
||||
|
||||
//ControlProtocolClose(fins_protocol);
|
||||
}
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(ControlOmronTest, Omron Plc FINS Demo, PRIV_SHELL_CMD_MAIN_ATTR);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
SRC_DIR := list
|
||||
SRC_DIR := list circular_area
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,11 @@
|
|||
include $(KERNEL_ROOT)/.config
|
||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||
include $(APPDIR)/Make.defs
|
||||
CSRCS += circular_area_app.c
|
||||
include $(APPDIR)/Application.mk
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
SRC_FILES := circular_area_app.c
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
endif
|
|
@ -0,0 +1,11 @@
|
|||
import os
|
||||
from building import *
|
||||
Import('RTT_ROOT')
|
||||
Import('rtconfig')
|
||||
cwd = GetCurrentDir()
|
||||
DEPENDS = [""]
|
||||
|
||||
SOURCES = ['circular_area_app.c']
|
||||
path = [cwd]
|
||||
objs = DefineGroup('circular_area', src = SOURCES, depend = DEPENDS,CPPPATH = path)
|
||||
Return("objs")
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: circular_area_app.c
|
||||
* @brief: circular area file for applications
|
||||
* @version: 3.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2022/11/21
|
||||
*
|
||||
*/
|
||||
|
||||
#include "circular_area_app.h"
|
||||
|
||||
/**
|
||||
* This function will return whether the circular_area is full or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
int CircularAreaAppIsFull(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if((circular_area->readidx == circular_area->writeidx) && (circular_area->b_status)) {
|
||||
printf("the circular area is full\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether the circular_area is empty or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
int CircularAreaAppIsEmpty(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if((circular_area->readidx == circular_area->writeidx) && (!circular_area->b_status)) {
|
||||
printf("the circular area is empty\n");
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will reset the circular_area and set the descriptor to default
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
void CircularAreaAppReset(CircularAreaAppType circular_area)
|
||||
{
|
||||
circular_area->writeidx = 0;
|
||||
circular_area->readidx = 0;
|
||||
circular_area->b_status = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will release the circular_area descriptor and free the memory
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
void CircularAreaAppRelease(CircularAreaAppType circular_area)
|
||||
{
|
||||
circular_area->readidx = 0;
|
||||
circular_area->writeidx = 0;
|
||||
circular_area->p_head = NULL;
|
||||
circular_area->p_tail = NULL;
|
||||
circular_area->b_status = 0;
|
||||
circular_area->area_length = 0;
|
||||
|
||||
PrivFree(circular_area->data_buffer);
|
||||
PrivFree(circular_area);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the circual_area max length
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
return circular_area->area_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will get the data length of the circular_area
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
*/
|
||||
uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if(CircularAreaAppIsFull(circular_area)) {
|
||||
return circular_area->area_length;
|
||||
} else {
|
||||
return (circular_area->writeidx - circular_area->readidx + circular_area->area_length) % circular_area->area_length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether it is need to divide the read data into two parts or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param data_length output data length
|
||||
*/
|
||||
static uint32_t CircularAreaAppDivideRdData(CircularAreaAppType circular_area, uint32_t data_length)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if(circular_area->readidx + data_length <= circular_area->area_length) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will return whether it is need to divide the write data into two parts or not
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param data_length input data length
|
||||
*/
|
||||
static uint32_t CircularAreaAppDivideWrData(CircularAreaAppType circular_area, uint32_t data_length)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
|
||||
if(circular_area->writeidx + data_length <= circular_area->area_length) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will read data from the circular_area
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param output_buffer output data buffer poniter
|
||||
* @param data_length output data length
|
||||
*/
|
||||
int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
CA_PARAM_CHECK(output_buffer);
|
||||
CHECK(data_length > 0);
|
||||
|
||||
if(CircularAreaAppIsEmpty(circular_area)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t read_length = (data_length > CircularAreaAppGetDataLength(circular_area)) ? CircularAreaAppGetDataLength(circular_area) : data_length;
|
||||
// if (data_length > CircularAreaAppGetDataLength(circular_area)) {
|
||||
// return -1;
|
||||
// }
|
||||
|
||||
if(CircularAreaAppDivideRdData(circular_area, read_length)) {
|
||||
uint32_t read_len_up = circular_area->area_length - circular_area->readidx;
|
||||
uint32_t read_len_down = read_length - read_len_up;
|
||||
|
||||
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_len_up);
|
||||
memcpy(output_buffer + read_len_up, circular_area->p_head, read_len_down);
|
||||
|
||||
circular_area->readidx = read_len_down;
|
||||
} else {
|
||||
memcpy(output_buffer, &circular_area->data_buffer[circular_area->readidx], read_length);
|
||||
circular_area->readidx = (circular_area->readidx + read_length) % circular_area->area_length;
|
||||
}
|
||||
|
||||
circular_area->b_status = 0;
|
||||
|
||||
return read_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will write data to the circular_area
|
||||
*
|
||||
* @param circular_area CircularAreaApp descriptor
|
||||
* @param input_buffer input data buffer poniter
|
||||
* @param data_length input data length
|
||||
* @param b_force whether to force to write data disregard the length limit
|
||||
*/
|
||||
int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force)
|
||||
{
|
||||
CA_PARAM_CHECK(circular_area);
|
||||
CA_PARAM_CHECK(input_buffer);
|
||||
CHECK(data_length > 0);
|
||||
|
||||
if(CircularAreaAppIsFull(circular_area) && (!b_force)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t write_data_length = circular_area->area_length - CircularAreaAppGetDataLength(circular_area);
|
||||
//data_length = (data_length > write_data_length) ? write_data_length : data_length;
|
||||
if (data_length > write_data_length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(CircularAreaAppDivideWrData(circular_area, data_length)) {
|
||||
uint32_t write_len_up = circular_area->area_length - circular_area->writeidx;
|
||||
uint32_t write_len_down = data_length - write_len_up;
|
||||
|
||||
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, write_len_up);
|
||||
memcpy(circular_area->p_head, input_buffer + write_len_up, write_len_down);
|
||||
|
||||
circular_area->writeidx = write_len_down;
|
||||
} else {
|
||||
memcpy(&circular_area->data_buffer[circular_area->writeidx], input_buffer, data_length);
|
||||
circular_area->writeidx = (circular_area->writeidx + data_length) % circular_area->area_length;
|
||||
}
|
||||
|
||||
circular_area->b_status = 1;
|
||||
|
||||
if(b_force) {
|
||||
circular_area->readidx = circular_area->writeidx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct CircularAreaAppOps CircularAreaAppOperations =
|
||||
{
|
||||
CircularAreaAppRead,
|
||||
CircularAreaAppWrite,
|
||||
CircularAreaAppRelease,
|
||||
CircularAreaAppReset,
|
||||
};
|
||||
|
||||
/**
|
||||
* This function will initialize the circular_area
|
||||
*
|
||||
* @param circular_area_length circular_area length
|
||||
*/
|
||||
CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length)
|
||||
{
|
||||
CHECK(circular_area_length > 0);
|
||||
|
||||
circular_area_length = CA_ALIGN_DOWN(circular_area_length, 8);
|
||||
|
||||
CircularAreaAppType circular_area = PrivMalloc(sizeof(struct CircularAreaApp));
|
||||
if(NULL == circular_area) {
|
||||
printf("CircularAreaAppInit malloc struct circular_area failed\n");
|
||||
PrivFree(circular_area);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CircularAreaAppReset(circular_area);
|
||||
|
||||
circular_area->data_buffer = PrivMalloc(circular_area_length);
|
||||
if(NULL == circular_area->data_buffer) {
|
||||
printf("CircularAreaAppInit malloc circular_area data_buffer failed\n");
|
||||
PrivFree(circular_area->data_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
circular_area->p_head = circular_area->data_buffer;
|
||||
circular_area->p_tail = circular_area->data_buffer + circular_area_length;
|
||||
circular_area->area_length = circular_area_length;
|
||||
|
||||
printf("CircularAreaAppInit done p_head %8p p_tail %8p length %u\n",
|
||||
circular_area->p_head, circular_area->p_tail, circular_area->area_length);
|
||||
|
||||
circular_area->CircularAreaAppOperations = &CircularAreaAppOperations;
|
||||
|
||||
return circular_area;
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file: circular_area_app.h
|
||||
* @brief: function declaration and structure defintion of circular area for applications
|
||||
* @version: 3.0
|
||||
* @author: AIIT XUOS Lab
|
||||
* @date: 2022/11/21
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CIRCULAR_AREA_APP_H
|
||||
#define CIRCULAR_AREA_APP_H
|
||||
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CA_PARAM_CHECK(param) \
|
||||
do \
|
||||
{ \
|
||||
if(param == NULL) { \
|
||||
KPrintf("PARAM CHECK FAILED ...%s %d %s is NULL.\n", __func__, __LINE__, #param); \
|
||||
while(1); \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
#define CA_ALIGN_DOWN(size, align) ((size)/(align)*(align))
|
||||
|
||||
typedef struct CircularAreaApp *CircularAreaAppType;
|
||||
|
||||
struct CircularAreaAppOps
|
||||
{
|
||||
int (*read) (CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length);
|
||||
int (*write) (CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force);
|
||||
void (*release) (CircularAreaAppType circular_area);
|
||||
void (*reset) (CircularAreaAppType circular_area);
|
||||
};
|
||||
|
||||
struct CircularAreaApp
|
||||
{
|
||||
uint8_t *data_buffer;
|
||||
|
||||
uint32_t readidx;
|
||||
uint32_t writeidx;
|
||||
|
||||
uint8_t *p_head;
|
||||
uint8_t *p_tail;
|
||||
|
||||
uint32_t area_length;
|
||||
int b_status;
|
||||
|
||||
struct CircularAreaAppOps *CircularAreaAppOperations;
|
||||
};
|
||||
|
||||
/*This function will return whether the circular_area is full or not*/
|
||||
int CircularAreaAppIsFull(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will return whether the circular_area is empty or not*/
|
||||
int CircularAreaAppIsEmpty(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will reset the circular_area and set the descriptor to default*/
|
||||
void CircularAreaAppReset(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will release the circular_area descriptor and free the memory*/
|
||||
void CircularAreaAppRelease(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will read data from the circular_area*/
|
||||
int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffer, uint32_t data_length);
|
||||
|
||||
/*This function will write data to the circular_area*/
|
||||
int CircularAreaAppWrite(CircularAreaAppType circular_area, uint8_t *input_buffer, uint32_t data_length, int b_force);
|
||||
|
||||
/*This function will get the circual_area max length*/
|
||||
uint32_t CircularAreaAppGetMaxLength(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will get the data length of the circular_area*/
|
||||
uint32_t CircularAreaAppGetDataLength(CircularAreaAppType circular_area);
|
||||
|
||||
/*This function will initialize the circular_area*/
|
||||
CircularAreaAppType CircularAreaAppInit(uint32_t circular_area_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
############################################################################
|
||||
# APP_Framework/Framework/Make.defs
|
||||
############################################################################
|
||||
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework
|
||||
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/transform_layer/nuttx
|
||||
include $(wildcard $(APPDIR)/../../../APP_Framework/Framework/*/Make.defs)
|
||||
|
|
|
@ -1,28 +1,40 @@
|
|||
SRC_DIR := transform_layer
|
||||
include $(KERNEL_ROOT)/.config
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
|
||||
SRC_DIR += sensor
|
||||
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
|
||||
include $(APPDIR)/Make.defs
|
||||
CSRCS += framework_init.c
|
||||
include $(APPDIR)/Application.mk
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y)
|
||||
SRC_DIR += connection
|
||||
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
|
||||
SRC_FILES := framework_init.c
|
||||
SRC_DIR := transform_layer
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
|
||||
SRC_DIR += sensor
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y)
|
||||
SRC_DIR += connection
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y)
|
||||
SRC_DIR += knowing
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y)
|
||||
SRC_DIR += control
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO),y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MBEDTLS), y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y)
|
||||
SRC_DIR += knowing
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y)
|
||||
SRC_DIR += control
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CRYPTO),y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MBEDTLS), y)
|
||||
SRC_DIR += security
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
@ -21,11 +21,8 @@
|
|||
#include <adapter.h>
|
||||
|
||||
static DoublelistType adapter_list;
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
static int adapter_list_lock;
|
||||
#else
|
||||
static pthread_mutex_t adapter_list_lock;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @description: Init adapter framework
|
||||
* @return 0
|
||||
|
|
|
@ -2,8 +2,28 @@ menuconfig SUPPORT_CONTROL_FRAMEWORK
|
|||
bool "support control framework"
|
||||
default n
|
||||
select TRANSFORM_LAYER_ATTRIUBUTE
|
||||
select BSP_USING_LWIP
|
||||
select BSP_USING_SDIO
|
||||
select MOUNT_SDCARD_FS
|
||||
select LIB_USING_CJSON
|
||||
|
||||
if SUPPORT_CONTROL_FRAMEWORK
|
||||
source "$APP_DIR/Framework/control/ipc_protocol/Kconfig"
|
||||
source "$APP_DIR/Framework/control/plc_protocol/Kconfig"
|
||||
config CONTROL_RECIPE_FILE
|
||||
string "control framework recipe file name"
|
||||
default "test_recipe.json"
|
||||
|
||||
menuconfig CONTROL_IPC_PROTOCOL
|
||||
bool "Using ipc protocol"
|
||||
default n
|
||||
if CONTROL_IPC_PROTOCOL
|
||||
source "$APP_DIR/Framework/control/ipc_protocol/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig CONTROL_PLC_PROTOCOL
|
||||
bool "Using plc protocol"
|
||||
default n
|
||||
if CONTROL_PLC_PROTOCOL
|
||||
source "$APP_DIR/Framework/control/plc_protocol/Kconfig"
|
||||
endif
|
||||
|
||||
endif
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
SRC_DIR := ipc_protocol plc_protocol shared
|
||||
SRC_DIR := shared
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_IPC_PROTOCOL), y)
|
||||
SRC_DIR += ipc_protocol
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PLC_PROTOCOL), y)
|
||||
SRC_DIR += plc_protocol
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -1,2 +1,8 @@
|
|||
config CONTROL_PROTOCOL_MODBUS_TCP
|
||||
bool "Using modbus_tcp control protocol"
|
||||
default n
|
||||
|
||||
config CONTROL_PROTOCOL_MODBUS_UART
|
||||
bool "Using modbus_uart control protocol"
|
||||
default n
|
||||
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
SRC_DIR := modbus_tcp modbus_uart
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_TCP), y)
|
||||
SRC_DIR := modbus_tcp
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_MODBUS_UART), y)
|
||||
SRC_DIR := modbus_uart
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
@ -1,365 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file plc_socket.c
|
||||
* @brief Demo for PLC socket communication function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.16
|
||||
*/
|
||||
|
||||
#include "transform.h"
|
||||
#include "plc_socket.h"
|
||||
#include "sys_arch.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "control_file.h"
|
||||
|
||||
// max support plc socket test commands number
|
||||
#define PLC_SOCK_CMD_NUM CTL_CMD_NUM
|
||||
#define PLC_SOCK_TIMEOUT 50000
|
||||
|
||||
// for saving PLC command index
|
||||
int plc_cmd_index = 0;
|
||||
|
||||
// only for test
|
||||
#define SUPPORT_PLC_SIEMENS
|
||||
|
||||
//siemens test
|
||||
PlcBinCmdType TestPlcCmd[PLC_SOCK_CMD_NUM] = {0};
|
||||
|
||||
//Test information
|
||||
//SIEMENS ip: 192.168.250.9 port: 102
|
||||
//S7-200 ip: 192.168.250.8 port: 102
|
||||
//S7-1200 ip: 192.168.250.6 port: 102
|
||||
//OML ip: 192.168.250.3 port: 9600
|
||||
|
||||
PlcSocketParamType plc_socket_demo_data = {
|
||||
#ifdef SUPPORT_PLC_SIEMENS
|
||||
.ip = {192, 168, 250, 6},
|
||||
.port = 102,
|
||||
.device_type = PLC_DEV_TYPE_SIEMENS,
|
||||
.socket_type = SOCK_STREAM,
|
||||
.cmd_num = 3,
|
||||
#else
|
||||
.ip = {192, 168, 250, 3},
|
||||
.port = 9600,
|
||||
.device_type = PLC_DEV_TYPE_OML,
|
||||
.socket_type = SOCK_DGRAM,
|
||||
.cmd_num = 1,
|
||||
#endif
|
||||
.recv_len = PLC_RECV_BUF_LEN,
|
||||
.recv_buf = NULL,
|
||||
};
|
||||
|
||||
#define OML_HEADER_LEN 78
|
||||
#define CHECK_OML_HEADER(_s) ((0xC0 == *(_s)) && (0x00 == *(_s + 1)) && (0x02 == *(_s + 2)) && (0x00 == *(_s + 3)))
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void plc_print_array(char *title, int size, uint8_t *cmd)
|
||||
{
|
||||
lw_notice("%s : %d - ", title, size);
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
lw_notice(" %#x", cmd[i]);
|
||||
}
|
||||
lw_notice("\n");
|
||||
}
|
||||
|
||||
static void *PlcSocketStart(void *arg)
|
||||
{
|
||||
int fd = -1;
|
||||
int timeout, recv_len;
|
||||
struct sockaddr_in sock_addr;
|
||||
socklen_t addr_len = sizeof(struct sockaddr_in);
|
||||
PlcSocketParamType *param = (PlcSocketParamType *)&plc_socket_demo_data;
|
||||
|
||||
plc_print("start %d.%d.%d.%d:%d dev %d sock %d\n",
|
||||
param->ip[0],
|
||||
param->ip[1],
|
||||
param->ip[2],
|
||||
param->ip[3],
|
||||
param->port,
|
||||
param->device_type,
|
||||
param->socket_type);
|
||||
|
||||
param->recv_len = PLC_RECV_BUF_LEN;
|
||||
|
||||
//malloc memory
|
||||
param->recv_buf = (char *)malloc(param->recv_len);
|
||||
if (param->recv_buf == NULL)
|
||||
{
|
||||
plc_error("No memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = socket(AF_INET, param->socket_type, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
plc_error("Socket error %d\n", param->socket_type);
|
||||
free(param->recv_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plc_print("start %d.%d.%d.%d:%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3], param->port);
|
||||
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_port = htons(param->port);
|
||||
sock_addr.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(param->ip[0], param->ip[1], param->ip[2], param->ip[3]));
|
||||
memset(&(sock_addr.sin_zero), 0, sizeof(sock_addr.sin_zero));
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr)) < 0)
|
||||
{
|
||||
plc_error("Unable to connect\n");
|
||||
closesocket(fd);
|
||||
free(param->recv_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lw_notice("client %s connected\n", inet_ntoa(sock_addr.sin_addr));
|
||||
|
||||
for(int i = 0; i < param->cmd_num; i ++)
|
||||
{
|
||||
PlcBinCmdType *cmd = &TestPlcCmd[i];
|
||||
sendto(fd, cmd->cmd, cmd->cmd_len, 0, (struct sockaddr*)&sock_addr, addr_len);
|
||||
plc_print_array("Send cmd", cmd->cmd_len, cmd->cmd);
|
||||
|
||||
MdelayKTask(cmd->delay_ms);
|
||||
timeout = PLC_SOCK_TIMEOUT;
|
||||
memset(param->recv_buf, 0, param->recv_len);
|
||||
while(timeout --)
|
||||
{
|
||||
recv_len = recvfrom(fd, param->recv_buf, param->recv_len, 0, (struct sockaddr *)&sock_addr, &addr_len);
|
||||
if(recv_len > 0)
|
||||
{
|
||||
if(param->device_type == PLC_DEV_TYPE_OML)
|
||||
{
|
||||
if((recv_len == OML_HEADER_LEN) && (CHECK_OML_HEADER(param->recv_buf)))
|
||||
{
|
||||
lw_notice("This is Oml package!!!\n");
|
||||
}
|
||||
}
|
||||
lw_notice("Receive from : %s\n", inet_ntoa(sock_addr.sin_addr));
|
||||
plc_print_array("Receive data", recv_len, param->recv_buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closesocket(fd);
|
||||
free(param->recv_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void PlcGetParamCmd(char *cmd)
|
||||
{
|
||||
const char s[2] = ",";
|
||||
char *token;
|
||||
uint16_t cmd_index = 0;
|
||||
char bin_cmd[PLC_BIN_CMD_LEN] = {0};
|
||||
token = strtok(cmd, s);
|
||||
while(token != NULL)
|
||||
{
|
||||
sscanf(token, "%x", &bin_cmd[cmd_index]);
|
||||
plc_print("%d - %s %d\n", cmd_index, token, bin_cmd[cmd_index]);
|
||||
token = strtok(NULL, s);
|
||||
cmd_index ++;
|
||||
}
|
||||
TestPlcCmd[plc_cmd_index].cmd_len = cmd_index;
|
||||
memcpy(TestPlcCmd[plc_cmd_index].cmd, bin_cmd, cmd_index);
|
||||
plc_print("get %d cmd len %d\n", plc_cmd_index, TestPlcCmd[plc_cmd_index].cmd_len);
|
||||
plc_cmd_index ++;
|
||||
plc_socket_demo_data.cmd_num = plc_cmd_index;
|
||||
}
|
||||
|
||||
void PlcShowUsage(void)
|
||||
{
|
||||
plc_notice("------------------------------------\n");
|
||||
plc_notice("PlcSocket [ip].[ip].[ip].[ip]:[port]\n");
|
||||
plc_notice("PlcSocket support other param:\n");
|
||||
plc_notice("plc=[] 0: OML 1:SIEMENS\n");
|
||||
plc_notice("tcp=[] 0: udp 1:tcp\n");
|
||||
plc_notice("ip=[ip.ip.ip.ip]\n");
|
||||
plc_notice("port=port\n");
|
||||
plc_notice("file: use %s\n", PLC_SOCK_FILE_NAME);
|
||||
plc_notice("------------------------------------\n");
|
||||
}
|
||||
|
||||
#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON)
|
||||
void PlcGetParamFromFile(char *file_name)
|
||||
{
|
||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
||||
|
||||
char *file_buf = malloc(CTL_FILE_LEN);
|
||||
if(file_buf == NULL)
|
||||
{
|
||||
plc_error("No enough buffer %d\n", CTL_FILE_LEN);
|
||||
return;
|
||||
}
|
||||
memset(file_buf, 0, CTL_FILE_LEN);
|
||||
|
||||
if(CtlFileReadWithFilename(file_name, CTL_FILE_LEN, file_buf) != EOK)
|
||||
{
|
||||
plc_error("Can't open file %s\n", file_name);
|
||||
//try again default file
|
||||
if(strcmp(file_name, PLC_SOCK_FILE_NAME) != 0)
|
||||
{
|
||||
if(CtlFileReadWithFilename(PLC_SOCK_FILE_NAME, CTL_FILE_LEN, file_buf) != EOK)
|
||||
{
|
||||
plc_error("Can't open file %s\n", file_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
CtlParseJsonData(file_buf);
|
||||
|
||||
memcpy(param->ip, ctl_file_param.ip, 4);
|
||||
param->port = ctl_file_param.port;
|
||||
param->cmd_num = ctl_file_param.cmd_num;
|
||||
param->socket_type = ctl_file_param.tcp ? SOCK_STREAM : SOCK_DGRAM;
|
||||
|
||||
for(int i = 0; i < param->cmd_num; i++)
|
||||
{
|
||||
TestPlcCmd[i].cmd_len = ctl_file_param.cmd_len[i];
|
||||
memcpy(TestPlcCmd[i].cmd, ctl_file_param.cmd[i], TestPlcCmd[i].cmd_len);
|
||||
}
|
||||
|
||||
plc_print("ip: %d.%d.%d.%d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]);
|
||||
plc_print("port: %d", param->port);
|
||||
plc_print("tcp: %d", param->socket_type);
|
||||
plc_print("cmd number: %d\n", param->cmd_num);
|
||||
|
||||
for(int i = 0; i < param->cmd_num; i++)
|
||||
{
|
||||
plc_print_array("cmd", TestPlcCmd[i].cmd_len, TestPlcCmd[i].cmd);
|
||||
}
|
||||
free(file_buf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void PlcCheckParam(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
||||
plc_cmd_index = 0;
|
||||
|
||||
for(i = 0; i < argc; i++)
|
||||
{
|
||||
char *str = argv[i];
|
||||
int is_tcp = 0;
|
||||
char cmd_str[PLC_BIN_CMD_LEN] = {0};
|
||||
|
||||
plc_print("check %d %s\n", i, str);
|
||||
|
||||
#if defined(MOUNT_SDCARD) && defined(LIB_USING_CJSON)
|
||||
if(strncmp(str, "file", 4) == 0)
|
||||
{
|
||||
char file_name[CTL_FILE_NAME_LEN] = {0};
|
||||
if(sscanf(str, "file=%s", file_name) == EOF)
|
||||
{
|
||||
strcpy(file_name, PLC_SOCK_FILE_NAME);
|
||||
}
|
||||
plc_notice("get %s parameter file %s\n", str, file_name);
|
||||
PlcGetParamFromFile(file_name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(sscanf(str, "ip=%d.%d.%d.%d",
|
||||
¶m->ip[0],
|
||||
¶m->ip[1],
|
||||
¶m->ip[2],
|
||||
¶m->ip[3]) == 4)
|
||||
{
|
||||
plc_print("find ip %d %d %d %d\n", param->ip[0], param->ip[1], param->ip[2], param->ip[3]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "port=%d", ¶m->port) == 1)
|
||||
{
|
||||
plc_print("find port %d\n", param->port);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "tcp=%d", &is_tcp) == 1)
|
||||
{
|
||||
plc_print("find tcp %d\n", is_tcp);
|
||||
param->socket_type = is_tcp ? SOCK_STREAM:SOCK_DGRAM;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "plc=%d", ¶m->device_type) == 1)
|
||||
{
|
||||
plc_print("find device %d\n", param->device_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(sscanf(str, "cmd=%s", cmd_str) == 1)
|
||||
{
|
||||
plc_print("find cmd %s\n", cmd_str);
|
||||
PlcGetParamCmd(cmd_str);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc >= 2)
|
||||
{
|
||||
if(sscanf(argv[1], "%d.%d.%d.%d:%d",
|
||||
¶m->ip[0],
|
||||
¶m->ip[1],
|
||||
¶m->ip[2],
|
||||
¶m->ip[3],
|
||||
¶m->port) != EOF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(sscanf(argv[1], "%d.%d.%d.%d",
|
||||
¶m->ip[0],
|
||||
¶m->ip[1],
|
||||
¶m->ip[2],
|
||||
¶m->ip[3]) != EOF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PlcShowUsage();
|
||||
}
|
||||
}
|
||||
|
||||
void PlcSocketTask(int argc, char *argv[])
|
||||
{
|
||||
int result = 0;
|
||||
pthread_t th_id;
|
||||
uint8_t enet_port = 0; ///< test enet port 0
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO;
|
||||
attr.stacksize = LWIP_TASK_STACK_SIZE;
|
||||
PlcSocketParamType *param = &plc_socket_demo_data;
|
||||
|
||||
PlcCheckParam(argc, argv);
|
||||
|
||||
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, param->ip);
|
||||
PrivTaskCreate(&th_id, &attr, PlcSocketStart, param);
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
|
||||
PlcSocket, PlcSocketTask, Test PLC Socket);
|
||||
|
|
@ -1,2 +1,15 @@
|
|||
config CONTROL_PROTOCOL_FINS
|
||||
bool "Using fins control protocol"
|
||||
default n
|
||||
|
||||
config CONTROL_PROTOCOL_MELSEC
|
||||
bool "Using melsec control protocol"
|
||||
default n
|
||||
|
||||
config CONTROL_PROTOCOL_OPCUA
|
||||
bool "Using opcua control protocol"
|
||||
default n
|
||||
|
||||
config CONTROL_PROTOCOL_S7
|
||||
bool "Using s7 control protocol"
|
||||
default n
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
SRC_DIR := fins melsec opcua s7
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_FINS), y)
|
||||
SRC_DIR := fins
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_MELSEC), y)
|
||||
SRC_DIR := melsec
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_OPCUA), y)
|
||||
SRC_DIR := opcua
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_S7), y)
|
||||
SRC_DIR := s7
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SRC_FILES :=
|
||||
SRC_FILES := fins.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fins.c
|
||||
* @brief plc protocol fins
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
||||
#include <fins.h>
|
||||
|
||||
#define FINS_COMMAND_LENGTH 34
|
||||
|
||||
static BasicSocketPlc plc_socket = {0};
|
||||
|
||||
static uint8_t handshake_require_command[] = {0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
static uint8_t handshake_respond_buff[24] = {0};
|
||||
static uint8_t recv_buff[1024] = {0};
|
||||
|
||||
/**
|
||||
* @description: Fins Get Area Code
|
||||
* @param area_char - area char
|
||||
* @param type - fins data type
|
||||
* @return success : area_char error : 0
|
||||
*/
|
||||
static uint8_t FinsAreaCode(char area_char, FinsDataType type)
|
||||
{
|
||||
uint8_t area_code = 0;
|
||||
if (area_char == 'C')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x30 : 0xB0);
|
||||
if (area_char == 'W')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x31 : 0xB1);
|
||||
if (area_char == 'H')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x32 : 0xB2);
|
||||
if (area_char == 'D')
|
||||
area_code = (type == FINS_DATA_TYPE_BIT ? 0x02 : 0x82);
|
||||
return area_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Cmd Genetare
|
||||
* @param p_command - command pointer
|
||||
* @param plc_ip_4 - last plc ip
|
||||
* @param local_ip_4 - last local ip
|
||||
* @param p_read_item - p_read_item pointer
|
||||
* @return success : index error : 0
|
||||
*/
|
||||
static uint16_t FinsCommandGenerate(uint8_t *p_command, uint16_t plc_ip_4, uint16_t local_ip_4, FinsReadItem *p_read_item)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
uint16_t command_code = p_read_item->data_info.command_code;
|
||||
uint8_t area_char = p_read_item->area_char;
|
||||
uint16_t data_type = p_read_item->data_type;
|
||||
uint16_t start_address = p_read_item->start_address;
|
||||
uint8_t bit_address = p_read_item->bit_address;
|
||||
uint16_t data_length = p_read_item->data_length;
|
||||
|
||||
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (3 * 8));
|
||||
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (2 * 8));
|
||||
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (1 * 8));
|
||||
p_command[index++] = (uint8_t)FINS_HEADER_HEAD;
|
||||
p_command[index++] = (uint8_t)FINS_HEADER_READ_COMMAND_LENGTH >> (3 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (2 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (1 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH;
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (3 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (2 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (1 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND;
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (3 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (2 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (1 * 8);
|
||||
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE;
|
||||
p_command[index++] = FINS_ICF;
|
||||
p_command[index++] = FINS_RSV;
|
||||
p_command[index++] = FINS_GCT;
|
||||
|
||||
p_command[index++] = FINS_DNA;
|
||||
p_command[index++] = plc_ip_4;
|
||||
p_command[index++] = FINS_DA2;
|
||||
|
||||
p_command[index++] = FINS_SNA;
|
||||
p_command[index++] = local_ip_4;
|
||||
p_command[index++] = FINS_SA2;
|
||||
|
||||
p_command[index++] = FINS_SID;
|
||||
|
||||
p_command[index++] = command_code >> 8;
|
||||
p_command[index++] = command_code;
|
||||
p_command[index++] = FinsAreaCode(area_char, data_type);
|
||||
p_command[index++] = start_address >> 8;
|
||||
p_command[index++] = start_address;
|
||||
p_command[index++] = bit_address;
|
||||
p_command[index++] = data_length >> 8;
|
||||
p_command[index++] = data_length;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Data Transform from Receive Buffer To Control-Data
|
||||
* @param p_read_item - read item pointer
|
||||
* @param recv_buff - receive buff
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int FinsTransformRecvBuffToData(FinsReadItem *p_read_item, uint8_t *recv_buff)
|
||||
{
|
||||
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
|
||||
uint8_t error_code = recv_buff[15];
|
||||
if (error_code) {
|
||||
printf("Data abnormal, abnormal error code is 0x%x!\n", error_code);
|
||||
return -1;
|
||||
}
|
||||
recv_buff += 30;
|
||||
|
||||
FinsCommandCode command_code = p_fins_data_info->command_code;
|
||||
if (FINS_COMMAND_CODE_READ == command_code) {
|
||||
|
||||
uint16_t data_length = p_read_item->data_length;
|
||||
ControlPrintfList("DATA", recv_buff, data_length * (FINS_DATA_TYPE_BIT == p_read_item->data_type ? 1 : 2));
|
||||
printf("Receive data is ");
|
||||
|
||||
if (FINS_DATA_TYPE_BIT == p_read_item->data_type) {
|
||||
memcpy(p_fins_data_info->base_data_info.p_data, recv_buff, data_length);
|
||||
|
||||
printf("0x%x", p_fins_data_info->base_data_info.p_data[0]);
|
||||
} else {
|
||||
uint8_t *p_data = p_fins_data_info->base_data_info.p_data;
|
||||
|
||||
for (uint16_t i = 0; i < data_length; i ++) {
|
||||
p_data[2 * i] = recv_buff[2 * (data_length - i - 1)];
|
||||
p_data[2 * i + 1] = recv_buff[2 * (data_length - i - 1) + 1];
|
||||
printf("0x%x 0x%x", p_data[2 * i], p_data[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nRead fins plc data success!\n");
|
||||
} else if (FINS_COMMAND_CODE_WRITE == command_code) {
|
||||
/*to do*/
|
||||
printf("Write fins plc cmd success!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Handshake
|
||||
* @param socket - socket
|
||||
* @param local_ip_4 - last local ip
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int FinsHandshake(int32_t socket, uint16_t local_ip_4)
|
||||
{
|
||||
handshake_require_command[18] = (uint8_t)(local_ip_4 >> 8);
|
||||
handshake_require_command[19] = (uint8_t)local_ip_4;
|
||||
uint8_t try_count = 0;
|
||||
|
||||
while (try_count < 10) {
|
||||
ControlPrintfList("SEND", (uint8_t *)handshake_require_command, sizeof(handshake_require_command));
|
||||
int32_t write_error = socket_write(socket, handshake_require_command, sizeof(handshake_require_command));
|
||||
if (write_error < 0) {
|
||||
printf("Write socket error, errno is %d!", errno);
|
||||
} else {
|
||||
int32_t recv_length = socket_read(socket, (uint8_t *)handshake_respond_buff, sizeof(handshake_respond_buff));
|
||||
if (recv_length < 0) {
|
||||
printf("Read socket error, errno is %d!", errno);
|
||||
} else {
|
||||
ControlPrintfList("RECV", (uint8_t *)handshake_respond_buff, recv_length);
|
||||
|
||||
/*check fins handshake respond*/
|
||||
uint8_t error_code = handshake_respond_buff[15];
|
||||
if (error_code == 0 || error_code == 0x21) {
|
||||
return 0;
|
||||
} else {
|
||||
printf("Fins handshake failed, errno is %05x!", handshake_respond_buff[15]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
printf("Send plc command failed, errno is %d!", errno);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Get Data From Socket
|
||||
* @param socket - socket
|
||||
* @param p_read_item - read item pointer
|
||||
* @return success : 0 error : -1 -2
|
||||
*/
|
||||
static int FinsGetData(int32_t socket, FinsReadItem *p_read_item)
|
||||
{
|
||||
uint8_t try_count = 0;
|
||||
int32_t write_error = 0;
|
||||
|
||||
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_fins_data_info->base_data_info);
|
||||
|
||||
memset(recv_buff, 0, sizeof(recv_buff));
|
||||
|
||||
while (try_count < 10) {
|
||||
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
try_count++;
|
||||
|
||||
write_error = socket_write(socket, p_base_data_info->p_command, p_base_data_info->command_length);
|
||||
if (write_error < 0) {
|
||||
printf("Write socket error, errno is %d!", errno);
|
||||
} else {
|
||||
PrivTaskDelay(20);
|
||||
|
||||
int32_t recv_length = socket_read(socket, recv_buff, sizeof(recv_buff));
|
||||
if (recv_length < 0) {
|
||||
printf("Read socket error, errno is %d!", errno);
|
||||
} else {
|
||||
ControlPrintfList("RECV", recv_buff, recv_length);
|
||||
return FinsTransformRecvBuffToData(p_read_item, recv_buff);
|
||||
}
|
||||
}
|
||||
|
||||
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
|
||||
printf("Send plc command failed, errno is %d!", errno);
|
||||
continue;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Data Info Init
|
||||
* @param p_read_item - read item pointer
|
||||
* @param plc_ip_4 - last plc ip
|
||||
* @param local_ip_4 - last local ip
|
||||
* @param p_data - control-data pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int FinsInitialDataInfo(FinsReadItem *p_read_item, uint16_t plc_ip_4, uint16_t local_ip_4, uint8_t *p_data)
|
||||
{
|
||||
uint16_t data_length = p_read_item->data_length;
|
||||
|
||||
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
|
||||
switch (p_read_item->data_info.command_code)
|
||||
{
|
||||
case FINS_COMMAND_CODE_READ:
|
||||
data_length *= (p_read_item->data_type == FINS_DATA_TYPE_BIT ? 1 : 2);
|
||||
p_base_data_info->command_length = FINS_COMMAND_LENGTH;
|
||||
p_base_data_info->p_command = PrivMalloc(FINS_COMMAND_LENGTH);
|
||||
p_base_data_info->data_size = data_length;
|
||||
p_base_data_info->p_data = p_data;
|
||||
break;
|
||||
case FINS_COMMAND_CODE_WRITE:
|
||||
//To Do
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
FinsCommandGenerate(p_base_data_info->p_command, plc_ip_4, local_ip_4, p_read_item);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Receive Plc Data Task
|
||||
* @param parameter - parameter pointer
|
||||
* @return
|
||||
*/
|
||||
void *ReceivePlcDataTask(void *parameter)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t try_count = 0;
|
||||
uint16_t data_length = 0;
|
||||
uint8_t *fins_data;
|
||||
uint16_t read_item_size = sizeof(FinsReadItem);
|
||||
|
||||
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
FinsReadItem *fins_read_item = (FinsReadItem *)control_protocol->recipe->read_item;
|
||||
fins_data = control_protocol->recipe->protocol_data.data;
|
||||
data_length = control_protocol->recipe->protocol_data.data_length;
|
||||
|
||||
memset(&plc_socket, 0, sizeof(BasicSocketPlc));
|
||||
memcpy(plc_socket.ip, control_protocol->recipe->socket_config.plc_ip, 4);
|
||||
plc_socket.port = control_protocol->recipe->socket_config.port;
|
||||
plc_socket.socket = -1;
|
||||
plc_socket.secondary_connect_flag = 0;
|
||||
|
||||
while (1) {
|
||||
for (i = 0; i < control_protocol->recipe->read_item_count; i ++) {
|
||||
/*only connect socket when close socket or init*/
|
||||
while (ControlConnectSocket(&plc_socket) < 0) {
|
||||
PrivTaskDelay(1000);
|
||||
}
|
||||
|
||||
/*need to handshake after connect socket using FINS protocol*/
|
||||
if (0 == plc_socket.secondary_connect_flag) {
|
||||
if (FinsHandshake(plc_socket.socket, control_protocol->recipe->socket_config.local_ip[3]) < 0) {
|
||||
plc_socket.secondary_connect_flag = 0;
|
||||
ControlDisconnectSocket(&plc_socket);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
plc_socket.secondary_connect_flag = 1;
|
||||
|
||||
FinsGetData(plc_socket.socket, (FinsReadItem *)fins_read_item + i);
|
||||
}
|
||||
|
||||
/*read all variable item data, put them into circular_area*/
|
||||
if (i == control_protocol->recipe->read_item_count) {
|
||||
printf("%s get %d item %d length\n", __func__, i, data_length);
|
||||
CircularAreaAppWrite(circular_area, fins_data, data_length, 0);
|
||||
}
|
||||
|
||||
/*read data every single 200ms*/
|
||||
PrivTaskDelay(control_protocol->recipe->read_period);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Open
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int FinsOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlProtocolOpenDef(control_protocol);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Close
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int FinsClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlDisconnectSocket(&plc_socket);
|
||||
|
||||
ControlProtocolCloseDef();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Read Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - read data buffer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int FinsRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||
{
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
return CircularAreaAppRead(circular_area, buf, len);
|
||||
}
|
||||
|
||||
static struct ControlDone fins_protocol_done =
|
||||
{
|
||||
._open = FinsOpen,
|
||||
._close = FinsClose,
|
||||
._read = FinsRead,
|
||||
._write = NULL,
|
||||
._ioctl = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Cmd Generate
|
||||
* @param p_recipe - recipe pointer
|
||||
* @param protocol_format_info - protocol format info pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int FinsProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
FinsReadItem *fins_read_item = (FinsReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index;
|
||||
|
||||
fins_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
|
||||
strncpy(fins_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
|
||||
strncpy(&fins_read_item->area_char, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "area_char")->valuestring, 1);
|
||||
fins_read_item->data_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_type")->valueint;
|
||||
fins_read_item->data_info.command_code = FINS_COMMAND_CODE_READ;
|
||||
fins_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint;
|
||||
fins_read_item->bit_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "bit_address")->valueint;
|
||||
fins_read_item->data_length = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_length")->valueint;
|
||||
|
||||
ret = FinsInitialDataInfo(fins_read_item,
|
||||
p_recipe->socket_config.plc_ip[3],
|
||||
p_recipe->socket_config.local_ip[3],
|
||||
protocol_format_info->p_read_item_data + protocol_format_info->last_item_size);
|
||||
|
||||
ControlPrintfList("CMD", fins_read_item->data_info.base_data_info.p_command, fins_read_item->data_info.base_data_info.command_length);
|
||||
protocol_format_info->last_item_size = GetValueTypeMemorySize(fins_read_item->value_type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Fins Protocol Init
|
||||
* @param p_recipe - recipe pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int FinsProtocolInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
p_recipe->read_item = PrivMalloc(sizeof(FinsReadItem) * p_recipe->read_item_count);
|
||||
if (NULL == p_recipe->read_item) {
|
||||
PrivFree(p_recipe->read_item);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_recipe->ControlProtocolFormatCmd = FinsProtocolFormatCmd;
|
||||
|
||||
p_recipe->done = &fins_protocol_done;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,331 @@
|
|||
{
|
||||
"device_id": 769,
|
||||
"device_name": "S01",
|
||||
"communication_type": 0,
|
||||
"socket_config": {
|
||||
"plc_ip": "192.168.250.22",
|
||||
"local_ip": "192.168.250.233",
|
||||
"gateway": "192.168.250.1",
|
||||
"netmask": "255.255.254.0",
|
||||
"port": 9600
|
||||
},
|
||||
"protocol_type": 5,
|
||||
"read_period": 100,
|
||||
"read_item_list": [
|
||||
{
|
||||
"value_name": "启动",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "停止",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 1,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "使能",
|
||||
"value_type": 1,
|
||||
"area_char": "H",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 2,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "回零",
|
||||
"value_type": 1,
|
||||
"area_char": "D",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 3,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "急停",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 0,
|
||||
"bit_address": 4,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "正限位",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 10,
|
||||
"bit_address": 11,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "负限位",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 10,
|
||||
"bit_address": 12,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "自动运行中",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 200,
|
||||
"bit_address": 5,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "故障",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 200,
|
||||
"bit_address": 6,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "待机",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 200,
|
||||
"bit_address": 7,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "手动模式",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 300,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "自动模式",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 300,
|
||||
"bit_address": 1,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "运行方向",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 300,
|
||||
"bit_address": 2,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "复位",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 400,
|
||||
"bit_address": 3,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "备用1",
|
||||
"value_type": 1,
|
||||
"area_char": "W",
|
||||
"data_type": 0,
|
||||
"start_address": 400,
|
||||
"bit_address": 4,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "产量",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 10,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型1",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 11,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型2",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 20,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型3",
|
||||
"value_type": 3,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 100,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型4",
|
||||
"value_type": 3,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 100,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型5",
|
||||
"value_type": 3,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 101,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型6",
|
||||
"value_type": 3,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 110,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型7",
|
||||
"value_type": 3,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 10,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型8",
|
||||
"value_type": 3,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 20,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "整型9",
|
||||
"value_type": 3,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 21,
|
||||
"bit_address": 0,
|
||||
"data_length": 1
|
||||
},
|
||||
{
|
||||
"value_name": "速度",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 2000,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "加速度",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 2002,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "减速度",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 2004,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "起始位置",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 300,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "终点位置",
|
||||
"value_type": 9,
|
||||
"area_char": "D",
|
||||
"data_type": 1,
|
||||
"start_address": 302,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "张力值",
|
||||
"value_type": 9,
|
||||
"area_char": "W",
|
||||
"data_type": 1,
|
||||
"start_address": 80,
|
||||
"bit_address": 0,
|
||||
"data_length": 2
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型1",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 100,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型2",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 104,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型3",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 108,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
},
|
||||
{
|
||||
"value_name": "浮点型4",
|
||||
"value_type": 8,
|
||||
"area_char": "H",
|
||||
"data_type": 1,
|
||||
"start_address": 112,
|
||||
"bit_address": 0,
|
||||
"data_length": 4
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fins.h
|
||||
* @brief plc protocol fins
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
||||
#ifndef FINS_H
|
||||
#define FINS_H
|
||||
|
||||
#include <control_def.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FINS_HEADER_HEAD 0x46494E53
|
||||
#define FINS_HEADER_READ_COMMAND_LENGTH 0x0000001A
|
||||
#define FINS_HEADER_COMMAND 0x00000002
|
||||
#define FINS_HEADER_ERROR_CODE 0x00000000
|
||||
#define FINS_ICF 0x80
|
||||
#define FINS_RSV 0x00
|
||||
#define FINS_REPLY_ICF 0xC0
|
||||
#define FINS_GCT 0x02
|
||||
#define FINS_DNA 0x00
|
||||
#define FINS_DA2 0x00
|
||||
#define FINS_SNA 0x00
|
||||
#define FINS_SA2 0x00
|
||||
#define FINS_SID 0x00
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FINS_COMMAND_CODE_READ = 0x0101,
|
||||
FINS_COMMAND_CODE_WRITE = 0x0102
|
||||
}FinsCommandCode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FINS_DATA_TYPE_BIT,
|
||||
FINS_DATA_TYPE_WORD
|
||||
}FinsDataType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BasicPlcDataInfo base_data_info;
|
||||
FinsCommandCode command_code;
|
||||
}FinsDataInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t socket;
|
||||
uint16_t plc_ip_4;
|
||||
}FinsHandshakeParameter;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FinsDataInfo data_info;
|
||||
|
||||
UniformValueType value_type;
|
||||
uint8_t value_name[20];
|
||||
|
||||
uint8_t area_char;
|
||||
FinsDataType data_type;
|
||||
uint16_t start_address;
|
||||
uint8_t bit_address;
|
||||
uint16_t data_length;
|
||||
}FinsReadItem;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
10
APP_Framework/Framework/control/shared/control_file.c → APP_Framework/Framework/control/plc_protocol/include/melsec.h
Executable file → Normal file
10
APP_Framework/Framework/control/shared/control_file.c → APP_Framework/Framework/control/plc_protocol/include/melsec.h
Executable file → Normal file
|
@ -11,11 +11,9 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file control_file.c
|
||||
* @brief control relative file operation
|
||||
* @file melsec.h
|
||||
* @brief plc protocol melsec
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-37
|
||||
*/
|
||||
|
||||
|
||||
* @date 2022-10-08
|
||||
*/
|
15
APP_Framework/Framework/control/shared/control_file.h → APP_Framework/Framework/control/plc_protocol/include/opcua.h
Executable file → Normal file
15
APP_Framework/Framework/control/shared/control_file.h → APP_Framework/Framework/control/plc_protocol/include/opcua.h
Executable file → Normal file
|
@ -11,16 +11,9 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file control_file.h
|
||||
* @brief control file function relative API
|
||||
* @file opcua.h
|
||||
* @brief control protocol opcua
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-27
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_FILE_H
|
||||
#define CONTROL_FILE_H
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
* @date 2022-10-08
|
||||
*/
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file s7.h
|
||||
* @brief plc protocol s7
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
|
@ -1,8 +1,4 @@
|
|||
SRC_FILES := control.c
|
||||
|
||||
ifeq ($(CONFIG_MOUNT_SDCARD),y)
|
||||
SRC_FILES += control_file.c
|
||||
endif
|
||||
SRC_FILES := control.c control_def.c control_io.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"siemens plc":
|
||||
{
|
||||
"device type": "PLC",
|
||||
"control type": "HSC",
|
||||
"info":
|
||||
{
|
||||
"plc ability" : 1,
|
||||
"plc device id": 1,
|
||||
"soft version" : 1,
|
||||
"hardware version": 1,
|
||||
"date": "2022-1-28",
|
||||
"vendor": "siemens",
|
||||
"model":"S300"
|
||||
},
|
||||
|
||||
"serial config":
|
||||
{
|
||||
"serial type":"485",
|
||||
"station id" : "station1",
|
||||
"serial port" : 1
|
||||
},
|
||||
|
||||
"network config":
|
||||
{
|
||||
"ip addr" : "192.168.250.5",
|
||||
"ip port" : 4840
|
||||
},
|
||||
|
||||
"interface":
|
||||
{
|
||||
"inhybridnet":"OPCUA",
|
||||
"transport":"TCP",
|
||||
"ip address": "192.168.250.5",
|
||||
"attribute" : "1"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,16 +12,278 @@
|
|||
|
||||
/**
|
||||
* @file control.c
|
||||
* @brief control framework code
|
||||
* @brief code for control framework app
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-27
|
||||
*/
|
||||
|
||||
#include <control.h>
|
||||
#include <control_def.h>
|
||||
|
||||
void control_init(void)
|
||||
ControlProtocolType control_protocol;
|
||||
|
||||
/**
|
||||
* @description: Control Framework Find certain Protocol
|
||||
* @param void
|
||||
* @return Control Protocol pointer
|
||||
*/
|
||||
ControlProtocolType ControlProtocolFind(void)
|
||||
{
|
||||
//to do
|
||||
return control_protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Init
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ControlProtocolInit(ControlProtocolType control_protocol)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
int ret = -1;
|
||||
|
||||
control_protocol->protocol_status = CONTROL_INIT;
|
||||
|
||||
ret = PrivMutexCreate(&control_protocol->lock, 0);
|
||||
if(ret < 0) {
|
||||
printf("ControlProtocolInit mutex create failed.\n");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
ret = PrivSemaphoreCreate(&control_protocol->sem, 0, 0);
|
||||
if (ret < 0) {
|
||||
printf("ControlProtocolInit create sem error\n");
|
||||
goto _out;
|
||||
}
|
||||
|
||||
_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Analyze Recipe
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param recipe_name - recipe name
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ControlAnalyzeRecipe(ControlProtocolType control_protocol, const char *recipe_name)
|
||||
{
|
||||
int recipe_file_fd = -1;
|
||||
struct stat recipe_file_status;
|
||||
uint16_t recipe_file_length = 0;
|
||||
char *recipe_file_buf;
|
||||
|
||||
/*wait for SD-card mount done*/
|
||||
PrivTaskDelay(5000);
|
||||
|
||||
//Step1 : read recipe file data from SD card or other store device
|
||||
recipe_file_fd = PrivOpen(recipe_name, O_RDONLY);
|
||||
if (recipe_file_fd < 0) {
|
||||
printf("Open recipe file %s failed\n", recipe_name);
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != fstat(recipe_file_fd, &recipe_file_status)) {
|
||||
printf("Get recipe file information failed!\n");
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
} else {
|
||||
recipe_file_length = recipe_file_status.st_size;
|
||||
}
|
||||
|
||||
recipe_file_buf = PrivMalloc(recipe_file_length);
|
||||
if (NULL == recipe_file_buf) {
|
||||
printf("Get recipe file memory failed!\n");
|
||||
PrivFree(recipe_file_buf);
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PrivRead(recipe_file_fd, recipe_file_buf, recipe_file_length) < 0) {
|
||||
printf("Read recipe file failed!\n");
|
||||
PrivFree(recipe_file_buf);
|
||||
PrivClose(recipe_file_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PrivClose(recipe_file_fd);
|
||||
|
||||
//Step2 : CJSON analyze
|
||||
#ifdef LIB_USING_CJSON
|
||||
cJSON *recipe_file_json = cJSON_Parse(recipe_file_buf);
|
||||
if (NULL == recipe_file_json) {
|
||||
printf("Parse recipe_file_buf failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
control_protocol->recipe = (struct ControlRecipe *)PrivMalloc(sizeof(struct ControlRecipe));
|
||||
memset(control_protocol->recipe, 0, sizeof(struct ControlRecipe));
|
||||
|
||||
/*Get basic information from recipe file*/
|
||||
if (RecipeBasicInformation(control_protocol->recipe, recipe_file_json) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
control_protocol->protocol_type = control_protocol->recipe->protocol_type;
|
||||
|
||||
/*Get the variable need to read from recipe file*/
|
||||
RecipeReadVariableItem(control_protocol->recipe, recipe_file_json);
|
||||
|
||||
control_protocol->done = control_protocol->recipe->done;
|
||||
|
||||
cJSON_Delete(recipe_file_json);
|
||||
|
||||
PrivFree(recipe_file_buf);
|
||||
printf("Read and parse recipe file done!\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Open
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_open) {
|
||||
ret = control_protocol->done->_open(control_protocol);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Close
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_close) {
|
||||
ret = control_protocol->done->_close(control_protocol);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Read Data
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param buf - read buffer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : -1
|
||||
*/
|
||||
int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_read) {
|
||||
ret = control_protocol->done->_read(control_protocol, buf, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Write Cmd
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param buf - write buffer
|
||||
* @param len - write data length
|
||||
* @return success : data length error : -1
|
||||
*/
|
||||
int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_write) {
|
||||
ret = control_protocol->done->_write(control_protocol, buf, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Ioctl
|
||||
* @param control_protocol - Control Protocol pointer
|
||||
* @param cmd - ioctl cmd
|
||||
* @param args - args
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args)
|
||||
{
|
||||
CONTROL_PARAM_CHECK(control_protocol);
|
||||
CONTROL_PARAM_CHECK(control_protocol->done);
|
||||
int ret = -1;
|
||||
|
||||
if (control_protocol->done->_ioctl) {
|
||||
ret = control_protocol->done->_ioctl(control_protocol, cmd, args);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Init
|
||||
* @param void
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlFrameworkInit(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
control_protocol = (struct ControlProtocol *)PrivMalloc(sizeof(struct ControlProtocol));
|
||||
if (NULL == control_protocol) {
|
||||
printf("%s malloc control protocol failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
ret = -1;
|
||||
goto _out;
|
||||
}
|
||||
|
||||
//Control Protocol Struct Init
|
||||
ret = ControlProtocolInit(control_protocol);
|
||||
if (ret < 0) {
|
||||
printf("%s failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
goto _out;
|
||||
}
|
||||
|
||||
printf("%s malloc CONTROL_RECIPE_FILE %s\n", __func__, CONTROL_RECIPE_FILE);
|
||||
|
||||
//Read Recipe File, Get Control Protocol Configure Param
|
||||
ret = ControlAnalyzeRecipe(control_protocol, CONTROL_RECIPE_FILE);
|
||||
if (ret < 0) {
|
||||
printf("%s failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
goto _out;
|
||||
}
|
||||
|
||||
control_protocol->protocol_status = CONTROL_REGISTERED;
|
||||
|
||||
ret = ControlPeripheralInit(control_protocol->recipe);
|
||||
if (ret < 0) {
|
||||
printf("%s failed!\n", __func__);
|
||||
PrivFree(control_protocol);
|
||||
goto _out;
|
||||
}
|
||||
|
||||
printf("%s ControlPeripheralInit done\n", __func__);
|
||||
|
||||
_out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -12,13 +12,95 @@
|
|||
|
||||
/**
|
||||
* @file control.h
|
||||
* @brief control framework code
|
||||
* @brief DEFINE code for control framework app
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-09-27
|
||||
*/
|
||||
|
||||
#include <control_file.h>
|
||||
#include <cJSON.h>
|
||||
#ifndef CONTROL_H
|
||||
#define CONTROL_H
|
||||
|
||||
#include <transform.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ControlProtocol;
|
||||
typedef struct ControlProtocol *ControlProtocolType;
|
||||
|
||||
struct ControlDone
|
||||
{
|
||||
int (*_open)(struct ControlProtocol *control_protocol);
|
||||
int (*_close)(struct ControlProtocol *control_protocol);
|
||||
int (*_read)(struct ControlProtocol *control_protocol, void *buf, size_t len);
|
||||
int (*_write)(struct ControlProtocol *control_protocol, const void *buf, size_t len);
|
||||
int (*_ioctl)(struct ControlProtocol *control_protocol, int cmd, void *args);
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROTOCOL_S7 = 1,
|
||||
PROTOCOL_MODBUS_TCP,
|
||||
PROTOCOL_MODBUS_UART,
|
||||
PROTOCOL_OPC_UA,
|
||||
PROTOCOL_FINS,
|
||||
PROTOCOL_MELSEC_1E,
|
||||
PROTOCOL_MELSEC_3E_Q_L,
|
||||
PROTOCOL_MELSEC_3E_IQ_R,
|
||||
PROTOCOL_MELSEC_1C,
|
||||
PROTOCOL_MELSEC_3C,
|
||||
PROTOCOL_END
|
||||
}ProtocolType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CONTROL_INIT,
|
||||
CONTROL_REGISTERED,
|
||||
CONTROL_UNREGISTERED,
|
||||
}ProtocolStatus;
|
||||
|
||||
struct ControlProtocol
|
||||
{
|
||||
char *name;
|
||||
ProtocolType protocol_type;
|
||||
ProtocolStatus protocol_status;
|
||||
|
||||
struct ControlRecipe *recipe;
|
||||
struct ControlDone *done;
|
||||
|
||||
void *args;
|
||||
|
||||
sem_t sem;
|
||||
pthread_mutex_t lock;
|
||||
};
|
||||
|
||||
/*Control Framework Protocol Init*/
|
||||
int ControlFrameworkInit(void);
|
||||
|
||||
/*Control Framework Find certain Protocol*/
|
||||
ControlProtocolType ControlProtocolFind(void);
|
||||
|
||||
/*Control Framework Protocol Open*/
|
||||
int ControlProtocolOpen(struct ControlProtocol *control_protocol);
|
||||
|
||||
/*Control Framework Protocol Close*/
|
||||
int ControlProtocolClose(struct ControlProtocol *control_protocol);
|
||||
|
||||
/*Control Framework Protocol Read*/
|
||||
int ControlProtocolRead(struct ControlProtocol *control_protocol, void *buf, size_t len);
|
||||
|
||||
/*Control Framework Protocol Write*/
|
||||
int ControlProtocolWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len);
|
||||
|
||||
/*Control Framework Protocol Ioctl*/
|
||||
int ControlProtocolIoctl(struct ControlProtocol *control_protocol, int cmd, void *args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,446 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_def.c
|
||||
* @brief code for control framework
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-9
|
||||
*/
|
||||
|
||||
#include <control_def.h>
|
||||
#include <control_io.h>
|
||||
|
||||
/*using cirtular area to receive data*/
|
||||
#define PLC_DATA_LENGTH 1024
|
||||
struct CircularAreaApp *g_circular_area;
|
||||
static pthread_t recv_plc_data_task;
|
||||
|
||||
/*extern function*/
|
||||
extern void *ReceivePlcDataTask(void *parameter);
|
||||
|
||||
#ifdef CONTROL_PROTOCOL_FINS
|
||||
extern int FinsProtocolInit(struct ControlRecipe *p_recipe);
|
||||
#endif
|
||||
|
||||
/*
|
||||
CONTROL FRAMEWORK READ DATA FORMAT:
|
||||
| HEAD |device_id|read data length|read item count| data |
|
||||
|2 Bytes| 2 Bytes | 2 Bytes | 2 Bytes |read data length Bytes|
|
||||
*/
|
||||
#define CONTROL_DATA_HEAD_LENGTH 8
|
||||
#define CONTROL_DATA_HEAD_1 0xAA
|
||||
#define CONTROL_DATA_HEAD_2 0xBB
|
||||
|
||||
typedef int (*ControlProtocolInitFunc)(struct ControlRecipe *p_recipe);
|
||||
|
||||
struct ControlProtocolInitParam
|
||||
{
|
||||
int protocol_type;
|
||||
const ControlProtocolInitFunc fn;
|
||||
};
|
||||
|
||||
static struct ControlProtocolInitParam protocol_init[] =
|
||||
{
|
||||
#ifdef CONTROL_PROTOCOL_FINS
|
||||
{ PROTOCOL_FINS, FinsProtocolInit },
|
||||
#endif
|
||||
|
||||
{ PROTOCOL_END, NULL },
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Control Framework Sub_Protocol Desc Init
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param sub_protocol_desc - sub_protocol desc
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
static int ControlProtocolInitDesc(struct ControlRecipe *p_recipe, struct ControlProtocolInitParam sub_protocol_desc[])
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
for( i = 0; sub_protocol_desc[i].fn != NULL; i++ ) {
|
||||
if (p_recipe->protocol_type == sub_protocol_desc[i].protocol_type) {
|
||||
ret = sub_protocol_desc[i].fn(p_recipe);
|
||||
printf("%s initialize %d %s\n", __func__, sub_protocol_desc[i].protocol_type, ret == 0 ? "success" : "failed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Data Header Format
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @return
|
||||
*/
|
||||
static void FormatDataHeader(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
uint16_t plc_read_data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;//Head length is CONTROL_DATA_HEAD_LENGTH
|
||||
uint8_t *data = p_recipe->protocol_data.data;
|
||||
|
||||
data[0] = CONTROL_DATA_HEAD_1;
|
||||
data[1] = CONTROL_DATA_HEAD_2;
|
||||
data[2] = (uint8_t)(p_recipe->device_id >> 8);
|
||||
data[3] = (uint8_t)p_recipe->device_id;
|
||||
data[4] = (uint8_t)(plc_read_data_length >> 8);
|
||||
data[5] = (uint8_t)plc_read_data_length;
|
||||
data[6] = (uint8_t)(p_recipe->read_item_count >> 8);
|
||||
data[7] = (uint8_t)p_recipe->read_item_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Get Recipe Total Data Length
|
||||
* @param read_item_list_json - read_item_list_json pointer
|
||||
* @return success : total_data_length error : 0
|
||||
*/
|
||||
static uint16_t GetRecipeTotalDataLength(cJSON* read_item_list_json)
|
||||
{
|
||||
uint16_t read_item_count = cJSON_GetArraySize(read_item_list_json);
|
||||
uint16_t total_data_length = 0;
|
||||
for (uint16_t read_item_index = 0; read_item_index < read_item_count; read_item_index++) {
|
||||
cJSON* read_item_json = cJSON_GetArrayItem(read_item_list_json, read_item_index);
|
||||
UniformValueType value_type = cJSON_GetObjectItem(read_item_json, "value_type")->valueint;
|
||||
total_data_length += GetValueTypeMemorySize(value_type);
|
||||
}
|
||||
return total_data_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Basic Serial Configure
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - p_recipe_file_json pointer
|
||||
* @return
|
||||
*/
|
||||
static void ControlBasicSerialConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
cJSON *p_serial_config_json = cJSON_GetObjectItem(p_recipe_file_json, "serial_config");
|
||||
p_recipe->serial_config.baud_rate = cJSON_GetObjectItem(p_serial_config_json, "baud_rate")->valueint;
|
||||
p_recipe->serial_config.data_bits = cJSON_GetObjectItem(p_serial_config_json, "data_bits")->valueint;
|
||||
p_recipe->serial_config.stop_bits = cJSON_GetObjectItem(p_serial_config_json, "stop_bits")->valueint;
|
||||
p_recipe->serial_config.check_mode = cJSON_GetObjectItem(p_serial_config_json, "check_mode")->valueint;
|
||||
printf("Serial_config: baud_rate: %d, data_bits: %d, stop_bits: %d, check_mode is %d\n",
|
||||
p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Basic Socket Configure
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - p_recipe_file_json pointer
|
||||
* @return
|
||||
*/
|
||||
static void ControlBasicSocketConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
cJSON *p_socket_address_json = cJSON_GetObjectItem(p_recipe_file_json, "socket_config");
|
||||
char *plc_ip_string = cJSON_GetObjectItem(p_socket_address_json, "plc_ip")->valuestring;
|
||||
sscanf(plc_ip_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.plc_ip,
|
||||
p_recipe->socket_config.plc_ip + 1,
|
||||
p_recipe->socket_config.plc_ip + 2,
|
||||
p_recipe->socket_config.plc_ip + 3);
|
||||
|
||||
char *local_ip_string = cJSON_GetObjectItem(p_socket_address_json, "local_ip")->valuestring;
|
||||
sscanf(local_ip_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.local_ip,
|
||||
p_recipe->socket_config.local_ip + 1,
|
||||
p_recipe->socket_config.local_ip + 2,
|
||||
p_recipe->socket_config.local_ip + 3);
|
||||
|
||||
char *gateway_ip_string = cJSON_GetObjectItem(p_socket_address_json, "gateway")->valuestring;
|
||||
sscanf(gateway_ip_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.gateway,
|
||||
p_recipe->socket_config.gateway + 1,
|
||||
p_recipe->socket_config.gateway + 2,
|
||||
p_recipe->socket_config.gateway + 3);
|
||||
|
||||
char *netmask_string = cJSON_GetObjectItem(p_socket_address_json, "netmask")->valuestring;
|
||||
sscanf(netmask_string, "%d.%d.%d.%d",
|
||||
p_recipe->socket_config.netmask,
|
||||
p_recipe->socket_config.netmask + 1,
|
||||
p_recipe->socket_config.netmask + 2,
|
||||
p_recipe->socket_config.netmask + 3);
|
||||
|
||||
p_recipe->socket_config.port = cJSON_GetObjectItem(p_socket_address_json, "port")->valueint;
|
||||
printf("Socket_config: local ip is %s, plc ip is %s, gateway is %s, port is %d.\n",
|
||||
local_ip_string, plc_ip_string, gateway_ip_string, p_recipe->socket_config.port);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Printf List Function
|
||||
* @param name - printf function name
|
||||
* @param number_list - number_list pointer
|
||||
* @param length - number_list length
|
||||
* @return
|
||||
*/
|
||||
void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length)
|
||||
{
|
||||
printf("\n******************%5s****************\n", name);
|
||||
for (int32_t i = 0;i < length;i ++) {
|
||||
printf("0x%x ", number_list[i]);
|
||||
}
|
||||
printf("\n**************************************\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Connect Socket
|
||||
* @param p_plc - basic socket plc pointer
|
||||
* @return success : 0 error : -1 -2 -3 -4 -5
|
||||
*/
|
||||
int ControlConnectSocket(BasicSocketPlc *p_plc)
|
||||
{
|
||||
if (p_plc->socket >= 0)
|
||||
return 0;
|
||||
|
||||
struct sockaddr_in plc_addr_in;
|
||||
plc_addr_in.sin_family = AF_INET;
|
||||
plc_addr_in.sin_port = htons(p_plc->port);
|
||||
|
||||
char ip_string[20] = {0};
|
||||
sprintf(ip_string, "%u.%u.%u.%u", p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3]);
|
||||
plc_addr_in.sin_addr.s_addr = inet_addr(ip_string);
|
||||
memset(&(plc_addr_in.sin_zero), 0, sizeof(plc_addr_in.sin_zero));
|
||||
|
||||
int plc_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
int flag = 1;
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 10;
|
||||
timeout.tv_usec = 0;
|
||||
if (setsockopt(plc_socket, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag)) < 0) {
|
||||
printf("Error setting TCP_NODELAY function!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(plc_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) {
|
||||
printf("Error setting SO_SNDTIMEO function!\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (setsockopt(plc_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, (socklen_t)sizeof(struct timeval)) < 0) {
|
||||
printf("Error setting SO_RCVTIMEO function!\n");
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (plc_socket < 0) {
|
||||
printf("Get socket error!\n");
|
||||
return -4;
|
||||
}
|
||||
|
||||
printf("%s %d ip %u.%u.%u.%u port %d\n", __func__, __LINE__,
|
||||
p_plc->ip[0], p_plc->ip[1], p_plc->ip[2], p_plc->ip[3],
|
||||
p_plc->port);
|
||||
|
||||
if (connect(plc_socket, (struct sockaddr*)&plc_addr_in, sizeof(struct sockaddr)) == -1) {
|
||||
printf("Connect plc socket failed!errno %d\n", errno);
|
||||
closesocket(plc_socket);
|
||||
return -5;
|
||||
} else {
|
||||
p_plc->socket = plc_socket;
|
||||
printf("Connect plc socket success!\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Disconnect Socket
|
||||
* @param p_plc - basic socket plc pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlDisconnectSocket(BasicSocketPlc *p_plc)
|
||||
{
|
||||
if (p_plc->socket < 0)
|
||||
return -1;
|
||||
|
||||
int error = closesocket(p_plc->socket);
|
||||
if (0 == error)
|
||||
p_plc->socket = -1;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task
|
||||
* @param control_protocol - Control protocol pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolOpenDef(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
g_circular_area = CircularAreaAppInit(PLC_DATA_LENGTH);
|
||||
if (NULL == g_circular_area) {
|
||||
printf("%s CircularAreaInit error\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
control_protocol->args = (void *)g_circular_area;
|
||||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = 19;
|
||||
attr.stacksize = 2048;
|
||||
|
||||
PrivTaskCreate(&recv_plc_data_task, &attr, &ReceivePlcDataTask, control_protocol);
|
||||
PrivTaskStartup(&recv_plc_data_task);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task
|
||||
* @param void
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int ControlProtocolCloseDef(void)
|
||||
{
|
||||
CircularAreaAppRelease(g_circular_area);
|
||||
|
||||
PrivTaskDelete(recv_plc_data_task, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Get Value Memory Size From Recipe File
|
||||
* @param uniform_value_type - uniform value type
|
||||
* @return success : size error : 0
|
||||
*/
|
||||
uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type)
|
||||
{
|
||||
switch (uniform_value_type)
|
||||
{
|
||||
case UNIFORM_BOOL:
|
||||
case UNIFORM_INT8:
|
||||
case UNIFORM_UINT8:
|
||||
return 1;
|
||||
break;
|
||||
case UNIFORM_INT16:
|
||||
case UNIFORM_UINT16:
|
||||
return 2;
|
||||
break;
|
||||
case UNIFORM_INT32:
|
||||
case UNIFORM_UINT32:
|
||||
case UNIFORM_FLOAT:
|
||||
return 4;
|
||||
break;
|
||||
case UNIFORM_DOUBLE:
|
||||
return 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Peripheral Device Init
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @return success : 0 error :
|
||||
*/
|
||||
int ControlPeripheralInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
switch (p_recipe->communication_type)
|
||||
{
|
||||
case 0://Socket Init
|
||||
SocketInit(p_recipe->socket_config.local_ip, p_recipe->socket_config.netmask, p_recipe->socket_config.gateway);
|
||||
break;
|
||||
case 1://Serial Init
|
||||
SerialInit(p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Get Recipe Basic Information
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - recipe_file_json pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
p_recipe->protocol_type = (ProtocolType)(cJSON_GetObjectItem(p_recipe_file_json, "protocol_type")->valueint);
|
||||
|
||||
p_recipe->device_id = cJSON_GetObjectItem(p_recipe_file_json, "device_id")->valueint;
|
||||
strncpy(p_recipe->device_name, cJSON_GetObjectItem(p_recipe_file_json, "device_name")->valuestring, 20);
|
||||
p_recipe->read_period = cJSON_GetObjectItem(p_recipe_file_json, "read_period")->valueint;
|
||||
p_recipe->communication_type = cJSON_GetObjectItem(p_recipe_file_json, "communication_type")->valueint;
|
||||
|
||||
printf("\n**************** RECIPE BASIC INFORMATION ******************\n");
|
||||
printf("\nprotocol_type: %d, communication_type: %d, device_id: %d, device_name: %s, read_period is %d\n",
|
||||
p_recipe->protocol_type, p_recipe->communication_type, p_recipe->device_id, p_recipe->device_name, p_recipe->read_period);
|
||||
|
||||
switch (p_recipe->communication_type)
|
||||
{
|
||||
case 0://Get Socket Config
|
||||
ControlBasicSocketConfig(p_recipe, p_recipe_file_json);
|
||||
break;
|
||||
case 1://Get Serial Config
|
||||
ControlBasicSerialConfig(p_recipe, p_recipe_file_json);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("\n************************************************************\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Read Variable Item Function
|
||||
* @param p_recipe - Control recipe pointer
|
||||
* @param p_recipe_file_json - recipe_file_json pointer
|
||||
* @return
|
||||
*/
|
||||
void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
ProtocolFormatInfo protocol_format_info;
|
||||
memset(&protocol_format_info, 0, sizeof(ProtocolFormatInfo));
|
||||
|
||||
cJSON *read_item_list_json = cJSON_GetObjectItem(p_recipe_file_json, "read_item_list");
|
||||
if (cJSON_IsArray(read_item_list_json)) {
|
||||
/*Get Recipe Variable Item Count and total length*/
|
||||
p_recipe->read_item_count = cJSON_GetArraySize(read_item_list_json);
|
||||
p_recipe->total_data_length = GetRecipeTotalDataLength(read_item_list_json);
|
||||
|
||||
/*Malloc Read Data Pointer, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/
|
||||
p_recipe->protocol_data.data = PrivMalloc(CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length);
|
||||
p_recipe->protocol_data.data_length = CONTROL_DATA_HEAD_LENGTH + p_recipe->total_data_length;
|
||||
memset(p_recipe->protocol_data.data, 0, p_recipe->protocol_data.data_length);
|
||||
|
||||
protocol_format_info.p_read_item_data = p_recipe->protocol_data.data + CONTROL_DATA_HEAD_LENGTH;
|
||||
|
||||
/*Init The Control Protocol*/
|
||||
ControlProtocolInitDesc(p_recipe, protocol_init);
|
||||
|
||||
/*Format Data Header, Reference "CONTROL FRAMEWORK READ DATA FORMAT"*/
|
||||
FormatDataHeader(p_recipe);
|
||||
|
||||
uint16_t read_item_count = p_recipe->read_item_count;
|
||||
|
||||
for (i = 0; i < read_item_count; i ++) {
|
||||
cJSON *read_single_item_json = cJSON_GetArrayItem(read_item_list_json, i);
|
||||
|
||||
protocol_format_info.read_single_item_json = read_single_item_json;
|
||||
protocol_format_info.read_item_index = i;
|
||||
|
||||
/*Format Protocol Cmd By Analyze Variable Item One By One*/
|
||||
ret = p_recipe->ControlProtocolFormatCmd(p_recipe, &protocol_format_info);
|
||||
if (ret < 0) {
|
||||
printf("%s read %d item failed!\n", __func__, i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_def.h
|
||||
* @brief DEFINE code for control framework
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_DEF_H
|
||||
#define CONTROL_DEF_H
|
||||
|
||||
#include <transform.h>
|
||||
#include <list.h>
|
||||
#include <circular_area_app.h>
|
||||
#include <control.h>
|
||||
#include <control_io.h>
|
||||
|
||||
#ifdef LIB_USING_CJSON
|
||||
#include <cJSON.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CONTROL_PARAM_CHECK(param) \
|
||||
do \
|
||||
{ \
|
||||
if(NULL == param) { \
|
||||
KPrintf("CONTROL CHECK FAILED ...%s %d %s is NULL.\n", __FUNCTION__, __LINE__, #param); \
|
||||
return -1; \
|
||||
} \
|
||||
}while (0)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
UNIFORM_BOOL = 1,
|
||||
UNIFORM_INT8,
|
||||
UNIFORM_INT16,
|
||||
UNIFORM_INT32,
|
||||
UNIFORM_UINT8,
|
||||
UNIFORM_UINT16,
|
||||
UNIFORM_UINT32,
|
||||
UNIFORM_DOUBLE,
|
||||
UNIFORM_FLOAT
|
||||
}UniformValueType;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t ip[4];
|
||||
uint16_t port;
|
||||
int32_t socket;
|
||||
int8_t secondary_connect_flag;//0: enble, no connected; 1: enable, connected; -1: disable
|
||||
}BasicSocketPlc;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t command_length;
|
||||
uint16_t data_size;
|
||||
uint8_t *p_command;
|
||||
uint8_t *p_data;
|
||||
}BasicPlcDataInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cJSON *read_single_item_json;
|
||||
uint8_t *p_read_item_data;
|
||||
uint16_t read_item_index;//Variable item index(1 ++)
|
||||
uint8_t last_item_size;
|
||||
}ProtocolFormatInfo;
|
||||
|
||||
struct ProtocolData
|
||||
{
|
||||
uint8_t *data;
|
||||
uint16_t data_length;
|
||||
};
|
||||
|
||||
struct SerialConfig
|
||||
{
|
||||
uint32_t baud_rate;
|
||||
uint8_t data_bits;
|
||||
uint8_t stop_bits;
|
||||
uint8_t check_mode;
|
||||
};
|
||||
|
||||
struct SocketConfig
|
||||
{
|
||||
uint16_t port;
|
||||
uint8_t plc_ip[4];
|
||||
uint8_t local_ip[4];
|
||||
uint8_t gateway[4];
|
||||
uint8_t netmask[4];
|
||||
};
|
||||
|
||||
struct ControlRecipe
|
||||
{
|
||||
uint8_t device_name[20];
|
||||
uint16_t device_id;
|
||||
uint16_t read_period;
|
||||
uint16_t read_item_count;
|
||||
uint16_t total_data_length;
|
||||
uint8_t communication_type;
|
||||
|
||||
ProtocolType protocol_type;
|
||||
|
||||
void *read_item;
|
||||
struct ControlDone *done;
|
||||
|
||||
struct SerialConfig serial_config;
|
||||
struct SocketConfig socket_config;
|
||||
|
||||
struct ProtocolData protocol_data;
|
||||
|
||||
int (*ControlProtocolFormatCmd)(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info);
|
||||
};
|
||||
|
||||
/*Get Value Type Memory Size*/
|
||||
uint8_t GetValueTypeMemorySize(UniformValueType uniform_value_type);
|
||||
|
||||
/*Get basic information from recipe file*/
|
||||
int RecipeBasicInformation(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json);
|
||||
|
||||
/*Get the variable need to read from recipe file*/
|
||||
void RecipeReadVariableItem(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json);
|
||||
|
||||
/*Control Framework Peripheral Device Init*/
|
||||
int ControlPeripheralInit(struct ControlRecipe *p_recipe);
|
||||
|
||||
/*Control Framework Printf List Function*/
|
||||
void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length);
|
||||
|
||||
/*Control Framework Connect Socket*/
|
||||
int ControlConnectSocket(BasicSocketPlc *p_plc);
|
||||
|
||||
/*Control Framework Disconnect Socket*/
|
||||
int ControlDisconnectSocket(BasicSocketPlc *p_plc);
|
||||
|
||||
/*Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task*/
|
||||
int ControlProtocolOpenDef(struct ControlProtocol *control_protocol);
|
||||
|
||||
/*Control Framework Protocol Open for Sub_Protocol, Release Circular Area and Delete Receive Data Task*/
|
||||
int ControlProtocolCloseDef(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_io.c
|
||||
* @brief low level io code for control framework
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-11-21
|
||||
*/
|
||||
|
||||
#include <control_io.h>
|
||||
|
||||
/**
|
||||
* @description: Control Framework Socket Init
|
||||
* @param ip - local ip pointer
|
||||
* @param mask - netmask pointer
|
||||
* @param gw - gateway pointer
|
||||
* @return
|
||||
*/
|
||||
void SocketInit(char *ip, char *mask, char *gw)
|
||||
{
|
||||
printf("%s ip %d.%d.%d.%d mask %d.%d.%d.%d gw %d.%d.%d.%d\n", __func__,
|
||||
ip[0], ip[1], ip[2], ip[3],
|
||||
mask[0], mask[1], mask[2], mask[3],
|
||||
gw[0], gw[1], gw[2], gw[3]);
|
||||
#ifdef BSP_USING_LWIP
|
||||
lwip_config_tcp(0, ip, mask, gw);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Control Framework Serial Init
|
||||
* @param baud_rate - baud rate
|
||||
* @param data_bits - data bits
|
||||
* @param stop_bits - stop bits
|
||||
* @param check_mode - check mode
|
||||
* @return
|
||||
*/
|
||||
void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode)
|
||||
{
|
||||
// Uart485Init(baud_rate, data_bits, stop_bits, check_mode);
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file control_io.h
|
||||
* @brief code for control framework io adapter
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-11-21
|
||||
*/
|
||||
|
||||
#ifndef CONTROL_IO_H
|
||||
#define CONTROL_IO_H
|
||||
|
||||
#include <transform.h>
|
||||
#include <list.h>
|
||||
|
||||
#ifdef BSP_USING_LWIP
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/sockets.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_LWIP
|
||||
#define socket_write lwip_write
|
||||
#define socket_read lwip_read
|
||||
#endif
|
||||
|
||||
/*Control Framework Socket Init*/
|
||||
void SocketInit(char *ip, char *mask, char *gw);
|
||||
|
||||
/*Control Framework Serial Init*/
|
||||
void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
extern int SensorFrameworkInit(void);
|
||||
extern int AdapterFrameworkInit(void);
|
||||
extern int ControlFrameworkInit(void);
|
||||
|
||||
extern int Adapter4GInit(void);
|
||||
extern int AdapterNbiotInit(void);
|
||||
|
@ -73,6 +74,10 @@ static struct InitDesc framework[] =
|
|||
{ "connection_framework", AdapterFrameworkInit },
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_CONTROL_FRAMEWORK
|
||||
{ "control_framework", ControlFrameworkInit },
|
||||
#endif
|
||||
|
||||
{ "NULL", NULL },
|
||||
};
|
||||
|
||||
|
@ -229,6 +234,10 @@ int FrameworkInit(void)
|
|||
ConnectionDeviceFrameworkInit(framework);
|
||||
#endif
|
||||
|
||||
#ifdef SUPPORT_CONTROL_FRAMEWORK
|
||||
ControlFrameworkInit();
|
||||
#endif
|
||||
|
||||
#ifdef LIB_LV
|
||||
lv_port_init();
|
||||
#endif
|
|
@ -0,0 +1,42 @@
|
|||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see misc/tools/kconfig-language.txt.
|
||||
#
|
||||
|
||||
if ARCH_BOARD_EDU_RISCV64
|
||||
|
||||
menuconfig BSP_USING_CH376
|
||||
bool "Using CH376 device"
|
||||
default n
|
||||
select K210_UART
|
||||
select K210_UART3
|
||||
|
||||
if BSP_USING_CH376
|
||||
|
||||
choice
|
||||
prompt "select ch376 function."
|
||||
default CH376_USB_FUNCTION
|
||||
|
||||
config CH376_USB_FUNCTION
|
||||
bool "select ch376 usb function"
|
||||
|
||||
config CH376_SD_FUNCTION
|
||||
bool "select ch376 sd function"
|
||||
endchoice
|
||||
|
||||
config CH376_WORK_MODE
|
||||
hex "ch376 work mode set:0x03 sd,0x06 u-disk"
|
||||
default 0x03 if CH376_SD_FUNCTION
|
||||
default 0x06 if CH376_USB_FUNCTION
|
||||
|
||||
endif # BSP_USING_CH376
|
||||
|
||||
menuconfig BSP_USING_ENET
|
||||
bool "Using ENET device"
|
||||
default n
|
||||
|
||||
menuconfig BSP_USING_TOUCH
|
||||
bool "Using touch device"
|
||||
default n
|
||||
|
||||
endif # ARCH_BOARD_EDU_RISCV64
|
|
@ -0,0 +1,42 @@
|
|||
1. Download and install toolchain and openocd-k210
|
||||
|
||||
$ curl https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz
|
||||
$ export PATH=$PATH:/$TOOL_CHAIN_PATH/bin
|
||||
|
||||
2. Build openocd-k210
|
||||
|
||||
$ git clone https://github.com/kendryte/openocd-kendryte
|
||||
$ cd openocd-kendryte
|
||||
$ ./bootstrap & ./configure & make
|
||||
|
||||
3. Configure and build NuttX
|
||||
|
||||
$ mkdir ./nuttx; cd ./nuttx
|
||||
$ git clone https://github.com/apache/incubator-nuttx.git nuttx
|
||||
$ git clone https://github.com/apache/incubator-nuttx-apps.git apps
|
||||
$ cd nuttx
|
||||
$ make distclean
|
||||
$ ./tools/configure.sh edu-riscv64:nsh
|
||||
$ make V=1
|
||||
|
||||
4. Download and run the nuttx from SRAM (not SPI-Flash)
|
||||
|
||||
$ picocom -b 115200 /dev/ttyUSB0
|
||||
$ sudo ./src/openocd -s ./tcl -f ./tcl/kendryte.cfg -m 0
|
||||
$ riscv64-unknown-elf-gdb ./nuttx
|
||||
(gdb) target extended-remote :3333
|
||||
(gdb) load nuttx
|
||||
(gdb) c
|
||||
|
||||
5. Write nuttx.bin to SPI-Flash
|
||||
|
||||
$ pip3 install kflash
|
||||
$ kflash -p /dev/ttyUSB0 -b 1500000 ./nuttx/nuttx.bin
|
||||
|
||||
NOTE: The kflash_gui is not recommended because it's unstable
|
||||
|
||||
6. TODO
|
||||
|
||||
Support peripherals such as GPIO/SPI/I2C/...
|
||||
Support FPU
|
||||
Support RISC-V U-mode including memory protection
|
|
@ -0,0 +1,80 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_NSH_DISABLE_LOSMART is not set
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
CONFIG_ADD_NUTTX_FETURES=y
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_BOARD="xidatong-riscv64"
|
||||
CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y
|
||||
CONFIG_ARCH_CHIP="k210"
|
||||
CONFIG_ARCH_CHIP_K210=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_BINFMT_DISABLE=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=46000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INIT_STACKSIZE=3072
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LIBC_PERROR_STDOUT=y
|
||||
CONFIG_LIBC_STRERROR=y
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_DISABLE_IFUPDOWN=y
|
||||
CONFIG_NSH_DISABLE_MKDIR=y
|
||||
CONFIG_NSH_DISABLE_RM=y
|
||||
CONFIG_NSH_DISABLE_RMDIR=y
|
||||
CONFIG_NSH_DISABLE_UMOUNT=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_NSH_STRERROR=y
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_RAM_SIZE=2097152
|
||||
CONFIG_RAM_START=0x80400000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_READLINE_CMD_HISTORY_LEN=100
|
||||
CONFIG_READLINE_CMD_HISTORY_LINELEN=120
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=28
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2019
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_TASK_NAME_SIZE=20
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_READLINE_TABCOMPLETION=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_DEV_GPIO=y
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_K210_UART=y
|
||||
CONFIG_K210_UART2=y
|
||||
CONFIG_K210_UART2_BASE=0x50220000
|
||||
CONFIG_K210_UART2_CLOCK=195000000
|
||||
CONFIG_K210_UART2_IRQ=39
|
||||
CONFIG_K210_UART2_BAUD=115200
|
||||
CONFIG_K210_UART2_PARITY=0
|
||||
CONFIG_K210_UART2_BITS=8
|
||||
CONFIG_K210_UART2_2STOP=0
|
||||
CONFIG_K210_UART2_RXBUFSIZE=128
|
||||
CONFIG_K210_UART2_TXBUFSIZE=128
|
||||
CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y
|
||||
CONFIG_CONNECTION_FRAMEWORK_DEBUG=y
|
||||
CONFIG_CONNECTION_ADAPTER_LORA=y
|
||||
CONFIG_ADAPTER_E220=y
|
||||
CONFIG_ADAPTER_LORA_E220="e220"
|
||||
CONFIG_ADAPTER_E220_DRIVER_EXTUART=n
|
||||
CONFIG_ADAPTER_E220_DRIVER="/dev/ttyS2"
|
||||
CONFIG_ADAPTER_E220_M0_PATH="/dev/gpio0"
|
||||
CONFIG_ADAPTER_E220_M1_PATH="/dev/gpio1"
|
|
@ -0,0 +1,60 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_NSH_DISABLE_LOSMART is not set
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
CONFIG_ADD_NUTTX_FETURES=y
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_BOARD="edu-riscv64"
|
||||
CONFIG_ARCH_BOARD_EDU_RISCV64=y
|
||||
CONFIG_ARCH_CHIP="k210"
|
||||
CONFIG_ARCH_CHIP_K210=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_BINFMT_DISABLE=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=46000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INIT_STACKSIZE=3072
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_LIBC_PERROR_STDOUT=y
|
||||
CONFIG_LIBC_STRERROR=y
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_DISABLE_IFUPDOWN=y
|
||||
CONFIG_NSH_DISABLE_MKDIR=y
|
||||
CONFIG_NSH_DISABLE_RM=y
|
||||
CONFIG_NSH_DISABLE_RMDIR=y
|
||||
CONFIG_NSH_DISABLE_UMOUNT=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_NSH_STRERROR=y
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_RAM_SIZE=2097152
|
||||
CONFIG_RAM_START=0x80400000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_READLINE_CMD_HISTORY_LEN=100
|
||||
CONFIG_READLINE_CMD_HISTORY_LINELEN=120
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=28
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2019
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_TASK_NAME_SIZE=20
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
CONFIG_READLINE_TABCOMPLETION=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_DEV_GPIO=y
|
||||
CONFIG_BOARDCTL_RESET=y
|
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief edu-riscv64 board.h
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.17
|
||||
*/
|
||||
|
||||
#ifndef __BOARDS_RISCV_K210_EDU_RISCV64_INCLUDE_BOARD_H
|
||||
#define __BOARDS_RISCV_K210_EDU_RISCV64_INCLUDE_BOARD_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include "k210.h"
|
||||
|
||||
#include "k210_fpioa.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Map pad 14 to gpiohs io 0 */
|
||||
#define BOARD_LED_IO_FUNC K210_IO_FUNC_GPIOHS0
|
||||
|
||||
#define LED_STARTED 0 /* N/C */
|
||||
#define LED_HEAPALLOCATE 1 /* N/C */
|
||||
#define LED_IRQSENABLED 2 /* N/C */
|
||||
#define LED_STACKCREATED 3 /* N/C */
|
||||
#define LED_INIRQ 4 /* N/C */
|
||||
#define LED_SIGNAL 5 /* N/C */
|
||||
#define LED_ASSERTION 6 /* N/C */
|
||||
#define LED_PANIC 7 /* blink */
|
||||
|
||||
/* GPIO pins used by the GPIO Subsystem */
|
||||
|
||||
#define BOARD_NGPIOOUT 3 /* Amount of register GPIO Output pins */
|
||||
#define BOARD_NGPIOINT 0 /* Amount of GPIO Input */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/*************************** GPIO define ***************************/
|
||||
|
||||
/* UART IO */
|
||||
#define GPIO_WIFI_RXD 7
|
||||
#define GPIO_WIFI_TXD 6
|
||||
#define GPIO_E220_RXD 21
|
||||
#define GPIO_E220_TXD 20
|
||||
#define GPIO_CH376T_RXD 22
|
||||
#define GPIO_CH376T_TXD 23
|
||||
|
||||
/* w5500 IO */
|
||||
#define BSP_ENET_SCLK 9
|
||||
#define BSP_ENET_MISO 10
|
||||
#define BSP_ENET_MOSI 11
|
||||
#define BSP_ENET_NCS 12
|
||||
#define BSP_ENET_NRST 13
|
||||
#define BSP_ENET_NINT 14
|
||||
|
||||
/* LCD IO */
|
||||
#define BSP_LCD_NRST 37
|
||||
#define BSP_LCD_SCLK 38
|
||||
#define BSP_LCD_MOSI 39
|
||||
#define BSP_LCD_MISO 40
|
||||
#define BSP_LCD_NCS 41
|
||||
#define BSP_LCD_BL_PIN 47
|
||||
|
||||
/* I2C */
|
||||
#define BSP_IIC_SDA 15
|
||||
#define BSP_IIC_SCL 17
|
||||
|
||||
/* other mode io */
|
||||
#define GPIO_E220_M0 32
|
||||
#define GPIO_E220_M1 33
|
||||
#define GPIO_E18_MODE 46
|
||||
#define GPIO_WIFI_EN 8
|
||||
#define GPIO_CAN_CFG 43
|
||||
|
||||
/************************** end GPIO define **************************/
|
||||
|
||||
|
||||
/*************************** FPIOA define ***************************/
|
||||
|
||||
/* UART FPOA */
|
||||
#define FPOA_USART1_RX K210_IO_FUNC_UART1_RX
|
||||
#define FPOA_USART1_TX K210_IO_FUNC_UART1_TX
|
||||
#define FPOA_USART2_RX K210_IO_FUNC_UART2_RX
|
||||
#define FPOA_USART2_TX K210_IO_FUNC_UART2_TX
|
||||
#define FPOA_USART3_RX K210_IO_FUNC_UART3_RX
|
||||
#define FPOA_USART3_TX K210_IO_FUNC_UART3_TX
|
||||
|
||||
/* w5500 FPIOA */
|
||||
#define FPIOA_ENET_NRST 0
|
||||
#define FPIOA_ENET_NINT 9
|
||||
#define FPIOA_ENET_SCLK 28
|
||||
#define FPIOA_ENET_MISO 29
|
||||
#define FPIOA_ENET_MOSI 23
|
||||
#define FPIOA_ENET_NCS 31
|
||||
|
||||
/* LCD FPIOA */
|
||||
#define FPIOA_LCD_NRST 0
|
||||
#define FPIOA_LCD_BL 9
|
||||
#define FPIOA_LCD_SCLK 28
|
||||
#define FPIOA_LCD_MOSI 29
|
||||
#define FPIOA_LCD_MISO 23
|
||||
#define FPIOA_LCD_NCS 31
|
||||
|
||||
/* I2C */
|
||||
#define FPIOA_IIC_SDA 7
|
||||
#define FPIOA_IIC_SCL 8
|
||||
|
||||
/* other mode FPIOA */
|
||||
#define FPIOA_E220_M0 1
|
||||
#define FPIOA_E220_M1 2
|
||||
#define FPIOA_E18_MODE 3
|
||||
#define FPIOA_WIFI_EN 4
|
||||
#define FPIOA_CAN_NCFG 5
|
||||
|
||||
/************************** end FPIOA define **************************/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k210_boardinitialize
|
||||
****************************************************************************/
|
||||
|
||||
void k210_boardinitialize(void);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __BOARDS_RISC-V_K210_EDU_RISCV64_INCLUDE_BOARD_H */
|
|
@ -0,0 +1,92 @@
|
|||
############################################################################
|
||||
# boards/risc-v/k210/edu-riscv64/kernel/Makefile
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(TOPDIR)/Make.defs
|
||||
|
||||
# The entry point name (if none is provided in the .config file)
|
||||
|
||||
CONFIG_INIT_ENTRYPOINT ?= user_start
|
||||
ENTRYPT = $(patsubst "%",%,$(CONFIG_INIT_ENTRYPOINT))
|
||||
|
||||
# Get the paths to the libraries and the links script path in format that
|
||||
# is appropriate for the host OS
|
||||
|
||||
USER_LIBPATHS = $(addprefix -L,$(call CONVERT_PATH,$(addprefix $(TOPDIR)$(DELIM),$(dir $(USERLIBS)))))
|
||||
USER_LDSCRIPT = -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)memory.ld)
|
||||
USER_LDSCRIPT += -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)user-space.ld)
|
||||
USER_HEXFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.hex)
|
||||
USER_SRECFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.srec)
|
||||
USER_BINFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.bin)
|
||||
|
||||
USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(USER_LDSCRIPT)
|
||||
USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS))))
|
||||
USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
|
||||
|
||||
# Source files
|
||||
|
||||
CSRCS = k210_userspace.c
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
OBJS = $(COBJS)
|
||||
|
||||
# Targets:
|
||||
|
||||
all: $(TOPDIR)$(DELIM)nuttx_user.elf $(TOPDIR)$(DELIM)User.map
|
||||
.PHONY: nuttx_user.elf depend clean distclean
|
||||
|
||||
$(COBJS): %$(OBJEXT): %.c
|
||||
$(call COMPILE, $<, $@)
|
||||
|
||||
# Create the nuttx_user.elf file containing all of the user-mode code
|
||||
|
||||
nuttx_user.elf: $(OBJS)
|
||||
$(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) --start-group $(USER_LDLIBS) --end-group $(USER_LIBGCC)
|
||||
|
||||
$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf
|
||||
@echo "LD: nuttx_user.elf"
|
||||
$(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf
|
||||
ifeq ($(CONFIG_INTELHEX_BINARY),y)
|
||||
@echo "CP: nuttx_user.hex"
|
||||
$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE)
|
||||
endif
|
||||
ifeq ($(CONFIG_MOTOROLA_SREC),y)
|
||||
@echo "CP: nuttx_user.srec"
|
||||
$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O srec nuttx_user.elf $(USER_SRECFILE)
|
||||
endif
|
||||
ifeq ($(CONFIG_RAW_BINARY),y)
|
||||
@echo "CP: nuttx_user.bin"
|
||||
$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE)
|
||||
endif
|
||||
|
||||
$(TOPDIR)$(DELIM)User.map: nuttx_user.elf
|
||||
@echo "MK: User.map"
|
||||
$(Q) $(NM) -n nuttx_user.elf >$(TOPDIR)$(DELIM)User.map
|
||||
$(Q) $(CROSSDEV)size nuttx_user.elf
|
||||
|
||||
.depend:
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
$(call DELFILE, nuttx_user.elf)
|
||||
$(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*")
|
||||
$(call DELFILE, "$(TOPDIR)$(DELIM)User.map")
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_userspace.c
|
||||
* @brief edu-riscv64 k210_userspace.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.17
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/mm/mm.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
#include <nuttx/userspace.h>
|
||||
|
||||
#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
#ifndef CONFIG_NUTTX_USERSPACE
|
||||
# error "CONFIG_NUTTX_USERSPACE not defined"
|
||||
#endif
|
||||
|
||||
#if CONFIG_NUTTX_USERSPACE != 0x80100000
|
||||
# error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* These 'addresses' of these values are setup by the linker script.
|
||||
* They are not actual uint32_t storage locations!
|
||||
* They are only used meaningfully in the following way:
|
||||
*
|
||||
* - The linker script defines, for example, the symbol_sdata.
|
||||
* - The declaration extern uint32_t _sdata; makes C happy. C will believe
|
||||
* that the value _sdata is the address of a uint32_t variable _data
|
||||
* (it is not!).
|
||||
* - We can recover the linker value then by simply taking the address of
|
||||
* of _data. like: uint32_t *pdata = &_sdata;
|
||||
*/
|
||||
|
||||
extern uint32_t _stext; /* Start of .text */
|
||||
extern uint32_t _etext; /* End_1 of .text + .rodata */
|
||||
extern const uint32_t _eronly; /* End+1 of read only section */
|
||||
extern uint32_t _sdata; /* Start of .data */
|
||||
extern uint32_t _edata; /* End+1 of .data */
|
||||
extern uint32_t _sbss; /* Start of .bss */
|
||||
extern uint32_t _ebss; /* End+1 of .bss */
|
||||
|
||||
/* This is the user space entry point */
|
||||
|
||||
int CONFIG_INIT_ENTRYPOINT(int argc, char *argv[]);
|
||||
|
||||
const struct userspace_s userspace locate_data(".userspace") =
|
||||
{
|
||||
/* General memory map */
|
||||
|
||||
.us_entrypoint = (main_t)CONFIG_INIT_ENTRYPOINT,
|
||||
.us_textstart = (uintptr_t)&_stext,
|
||||
.us_textend = (uintptr_t)&_etext,
|
||||
.us_datasource = (uintptr_t)&_eronly,
|
||||
.us_datastart = (uintptr_t)&_sdata,
|
||||
.us_dataend = (uintptr_t)&_edata,
|
||||
.us_bssstart = (uintptr_t)&_sbss,
|
||||
.us_bssend = (uintptr_t)&_ebss,
|
||||
|
||||
/* Memory manager heap structure */
|
||||
|
||||
.us_heap = &g_mmheap,
|
||||
|
||||
/* Task/thread startup routines */
|
||||
|
||||
.task_startup = nxtask_startup,
|
||||
|
||||
/* Signal handler trampoline */
|
||||
|
||||
.signal_handler = up_signal_handler,
|
||||
|
||||
/* User-space work queue support (declared in include/nuttx/wqueue.h) */
|
||||
|
||||
#ifdef CONFIG_LIBC_USRWORK
|
||||
.work_usrstart = work_usrstart,
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */
|
|
@ -0,0 +1,174 @@
|
|||
# 从零开始构建矽璓工业物联操作系统:使用ARM架构的矽达通
|
||||
|
||||
# edu-riscv64
|
||||
|
||||
[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓XiUOS是一款面向智慧车间的工业物联网操作系统,主要由一个极简的微型实时操作系统内核和其上的工业物联框架构成,通过高效管理工业物联网设备、支撑工业物联应用,在生产车间内实现智能化的“感知环境、联网传输、知悉识别、控制调整”,促进以工业设备和工业控制系统为核心的人、机、物深度互联,帮助提升生产线的数字化和智能化水平。
|
||||
|
||||
## 1. 简介
|
||||
|
||||
| 硬件 | 描述 |
|
||||
| -- | -- |
|
||||
|芯片型号| 勘智K210 |
|
||||
|架构| 双核riscv64 |
|
||||
|主频| 400MHz |
|
||||
|片内SRAM| 8M |
|
||||
|外设支持| 内嵌AES与SHA256算法加速器 |
|
||||
|| DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I²S、I²C、WDT、Timer与PWM |
|
||||
|
||||
XiUOS板级当前支持使用CH438、GPIO、UART等。
|
||||
|
||||
## 2. 开发环境搭建
|
||||
|
||||
### 推荐使用:
|
||||
|
||||
**操作系统:** ubuntu18.04 [https://ubuntu.com/download/desktop](https://ubuntu.com/download/desktop)
|
||||
|
||||
更新`ubuntu 18.04`源的方法:(根据自身情况而定,可以不更改)
|
||||
|
||||
第一步:打开sources.list文件
|
||||
|
||||
```c
|
||||
sudo vim /etc/apt/sources.list
|
||||
```
|
||||
|
||||
第二步:将以下内容复制到sources.list文件
|
||||
|
||||
```c
|
||||
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
|
||||
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
|
||||
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
|
||||
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
|
||||
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
|
||||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
|
||||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
|
||||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
|
||||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
|
||||
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
|
||||
```
|
||||
|
||||
第三步:更新源和系统软件
|
||||
|
||||
```c
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
```
|
||||
|
||||
**开发工具推荐使用 VSCode ,VScode下载地址为:** VSCode [https://code.visualstudio.com/](https://code.visualstudio.com/),推荐下载地址为 [http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb](http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb)
|
||||
|
||||
### 依赖包安装:
|
||||
|
||||
```
|
||||
$ sudo apt install build-essential pkg-config git
|
||||
$ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev
|
||||
```
|
||||
|
||||
**XiUOS操作系统源码下载,这个仓里的代码可能不是最新的,最好git clone自己仓里的代码:** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos)
|
||||
|
||||
新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下:
|
||||
|
||||
```c
|
||||
mkdir test && cd test
|
||||
git clone https://gitlink.org.cn/xuos/xiuos.git
|
||||
git checkout origin/prepare_for_master (以实际分支为准)
|
||||
```
|
||||
|
||||
打开XiUOS源码文件包可以看到以下目录:
|
||||
| 名称 | 说明 |
|
||||
| -- | -- |
|
||||
| APP_Framework | 应用代码 |
|
||||
| Ubiquitous | 板级支持包,支持NuttX、RT-Thread和XiZi内核 |
|
||||
|
||||
|
||||
### 裁减配置工具的下载
|
||||
|
||||
裁减配置工具:
|
||||
|
||||
**工具地址:** kconfig-frontends [https://www.gitlink.org.cn/xuos/kconfig-frontends](https://www.gitlink.org.cn/xuos/kconfig-frontends),下载与安装的具体命令如下:
|
||||
|
||||
```c
|
||||
mkdir kfrontends && cd kfrontends
|
||||
git clone https://gitlink.org.cn/xuos/kconfig-frontends.git
|
||||
```
|
||||
|
||||
下载源码后按以下步骤执行软件安装:
|
||||
|
||||
```c
|
||||
cd kconfig-frontends
|
||||
./xs_build.sh
|
||||
```
|
||||
|
||||
### 编译工具链:
|
||||
|
||||
Riscv64: riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar,在我的个人仓保存有一份:
|
||||
|
||||
https://gitlink.org.cn/wgzAIIT/build_tools.git
|
||||
|
||||
下载后解压到Ubantu环境的/opt目录下。
|
||||
|
||||
再将/opt/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin目录下的全部二进制文件软连接到/usr/bin,例如
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 3.编译bin包
|
||||
|
||||
1.XiUOS操作系统源码下载: [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos)
|
||||
|
||||
目前大家都使用的个人仓,请注意此处的路径及分支,如果需要须进行分支切换
|
||||
|
||||
2.在Ubuntu18.04环境中的代码路径,执行以下命令,生成配置文件
|
||||
|
||||
```shell
|
||||
cd ./Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx
|
||||
source build.sh
|
||||
|
||||
执行完毕会自动进入./Ubiquitous/Nuttx_Fusion_XiUOS/nuttx下,继续执行
|
||||
|
||||
./tools/configure.sh edu-riscv64:nsh
|
||||
make menuconfig
|
||||
视情况而定,如果需要前面加sudo
|
||||
```
|
||||
|
||||
3..在menuconfig界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后保存并退出(本例旨在演示简单的输出例程,所以没有需要配置的选项,双击快捷键ESC退出配置)
|
||||
|
||||

|
||||
|
||||
退出时选择`yes`保存上面所配置的内容,如下图所示:
|
||||
|
||||

|
||||
|
||||
4.继续执行以下命令,进行编译
|
||||
|
||||
```shell
|
||||
make
|
||||
或
|
||||
make -j8
|
||||
```
|
||||
|
||||
make时加上V=1参数可以看到较为详细的编译信息,但是编译过程会比较慢。
|
||||
|
||||
5.如果编译正确无误,会在当前目录下产生nuttx.bin、nuttx、nuttx.hex等文件。
|
||||
|
||||
## 4. 烧写及运行
|
||||
|
||||
### 4.1 烧写
|
||||
1、烧写工具:K-Flash.exe,可https://gitlink.org.cn/wgzAIIT/build_tools.git下载
|
||||
|
||||

|
||||
|
||||
在①选择串口 com 号
|
||||
|
||||
在②处选择波特率,选择 115200
|
||||
|
||||
在③处选择编译出的 nuttx.bin 文件
|
||||
|
||||
设备在上电时确保 Boot 和 GND 短接,这是升级模式。
|
||||
|
||||
点击④处 Flash 开始烧录,显示烧录完成即可,中间有报错的话,重新 Flash。
|
||||
|
||||
### 4.2 运行结果
|
||||
|
||||
烧写完毕重新上电,进入 shell。
|
||||
|
||||

|
|
@ -0,0 +1,70 @@
|
|||
############################################################################
|
||||
# boards/risc-v/k210/edu-riscv64/scripts/Make.defs
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(TOPDIR)/.config
|
||||
include $(TOPDIR)/tools/Config.mk
|
||||
include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
|
||||
|
||||
LDSCRIPT = ld.script
|
||||
|
||||
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
|
||||
|
||||
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
|
||||
ARCHOPTIMIZATION = -g
|
||||
ASARCHCPUFLAGS += -Wa,-g
|
||||
endif
|
||||
|
||||
MAXOPTIMIZATION = -Os
|
||||
|
||||
ifneq ($(CONFIG_DEBUG_NOOPT),y)
|
||||
ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing
|
||||
endif
|
||||
|
||||
ARCHCPUFLAGS += -mcmodel=medany -mstrict-align
|
||||
ARCHCFLAGS = -fno-common -ffunction-sections -fdata-sections
|
||||
ARCHCXXFLAGS = -fno-common -fno-exceptions -fcheck-new -fno-rtti
|
||||
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
|
||||
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
|
||||
|
||||
CFLAGS := $(APPPATHS) $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
|
||||
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
|
||||
CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
|
||||
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
|
||||
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
|
||||
AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS)
|
||||
|
||||
# Loadable module definitions
|
||||
|
||||
CMODULEFLAGS = $(CFLAGS)
|
||||
|
||||
LDMODULEFLAGS = -r -e module_initialize
|
||||
LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld)
|
||||
|
||||
# ELF module definitions
|
||||
|
||||
CELFFLAGS = $(CFLAGS)
|
||||
CXXELFFLAGS = $(CXXFLAGS)
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)gnu-elf.ld)
|
||||
|
||||
# File extensions
|
||||
|
||||
LDFLAGS += --gc-sections -melf64lriscv
|
|
@ -0,0 +1,115 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/k210/edu-riscv64/scripts/gnu-elf.ld
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x00000000 :
|
||||
{
|
||||
_stext = . ;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.warning)
|
||||
*(.stub)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.jcr)
|
||||
|
||||
/* C++ support: The .init and .fini sections contain specific logic
|
||||
* to manage static constructors and destructors.
|
||||
*/
|
||||
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.init) /* Old ABI */
|
||||
*(.fini) /* Old ABI */
|
||||
_etext = . ;
|
||||
}
|
||||
|
||||
.rodata :
|
||||
{
|
||||
_srodata = . ;
|
||||
*(.rodata)
|
||||
*(.rodata1)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
_erodata = . ;
|
||||
}
|
||||
|
||||
.data :
|
||||
{
|
||||
_sdata = . ;
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
. = ALIGN(4);
|
||||
_edata = . ;
|
||||
}
|
||||
|
||||
/* C++ support. For each global and static local C++ object,
|
||||
* GCC creates a small subroutine to construct the object. Pointers
|
||||
* to these routines (not the routines themselves) are stored as
|
||||
* simple, linear arrays in the .ctors section of the object file.
|
||||
* Similarly, pointers to global/static destructor routines are
|
||||
* stored in .dtors.
|
||||
*/
|
||||
|
||||
.ctors :
|
||||
{
|
||||
_sctors = . ;
|
||||
*(.ctors) /* Old ABI: Unallocated */
|
||||
*(.init_array) /* New ABI: Allocated */
|
||||
_edtors = . ;
|
||||
}
|
||||
|
||||
.dtors :
|
||||
{
|
||||
_sdtors = . ;
|
||||
*(.dtors) /* Old ABI: Unallocated */
|
||||
*(.fini_array) /* New ABI: Allocated */
|
||||
_edtors = . ;
|
||||
}
|
||||
|
||||
.bss :
|
||||
{
|
||||
_sbss = . ;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.b*)
|
||||
*(COMMON)
|
||||
_ebss = . ;
|
||||
}
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/k210/edu-riscv64/scripts/ld.script
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Reg Access Start addr End addr Size
|
||||
* MEM0 CPU w/ cache 0x80000000 - 0x803fffff : 4MB
|
||||
* MEM1 CPU w/ cache 0x80400000 - 0x805fffff : 2MB
|
||||
* MEM0 CPU w/o cache 0x40000000 - 0x403fffff : 4MB
|
||||
* MEM1 CPU w/o cache 0x40400000 - 0x405fffff : 4MB
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
progmem (rx) : ORIGIN = 0x80000000, LENGTH = 4096K /* w/ cache */
|
||||
sram (rwx) : ORIGIN = 0x80400000, LENGTH = 2048K /* w/ cache */
|
||||
}
|
||||
|
||||
OUTPUT_ARCH("riscv")
|
||||
|
||||
ENTRY(_stext)
|
||||
EXTERN(_vectors)
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
_stext = ABSOLUTE(.);
|
||||
*(.vectors)
|
||||
*(.text .text.*)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
*(.rodata .rodata.* .srodata .srodata.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.got)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.r.*)
|
||||
_etext = ABSOLUTE(.);
|
||||
} > progmem
|
||||
|
||||
.init_section : ALIGN(4) {
|
||||
_sinit = ABSOLUTE(.);
|
||||
KEEP(*(.init_array .init_array.*))
|
||||
_einit = ABSOLUTE(.);
|
||||
} > progmem
|
||||
|
||||
_eronly = ABSOLUTE(.);
|
||||
|
||||
.data : ALIGN(4) {
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.* .sdata2.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(4);
|
||||
_edata = ABSOLUTE(.);
|
||||
} > sram AT > progmem
|
||||
|
||||
.bss : ALIGN(4) {
|
||||
_sbss = ABSOLUTE(.);
|
||||
*(.bss .bss.*)
|
||||
*(.sbss .sbss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(32);
|
||||
_ebss = ABSOLUTE(.);
|
||||
} > sram
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/k210/edu-riscv64/scripts/memory.ld
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Reg Access Start addr End addr Size
|
||||
* MEM0 CPU w/ cache 0x80000000 - 0x803fffff : 4MB
|
||||
* MEM1 CPU w/ cache 0x80400000 - 0x805fffff : 2MB
|
||||
* MEM0 CPU w/o cache 0x40000000 - 0x403fffff : 4MB
|
||||
* MEM1 CPU w/o cache 0x40400000 - 0x405fffff : 4MB
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
kflash (rx) : ORIGIN = 0x80000000, LENGTH = 1024K /* w/ cache */
|
||||
uflash (rx) : ORIGIN = 0x80100000, LENGTH = 1024K /* w/ cache */
|
||||
xflash (rx) : ORIGIN = 0x80200000, LENGTH = 2048K /* w/ cache */
|
||||
|
||||
ksram (rwx) : ORIGIN = 0x80400000, LENGTH = 512K /* w/ cache */
|
||||
usram (rwx) : ORIGIN = 0x80480000, LENGTH = 512K /* w/ cache */
|
||||
xsram (rwx) : ORIGIN = 0x80500000, LENGTH = 1024K /* w/ cache */
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/****************************************************************************
|
||||
* boards/risc-v/k210/edu-riscv64/scripts/user-space.ld
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* NOTE: This depends on the memory.ld script having been included prior to
|
||||
* this script.
|
||||
*/
|
||||
|
||||
OUTPUT_ARCH("riscv")
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.userspace : {
|
||||
*(.userspace)
|
||||
} > uflash
|
||||
|
||||
.text : {
|
||||
_stext = ABSOLUTE(.);
|
||||
*(.text .text.*)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
*(.rodata .rodata.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.got)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.r.*)
|
||||
_etext = ABSOLUTE(.);
|
||||
} > uflash
|
||||
|
||||
.init_section : {
|
||||
_sinit = ABSOLUTE(.);
|
||||
KEEP(*(.init_array .init_array.*))
|
||||
_einit = ABSOLUTE(.);
|
||||
} > uflash
|
||||
|
||||
__exidx_start = ABSOLUTE(.);
|
||||
|
||||
__exidx_end = ABSOLUTE(.);
|
||||
|
||||
_eronly = ABSOLUTE(.);
|
||||
|
||||
.data : {
|
||||
_sdata = ABSOLUTE(.);
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.* .sdata2.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
CONSTRUCTORS
|
||||
. = ALIGN(4);
|
||||
_edata = ABSOLUTE(.);
|
||||
} > usram AT > uflash
|
||||
|
||||
.bss : {
|
||||
_sbss = ABSOLUTE(.);
|
||||
*(.bss .bss.*)
|
||||
*(.sbss .sbss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = ABSOLUTE(.);
|
||||
} > usram
|
||||
|
||||
/* Stabs debugging sections */
|
||||
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
############################################################################
|
||||
# boards/risc-v/k210/edu-riscv64/src/Makefile
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(TOPDIR)/Make.defs
|
||||
|
||||
CSRCS = k210_bringup.c k210_boot.c
|
||||
|
||||
ifeq ($(CONFIG_BOARDCTL_RESET),y)
|
||||
CSRCS += k210_reset.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BOARDCTL),y)
|
||||
CSRCS += k210_appinit.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_LEDS),y)
|
||||
CSRCS += k210_leds.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_K210_LCD),y)
|
||||
CSRCS += k210_lcd.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_DEV_GPIO),y)
|
||||
CSRCS += k210_gpio.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_CH376),y)
|
||||
CSRCS += k210_ch376.c ch376_demo.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_ENET),y)
|
||||
CSRCS += k210_w5500.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_TOUCH),y)
|
||||
CSRCS += k210_touch.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/boards/Board.mk
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ch376_demo.c
|
||||
* @brief edu-riscv64 ch376_demo.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.10.11
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
#include "k210_ch376.h"
|
||||
|
||||
uint8_t buf[64];
|
||||
|
||||
void CH376Demo(void)
|
||||
{
|
||||
uint8_t s;
|
||||
s = mInitCH376Host();
|
||||
printf ("ch376 init stat=0x%02x\n",(uint16_t)s);
|
||||
|
||||
#ifdef CONFIG_CH376_USB_FUNCTION
|
||||
printf( "Wait Udisk/SD\n" );
|
||||
while ( CH376DiskConnect( ) != USB_INT_SUCCESS )
|
||||
{
|
||||
up_mdelay( 100 );
|
||||
}
|
||||
#endif
|
||||
|
||||
for ( s = 0; s < 10; s ++ )
|
||||
{
|
||||
up_mdelay( 50 );
|
||||
printf( "Ready ?\n" );
|
||||
if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break;
|
||||
}
|
||||
s = CH376ReadBlock( buf );
|
||||
if ( s == sizeof( INQUIRY_DATA ) )
|
||||
{
|
||||
buf[ s ] = 0;
|
||||
printf( "UdiskInfo: %s\n", ((P_INQUIRY_DATA)buf) -> VendorIdStr );
|
||||
}
|
||||
|
||||
printf( "Create /YEAR2022/DEMO2022.TXT \n" );
|
||||
s = CH376DirCreate((PUINT8)"/YEAR2022" );
|
||||
printf("CH376DirCreate:0x%02x\n",(uint16_t)s );
|
||||
|
||||
s = CH376FileCreatePath((PUINT8)"/YEAR2022/DEMO2022.TXT" );
|
||||
printf( "CH376FileCreatePath:0x%02x\n",(uint16_t)s );
|
||||
|
||||
printf( "Write some data to file\n" );
|
||||
strcpy( (char *)buf, "This is test case!\xd\xa" );
|
||||
s = CH376ByteWrite(buf, strlen((char *)buf), NULL );
|
||||
printf( "CH376ByteWrite:0x%02x\n",(uint16_t)s );
|
||||
|
||||
printf( "Close\n" );
|
||||
s = CH376FileClose( TRUE );
|
||||
printf( "CH376FileClose:0x%02x\n",(uint16_t)s );
|
||||
}
|
|
@ -0,0 +1,584 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ch376inc.h
|
||||
* @brief edu-riscv64 ch376inc.h
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.10.10
|
||||
*/
|
||||
|
||||
#ifndef __CH376INC_H__
|
||||
#define __CH376INC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Common types and constant definitions */
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef UINT8
|
||||
typedef unsigned char UINT8;
|
||||
#endif
|
||||
#ifndef UINT16
|
||||
typedef unsigned short UINT16;
|
||||
#endif
|
||||
#ifndef UINT32
|
||||
typedef unsigned long UINT32;
|
||||
#endif
|
||||
#ifndef PUINT8
|
||||
typedef unsigned char *PUINT8;
|
||||
#endif
|
||||
#ifndef PUINT16
|
||||
typedef unsigned short *PUINT16;
|
||||
#endif
|
||||
#ifndef PUINT32
|
||||
typedef unsigned long *PUINT32;
|
||||
#endif
|
||||
#ifndef UINT8V
|
||||
typedef unsigned char volatile UINT8V;
|
||||
#endif
|
||||
#ifndef PUINT8V
|
||||
typedef unsigned char volatile *PUINT8V;
|
||||
#endif
|
||||
|
||||
#define CH376_DAT_BLOCK_LEN 0x40
|
||||
#define CMD01_GET_IC_VER 0x01
|
||||
#define CMD21_SET_BAUDRATE 0x02
|
||||
#define CMD00_ENTER_SLEEP 0x03
|
||||
#define CMD00_RESET_ALL 0x05
|
||||
#define CMD11_CHECK_EXIST 0x06
|
||||
#define CMD20_CHK_SUSPEND 0x0B
|
||||
#define CMD20_SET_SDO_INT 0x0B
|
||||
#define CMD14_GET_FILE_SIZE 0x0C
|
||||
#define CMD50_SET_FILE_SIZE 0x0D
|
||||
#define CMD11_SET_USB_MODE 0x15
|
||||
#define CMD01_GET_STATUS 0x22
|
||||
#define CMD00_UNLOCK_USB 0x23
|
||||
#define CMD01_RD_USB_DATA0 0x27
|
||||
#define CMD01_RD_USB_DATA 0x28
|
||||
#define CMD10_WR_USB_DATA7 0x2B
|
||||
#define CMD10_WR_HOST_DATA 0x2C
|
||||
#define CMD01_WR_REQ_DATA 0x2D
|
||||
#define CMD20_WR_OFS_DATA 0x2E
|
||||
#define CMD10_SET_FILE_NAME 0x2F
|
||||
#define CMD0H_DISK_CONNECT 0x30
|
||||
#define CMD0H_DISK_MOUNT 0x31
|
||||
#define CMD0H_FILE_OPEN 0x32
|
||||
#define CMD0H_FILE_ENUM_GO 0x33
|
||||
#define CMD0H_FILE_CREATE 0x34
|
||||
#define CMD0H_FILE_ERASE 0x35
|
||||
#define CMD1H_FILE_CLOSE 0x36
|
||||
#define CMD1H_DIR_INFO_READ 0x37
|
||||
#define CMD0H_DIR_INFO_SAVE 0x38
|
||||
#define CMD4H_BYTE_LOCATE 0x39
|
||||
#define CMD2H_BYTE_READ 0x3A
|
||||
#define CMD0H_BYTE_RD_GO 0x3B
|
||||
#define CMD2H_BYTE_WRITE 0x3C
|
||||
#define CMD0H_BYTE_WR_GO 0x3D
|
||||
#define CMD0H_DISK_CAPACITY 0x3E
|
||||
#define CMD0H_DISK_QUERY 0x3F
|
||||
#define CMD0H_DIR_CREATE 0x40
|
||||
#define CMD4H_SEC_LOCATE 0x4A
|
||||
#define CMD1H_SEC_READ 0x4B
|
||||
#define CMD1H_SEC_WRITE 0x4C
|
||||
#define CMD0H_DISK_BOC_CMD 0x50
|
||||
#define CMD5H_DISK_READ 0x54
|
||||
#define CMD0H_DISK_RD_GO 0x55
|
||||
#define CMD5H_DISK_WRITE 0x56
|
||||
#define CMD0H_DISK_WR_GO 0x57
|
||||
#define CMD10_SET_USB_SPEED 0x04
|
||||
#define CMD11_GET_DEV_RATE 0x0A
|
||||
#define CMD11_GET_TOGGLE 0x0A
|
||||
#define CMD11_READ_VAR8 0x0A
|
||||
#define CMD20_SET_RETRY 0x0B
|
||||
#define CMD20_WRITE_VAR8 0x0B
|
||||
#define CMD14_READ_VAR32 0x0C
|
||||
#define CMD50_WRITE_VAR32 0x0D
|
||||
#define CMD01_DELAY_100US 0x0F
|
||||
#define CMD40_SET_USB_ID 0x12
|
||||
#define CMD10_SET_USB_ADDR 0x13
|
||||
#define CMD01_TEST_CONNECT 0x16
|
||||
#define CMD00_ABORT_NAK 0x17
|
||||
#define CMD10_SET_ENDP2 0x18
|
||||
#define CMD10_SET_ENDP3 0x19
|
||||
#define CMD10_SET_ENDP4 0x1A
|
||||
#define CMD10_SET_ENDP5 0x1B
|
||||
#define CMD10_SET_ENDP6 0x1C
|
||||
#define CMD10_SET_ENDP7 0x1D
|
||||
#define CMD00_DIRTY_BUFFER 0x25
|
||||
#define CMD10_WR_USB_DATA3 0x29
|
||||
#define CMD10_WR_USB_DATA5 0x2A
|
||||
#define CMD1H_CLR_STALL 0x41
|
||||
#define CMD1H_SET_ADDRESS 0x45
|
||||
#define CMD1H_GET_DESCR 0x46
|
||||
#define CMD1H_SET_CONFIG 0x49
|
||||
#define CMD0H_AUTO_SETUP 0x4D
|
||||
#define CMD2H_ISSUE_TKN_X 0x4E
|
||||
#define CMD1H_ISSUE_TOKEN 0x4F
|
||||
#define CMD0H_DISK_INIT 0x51
|
||||
#define CMD0H_DISK_RESET 0x52
|
||||
#define CMD0H_DISK_SIZE 0x53
|
||||
#define CMD0H_DISK_INQUIRY 0x58
|
||||
#define CMD0H_DISK_READY 0x59
|
||||
#define CMD0H_DISK_R_SENSE 0x5A
|
||||
#define CMD0H_RD_DISK_SEC 0x5B
|
||||
#define CMD0H_WR_DISK_SEC 0x5C
|
||||
#define CMD0H_DISK_MAX_LUN 0x5D
|
||||
|
||||
/* The following definitions are only for compatibility with the command name format in the INCLUDE file of CH375 */
|
||||
|
||||
#ifndef _NO_CH375_COMPATIBLE_
|
||||
#define CMD_GET_IC_VER CMD01_GET_IC_VER
|
||||
#define CMD_SET_BAUDRATE CMD21_SET_BAUDRATE
|
||||
#define CMD_ENTER_SLEEP CMD00_ENTER_SLEEP
|
||||
#define CMD_RESET_ALL CMD00_RESET_ALL
|
||||
#define CMD_CHECK_EXIST CMD11_CHECK_EXIST
|
||||
#define CMD_CHK_SUSPEND CMD20_CHK_SUSPEND
|
||||
#define CMD_SET_SDO_INT CMD20_SET_SDO_INT
|
||||
#define CMD_GET_FILE_SIZE CMD14_GET_FILE_SIZE
|
||||
#define CMD_SET_FILE_SIZE CMD50_SET_FILE_SIZE
|
||||
#define CMD_SET_USB_MODE CMD11_SET_USB_MODE
|
||||
#define CMD_GET_STATUS CMD01_GET_STATUS
|
||||
#define CMD_UNLOCK_USB CMD00_UNLOCK_USB
|
||||
#define CMD_RD_USB_DATA0 CMD01_RD_USB_DATA0
|
||||
#define CMD_RD_USB_DATA CMD01_RD_USB_DATA
|
||||
#define CMD_WR_USB_DATA7 CMD10_WR_USB_DATA7
|
||||
#define CMD_WR_HOST_DATA CMD10_WR_HOST_DATA
|
||||
#define CMD_WR_REQ_DATA CMD01_WR_REQ_DATA
|
||||
#define CMD_WR_OFS_DATA CMD20_WR_OFS_DATA
|
||||
#define CMD_SET_FILE_NAME CMD10_SET_FILE_NAME
|
||||
#define CMD_DISK_CONNECT CMD0H_DISK_CONNECT
|
||||
#define CMD_DISK_MOUNT CMD0H_DISK_MOUNT
|
||||
#define CMD_FILE_OPEN CMD0H_FILE_OPEN
|
||||
#define CMD_FILE_ENUM_GO CMD0H_FILE_ENUM_GO
|
||||
#define CMD_FILE_CREATE CMD0H_FILE_CREATE
|
||||
#define CMD_FILE_ERASE CMD0H_FILE_ERASE
|
||||
#define CMD_FILE_CLOSE CMD1H_FILE_CLOSE
|
||||
#define CMD_DIR_INFO_READ CMD1H_DIR_INFO_READ
|
||||
#define CMD_DIR_INFO_SAVE CMD0H_DIR_INFO_SAVE
|
||||
#define CMD_BYTE_LOCATE CMD4H_BYTE_LOCATE
|
||||
#define CMD_BYTE_READ CMD2H_BYTE_READ
|
||||
#define CMD_BYTE_RD_GO CMD0H_BYTE_RD_GO
|
||||
#define CMD_BYTE_WRITE CMD2H_BYTE_WRITE
|
||||
#define CMD_BYTE_WR_GO CMD0H_BYTE_WR_GO
|
||||
#define CMD_DISK_CAPACITY CMD0H_DISK_CAPACITY
|
||||
#define CMD_DISK_QUERY CMD0H_DISK_QUERY
|
||||
#define CMD_DIR_CREATE CMD0H_DIR_CREATE
|
||||
#define CMD_SEC_LOCATE CMD4H_SEC_LOCATE
|
||||
#define CMD_SEC_READ CMD1H_SEC_READ
|
||||
#define CMD_SEC_WRITE CMD1H_SEC_WRITE
|
||||
#define CMD_DISK_BOC_CMD CMD0H_DISK_BOC_CMD
|
||||
#define CMD_DISK_READ CMD5H_DISK_READ
|
||||
#define CMD_DISK_RD_GO CMD0H_DISK_RD_GO
|
||||
#define CMD_DISK_WRITE CMD5H_DISK_WRITE
|
||||
#define CMD_DISK_WR_GO CMD0H_DISK_WR_GO
|
||||
#define CMD_SET_USB_SPEED CMD10_SET_USB_SPEED
|
||||
#define CMD_GET_DEV_RATE CMD11_GET_DEV_RATE
|
||||
#define CMD_GET_TOGGLE CMD11_GET_TOGGLE
|
||||
#define CMD_READ_VAR8 CMD11_READ_VAR8
|
||||
#define CMD_SET_RETRY CMD20_SET_RETRY
|
||||
#define CMD_WRITE_VAR8 CMD20_WRITE_VAR8
|
||||
#define CMD_READ_VAR32 CMD14_READ_VAR32
|
||||
#define CMD_WRITE_VAR32 CMD50_WRITE_VAR32
|
||||
#define CMD_DELAY_100US CMD01_DELAY_100US
|
||||
#define CMD_SET_USB_ID CMD40_SET_USB_ID
|
||||
#define CMD_SET_USB_ADDR CMD10_SET_USB_ADDR
|
||||
#define CMD_TEST_CONNECT CMD01_TEST_CONNECT
|
||||
#define CMD_ABORT_NAK CMD00_ABORT_NAK
|
||||
#define CMD_SET_ENDP2 CMD10_SET_ENDP2
|
||||
#define CMD_SET_ENDP3 CMD10_SET_ENDP3
|
||||
#define CMD_SET_ENDP4 CMD10_SET_ENDP4
|
||||
#define CMD_SET_ENDP5 CMD10_SET_ENDP5
|
||||
#define CMD_SET_ENDP6 CMD10_SET_ENDP6
|
||||
#define CMD_SET_ENDP7 CMD10_SET_ENDP7
|
||||
#define CMD_DIRTY_BUFFER CMD00_DIRTY_BUFFER
|
||||
#define CMD_WR_USB_DATA3 CMD10_WR_USB_DATA3
|
||||
#define CMD_WR_USB_DATA5 CMD10_WR_USB_DATA5
|
||||
#define CMD_CLR_STALL CMD1H_CLR_STALL
|
||||
#define CMD_SET_ADDRESS CMD1H_SET_ADDRESS
|
||||
#define CMD_GET_DESCR CMD1H_GET_DESCR
|
||||
#define CMD_SET_CONFIG CMD1H_SET_CONFIG
|
||||
#define CMD_AUTO_SETUP CMD0H_AUTO_SETUP
|
||||
#define CMD_ISSUE_TKN_X CMD2H_ISSUE_TKN_X
|
||||
#define CMD_ISSUE_TOKEN CMD1H_ISSUE_TOKEN
|
||||
#define CMD_DISK_INIT CMD0H_DISK_INIT
|
||||
#define CMD_DISK_RESET CMD0H_DISK_RESET
|
||||
#define CMD_DISK_SIZE CMD0H_DISK_SIZE
|
||||
#define CMD_DISK_INQUIRY CMD0H_DISK_INQUIRY
|
||||
#define CMD_DISK_READY CMD0H_DISK_READY
|
||||
#define CMD_DISK_R_SENSE CMD0H_DISK_R_SENSE
|
||||
#define CMD_RD_DISK_SEC CMD0H_RD_DISK_SEC
|
||||
#define CMD_WR_DISK_SEC CMD0H_WR_DISK_SEC
|
||||
#define CMD_DISK_MAX_LUN CMD0H_DISK_MAX_LUN
|
||||
#endif
|
||||
|
||||
/* ********************************************************************************************************************* */
|
||||
#ifndef PARA_STATE_INTB
|
||||
#define PARA_STATE_INTB 0x80
|
||||
#define PARA_STATE_BUSY 0x10
|
||||
#endif
|
||||
|
||||
#ifndef SER_CMD_TIMEOUT
|
||||
#define SER_CMD_TIMEOUT 32
|
||||
#define SER_SYNC_CODE1 0x57
|
||||
#define SER_SYNC_CODE2 0xAB
|
||||
#endif
|
||||
|
||||
#ifndef CMD_RET_SUCCESS
|
||||
#define CMD_RET_SUCCESS 0x51
|
||||
#define CMD_RET_ABORT 0x5F
|
||||
#endif
|
||||
|
||||
/***********************************************************************************************************************/
|
||||
#ifndef USB_INT_EP0_SETUP
|
||||
|
||||
#define USB_INT_USB_SUSPEND 0x05
|
||||
#define USB_INT_WAKE_UP 0x06
|
||||
#define USB_INT_EP0_SETUP 0x0C
|
||||
#define USB_INT_EP0_OUT 0x00
|
||||
#define USB_INT_EP0_IN 0x08
|
||||
#define USB_INT_EP1_OUT 0x01
|
||||
#define USB_INT_EP1_IN 0x09
|
||||
#define USB_INT_EP2_OUT 0x02
|
||||
#define USB_INT_EP2_IN 0x0A
|
||||
#define USB_INT_BUS_RESET1 0x03
|
||||
#define USB_INT_BUS_RESET2 0x07
|
||||
#define USB_INT_BUS_RESET3 0x0B
|
||||
#define USB_INT_BUS_RESET4 0x0F
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef USB_INT_SUCCESS
|
||||
#define USB_INT_SUCCESS 0x14
|
||||
#define USB_INT_CONNECT 0x15
|
||||
#define USB_INT_DISCONNECT 0x16
|
||||
#define USB_INT_BUF_OVER 0x17
|
||||
#define USB_INT_USB_READY 0x18
|
||||
#define USB_INT_DISK_READ 0x1D
|
||||
#define USB_INT_DISK_WRITE 0x1E
|
||||
#define USB_INT_DISK_ERR 0x1F
|
||||
#endif
|
||||
|
||||
#ifndef ERR_DISK_DISCON
|
||||
#define ERR_DISK_DISCON 0x82
|
||||
#define ERR_LARGE_SECTOR 0x84
|
||||
#define ERR_TYPE_ERROR 0x92
|
||||
#define ERR_BPB_ERROR 0xA1
|
||||
#define ERR_DISK_FULL 0xB1
|
||||
#define ERR_FDT_OVER 0xB2
|
||||
#define ERR_FILE_CLOSE 0xB4
|
||||
#define ERR_OPEN_DIR 0x41
|
||||
#define ERR_MISS_FILE 0x42
|
||||
#define ERR_FOUND_NAME 0x43
|
||||
|
||||
|
||||
#define ERR_MISS_DIR 0xB3
|
||||
#define ERR_LONG_BUF_OVER 0x48
|
||||
#define ERR_LONG_NAME_ERR 0x49
|
||||
#define ERR_NAME_EXIST 0x4A
|
||||
#endif
|
||||
|
||||
/* ******************************************************************************************************************** */
|
||||
#ifndef DEF_DISK_UNKNOWN
|
||||
#define DEF_DISK_UNKNOWN 0x00
|
||||
#define DEF_DISK_DISCONN 0x01
|
||||
#define DEF_DISK_CONNECT 0x02
|
||||
#define DEF_DISK_MOUNTED 0x03
|
||||
#define DEF_DISK_READY 0x10
|
||||
#define DEF_DISK_OPEN_ROOT 0x12
|
||||
#define DEF_DISK_OPEN_DIR 0x13
|
||||
#define DEF_DISK_OPEN_FILE 0x14
|
||||
#endif
|
||||
|
||||
/* **********************************************************************************************************************/
|
||||
#ifndef DEF_SECTOR_SIZE
|
||||
#define DEF_SECTOR_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef DEF_WILDCARD_CHAR
|
||||
#define DEF_WILDCARD_CHAR 0x2A
|
||||
#define DEF_SEPAR_CHAR1 0x5C
|
||||
#define DEF_SEPAR_CHAR2 0x2F
|
||||
#define DEF_FILE_YEAR 2004
|
||||
#define DEF_FILE_MONTH 1
|
||||
#define DEF_FILE_DATE 1
|
||||
#endif
|
||||
|
||||
#ifndef ATTR_DIRECTORY
|
||||
|
||||
typedef struct _FAT_DIR_INFO {
|
||||
UINT8 DIR_Name[11];
|
||||
UINT8 DIR_Attr;
|
||||
UINT8 DIR_NTRes;
|
||||
UINT8 DIR_CrtTimeTenth;
|
||||
UINT16 DIR_CrtTime;
|
||||
UINT16 DIR_CrtDate;
|
||||
UINT16 DIR_LstAccDate;
|
||||
UINT16 DIR_FstClusHI;
|
||||
UINT16 DIR_WrtTime;
|
||||
UINT16 DIR_WrtDate;
|
||||
UINT16 DIR_FstClusLO;
|
||||
UINT32 DIR_FileSize;
|
||||
} FAT_DIR_INFO, *P_FAT_DIR_INFO;
|
||||
|
||||
#define ATTR_READ_ONLY 0x01
|
||||
#define ATTR_HIDDEN 0x02
|
||||
#define ATTR_SYSTEM 0x04
|
||||
#define ATTR_VOLUME_ID 0x08
|
||||
#define ATTR_DIRECTORY 0x10
|
||||
#define ATTR_ARCHIVE 0x20
|
||||
#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
|
||||
#define ATTR_LONG_NAME_MASK (ATTR_LONG_NAME | ATTR_DIRECTORY | ATTR_ARCHIVE)
|
||||
|
||||
#define MAKE_FILE_TIME( h, m, s ) ( (h<<11) + (m<<5) + (s>>1) )
|
||||
#define MAKE_FILE_DATE( y, m, d ) ( ((y-1980)<<9) + (m<<5) + d )
|
||||
|
||||
#define LONE_NAME_MAX_CHAR (255*2)
|
||||
#define LONG_NAME_PER_DIR (13*2)
|
||||
|
||||
#endif
|
||||
|
||||
/* ********************************************************************************************************************* */
|
||||
#ifndef SPC_CMD_INQUIRY
|
||||
|
||||
#define SPC_CMD_INQUIRY 0x12
|
||||
#define SPC_CMD_READ_CAPACITY 0x25
|
||||
#define SPC_CMD_READ10 0x28
|
||||
#define SPC_CMD_WRITE10 0x2A
|
||||
#define SPC_CMD_TEST_READY 0x00
|
||||
#define SPC_CMD_REQUEST_SENSE 0x03
|
||||
#define SPC_CMD_MODESENSE6 0x1A
|
||||
#define SPC_CMD_MODESENSE10 0x5A
|
||||
#define SPC_CMD_START_STOP 0x1B
|
||||
|
||||
typedef struct _BULK_ONLY_CBW {
|
||||
UINT32 CBW_Sig;
|
||||
UINT32 CBW_Tag;
|
||||
UINT8 CBW_DataLen0;
|
||||
UINT8 CBW_DataLen1;
|
||||
UINT16 CBW_DataLen2;
|
||||
UINT8 CBW_Flag;
|
||||
UINT8 CBW_LUN;
|
||||
UINT8 CBW_CB_Len;
|
||||
UINT8 CBW_CB_Buf[16];
|
||||
} BULK_ONLY_CBW, *P_BULK_ONLY_CBW;
|
||||
|
||||
typedef struct _INQUIRY_DATA {
|
||||
UINT8 DeviceType;
|
||||
UINT8 RemovableMedia;
|
||||
UINT8 Versions;
|
||||
UINT8 DataFormatAndEtc;
|
||||
UINT8 AdditionalLength;
|
||||
UINT8 Reserved1;
|
||||
UINT8 Reserved2;
|
||||
UINT8 MiscFlag;
|
||||
UINT8 VendorIdStr[8];
|
||||
UINT8 ProductIdStr[16];
|
||||
UINT8 ProductRevStr[4];
|
||||
} INQUIRY_DATA, *P_INQUIRY_DATA;
|
||||
|
||||
|
||||
typedef struct _SENSE_DATA {
|
||||
UINT8 ErrorCode;
|
||||
UINT8 SegmentNumber;
|
||||
UINT8 SenseKeyAndEtc;
|
||||
UINT8 Information0;
|
||||
UINT8 Information1;
|
||||
UINT8 Information2;
|
||||
UINT8 Information3;
|
||||
UINT8 AdditSenseLen;
|
||||
UINT8 CmdSpecInfo[4];
|
||||
UINT8 AdditSenseCode;
|
||||
UINT8 AddSenCodeQual;
|
||||
UINT8 FieldReplaUnit;
|
||||
UINT8 SenseKeySpec[3];
|
||||
} SENSE_DATA, *P_SENSE_DATA;
|
||||
|
||||
#endif
|
||||
|
||||
/* ********************************************************************************************************************* */
|
||||
#ifndef MAX_FILE_NAME_LEN
|
||||
|
||||
#define MAX_FILE_NAME_LEN (13+1)
|
||||
|
||||
typedef union _CH376_CMD_DATA {
|
||||
struct {
|
||||
UINT8 mBuffer[ MAX_FILE_NAME_LEN ];
|
||||
} Default;
|
||||
|
||||
INQUIRY_DATA DiskMountInq;
|
||||
FAT_DIR_INFO OpenDirInfo;
|
||||
FAT_DIR_INFO EnumDirInfo;
|
||||
struct {
|
||||
UINT8 mUpdateFileSz;
|
||||
} FileCLose;
|
||||
|
||||
struct {
|
||||
UINT8 mDirInfoIndex;
|
||||
} DirInfoRead;
|
||||
|
||||
union {
|
||||
UINT32 mByteOffset;
|
||||
UINT32 mSectorLba;
|
||||
} ByteLocate;
|
||||
|
||||
struct {
|
||||
UINT16 mByteCount;
|
||||
} ByteRead;
|
||||
|
||||
struct {
|
||||
UINT16 mByteCount;
|
||||
} ByteWrite;
|
||||
|
||||
union {
|
||||
UINT32 mSectorOffset;
|
||||
UINT32 mSectorLba;
|
||||
} SectorLocate;
|
||||
|
||||
struct {
|
||||
UINT8 mSectorCount;
|
||||
UINT8 mReserved1;
|
||||
UINT8 mReserved2;
|
||||
UINT8 mReserved3;
|
||||
UINT32 mStartSector;
|
||||
} SectorRead;
|
||||
|
||||
struct {
|
||||
UINT8 mSectorCount;
|
||||
UINT8 mReserved1;
|
||||
UINT8 mReserved2;
|
||||
UINT8 mReserved3;
|
||||
UINT32 mStartSector;
|
||||
} SectorWrite;
|
||||
|
||||
struct {
|
||||
UINT32 mDiskSizeSec;
|
||||
} DiskCapacity;
|
||||
|
||||
struct {
|
||||
UINT32 mTotalSector;
|
||||
UINT32 mFreeSector;
|
||||
UINT8 mDiskFat;
|
||||
} DiskQuery;
|
||||
|
||||
BULK_ONLY_CBW DiskBocCbw;
|
||||
|
||||
struct {
|
||||
UINT8 mMaxLogicUnit;
|
||||
} DiskMaxLun;
|
||||
|
||||
INQUIRY_DATA DiskInitInq;
|
||||
INQUIRY_DATA DiskInqData;
|
||||
SENSE_DATA ReqSenseData;
|
||||
struct {
|
||||
UINT32 mDiskSizeSec;
|
||||
} DiskSize;
|
||||
|
||||
struct {
|
||||
UINT32 mStartSector;
|
||||
UINT8 mSectorCount;
|
||||
} DiskRead;
|
||||
|
||||
struct {
|
||||
UINT32 mStartSector;
|
||||
UINT8 mSectorCount;
|
||||
} DiskWrite;
|
||||
} CH376_CMD_DATA, *P_CH376_CMD_DATA;
|
||||
|
||||
#endif
|
||||
|
||||
/* ********************************************************************************************************************* */
|
||||
|
||||
#ifndef VAR_FILE_SIZE
|
||||
|
||||
#define VAR_SYS_BASE_INFO 0x20
|
||||
#define VAR_RETRY_TIMES 0x25
|
||||
#define VAR_FILE_BIT_FLAG 0x26
|
||||
#define VAR_DISK_STATUS 0x2B
|
||||
#define VAR_SD_BIT_FLAG 0x30
|
||||
#define VAR_UDISK_TOGGLE 0x31
|
||||
#define VAR_UDISK_LUN 0x34
|
||||
#define VAR_SEC_PER_CLUS 0x38
|
||||
#define VAR_FILE_DIR_INDEX 0x3B
|
||||
#define VAR_CLUS_SEC_OFS 0x3C
|
||||
|
||||
#define VAR_DISK_ROOT 0x44
|
||||
#define VAR_DSK_TOTAL_CLUS 0x48
|
||||
#define VAR_DSK_START_LBA 0x4C
|
||||
#define VAR_DSK_DAT_START 0x50
|
||||
#define VAR_LBA_BUFFER 0x54
|
||||
#define VAR_LBA_CURRENT 0x58
|
||||
#define VAR_FAT_DIR_LBA 0x5C
|
||||
#define VAR_START_CLUSTER 0x60
|
||||
#define VAR_CURRENT_CLUST 0x64
|
||||
#define VAR_FILE_SIZE 0x68
|
||||
#define VAR_CURRENT_OFFSET 0x6C
|
||||
|
||||
#endif
|
||||
|
||||
/* ********************************************************************************************************************* */
|
||||
#ifndef DEF_USB_PID_SETUP
|
||||
#define DEF_USB_PID_NULL 0x00
|
||||
#define DEF_USB_PID_SOF 0x05
|
||||
#define DEF_USB_PID_SETUP 0x0D
|
||||
#define DEF_USB_PID_IN 0x09
|
||||
#define DEF_USB_PID_OUT 0x01
|
||||
#define DEF_USB_PID_ACK 0x02
|
||||
#define DEF_USB_PID_NAK 0x0A
|
||||
#define DEF_USB_PID_STALL 0x0E
|
||||
#define DEF_USB_PID_DATA0 0x03
|
||||
#define DEF_USB_PID_DATA1 0x0B
|
||||
#define DEF_USB_PID_PRE 0x0C
|
||||
#endif
|
||||
|
||||
#ifndef DEF_USB_REQ_TYPE
|
||||
#define DEF_USB_REQ_READ 0x80
|
||||
#define DEF_USB_REQ_WRITE 0x00
|
||||
#define DEF_USB_REQ_TYPE 0x60
|
||||
#define DEF_USB_REQ_STAND 0x00
|
||||
#define DEF_USB_REQ_CLASS 0x20
|
||||
#define DEF_USB_REQ_VENDOR 0x40
|
||||
#define DEF_USB_REQ_RESERVE 0x60
|
||||
#endif
|
||||
|
||||
#ifndef DEF_USB_GET_DESCR
|
||||
#define DEF_USB_CLR_FEATURE 0x01
|
||||
#define DEF_USB_SET_FEATURE 0x03
|
||||
#define DEF_USB_GET_STATUS 0x00
|
||||
#define DEF_USB_SET_ADDRESS 0x05
|
||||
#define DEF_USB_GET_DESCR 0x06
|
||||
#define DEF_USB_SET_DESCR 0x07
|
||||
#define DEF_USB_GET_CONFIG 0x08
|
||||
#define DEF_USB_SET_CONFIG 0x09
|
||||
#define DEF_USB_GET_INTERF 0x0A
|
||||
#define DEF_USB_SET_INTERF 0x0B
|
||||
#define DEF_USB_SYNC_FRAME 0x0C
|
||||
#endif
|
||||
|
||||
/* ********************************************************************************************************************* */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file edu-riscv64.h
|
||||
* @brief edu-riscv64 edu-riscv64.h
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.17
|
||||
*/
|
||||
|
||||
#ifndef __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H
|
||||
#define __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
int k210_bringup(void);
|
||||
|
||||
#ifdef CONFIG_DEV_GPIO
|
||||
int k210_gpio_init(void);
|
||||
#endif
|
||||
|
||||
#endif /* __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H */
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_appinit.c
|
||||
* @brief edu-riscv64 k210_appinit.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.17
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#include "k210.h"
|
||||
#include "edu-riscv64.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_app_initialize
|
||||
*
|
||||
* Description:
|
||||
* Perform architecture specific initialization
|
||||
*
|
||||
* Input Parameters:
|
||||
* arg - The boardctl() argument is passed to the board_app_initialize()
|
||||
* implementation without modification. The argument has no
|
||||
* meaning to NuttX; the meaning of the argument is a contract
|
||||
* between the board-specific initialization logic and the
|
||||
* matching application logic. The value could be such things as a
|
||||
* mode enumeration value, a set of DIP switch switch settings, a
|
||||
* pointer to configuration data read from a file or serial FLASH,
|
||||
* or whatever you would like to do with it. Every implementation
|
||||
* should accept zero/NULL as a default configuration.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure to indicate the nature of the failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int board_app_initialize(uintptr_t arg)
|
||||
{
|
||||
#ifdef CONFIG_BOARD_LATE_INITIALIZE
|
||||
/* Board initialization already performed by board_late_initialize() */
|
||||
|
||||
return OK;
|
||||
#else
|
||||
/* Perform board-specific initialization */
|
||||
|
||||
return k210_bringup();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_boot.c
|
||||
* @brief edu-riscv64 k210_boot.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.17
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k210_boardinitialize
|
||||
*
|
||||
* Description:
|
||||
* All K210 architectures must provide the following entry point.
|
||||
* This entry point is called early in the initialization -- after all
|
||||
* memory has been configured and mapped but before any devices have been
|
||||
* initialized.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void k210_boardinitialize(void)
|
||||
{
|
||||
board_autoled_initialize();
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_bringup.c
|
||||
* @brief edu-riscv64 k210_bringup.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.03.17
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include "k210.h"
|
||||
#include "k210_clockconfig.h"
|
||||
#include "edu-riscv64.h"
|
||||
#include <arch/board/board.h>
|
||||
#include "k210_sysctl.h"
|
||||
#include "k210_fpioa.h"
|
||||
#include "k210_gpiohs.h"
|
||||
#include "k210_gpio_common.h"
|
||||
|
||||
#ifdef CONFIG_BSP_USING_CH438
|
||||
# include "k210_ch438.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BSP_USING_TOUCH
|
||||
# include "k210_touch.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k210_bringup
|
||||
****************************************************************************/
|
||||
|
||||
int k210_bringup(void)
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
#ifdef CONFIG_FS_PROCFS
|
||||
/* Mount the procfs file system */
|
||||
|
||||
ret = nx_mount(NULL, "/proc", "procfs", 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to mount procfs at %s: %d\n", "/proc", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEV_GPIO
|
||||
ret = k210_gpio_init();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_K210_LCD
|
||||
k210_sysctl_init();
|
||||
board_lcd_initialize();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BSP_USING_TOUCH
|
||||
board_touch_initialize();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_K210_UART1
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_UART1);
|
||||
sysctl_reset(SYSCTL_RESET_UART1);
|
||||
|
||||
fpioa_set_function(GPIO_WIFI_TXD, FPOA_USART1_RX);
|
||||
fpioa_set_function(GPIO_WIFI_RXD, FPOA_USART1_TX);
|
||||
|
||||
fpioa_set_function(GPIO_WIFI_EN, K210_IO_FUNC_GPIOHS0 + FPIOA_WIFI_EN);
|
||||
k210_gpiohs_set_direction(FPIOA_WIFI_EN, GPIO_DM_OUTPUT);
|
||||
k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_LOW);
|
||||
up_mdelay(50);
|
||||
k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_K210_UART2
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_UART2);
|
||||
sysctl_reset(SYSCTL_RESET_UART2);
|
||||
|
||||
fpioa_set_function(GPIO_E220_RXD, FPOA_USART2_RX);
|
||||
fpioa_set_function(GPIO_E220_TXD, FPOA_USART2_TX);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_K210_UART3
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_UART3);
|
||||
sysctl_reset(SYSCTL_RESET_UART3);
|
||||
|
||||
fpioa_set_function(GPIO_CH376T_RXD, FPOA_USART3_RX);
|
||||
fpioa_set_function(GPIO_CH376T_TXD, FPOA_USART3_TX);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,960 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_ch376.c
|
||||
* @brief edu-riscv64 k210_ch376.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.10.10
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
#define DEF_IC_V43_U 1
|
||||
#endif
|
||||
|
||||
#include "k210_ch376.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
static int fd;
|
||||
|
||||
/* Serial port mode is not used */
|
||||
void xEndCH376Cmd(void)
|
||||
{
|
||||
}
|
||||
|
||||
void xWriteCH376Cmd(UINT8 cmd)
|
||||
{
|
||||
UINT8 temp[3];
|
||||
temp[0] = 0x57;
|
||||
temp[1] = 0xab;
|
||||
temp[2] = cmd;
|
||||
up_udelay(5);
|
||||
write(fd, temp, 3);
|
||||
}
|
||||
|
||||
void xWriteCH376Data(UINT8 dat)
|
||||
{
|
||||
UINT8 tmp = dat;
|
||||
write(fd, &tmp, 1);
|
||||
up_udelay(2);
|
||||
}
|
||||
|
||||
UINT8 xReadCH376Data(void)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT8 data;
|
||||
int res;
|
||||
for(i=0;i<500000;i++)
|
||||
{
|
||||
res = read(fd, &data, 1);
|
||||
if(res == 1)
|
||||
{
|
||||
return ((UINT8)data);
|
||||
}
|
||||
up_udelay(1);
|
||||
}
|
||||
return ERR_USB_UNKNOWN;
|
||||
}
|
||||
|
||||
UINT8 CH376ReadBlock(PUINT8 buf)
|
||||
{
|
||||
UINT8 s, l;
|
||||
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
|
||||
s = l = xReadCH376Data( );
|
||||
if ( l ) {
|
||||
do {
|
||||
*buf = xReadCH376Data( );
|
||||
buf ++;
|
||||
} while ( -- l );
|
||||
}
|
||||
xEndCH376Cmd( );
|
||||
return( s );
|
||||
}
|
||||
|
||||
UINT8 Query376Interrupt(void)
|
||||
{
|
||||
//When an interrupt occurs, the serial port will receive a data, read it directly, and discard it
|
||||
if(xReadCH376Data() == ERR_USB_UNKNOWN) return FALSE ;
|
||||
else return TRUE ;
|
||||
}
|
||||
|
||||
/* CH376 INIT */
|
||||
UINT8 mInitCH376Host(void)
|
||||
{
|
||||
UINT8 res;
|
||||
/* After power on, delay operation for at least 50ms */
|
||||
up_mdelay(50);
|
||||
fd = open("/dev/ttyS3", O_RDWR);
|
||||
up_mdelay(600);
|
||||
/* Test the communication interface between SCM and CH376 */
|
||||
xWriteCH376Cmd(CMD11_CHECK_EXIST);
|
||||
xWriteCH376Data(0x65);
|
||||
res = xReadCH376Data();
|
||||
xEndCH376Cmd();
|
||||
if ( res != 0x9A ) return( ERR_USB_UNKNOWN );
|
||||
|
||||
xWriteCH376Cmd(CMD11_SET_USB_MODE); /* SET USB MODE */
|
||||
xWriteCH376Data(CONFIG_CH376_WORK_MODE);
|
||||
up_udelay(20);
|
||||
res = xReadCH376Data();
|
||||
xEndCH376Cmd();
|
||||
if (res == CMD_RET_SUCCESS) return(USB_INT_SUCCESS);
|
||||
else return(ERR_USB_UNKNOWN); /* SET MODE ERROR */
|
||||
|
||||
}
|
||||
|
||||
/* Write the requested data block to the internally specified buffer, and return the length */
|
||||
UINT8 CH376WriteReqBlock(PUINT8 buf)
|
||||
{
|
||||
UINT8 s, l;
|
||||
xWriteCH376Cmd( CMD01_WR_REQ_DATA );
|
||||
s = l = xReadCH376Data();
|
||||
if ( l ) {
|
||||
do {
|
||||
xWriteCH376Data( *buf );
|
||||
buf ++;
|
||||
} while ( -- l );
|
||||
}
|
||||
xEndCH376Cmd( );
|
||||
return( s );
|
||||
}
|
||||
|
||||
/* Write data block to the send buffer of USB host endpoint */
|
||||
void CH376WriteHostBlock(PUINT8 buf, UINT8 len)
|
||||
{
|
||||
xWriteCH376Cmd( CMD10_WR_HOST_DATA );
|
||||
xWriteCH376Data( len );
|
||||
if ( len ) {
|
||||
do {
|
||||
xWriteCH376Data( *buf );
|
||||
buf ++;
|
||||
} while ( -- len );
|
||||
}
|
||||
xEndCH376Cmd( );
|
||||
}
|
||||
|
||||
/* Specify offset address to write data block to internal buffer */
|
||||
void CH376WriteOfsBlock( PUINT8 buf, UINT8 ofs, UINT8 len )
|
||||
{
|
||||
xWriteCH376Cmd( CMD20_WR_OFS_DATA );
|
||||
xWriteCH376Data( ofs ); /* Offset address */
|
||||
xWriteCH376Data( len ); /* length */
|
||||
if ( len ) {
|
||||
do {
|
||||
xWriteCH376Data( *buf );
|
||||
buf ++;
|
||||
} while ( -- len );
|
||||
}
|
||||
xEndCH376Cmd( );
|
||||
}
|
||||
|
||||
/* Set the file name of the file to be operated on */
|
||||
void CH376SetFileName( PUINT8 name )
|
||||
{
|
||||
UINT8 c;
|
||||
#ifndef DEF_IC_V43_U
|
||||
UINT8 s;
|
||||
xWriteCH376Cmd( CMD01_GET_IC_VER );
|
||||
if ( xReadCH376Data( ) < 0x43 ) {
|
||||
if ( CH376ReadVar8( VAR_DISK_STATUS ) < DEF_DISK_READY ) {
|
||||
xWriteCH376Cmd( CMD10_SET_FILE_NAME );
|
||||
xWriteCH376Data( 0 );
|
||||
s = CH376SendCmdWaitInt( CMD0H_FILE_OPEN );
|
||||
if ( s == USB_INT_SUCCESS ) {
|
||||
s = CH376ReadVar8( 0xCF );
|
||||
if ( s ) {
|
||||
CH376WriteVar32( 0x4C, CH376ReadVar32( 0x4C ) + ( (UINT16)s << 8 ) );
|
||||
CH376WriteVar32( 0x50, CH376ReadVar32( 0x50 ) + ( (UINT16)s << 8 ) );
|
||||
CH376WriteVar32( 0x70, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
xWriteCH376Cmd( CMD10_SET_FILE_NAME );
|
||||
c = *name;
|
||||
xWriteCH376Data( c );
|
||||
while ( c ) {
|
||||
name ++;
|
||||
c = *name;
|
||||
/* Force the file name to expire */
|
||||
if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) c = 0;
|
||||
xWriteCH376Data( c );
|
||||
}
|
||||
xEndCH376Cmd( );
|
||||
}
|
||||
|
||||
/* Read 32-bit data from CH376 chip and end the command */
|
||||
UINT32 CH376Read32bitDat( void )
|
||||
{
|
||||
UINT8 c0, c1, c2, c3;
|
||||
c0 = xReadCH376Data( );
|
||||
c1 = xReadCH376Data( );
|
||||
c2 = xReadCH376Data( );
|
||||
c3 = xReadCH376Data( );
|
||||
xEndCH376Cmd( );
|
||||
return( c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24 );
|
||||
}
|
||||
|
||||
|
||||
UINT8 CH376ReadVar8( UINT8 var )
|
||||
{
|
||||
UINT8 c0;
|
||||
xWriteCH376Cmd( CMD11_READ_VAR8 );
|
||||
xWriteCH376Data( var );
|
||||
c0 = xReadCH376Data( );
|
||||
xEndCH376Cmd( );
|
||||
return( c0 );
|
||||
}
|
||||
|
||||
void CH376WriteVar8( UINT8 var, UINT8 dat )
|
||||
{
|
||||
xWriteCH376Cmd( CMD20_WRITE_VAR8 );
|
||||
xWriteCH376Data( var );
|
||||
xWriteCH376Data( dat );
|
||||
xEndCH376Cmd( );
|
||||
}
|
||||
|
||||
UINT32 CH376ReadVar32( UINT8 var )
|
||||
{
|
||||
xWriteCH376Cmd( CMD14_READ_VAR32 );
|
||||
xWriteCH376Data( var );
|
||||
return( CH376Read32bitDat( ) );
|
||||
}
|
||||
|
||||
void CH376WriteVar32( UINT8 var, UINT32 dat )
|
||||
{
|
||||
xWriteCH376Cmd( CMD50_WRITE_VAR32 );
|
||||
xWriteCH376Data( var );
|
||||
xWriteCH376Data( (UINT8)dat );
|
||||
xWriteCH376Data( (UINT8)( (UINT16)dat >> 8 ) );
|
||||
xWriteCH376Data( (UINT8)( dat >> 16 ) );
|
||||
xWriteCH376Data( (UINT8)( dat >> 24 ) );
|
||||
xEndCH376Cmd( );
|
||||
}
|
||||
|
||||
void CH376EndDirInfo( void )
|
||||
{
|
||||
CH376WriteVar8( 0x0D, 0x00 );
|
||||
}
|
||||
|
||||
UINT32 CH376GetFileSize( void )
|
||||
{
|
||||
return( CH376ReadVar32( VAR_FILE_SIZE ) );
|
||||
}
|
||||
|
||||
UINT8 CH376GetDiskStatus( void )
|
||||
{
|
||||
return( CH376ReadVar8( VAR_DISK_STATUS ) );
|
||||
}
|
||||
|
||||
UINT8 CH376GetIntStatus( void )
|
||||
{
|
||||
UINT8 s;
|
||||
xWriteCH376Cmd( CMD01_GET_STATUS );
|
||||
s = xReadCH376Data( );
|
||||
xEndCH376Cmd( );
|
||||
return( s );
|
||||
}
|
||||
|
||||
#ifndef NO_DEFAULT_CH376_INT
|
||||
UINT8 Wait376Interrupt( void )
|
||||
{
|
||||
#ifdef DEF_INT_TIMEOUT
|
||||
#if DEF_INT_TIMEOUT < 1
|
||||
while ( Query376Interrupt( ) == FALSE );
|
||||
return( CH376GetIntStatus( ) );
|
||||
#else
|
||||
UINT32 i;
|
||||
for ( i = 0; i < DEF_INT_TIMEOUT; i ++ ) {
|
||||
if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) );
|
||||
}
|
||||
return( ERR_USB_UNKNOWN );
|
||||
#endif
|
||||
#else
|
||||
UINT32 i;
|
||||
for ( i = 0; i < 5000000; i ++ ) {
|
||||
if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) );
|
||||
}
|
||||
return( ERR_USB_UNKNOWN );
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT8 CH376SendCmdWaitInt( UINT8 mCmd )
|
||||
{
|
||||
xWriteCH376Cmd( mCmd );
|
||||
xEndCH376Cmd( );
|
||||
return( Wait376Interrupt( ) );
|
||||
}
|
||||
|
||||
UINT8 CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat )
|
||||
{
|
||||
xWriteCH376Cmd( mCmd );
|
||||
xWriteCH376Data( mDat );
|
||||
xEndCH376Cmd( );
|
||||
return(Wait376Interrupt());
|
||||
}
|
||||
|
||||
UINT8 CH376DiskReqSense( void )
|
||||
{
|
||||
UINT8 s;
|
||||
up_mdelay( 5 );
|
||||
s = CH376SendCmdWaitInt( CMD0H_DISK_R_SENSE );
|
||||
up_mdelay( 5 );
|
||||
return( s );
|
||||
}
|
||||
|
||||
UINT8 CH376DiskConnect( void )
|
||||
{
|
||||
if ( Query376Interrupt( ) ) CH376GetIntStatus( );
|
||||
return( CH376SendCmdWaitInt( CMD0H_DISK_CONNECT ) );
|
||||
}
|
||||
|
||||
UINT8 CH376DiskMount( void )
|
||||
{
|
||||
return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) );
|
||||
}
|
||||
|
||||
UINT8 CH376FileOpen( PUINT8 name )
|
||||
{
|
||||
CH376SetFileName( name );
|
||||
#ifndef DEF_IC_V43_U
|
||||
if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) CH376WriteVar32( VAR_CURRENT_CLUST, 0 );
|
||||
#endif
|
||||
return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) );
|
||||
}
|
||||
|
||||
UINT8 CH376FileCreate( PUINT8 name )
|
||||
{
|
||||
if ( name ) CH376SetFileName( name );
|
||||
return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) );
|
||||
}
|
||||
|
||||
UINT8 CH376DirCreate( PUINT8 name )
|
||||
{
|
||||
CH376SetFileName( name );
|
||||
#ifndef DEF_IC_V43_U
|
||||
if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) CH376WriteVar32( VAR_CURRENT_CLUST, 0 );
|
||||
#endif
|
||||
return( CH376SendCmdWaitInt( CMD0H_DIR_CREATE ) );
|
||||
}
|
||||
|
||||
UINT8 CH376SeparatePath( PUINT8 path )
|
||||
{
|
||||
PUINT8 pName;
|
||||
for ( pName = path; *pName != 0; ++ pName );
|
||||
while ( *pName != DEF_SEPAR_CHAR1 && *pName != DEF_SEPAR_CHAR2 && pName != path ) pName --;
|
||||
if ( pName != path ) pName ++;
|
||||
return( pName - path );
|
||||
}
|
||||
|
||||
UINT8 CH376FileOpenDir( PUINT8 PathName, UINT8 StopName )
|
||||
{
|
||||
UINT8 i, s;
|
||||
s = 0;
|
||||
i = 1;
|
||||
while ( 1 ) {
|
||||
while ( PathName[i] != DEF_SEPAR_CHAR1 && PathName[i] != DEF_SEPAR_CHAR2 && PathName[i] != 0 ) ++ i;
|
||||
if ( PathName[i] ) i ++;
|
||||
else i = 0;
|
||||
s = CH376FileOpen( &PathName[s] );
|
||||
if ( i && i != StopName ) {
|
||||
if ( s != ERR_OPEN_DIR ) {
|
||||
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME );
|
||||
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR );
|
||||
else return( s );
|
||||
}
|
||||
s = i;
|
||||
}
|
||||
else return( s );
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 CH376FileOpenPath( PUINT8 PathName )
|
||||
{
|
||||
return( CH376FileOpenDir( PathName, 0xFF ) );
|
||||
}
|
||||
|
||||
UINT8 CH376FileCreatePath( PUINT8 PathName )
|
||||
{
|
||||
UINT8 s;
|
||||
UINT8 Name;
|
||||
Name = CH376SeparatePath( PathName );
|
||||
if ( Name ) {
|
||||
s = CH376FileOpenDir( PathName, Name );
|
||||
if ( s != ERR_OPEN_DIR ) {
|
||||
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME );
|
||||
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR );
|
||||
else return( s );
|
||||
}
|
||||
}
|
||||
return( CH376FileCreate( &PathName[Name] ) );
|
||||
}
|
||||
|
||||
#ifdef EN_DIR_CREATE
|
||||
UINT8 CH376DirCreatePath( PUINT8 PathName )
|
||||
{
|
||||
UINT8 s;
|
||||
UINT8 Name;
|
||||
UINT8 ClustBuf[4];
|
||||
Name = CH376SeparatePath( PathName );
|
||||
if ( Name ) {
|
||||
s = CH376FileOpenDir( PathName, Name );
|
||||
if ( s != ERR_OPEN_DIR ) {
|
||||
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME );
|
||||
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR );
|
||||
else return( s );
|
||||
}
|
||||
xWriteCH376Cmd( CMD14_READ_VAR32 );
|
||||
xWriteCH376Data( VAR_START_CLUSTER );
|
||||
for ( s = 0; s != 4; s ++ ) ClustBuf[ s ] = xReadCH376Data( );
|
||||
xEndCH376Cmd( );
|
||||
s = CH376DirCreate( &PathName[Name] );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
CH376WriteVar32( VAR_FILE_SIZE, sizeof(FAT_DIR_INFO) * 2 );
|
||||
s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusHI ) );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
s = CH376ByteWrite( &ClustBuf[2], 2, NULL );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusLO ) );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
s = CH376ByteWrite( ClustBuf, 2, NULL );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
s = CH376ByteLocate( 0 );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
CH376WriteVar32( VAR_FILE_SIZE, 0 );
|
||||
return( s );
|
||||
}
|
||||
else {
|
||||
if ( PathName[0] == DEF_SEPAR_CHAR1 || PathName[0] == DEF_SEPAR_CHAR2 ) return( CH376DirCreate( PathName ) );
|
||||
else return( ERR_MISS_DIR );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT8 CH376FileErase( PUINT8 PathName )
|
||||
{
|
||||
UINT8 s;
|
||||
if ( PathName ) {
|
||||
for ( s = 1; PathName[s] != DEF_SEPAR_CHAR1 && PathName[s] != DEF_SEPAR_CHAR2 && PathName[s] != 0; ++ s );
|
||||
if ( PathName[s] ) {
|
||||
s = CH376FileOpenPath( PathName );
|
||||
if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s );
|
||||
}
|
||||
else CH376SetFileName( PathName );
|
||||
}
|
||||
return( CH376SendCmdWaitInt( CMD0H_FILE_ERASE ) );
|
||||
}
|
||||
|
||||
UINT8 CH376FileClose( UINT8 UpdateSz )
|
||||
{
|
||||
return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) );
|
||||
}
|
||||
|
||||
UINT8 CH376DirInfoRead( void )
|
||||
{
|
||||
return( CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, 0xFF ) );
|
||||
}
|
||||
|
||||
UINT8 CH376DirInfoSave( void )
|
||||
{
|
||||
return( CH376SendCmdWaitInt( CMD0H_DIR_INFO_SAVE ) );
|
||||
}
|
||||
|
||||
UINT8 CH376ByteLocate( UINT32 offset )
|
||||
{
|
||||
xWriteCH376Cmd( CMD4H_BYTE_LOCATE );
|
||||
xWriteCH376Data( (UINT8)offset );
|
||||
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
|
||||
xWriteCH376Data( (UINT8)(offset>>16) );
|
||||
xWriteCH376Data( (UINT8)(offset>>24) );
|
||||
xEndCH376Cmd( );
|
||||
return( Wait376Interrupt( ) );
|
||||
}
|
||||
|
||||
UINT8 CH376ByteRead( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount )
|
||||
{
|
||||
UINT8 s;
|
||||
xWriteCH376Cmd( CMD2H_BYTE_READ );
|
||||
xWriteCH376Data( (UINT8)ReqCount );
|
||||
xWriteCH376Data( (UINT8)(ReqCount>>8) );
|
||||
xEndCH376Cmd( );
|
||||
if ( RealCount ) *RealCount = 0;
|
||||
while ( 1 ) {
|
||||
s = Wait376Interrupt( );
|
||||
if ( s == USB_INT_DISK_READ ) {
|
||||
s = CH376ReadBlock( buf );
|
||||
xWriteCH376Cmd( CMD0H_BYTE_RD_GO );
|
||||
xEndCH376Cmd( );
|
||||
buf += s;
|
||||
if ( RealCount ) *RealCount += s;
|
||||
}
|
||||
else return( s );
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount )
|
||||
{
|
||||
UINT8 s;
|
||||
xWriteCH376Cmd( CMD2H_BYTE_WRITE );
|
||||
xWriteCH376Data( (UINT8)ReqCount );
|
||||
xWriteCH376Data( (UINT8)(ReqCount>>8) );
|
||||
xEndCH376Cmd( );
|
||||
if ( RealCount ) *RealCount = 0;
|
||||
while ( 1 ) {
|
||||
s = Wait376Interrupt( );
|
||||
if ( s == USB_INT_DISK_WRITE ) {
|
||||
s = CH376WriteReqBlock( buf );
|
||||
xWriteCH376Cmd( CMD0H_BYTE_WR_GO );
|
||||
xEndCH376Cmd( );
|
||||
buf += s;
|
||||
if ( RealCount ) *RealCount += s;
|
||||
}
|
||||
else return( s );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EN_DISK_QUERY
|
||||
|
||||
UINT8 CH376DiskCapacity( PUINT32 DiskCap )
|
||||
{
|
||||
UINT8 s;
|
||||
s = CH376SendCmdWaitInt( CMD0H_DISK_CAPACITY );
|
||||
if ( s == USB_INT_SUCCESS ) {
|
||||
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
|
||||
xReadCH376Data( );
|
||||
*DiskCap = CH376Read32bitDat( );
|
||||
}
|
||||
else *DiskCap = 0;
|
||||
return( s );
|
||||
}
|
||||
|
||||
UINT8 CH376DiskQuery( PUINT32 DiskFre )
|
||||
{
|
||||
UINT8 s;
|
||||
UINT8 c0, c1, c2, c3;
|
||||
#ifndef DEF_IC_V43_U
|
||||
xWriteCH376Cmd( CMD01_GET_IC_VER );
|
||||
if ( xReadCH376Data( ) < 0x43 ) {
|
||||
if ( CH376ReadVar8( VAR_DISK_STATUS ) >= DEF_DISK_READY ) CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_MOUNTED );
|
||||
}
|
||||
#endif
|
||||
s = CH376SendCmdWaitInt( CMD0H_DISK_QUERY );
|
||||
if ( s == USB_INT_SUCCESS ) {
|
||||
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
c0 = xReadCH376Data( );
|
||||
c1 = xReadCH376Data( );
|
||||
c2 = xReadCH376Data( );
|
||||
c3 = xReadCH376Data( );
|
||||
*DiskFre = c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24;
|
||||
xReadCH376Data( );
|
||||
xEndCH376Cmd( );
|
||||
}
|
||||
else *DiskFre = 0;
|
||||
return( s );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
UINT8 CH376SecLocate( UINT32 offset )
|
||||
{
|
||||
xWriteCH376Cmd( CMD4H_SEC_LOCATE );
|
||||
xWriteCH376Data( (UINT8)offset );
|
||||
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
|
||||
xWriteCH376Data( (UINT8)(offset>>16) );
|
||||
xWriteCH376Data( 0 );
|
||||
xEndCH376Cmd( );
|
||||
return( Wait376Interrupt( ) );
|
||||
}
|
||||
|
||||
#ifdef EN_SECTOR_ACCESS
|
||||
|
||||
UINT8 CH376DiskReadSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount )
|
||||
|
||||
{
|
||||
UINT8 s, err;
|
||||
UINT16 mBlockCount;
|
||||
for ( err = 0; err != 3; ++ err ) {
|
||||
xWriteCH376Cmd( CMD5H_DISK_READ );
|
||||
xWriteCH376Data( (UINT8)iLbaStart );
|
||||
xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) );
|
||||
xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) );
|
||||
xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) );
|
||||
xWriteCH376Data( iSectorCount );
|
||||
xEndCH376Cmd( );
|
||||
for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) {
|
||||
s = Wait376Interrupt( );
|
||||
if ( s == USB_INT_DISK_READ ) {
|
||||
s = CH376ReadBlock( buf );
|
||||
xWriteCH376Cmd( CMD0H_DISK_RD_GO );
|
||||
xEndCH376Cmd( );
|
||||
buf += s;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
if ( mBlockCount == 0 ) {
|
||||
s = Wait376Interrupt( );
|
||||
if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS );
|
||||
}
|
||||
if ( s == USB_INT_DISCONNECT ) return( s );
|
||||
CH376DiskReqSense( );
|
||||
}
|
||||
return( s );
|
||||
}
|
||||
|
||||
UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount )
|
||||
{
|
||||
UINT8 s, err;
|
||||
UINT16 mBlockCount;
|
||||
for ( err = 0; err != 3; ++ err ) {
|
||||
xWriteCH376Cmd( CMD5H_DISK_WRITE );
|
||||
xWriteCH376Data( (UINT8)iLbaStart );
|
||||
xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) );
|
||||
xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) );
|
||||
xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) );
|
||||
xWriteCH376Data( iSectorCount );
|
||||
xEndCH376Cmd( );
|
||||
for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) {
|
||||
s = Wait376Interrupt( );
|
||||
if ( s == USB_INT_DISK_WRITE ) {
|
||||
CH376WriteHostBlock( buf, CH376_DAT_BLOCK_LEN );
|
||||
xWriteCH376Cmd( CMD0H_DISK_WR_GO );
|
||||
xEndCH376Cmd( );
|
||||
buf += CH376_DAT_BLOCK_LEN;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
if ( mBlockCount == 0 ) {
|
||||
s = Wait376Interrupt( );
|
||||
if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS );
|
||||
}
|
||||
if ( s == USB_INT_DISCONNECT ) return( s );
|
||||
CH376DiskReqSense( );
|
||||
}
|
||||
return( s );
|
||||
}
|
||||
|
||||
UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount )
|
||||
{
|
||||
UINT8 s;
|
||||
UINT8 cnt;
|
||||
UINT32 StaSec;
|
||||
#ifndef DEF_IC_V43_U
|
||||
UINT32 fsz, fofs;
|
||||
#endif
|
||||
if ( RealCount ) *RealCount = 0;
|
||||
do {
|
||||
#ifndef DEF_IC_V43_U
|
||||
xWriteCH376Cmd( CMD01_GET_IC_VER );
|
||||
cnt = xReadCH376Data( );
|
||||
if ( cnt == 0x41 ) {
|
||||
xWriteCH376Cmd( CMD14_READ_VAR32 );
|
||||
xWriteCH376Data( VAR_FILE_SIZE );
|
||||
xReadCH376Data( );
|
||||
fsz = xReadCH376Data( );
|
||||
fsz |= (UINT16)(xReadCH376Data( )) << 8;
|
||||
cnt = xReadCH376Data( );
|
||||
fsz |= (UINT32)cnt << 16;
|
||||
xWriteCH376Cmd( CMD14_READ_VAR32 );
|
||||
xWriteCH376Data( VAR_CURRENT_OFFSET );
|
||||
xReadCH376Data( );
|
||||
fofs = xReadCH376Data( );
|
||||
fofs |= (UINT16)(xReadCH376Data( )) << 8;
|
||||
fofs |= (UINT32)(xReadCH376Data( )) << 16;
|
||||
if ( fsz >= fofs + 510 ) CH376WriteVar8( VAR_FILE_SIZE + 3, 0xFF );
|
||||
else cnt = 0xFF;
|
||||
}
|
||||
else cnt = 0xFF;
|
||||
#endif
|
||||
xWriteCH376Cmd( CMD1H_SEC_READ );
|
||||
xWriteCH376Data( ReqCount );
|
||||
xEndCH376Cmd( );
|
||||
s = Wait376Interrupt( );
|
||||
#ifndef DEF_IC_V43_U
|
||||
if ( cnt != 0xFF ) CH376WriteVar8( VAR_FILE_SIZE + 3, cnt );
|
||||
#endif
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
|
||||
xReadCH376Data( );
|
||||
cnt = xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
StaSec = CH376Read32bitDat( );
|
||||
if ( cnt == 0 ) break;
|
||||
s = CH376DiskReadSec( buf, StaSec, cnt );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
buf += cnt * DEF_SECTOR_SIZE;
|
||||
if ( RealCount ) *RealCount += cnt;
|
||||
ReqCount -= cnt;
|
||||
} while ( ReqCount );
|
||||
return( s );
|
||||
}
|
||||
|
||||
UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount )
|
||||
{
|
||||
UINT8 s;
|
||||
UINT8 cnt;
|
||||
UINT32 StaSec;
|
||||
if ( RealCount ) *RealCount = 0;
|
||||
do {
|
||||
xWriteCH376Cmd( CMD1H_SEC_WRITE );
|
||||
xWriteCH376Data( ReqCount );
|
||||
xEndCH376Cmd( );
|
||||
s = Wait376Interrupt( );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
|
||||
xReadCH376Data( );
|
||||
cnt = xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
xReadCH376Data( );
|
||||
StaSec = CH376Read32bitDat( );
|
||||
if ( cnt == 0 ) break;
|
||||
s = CH376DiskWriteSec( buf, StaSec, cnt );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
buf += cnt * DEF_SECTOR_SIZE;
|
||||
if ( RealCount ) *RealCount += cnt;
|
||||
ReqCount -= cnt;
|
||||
} while ( ReqCount );
|
||||
return( s );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef EN_LONG_NAME
|
||||
|
||||
UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount )
|
||||
{
|
||||
UINT8 s;
|
||||
#ifndef DEF_IC_V43_U
|
||||
UINT8 c;
|
||||
c = CH376ReadVar8( VAR_DISK_STATUS );
|
||||
if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_OPEN_DIR );
|
||||
#endif
|
||||
xWriteCH376Cmd( CMD2H_BYTE_WRITE );
|
||||
xWriteCH376Data( (UINT8)ReqCount );
|
||||
xWriteCH376Data( (UINT8)(ReqCount>>8) );
|
||||
xEndCH376Cmd( );
|
||||
while ( 1 ) {
|
||||
s = Wait376Interrupt( );
|
||||
if ( s == USB_INT_DISK_WRITE ) {
|
||||
if ( buf ) buf += CH376WriteReqBlock( buf );
|
||||
else {
|
||||
xWriteCH376Cmd( CMD01_WR_REQ_DATA );
|
||||
s = xReadCH376Data( );
|
||||
while ( s -- ) xWriteCH376Data( 0 );
|
||||
}
|
||||
xWriteCH376Cmd( CMD0H_BYTE_WR_GO );
|
||||
xEndCH376Cmd( );
|
||||
}
|
||||
else {
|
||||
#ifndef DEF_IC_V43_U
|
||||
if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, c );
|
||||
#endif
|
||||
return( s );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 CH376CheckNameSum( PUINT8 DirName )
|
||||
{
|
||||
UINT8 NameLen;
|
||||
UINT8 CheckSum;
|
||||
CheckSum = 0;
|
||||
for ( NameLen = 0; NameLen != 11; NameLen ++ ) CheckSum = ( CheckSum & 1 ? 0x80 : 0x00 ) + ( CheckSum >> 1 ) + *DirName++;
|
||||
return( CheckSum );
|
||||
}
|
||||
|
||||
UINT8 CH376LocateInUpDir( PUINT8 PathName )
|
||||
{
|
||||
UINT8 s;
|
||||
xWriteCH376Cmd( CMD14_READ_VAR32 );
|
||||
xWriteCH376Data( VAR_FAT_DIR_LBA );
|
||||
for ( s = 4; s != 8; s ++ ) GlobalBuf[ s ] = xReadCH376Data( );
|
||||
xEndCH376Cmd( );
|
||||
s = CH376SeparatePath( PathName );
|
||||
if ( s ) s = CH376FileOpenDir( PathName, s );
|
||||
else s = CH376FileOpen( "/" );
|
||||
if ( s != ERR_OPEN_DIR ) return( s );
|
||||
*(PUINT32)(&GlobalBuf[0]) = 0;
|
||||
while ( 1 ) {
|
||||
s = CH376SecLocate( *(PUINT32)(&GlobalBuf[0]) );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
CH376ReadBlock( &GlobalBuf[8] );
|
||||
if ( *(PUINT32)(&GlobalBuf[8]) == *(PUINT32)(&GlobalBuf[4]) ) return( USB_INT_SUCCESS );
|
||||
xWriteCH376Cmd( CMD50_WRITE_VAR32 );
|
||||
xWriteCH376Data( VAR_FAT_DIR_LBA );
|
||||
for ( s = 8; s != 12; s ++ ) xWriteCH376Data( GlobalBuf[ s ] );
|
||||
xEndCH376Cmd( );
|
||||
++ *(PUINT32)(&GlobalBuf[0]);
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName )
|
||||
{
|
||||
UINT8 s;
|
||||
UINT16 NameCount;
|
||||
s = CH376FileOpenPath( PathName );
|
||||
if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s );
|
||||
s = CH376DirInfoRead( );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
CH376ReadBlock( GlobalBuf );
|
||||
CH376EndDirInfo( );
|
||||
GlobalBuf[32] = CH376CheckNameSum( GlobalBuf );
|
||||
GlobalBuf[33] = CH376ReadVar8( VAR_FILE_DIR_INDEX );
|
||||
NameCount = 0;
|
||||
while ( 1 ) {
|
||||
if ( GlobalBuf[33] == 0 ) {
|
||||
s = CH376LocateInUpDir( PathName );
|
||||
if ( s != USB_INT_SUCCESS ) break;
|
||||
if ( CH376ReadVar32( VAR_CURRENT_OFFSET ) == 0 ) {
|
||||
s = ERR_LONG_NAME_ERR;
|
||||
break;
|
||||
}
|
||||
GlobalBuf[33] = DEF_SECTOR_SIZE / sizeof( FAT_DIR_INFO );
|
||||
}
|
||||
GlobalBuf[33] --;
|
||||
s = CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, GlobalBuf[33] );
|
||||
if ( s != USB_INT_SUCCESS ) break;
|
||||
CH376ReadBlock( GlobalBuf );
|
||||
CH376EndDirInfo( );
|
||||
if ( ( GlobalBuf[11] & ATTR_LONG_NAME_MASK ) != ATTR_LONG_NAME || GlobalBuf[13] != GlobalBuf[32] ) {
|
||||
s = ERR_LONG_NAME_ERR;
|
||||
break;
|
||||
}
|
||||
for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) {
|
||||
if ( s == 1 + 5 * 2 ) s = 14;
|
||||
else if ( s == 14 + 6 * 2 ) s = 28;
|
||||
LongName[ NameCount++ ] = GlobalBuf[ s ];
|
||||
LongName[ NameCount++ ] = GlobalBuf[ s + 1 ];
|
||||
if ( GlobalBuf[ s ] == 0 && GlobalBuf[ s + 1 ] == 0 ) break;
|
||||
if ( NameCount >= LONG_NAME_BUF_LEN ) {
|
||||
s = ERR_LONG_BUF_OVER;
|
||||
goto CH376GetLongNameE;
|
||||
}
|
||||
}
|
||||
if ( GlobalBuf[0] & 0x40 ) {
|
||||
if ( s >= sizeof( FAT_DIR_INFO ) ) *(PUINT16)( &LongName[ NameCount ] ) = 0x0000;
|
||||
s = USB_INT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CH376GetLongNameE:
|
||||
CH376FileClose( FALSE );
|
||||
return( s );
|
||||
}
|
||||
|
||||
UINT8 CH376CreateLongName( PUINT8 PathName, PUINT8 LongName )
|
||||
{
|
||||
UINT8 s, i;
|
||||
UINT8 DirBlockCnt;
|
||||
UINT16 count;
|
||||
UINT16 NameCount;
|
||||
UINT32 NewFileLoc;
|
||||
for ( count = 0; count < LONG_NAME_BUF_LEN; count += 2 ) if ( *(PUINT16)(&LongName[count]) == 0 ) break;
|
||||
if ( count == 0 || count >= LONG_NAME_BUF_LEN || count > LONE_NAME_MAX_CHAR ) return( ERR_LONG_NAME_ERR );
|
||||
DirBlockCnt = count / LONG_NAME_PER_DIR;
|
||||
i = count - DirBlockCnt * LONG_NAME_PER_DIR;
|
||||
if ( i ) {
|
||||
if ( ++ DirBlockCnt * LONG_NAME_PER_DIR > LONG_NAME_BUF_LEN ) return( ERR_LONG_BUF_OVER );
|
||||
count += 2;
|
||||
i += 2;
|
||||
if ( i < LONG_NAME_PER_DIR ) {
|
||||
while ( i++ < LONG_NAME_PER_DIR ) LongName[count++] = 0xFF;
|
||||
}
|
||||
}
|
||||
s = CH376FileOpenPath( PathName );
|
||||
if ( s == USB_INT_SUCCESS ) {
|
||||
s = ERR_NAME_EXIST;
|
||||
goto CH376CreateLongNameE;
|
||||
}
|
||||
if ( s != ERR_MISS_FILE ) return( s );
|
||||
s = CH376FileCreatePath( PathName );
|
||||
if ( s != USB_INT_SUCCESS ) return( s );
|
||||
i = CH376ReadVar8( VAR_FILE_DIR_INDEX );
|
||||
s = CH376LocateInUpDir( PathName );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET ) + i * sizeof(FAT_DIR_INFO);
|
||||
s = CH376ByteLocate( NewFileLoc );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
s = CH376ByteRead( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO), NULL );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
for ( i = DirBlockCnt; i != 0; -- i ) {
|
||||
s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
if ( count == 0 ) break;
|
||||
if ( GlobalBuf[0] && GlobalBuf[0] != 0xE5 ) {
|
||||
s = CH376ByteLocate( NewFileLoc );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
GlobalBuf[ 0 ] = 0xE5;
|
||||
for ( s = 1; s != sizeof(FAT_DIR_INFO); s ++ ) GlobalBuf[ s ] = GlobalBuf[ sizeof(FAT_DIR_INFO) + s ];
|
||||
s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
do {
|
||||
s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
} while ( count && GlobalBuf[0] );
|
||||
NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET );
|
||||
i = DirBlockCnt + 1;
|
||||
if ( count == 0 ) break;
|
||||
NewFileLoc -= sizeof(FAT_DIR_INFO);
|
||||
}
|
||||
}
|
||||
if ( i ) {
|
||||
s = CH376ReadVar8( VAR_SEC_PER_CLUS );
|
||||
if ( s == 128 ) {
|
||||
s = ERR_FDT_OVER;
|
||||
goto CH376CreateLongNameE;
|
||||
}
|
||||
count = s * DEF_SECTOR_SIZE;
|
||||
if ( count < i * sizeof(FAT_DIR_INFO) ) count <<= 1;
|
||||
s = CH376LongNameWrite( NULL, count );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
}
|
||||
s = CH376ByteLocate( NewFileLoc );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
GlobalBuf[11] = ATTR_LONG_NAME;
|
||||
GlobalBuf[12] = 0x00;
|
||||
GlobalBuf[13] = CH376CheckNameSum( &GlobalBuf[ sizeof(FAT_DIR_INFO) ] );
|
||||
GlobalBuf[26] = 0x00;
|
||||
GlobalBuf[27] = 0x00;
|
||||
for ( s = 0; DirBlockCnt != 0; ) {
|
||||
GlobalBuf[0] = s ? DirBlockCnt : DirBlockCnt | 0x40;
|
||||
DirBlockCnt --;
|
||||
NameCount = DirBlockCnt * LONG_NAME_PER_DIR;
|
||||
for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) {
|
||||
if ( s == 1 + 5 * 2 ) s = 14;
|
||||
else if ( s == 14 + 6 * 2 ) s = 28;
|
||||
GlobalBuf[ s ] = LongName[ NameCount++ ];
|
||||
GlobalBuf[ s + 1 ] = LongName[ NameCount++ ];
|
||||
}
|
||||
s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) );
|
||||
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
|
||||
}
|
||||
s = CH376LongNameWrite( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO) );
|
||||
CH376CreateLongNameE:
|
||||
CH376FileClose( FALSE );
|
||||
return( s );
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_ch376.h
|
||||
* @brief edu-riscv64 k210_ch376.h
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.10.10
|
||||
* */
|
||||
|
||||
#ifndef __CH376_FS_H__
|
||||
#define __CH376_FS_H__
|
||||
|
||||
#include "ch376inc.h"
|
||||
#include <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.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
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_gpio.c
|
||||
* @brief edu-riscv64 k210_gpio.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.06.08
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "k210_fpioa.h"
|
||||
#include "k210_gpiohs.h"
|
||||
|
||||
#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Pin 1 and 2 are used for this example as GPIO outputs. */
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct k210gpio_dev_s
|
||||
{
|
||||
struct gpio_dev_s gpio;
|
||||
uint8_t id;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#if BOARD_NGPIOOUT > 0
|
||||
static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value);
|
||||
static int gpout_write(FAR struct gpio_dev_s *dev, bool value);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#if BOARD_NGPIOOUT > 0
|
||||
static const struct gpio_operations_s gpout_ops =
|
||||
{
|
||||
.go_read = gpout_read,
|
||||
.go_write = gpout_write,
|
||||
.go_attach = NULL,
|
||||
.go_enable = NULL,
|
||||
};
|
||||
|
||||
/* This array maps the GPIO pins used as OUTPUT */
|
||||
|
||||
static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] =
|
||||
{
|
||||
GPIO_E220_M0,
|
||||
GPIO_E220_M1,
|
||||
GPIO_E18_MODE
|
||||
};
|
||||
|
||||
static const uint32_t g_fpioa[BOARD_NGPIOOUT] =
|
||||
{
|
||||
FPIOA_E220_M0,
|
||||
FPIOA_E220_M1,
|
||||
FPIOA_E18_MODE
|
||||
};
|
||||
|
||||
static struct k210gpio_dev_s g_gpout[BOARD_NGPIOOUT];
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gpout_read
|
||||
****************************************************************************/
|
||||
|
||||
#if BOARD_NGPIOOUT > 0
|
||||
static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value)
|
||||
{
|
||||
FAR struct k210gpio_dev_s *k210gpio =
|
||||
(FAR struct k210gpio_dev_s *)dev;
|
||||
|
||||
DEBUGASSERT(k210gpio != NULL && value != NULL);
|
||||
DEBUGASSERT(k210gpio->id < BOARD_NGPIOOUT);
|
||||
gpioinfo("Reading...\n");
|
||||
|
||||
*value = (int) k210_gpiohs_get_value(g_fpioa[k210gpio->id]);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gpout_write
|
||||
****************************************************************************/
|
||||
|
||||
static int gpout_write(FAR struct gpio_dev_s *dev, bool value)
|
||||
{
|
||||
FAR struct k210gpio_dev_s *k210gpio =
|
||||
(FAR struct k210gpio_dev_s *)dev;
|
||||
|
||||
DEBUGASSERT(k210gpio != NULL);
|
||||
DEBUGASSERT(k210gpio->id < BOARD_NGPIOOUT);
|
||||
gpioinfo("Writing %d\n", (int)value);
|
||||
|
||||
k210_gpiohs_set_value(g_fpioa[k210gpio->id], value);
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k210_gpio_init
|
||||
****************************************************************************/
|
||||
|
||||
int k210_gpio_init(void)
|
||||
{
|
||||
int i;
|
||||
int pincount = 0;
|
||||
|
||||
#if BOARD_NGPIOOUT > 0
|
||||
for (i = 0; i < BOARD_NGPIOOUT; i++)
|
||||
{
|
||||
/* Setup and register the GPIO pin */
|
||||
|
||||
g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
|
||||
g_gpout[i].gpio.gp_ops = &gpout_ops;
|
||||
g_gpout[i].id = i;
|
||||
gpio_pin_register(&g_gpout[i].gpio, pincount);
|
||||
|
||||
/* Configure the pins that will be used as output */
|
||||
|
||||
k210_fpioa_config(g_gpiooutputs[i],
|
||||
(K210_IO_FUNC_GPIOHS0 + g_fpioa[i]) | K210_IOFLAG_GPIOHS);
|
||||
k210_gpiohs_set_direction(g_fpioa[i], GPIO_DM_OUTPUT);
|
||||
k210_gpiohs_set_value(g_fpioa[i], false);
|
||||
pincount++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_lcd.c
|
||||
* @brief LCD relative driver
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.7.21
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
#include <nuttx/config.h>
|
||||
#include "k210_fpioa.h"
|
||||
#include "k210_gpiohs.h"
|
||||
#include "nuttx/arch.h"
|
||||
#include "nuttx/lcd/lt768.h"
|
||||
#include "nuttx/lcd/lt768_lib.h"
|
||||
#include "nuttx/lcd/if_port.h"
|
||||
#include "nuttx/lcd/lt768_learn.h"
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#ifdef CONFIG_LCD_LCDDRV_SPIIF
|
||||
#include "nuttx/lcd/lcddrv_spiif.h"
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
#define NCS_H() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_HIGH); up_udelay(20)
|
||||
#define NCS_L() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_LOW); up_udelay(20)
|
||||
#define CLK_H() k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_HIGH); up_udelay(20)
|
||||
#define CLK_L() k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_LOW); up_udelay(20)
|
||||
#define MOSI_H() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_HIGH)
|
||||
#define MOSI_L() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_LOW)
|
||||
|
||||
static int lcd_open(FAR struct file *filep);
|
||||
static int lcd_close(FAR struct file *filep);
|
||||
static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
|
||||
static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
/* LCD POSIX interface */
|
||||
static const struct file_operations g_lcdfops =
|
||||
{
|
||||
lcd_open,
|
||||
lcd_close,
|
||||
lcd_read,
|
||||
lcd_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void lcd_pin_init(void)
|
||||
{
|
||||
k210_fpioa_config(BSP_LCD_NRST, HS_GPIO(FPIOA_LCD_NRST) | K210_IOFLAG_GPIOHS);
|
||||
k210_fpioa_config(BSP_LCD_SCLK, HS_GPIO(FPIOA_LCD_SCLK) | K210_IOFLAG_GPIOHS);
|
||||
k210_fpioa_config(BSP_LCD_MOSI, HS_GPIO(FPIOA_LCD_MOSI) | K210_IOFLAG_GPIOHS);
|
||||
k210_fpioa_config(BSP_LCD_MISO, HS_GPIO(FPIOA_LCD_MISO) | K210_IOFLAG_GPIOHS);
|
||||
k210_fpioa_config(BSP_LCD_NCS, HS_GPIO(FPIOA_LCD_NCS) | K210_IOFLAG_GPIOHS);
|
||||
|
||||
k210_gpiohs_set_direction(FPIOA_LCD_MISO, GPIO_DM_INPUT);
|
||||
k210_gpiohs_set_direction(FPIOA_LCD_NRST, GPIO_DM_OUTPUT);
|
||||
k210_gpiohs_set_direction(FPIOA_LCD_SCLK, GPIO_DM_OUTPUT);
|
||||
k210_gpiohs_set_direction(FPIOA_LCD_MOSI, GPIO_DM_OUTPUT);
|
||||
k210_gpiohs_set_direction(FPIOA_LCD_NCS, GPIO_DM_OUTPUT);
|
||||
|
||||
k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_HIGH);
|
||||
k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_HIGH);
|
||||
k210_gpiohs_set_value(FPIOA_LCD_NRST, GPIO_PV_HIGH);
|
||||
}
|
||||
|
||||
void lcd_backlight_init(bool enable)
|
||||
{
|
||||
k210_fpioa_config(BSP_LCD_BL_PIN, HS_GPIO(FPIOA_LCD_BL) | K210_IOFLAG_GPIOHS);
|
||||
k210_gpiohs_set_direction(FPIOA_LCD_BL, GPIO_DM_OUTPUT);
|
||||
k210_gpiohs_set_value(FPIOA_LCD_BL, enable);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LCD_LCDDRV_SPIIF
|
||||
int spiif_backlight(FAR struct lcddrv_lcd_s *lcd, int level)
|
||||
{
|
||||
lcd_backlight_init(true);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t lcd_transfer_byte(uint8_t dat)
|
||||
{
|
||||
uint8_t i, rx_data = 0;
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
CLK_H();
|
||||
|
||||
// MOSI during falling edge
|
||||
if((dat << i) & 0x80)
|
||||
{
|
||||
MOSI_H();
|
||||
}
|
||||
else
|
||||
{
|
||||
MOSI_L();
|
||||
}
|
||||
|
||||
CLK_L();
|
||||
|
||||
// MISO during rising edge
|
||||
rx_data <<= 1;
|
||||
if(k210_gpiohs_get_value(FPIOA_LCD_MISO))
|
||||
rx_data ++;
|
||||
}
|
||||
CLK_H();
|
||||
return rx_data;
|
||||
}
|
||||
|
||||
void LCD_CmdWrite(uint8_t cmd)
|
||||
{
|
||||
NCS_L();
|
||||
lcd_transfer_byte(0x00);
|
||||
lcd_transfer_byte(cmd);
|
||||
NCS_H();
|
||||
}
|
||||
|
||||
void LCD_DataWrite(uint8_t data)
|
||||
{
|
||||
NCS_L();
|
||||
lcd_transfer_byte(0x80);
|
||||
lcd_transfer_byte(data);
|
||||
NCS_H();
|
||||
}
|
||||
|
||||
void LCD_DataWrite_Pixel(uint8_t data)
|
||||
{
|
||||
NCS_L();
|
||||
lcd_transfer_byte(0x80);
|
||||
lcd_transfer_byte(data);
|
||||
NCS_H();
|
||||
NCS_L();
|
||||
lcd_transfer_byte(0x80);
|
||||
lcd_transfer_byte(data >> 8);
|
||||
NCS_H();
|
||||
}
|
||||
|
||||
uint8_t LCD_StatusRead(void)
|
||||
{
|
||||
uint8_t temp = 0;
|
||||
NCS_L();
|
||||
lcd_transfer_byte(0x40);
|
||||
temp = lcd_transfer_byte(0xff);
|
||||
NCS_H();
|
||||
return temp;
|
||||
}
|
||||
|
||||
uint8_t LCD_DataRead(void)
|
||||
{
|
||||
uint8_t temp = 0;
|
||||
NCS_L();
|
||||
lcd_transfer_byte(0xc0);
|
||||
temp = lcd_transfer_byte(0xff);
|
||||
NCS_H();
|
||||
return temp;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void lcd_drv_init(void)
|
||||
{
|
||||
uint8_t PwmControl = 100;
|
||||
|
||||
lcd_pin_init();
|
||||
lt768_init();
|
||||
Select_SFI_Dual_Mode0();
|
||||
|
||||
// PWM1 enable backlight
|
||||
LT768_PWM1_Init(1, 0, 200, 100, PwmControl);
|
||||
|
||||
// enable RGB output
|
||||
Display_ON();
|
||||
|
||||
Main_Image_Start_Address(LCD_START_ADDR);
|
||||
Main_Image_Width(LCD_XSIZE_TFT);
|
||||
Main_Window_Start_XY(0, 0);
|
||||
Canvas_Image_Start_address(LCD_START_ADDR);
|
||||
Canvas_image_width(LCD_XSIZE_TFT);
|
||||
Active_Window_XY(0, 0);
|
||||
Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT);
|
||||
up_mdelay(10);
|
||||
Canvas_Image_Start_address(LCD_START_ADDR);
|
||||
|
||||
//fill blue background
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: k210_backlight
|
||||
*
|
||||
* Description:
|
||||
* If CONFIG_K210_LCD_BACKLIGHT is defined, then the board-specific
|
||||
* logic must provide this interface to turn the backlight on and off.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_K210_LCD_BACKLIGHT
|
||||
void k210_backlight(bool blon)
|
||||
{
|
||||
lcd_backlight_init(blon);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcd_open
|
||||
****************************************************************************/
|
||||
static int lcd_open(FAR struct file *filep)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcd_close
|
||||
****************************************************************************/
|
||||
static int lcd_close(FAR struct file *filep)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcd_read
|
||||
****************************************************************************/
|
||||
static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ch438_write
|
||||
****************************************************************************/
|
||||
static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
|
||||
{
|
||||
ssize_t ret = buflen;
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return -ERROR;
|
||||
}
|
||||
LcdWriteParam * show = (LcdWriteParam *)buffer;
|
||||
|
||||
/* output string */
|
||||
switch (show->type)
|
||||
{
|
||||
|
||||
/* output string */
|
||||
case SHOW_STRING:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
LT768_Select_Internal_Font_Init(show->string_info.height, 1, 1, 1, 1);
|
||||
LT768_Print_Internal_Font_String(show->string_info.x_pos, show->string_info.y_pos, show->string_info.font_color,show->string_info.back_color,show->string_info.addr);
|
||||
break;
|
||||
|
||||
/* output dot */
|
||||
case SHOW_WDOT:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
LT768_DrawSquare_Fill(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos, *(uint32_t *)(show->pixel_info.pixel_color));
|
||||
break;
|
||||
|
||||
/* output rgb */
|
||||
case SHOW_RGB:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
Display_RGB();
|
||||
break;
|
||||
|
||||
/* output pip */
|
||||
case SHOW_PIP:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
Display_PIP();
|
||||
break;
|
||||
|
||||
/* output Internal Font */
|
||||
case SHOW_INTERNAL_FONT:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
Display_Internal_Font();
|
||||
break;
|
||||
|
||||
/* output Outside Font */
|
||||
case SHOW_OUTSIDE_FONT:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
Display_Outside_Font();
|
||||
break;
|
||||
|
||||
/* output Triangle */
|
||||
case SHOW_TRIANGLE:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
Display_Triangle();
|
||||
break;
|
||||
|
||||
/* output picture */
|
||||
case SHOW_PICTURE:
|
||||
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
|
||||
Display_Picture();
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = -ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/****************************************************************************
|
||||
* Name: k210_lcd_initialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the LCD. Setup backlight (initially off)
|
||||
*
|
||||
****************************************************************************/
|
||||
int board_lcd_initialize(void)
|
||||
{
|
||||
/* Configure the LCD backlight (and turn the backlight off) */
|
||||
lcd_backlight_init(true);
|
||||
lcd_drv_init();
|
||||
up_mdelay(10);
|
||||
Main_Image_Start_Address(LCD_START_ADDR);
|
||||
Main_Image_Width(LCD_XSIZE_TFT);
|
||||
Main_Window_Start_XY(0, 0);
|
||||
Canvas_Image_Start_address(LCD_START_ADDR);
|
||||
Canvas_image_width(LCD_XSIZE_TFT);
|
||||
Active_Window_XY(0, 0);
|
||||
Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT);
|
||||
up_mdelay(10);
|
||||
Canvas_Image_Start_address(LCD_START_ADDR);
|
||||
/* register device */
|
||||
register_driver("/dev/lcd_dev", &g_lcdfops, 0666, NULL);
|
||||
return OK;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_leds.c
|
||||
* @brief edu-riscv64 k210_leds.c
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.06.08
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "k210_fpioa.h"
|
||||
#include "k210_gpiohs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void board_autoled_initialize(void)
|
||||
{
|
||||
}
|
||||
|
||||
void board_autoled_on(int led)
|
||||
{
|
||||
}
|
||||
|
||||
void board_autoled_off(int led)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_reset.c
|
||||
* @brief k210_reset.c support reboot
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.06.27
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#ifdef CONFIG_BOARDCTL_RESET
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: board_reset
|
||||
*
|
||||
* Description:
|
||||
* Reset board. Support for this function is required by board-level
|
||||
* logic if CONFIG_BOARDCTL_RESET is selected.
|
||||
*
|
||||
* Input Parameters:
|
||||
* status - Status information provided with the reset event. This
|
||||
* meaning of this status information is board-specific. If not
|
||||
* used by a board, the value zero may be provided in calls to
|
||||
* board_reset().
|
||||
*
|
||||
* Returned Value:
|
||||
* If this function returns, then it was not possible to power-off the
|
||||
* board due to some constraints. The return value int this case is a
|
||||
* board-specific reason for the failure to shutdown.
|
||||
*
|
||||
****************************************************************************/
|
||||
int board_reset(int status)
|
||||
{
|
||||
up_systemreset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BOARDCTL_RESET */
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_touch.c
|
||||
* @brief gt911 touch driver
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.10.25
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
#include "k210_touch.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
static void IIC_Init(void);
|
||||
static void SDA_IN(void);
|
||||
static void SDA_OUT(void);
|
||||
static uint8_t READ_SDA(void);
|
||||
static void IIC_SCL(uint8_t val);
|
||||
static void IIC_SDA(uint8_t val);
|
||||
static void IIC_Start(void);
|
||||
static void IIC_Stop(void);
|
||||
static uint8_t IIC_Wait_Ack(void);
|
||||
static void IIC_Ack(void);
|
||||
static void IIC_NAck(void);
|
||||
static void IIC_Send_Byte(uint8_t txd);
|
||||
static uint8_t IIC_Read_Byte(uint8_t ack);
|
||||
static bool GT911_Scan(POINT* point);
|
||||
|
||||
static int touch_open(FAR struct file *filep);
|
||||
static int touch_close(FAR struct file *filep);
|
||||
static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
|
||||
static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
/* touch POSIX interface */
|
||||
static const struct file_operations g_touchfops =
|
||||
{
|
||||
touch_open,
|
||||
touch_close,
|
||||
touch_read,
|
||||
touch_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_Init
|
||||
* Description: i2c pin mode configure
|
||||
* input: None
|
||||
* output: None
|
||||
* return:none
|
||||
****************************************************************************/
|
||||
static void IIC_Init(void)
|
||||
{
|
||||
/* config simluate IIC bus */
|
||||
k210_fpioa_config(BSP_IIC_SDA, GT911_FUNC_GPIO(FPIOA_IIC_SDA));
|
||||
k210_fpioa_config(BSP_IIC_SCL, GT911_FUNC_GPIO(FPIOA_IIC_SCL));
|
||||
|
||||
k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_OUTPUT);
|
||||
k210_gpiohs_set_direction(FPIOA_IIC_SCL, GPIO_DM_OUTPUT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: SDA_IN
|
||||
* Description: set sda input mode
|
||||
* input: None
|
||||
* output: None
|
||||
* return:none
|
||||
****************************************************************************/
|
||||
static void SDA_IN(void)
|
||||
{
|
||||
k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_INPUT_PULL_UP);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: SDA_OUT
|
||||
* Description: set sda output mode
|
||||
* input: None
|
||||
* output: None
|
||||
* return:none
|
||||
****************************************************************************/
|
||||
static void SDA_OUT(void)
|
||||
{
|
||||
k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_OUTPUT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: READ_SDA
|
||||
* Description: read sda value
|
||||
* input: None
|
||||
* output: None
|
||||
* return: sda pin value
|
||||
****************************************************************************/
|
||||
static uint8_t READ_SDA(void)
|
||||
{
|
||||
return k210_gpiohs_get_value(FPIOA_IIC_SDA);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_SCL
|
||||
* Description: set the value of scl
|
||||
* input: val:the value to be set
|
||||
* output: None
|
||||
* return: None
|
||||
****************************************************************************/
|
||||
static void IIC_SCL(uint8_t val)
|
||||
{
|
||||
if (val)
|
||||
k210_gpiohs_set_value(FPIOA_IIC_SCL,GPIO_PV_HIGH);
|
||||
else
|
||||
{
|
||||
k210_gpiohs_set_value(FPIOA_IIC_SCL,GPIO_PV_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_SDA
|
||||
* Description: set the value of sda
|
||||
* input: val:the value to be set
|
||||
* output: None
|
||||
* return: None
|
||||
****************************************************************************/
|
||||
static void IIC_SDA(uint8_t val)
|
||||
{
|
||||
if (val)
|
||||
k210_gpiohs_set_value(FPIOA_IIC_SDA,GPIO_PV_HIGH);
|
||||
else
|
||||
{
|
||||
k210_gpiohs_set_value(FPIOA_IIC_SDA,GPIO_PV_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_Start
|
||||
* Description: Generate i2c start signal
|
||||
* input: None
|
||||
* output: None
|
||||
* return: None
|
||||
****************************************************************************/
|
||||
static void IIC_Start(void)
|
||||
{
|
||||
SDA_OUT();
|
||||
IIC_SDA(1);
|
||||
IIC_SCL(1);
|
||||
up_mdelay(30);
|
||||
IIC_SDA(0);
|
||||
up_mdelay(2);
|
||||
IIC_SCL(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_Start
|
||||
* Description: Generate i2c stop signal
|
||||
* input: None
|
||||
* output: None
|
||||
* return: None
|
||||
****************************************************************************/
|
||||
static void IIC_Stop(void)
|
||||
{
|
||||
SDA_OUT();
|
||||
IIC_SCL(1);
|
||||
up_mdelay(30);
|
||||
IIC_SDA(0);
|
||||
up_mdelay(2);
|
||||
IIC_SDA(1);
|
||||
}
|
||||
|
||||
/*******************************************************************************************
|
||||
* Name: IIC_Wait_Ack
|
||||
* Description: Wait for the reply signal to arrive
|
||||
* input: None
|
||||
* output: None
|
||||
* return: Return value: 1:failed to receive response,0:the received response is successful.
|
||||
********************************************************************************************/
|
||||
static uint8_t IIC_Wait_Ack(void)
|
||||
{
|
||||
uint16_t ucErrTime=0;
|
||||
SDA_IN();
|
||||
IIC_SDA(1);
|
||||
IIC_SCL(1);
|
||||
up_mdelay(2);
|
||||
while(READ_SDA())
|
||||
{
|
||||
ucErrTime++;
|
||||
if(ucErrTime>2500)
|
||||
{
|
||||
IIC_Stop();
|
||||
return 1;
|
||||
}
|
||||
up_mdelay(2);
|
||||
}
|
||||
IIC_SCL(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_Ack
|
||||
* Description: generate ack response
|
||||
* input: None
|
||||
* output: None
|
||||
* return: None
|
||||
****************************************************************************/
|
||||
static void IIC_Ack(void)
|
||||
{
|
||||
IIC_SCL(0);
|
||||
SDA_OUT();
|
||||
up_mdelay(2);
|
||||
IIC_SDA(0);
|
||||
up_mdelay(2);
|
||||
IIC_SCL(1);
|
||||
up_mdelay(2);
|
||||
IIC_SCL(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_NAck
|
||||
* Description: No ACK response is generated
|
||||
* input: None
|
||||
* output: None
|
||||
* return: None
|
||||
****************************************************************************/
|
||||
static void IIC_NAck(void)
|
||||
{
|
||||
IIC_SCL(0);
|
||||
SDA_OUT();
|
||||
up_mdelay(2);
|
||||
IIC_SDA(1);
|
||||
up_mdelay(2);
|
||||
IIC_SCL(1);
|
||||
up_mdelay(2);
|
||||
IIC_SCL(0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_Send_Byte
|
||||
* Description: IIC sends a byte,Return whether the slave has a response
|
||||
* input: None
|
||||
* output: None
|
||||
* return: 1:there is a response,0:no response
|
||||
****************************************************************************/
|
||||
static void IIC_Send_Byte(uint8_t txd)
|
||||
{
|
||||
uint8_t t;
|
||||
SDA_OUT();
|
||||
IIC_SCL(0);
|
||||
up_mdelay(2);
|
||||
for(t=0;t<8;t++)
|
||||
{
|
||||
IIC_SDA((txd&0x80)>>7);
|
||||
txd<<=1;
|
||||
IIC_SCL(1);
|
||||
up_mdelay(2);
|
||||
IIC_SCL(0);
|
||||
up_mdelay(2);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: IIC_Read_Byte
|
||||
* Description: Read 1 byte, when ack=1, send ACK, when ack=0, send nACK
|
||||
* input: None
|
||||
* output: None
|
||||
* return: Returns one byte of data read
|
||||
****************************************************************************/
|
||||
static uint8_t IIC_Read_Byte(uint8_t ack)
|
||||
{
|
||||
uint8_t i,receive=0;
|
||||
SDA_IN();
|
||||
up_mdelay(30);
|
||||
for(i=0;i<8;i++ )
|
||||
{
|
||||
IIC_SCL(0);
|
||||
up_mdelay(2);
|
||||
IIC_SCL(1);
|
||||
up_udelay(1);
|
||||
receive<<=1;
|
||||
if(READ_SDA())receive++;
|
||||
up_udelay(1);
|
||||
}
|
||||
if (!ack)
|
||||
IIC_NAck();
|
||||
else
|
||||
IIC_Ack();
|
||||
return receive;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* Name: GT911_WR_Reg
|
||||
* Description: Write data to GT911 once
|
||||
* input: reg: start register address,buf: data cache area,len: write data length
|
||||
* output: None
|
||||
* return: Return value: 0, success; 1, failure.
|
||||
***********************************************************************************/
|
||||
static uint8_t GT911_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t ret=0;
|
||||
IIC_Start();
|
||||
IIC_Send_Byte(CT_CMD_WR);
|
||||
IIC_Wait_Ack();
|
||||
IIC_Send_Byte(reg>>8);
|
||||
IIC_Wait_Ack();
|
||||
IIC_Send_Byte(reg&0XFF);
|
||||
IIC_Wait_Ack();
|
||||
for(i=0;i<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_Scan
|
||||
* Description: point:structure to store coordinates
|
||||
* input: None
|
||||
* output: None
|
||||
* return: Returns true for touch, false for no touch
|
||||
***********************************************************************************/
|
||||
static 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: touch_open
|
||||
****************************************************************************/
|
||||
static int touch_open(FAR struct file *filep)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: touch_close
|
||||
****************************************************************************/
|
||||
static int touch_close(FAR struct file *filep)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcd_read
|
||||
****************************************************************************/
|
||||
static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
|
||||
{
|
||||
int ret = -ERROR;
|
||||
POINT touch_point = {0, 0, 0};
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return -ERROR;
|
||||
}
|
||||
|
||||
POINT* data = (POINT*)buffer;
|
||||
while(1)
|
||||
{
|
||||
if(GT911_Scan(&touch_point))
|
||||
{
|
||||
data->x = touch_point.x;
|
||||
data->y = touch_point.y;
|
||||
ret = buflen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lcd_read
|
||||
****************************************************************************/
|
||||
static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* Name: board_touch_initialize
|
||||
* Description: touch initialize
|
||||
* input: None
|
||||
* output: None
|
||||
* return: None
|
||||
***********************************************************************************/
|
||||
void board_touch_initialize(void)
|
||||
{
|
||||
IIC_Init();
|
||||
/* register device */
|
||||
register_driver("/dev/touch_dev", &g_touchfops, 0666, NULL);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 2022 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file k210_touch.h
|
||||
* @brief gt911 touch driver
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.10.25
|
||||
*/
|
||||
|
||||
#ifndef _K210_TOUCH_H_
|
||||
#define _K210_TOUCH_H_
|
||||
|
||||
#include <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;
|
||||
uint16_t press;
|
||||
}POINT;
|
||||
|
||||
void board_touch_initialize(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
|
|
@ -11,4 +11,27 @@ config HC32F4A0_BOARD
|
|||
---help---
|
||||
Select if you are using the HC32F4A0 base board with the HC32F4A0.
|
||||
|
||||
config HC32_ROMFS
|
||||
bool "Automount baked-in ROMFS image"
|
||||
default n
|
||||
depends on FS_ROMFS
|
||||
---help---
|
||||
Select HC32_ROMFS_IMAGEFILE, HC32_ROMFS_DEV_MINOR, HC32_ROMFS_MOUNTPOINT
|
||||
|
||||
config HC32_ROMFS_DEV_MINOR
|
||||
int "Minor for the block device backing the data"
|
||||
depends on HC32_ROMFS
|
||||
default 64
|
||||
|
||||
config HC32_ROMFS_MOUNTPOINT
|
||||
string "Mountpoint of the custom romfs image"
|
||||
depends on HC32_ROMFS
|
||||
default "/rom"
|
||||
|
||||
config HC32_ROMFS_IMAGEFILE
|
||||
string "ROMFS image file to include into build"
|
||||
depends on HC32_ROMFS
|
||||
default "../../../../../rom.img"
|
||||
|
||||
|
||||
endif
|
||||
|
|
|
@ -57,38 +57,42 @@
|
|||
/* for lowputc device output */
|
||||
|
||||
/* UART RX/TX Port/Pin definition */
|
||||
#define LP_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */
|
||||
#define LP_RX_PIN (GPIO_PIN_06)
|
||||
#define LP_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX)
|
||||
#define DBG_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */
|
||||
#define DBG_RX_PIN (GPIO_PIN_06)
|
||||
#define DBG_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX)
|
||||
|
||||
#define LP_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */
|
||||
#define LP_TX_PIN (GPIO_PIN_06)
|
||||
#define LP_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX)
|
||||
#define DBG_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */
|
||||
#define DBG_TX_PIN (GPIO_PIN_06)
|
||||
#define DBG_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX)
|
||||
|
||||
/* UART unit definition */
|
||||
#define LP_UNIT (M4_USART6)
|
||||
#define LP_FUNCTION_CLK_GATE (PWC_FCG3_USART6)
|
||||
#define DBG_UNIT (M4_USART6)
|
||||
#define DBG_BAUDRATE (115200UL)
|
||||
#define DBG_FUNCTION_CLK_GATE (PWC_FCG3_USART6)
|
||||
|
||||
/* UART unit interrupt definition */
|
||||
#define LP_UNIT_ERR_INT_SRC (INT_USART6_EI)
|
||||
#define LP_UNIT_ERR_INT_IRQn (Int015_IRQn + HC32_IRQ_FIRST)
|
||||
#define DBG_UNIT_ERR_INT_SRC (INT_USART6_EI)
|
||||
#define DBG_UNIT_ERR_INT_IRQn (Int010_IRQn)
|
||||
|
||||
#define LP_UNIT_RX_INT_SRC (INT_USART6_RI)
|
||||
#define LP_UNIT_RX_INT_IRQn (Int103_IRQn + HC32_IRQ_FIRST)
|
||||
#define DBG_UNIT_RX_INT_SRC (INT_USART6_RI)
|
||||
#define DBG_UNIT_RX_INT_IRQn (Int011_IRQn)
|
||||
|
||||
#define LP_UNIT_TX_INT_SRC (INT_USART6_TI)
|
||||
#define LP_UNIT_TX_INT_IRQn (Int102_IRQn + HC32_IRQ_FIRST)
|
||||
#define DBG_RXTO_INT_SRC (INT_USART6_RTO)
|
||||
#define DBG_RXTO_INT_IRQn (Int012_IRQn)
|
||||
|
||||
#define LP_UNIT_TCI_INT_SRC (INT_USART6_TCI)
|
||||
#define LP_UNIT_TCI_INT_IRQn (Int099_IRQn + HC32_IRQ_FIRST)
|
||||
#define DBG_UNIT_TX_INT_SRC (INT_USART6_TI)
|
||||
#define DBG_UNIT_TX_INT_IRQn (Int013_IRQn)
|
||||
|
||||
#define DBG_UNIT_TCI_INT_SRC (INT_USART6_TCI)
|
||||
#define DBG_UNIT_TCI_INT_IRQn (Int014_IRQn)
|
||||
|
||||
/* printf device s*/
|
||||
#define BSP_PRINTF_DEVICE LP_UNIT
|
||||
#define BSP_PRINTF_BAUDRATE (115200)
|
||||
#define BSP_PRINTF_DEVICE DBG_UNIT
|
||||
#define BSP_PRINTF_BAUDRATE DBG_BAUDRATE
|
||||
|
||||
#define BSP_PRINTF_PORT LP_TX_PORT
|
||||
#define BSP_PRINTF_PORT DBG_TX_PORT
|
||||
|
||||
#define BSP_PRINTF_PIN LP_TX_PIN
|
||||
#define BSP_PRINTF_PORT_FUNC LP_TX_GPIO_FUNC
|
||||
#define BSP_PRINTF_PIN DBG_TX_PIN
|
||||
#define BSP_PRINTF_PORT_FUNC DBG_TX_GPIO_FUNC
|
||||
|
||||
#endif /* __BOARDS_ARM_HC32_HC32F4A0_INCLUDE_BOARD_H */
|
||||
|
|
|
@ -41,7 +41,7 @@ USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
|
|||
|
||||
# Source files
|
||||
|
||||
CSRCS = stm32_userspace.c
|
||||
CSRCS = hc32_userspace.c
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
OBJS = $(COBJS)
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
# error "CONFIG_NUTTX_USERSPACE not defined"
|
||||
#endif
|
||||
|
||||
#if CONFIG_NUTTX_USERSPACE != 0x20060000
|
||||
#if CONFIG_NUTTX_USERSPACE != 0x20062000
|
||||
# error "CONFIG_NUTTX_USERSPACE must be 0x20060000 to match memory.ld"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* boards/arm/stm32/aiit-arm32-board/scripts/gnu-elf.ld
|
||||
* boards/arm/hc32/hc32f4a0/scripts/gnu-elf.ld
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld
|
||||
* boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
* For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of
|
||||
* FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which
|
||||
* should fit into 64KB and, of course, can be optimized as needed (See
|
||||
* also boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld). Allowing the
|
||||
* also boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld). Allowing the
|
||||
* additional does permit addition debug instrumentation to be added to the
|
||||
* kernel space without overflowing the partition.
|
||||
*
|
||||
|
@ -73,13 +73,13 @@ MEMORY
|
|||
{
|
||||
/* 2Mb FLASH */
|
||||
|
||||
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 2M
|
||||
uflash (rx) : ORIGIN = 0x00200000, LENGTH = 128K
|
||||
xflash (rx) : ORIGIN = 0x00220000, LENGTH = 768K
|
||||
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||
uflash (rx) : ORIGIN = 0x00010000, LENGTH = 1M
|
||||
xflash (rx) : ORIGIN = 0x00110000, LENGTH = 128K
|
||||
|
||||
/* 512Kb of contiguous SRAM */
|
||||
|
||||
ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 512K
|
||||
usram (rwx) : ORIGIN = 0x20060000, LENGTH = 4K
|
||||
xsram (rwx) : ORIGIN = 0x20062000, LENGTH = 4K
|
||||
ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 64K
|
||||
usram (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 448K
|
||||
xsram (rwx) : ORIGIN = 0x20070000, LENGTH = 4K
|
||||
}
|
||||
|
|
|
@ -48,16 +48,16 @@ SECTIONS
|
|||
_sinit = ABSOLUTE(.);
|
||||
*(.init_array .init_array.*)
|
||||
_einit = ABSOLUTE(.);
|
||||
} > kflash
|
||||
} > uflash
|
||||
|
||||
.ARM.extab : {
|
||||
*(.ARM.extab*)
|
||||
} > kflash
|
||||
} > uflash
|
||||
|
||||
__exidx_start = ABSOLUTE(.);
|
||||
.ARM.exidx : {
|
||||
*(.ARM.exidx*)
|
||||
} > kflash
|
||||
} > uflash
|
||||
|
||||
__exidx_end = ABSOLUTE(.);
|
||||
|
||||
|
@ -70,7 +70,7 @@ SECTIONS
|
|||
CONSTRUCTORS
|
||||
. = ALIGN(4);
|
||||
_edata = ABSOLUTE(.);
|
||||
} > ksram AT > kflash
|
||||
} > usram AT > uflash
|
||||
|
||||
.bss : {
|
||||
_sbss = ABSOLUTE(.);
|
||||
|
@ -79,7 +79,7 @@ SECTIONS
|
|||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = ABSOLUTE(.);
|
||||
} > ksram
|
||||
} > usram
|
||||
|
||||
/* Stabs debugging sections */
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@ ifeq ($(CONFIG_ARCH_LEDS),y)
|
|||
CSRCS +=
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_STM32_ROMFS),y)
|
||||
CSRCS += hc32_romfs_initialize.c
|
||||
endif
|
||||
|
||||
DEPPATH += --dep-path board
|
||||
VPATH += :board
|
||||
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
****************************************************************************/
|
||||
|
||||
extern int hc32_bringup(void);
|
||||
extern int hc32_spidev_initialized;
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hc32_boardinitialize
|
||||
|
@ -52,57 +53,57 @@ extern int hc32_bringup(void);
|
|||
|
||||
void hc32_boardinitialize(void)
|
||||
{
|
||||
//#ifdef CONFIG_SCHED_CRITMONITOR
|
||||
// /* Enable ITM and DWT resources, if not left enabled by debugger. */
|
||||
//
|
||||
// modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA);
|
||||
//
|
||||
// /* Make sure the high speed cycle counter is running. It will be started
|
||||
// * automatically only if a debugger is connected.
|
||||
// */
|
||||
//
|
||||
// putreg32(0xc5acce55, ITM_LAR);
|
||||
// modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK);
|
||||
//#endif
|
||||
//
|
||||
//#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3)
|
||||
// /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak
|
||||
// * function hc32_spidev_initialize() has been brought into the link.
|
||||
// */
|
||||
//
|
||||
// if (hc32_spidev_initialize)
|
||||
// {
|
||||
// hc32_spidev_initialize();
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
//#ifdef CONFIG_HC32_OTGFS
|
||||
// /* Initialize USB if the 1) OTG FS controller is in the configuration and
|
||||
// * 2) disabled, and 3) the weak function hc32_usbinitialize() has been
|
||||
// * brought into the build. Presumably either CONFIG_USBDEV or
|
||||
// * CONFIG_USBHOST is also selected.
|
||||
// */
|
||||
//
|
||||
// if (hc32_usbinitialize)
|
||||
// {
|
||||
// hc32_usbinitialize();
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
//#ifdef HAVE_NETMONITOR
|
||||
// /* Configure board resources to support networking. */
|
||||
//
|
||||
// if (hc32_netinitialize)
|
||||
// {
|
||||
// hc32_netinitialize();
|
||||
// }
|
||||
//#endif
|
||||
//
|
||||
//#ifdef CONFIG_ARCH_LEDS
|
||||
// /* Configure on-board LEDs if LED support has been selected. */
|
||||
//
|
||||
// board_autoled_initialize();
|
||||
//#endif
|
||||
#ifdef CONFIG_SCHED_CRITMONITOR
|
||||
/* Enable ITM and DWT resources, if not left enabled by debugger. */
|
||||
|
||||
modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA);
|
||||
|
||||
/* Make sure the high speed cycle counter is running. It will be started
|
||||
* automatically only if a debugger is connected.
|
||||
*/
|
||||
|
||||
putreg32(0xc5acce55, ITM_LAR);
|
||||
modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3)
|
||||
/* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak
|
||||
* function hc32_spidev_initialize() has been brought into the link.
|
||||
*/
|
||||
|
||||
if (hc32_spidev_initialized)
|
||||
{
|
||||
hc32_spidev_initialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HC32_OTGFS
|
||||
/* Initialize USB if the 1) OTG FS controller is in the configuration and
|
||||
* 2) disabled, and 3) the weak function hc32_usbinitialize() has been
|
||||
* brought into the build. Presumably either CONFIG_USBDEV or
|
||||
* CONFIG_USBHOST is also selected.
|
||||
*/
|
||||
|
||||
if (hc32_usbinitialize)
|
||||
{
|
||||
hc32_usbinitialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETMONITOR
|
||||
/* Configure board resources to support networking. */
|
||||
|
||||
if (hc32_netinitialize)
|
||||
{
|
||||
hc32_netinitialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_LEDS
|
||||
/* Configure on-board LEDs if LED support has been selected. */
|
||||
|
||||
board_autoled_initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include <hc32_common.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hc32_bringup
|
||||
*
|
||||
|
@ -48,6 +50,27 @@
|
|||
int hc32_bringup(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CONFIG_FS_PROCFS
|
||||
/* Mount the procfs file system */
|
||||
|
||||
ret = nx_mount(NULL, HC32_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to mount procfs at %s: %d\n",
|
||||
HC32_PROCFS_MOUNTPOINT, ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HC32_ROMFS
|
||||
ret = hc32_romfs_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
serr("ERROR: Failed to mount romfs at %s: %d\n",
|
||||
CONFIG_HC32_ROMFS_MOUNTPOINT, ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("start %s\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/****************************************************************************
|
||||
* boards/arm/hc32/hc32f4a0/src/hc32_romfs.h
|
||||
*
|
||||
* Copyright (C) 2017 Tomasz Wozniak. All rights reserved.
|
||||
* Author: Tomasz Wozniak <t.wozniak@samsung.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H
|
||||
#define __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifdef CONFIG_HC32_ROMFS
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ROMFS_SECTOR_SIZE 64
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_romfs_initialize
|
||||
*
|
||||
* Description:
|
||||
* Registers built-in ROMFS image as block device and mounts it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success, a negated errno value on error.
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain
|
||||
* ROMFS volume data, as included in the assembly snippet above (l. 84).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hc32_romfs_initialize(void);
|
||||
|
||||
#endif /* CONFIG_STM32_ROMFS */
|
||||
|
||||
#endif /* __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H */
|
|
@ -0,0 +1,158 @@
|
|||
/****************************************************************************
|
||||
* boards/arm/hc32/hc32f4a0/src/hc32_romfs_initialize.c
|
||||
* This file provides contents of an optional ROMFS volume, mounted at boot.
|
||||
*
|
||||
* Copyright (C) 2017 Tomasz Wozniak. All rights reserved.
|
||||
* Author: Tomasz Wozniak <t.wozniak@samsung.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/drivers/ramdisk.h>
|
||||
#include "hc32_romfs.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_HC32_ROMFS
|
||||
# error "CONFIG_HC32_ROMFS must be defined"
|
||||
#else
|
||||
|
||||
#ifndef CONFIG_HC32_ROMFS_IMAGEFILE
|
||||
# error "CONFIG_HC32_ROMFS_IMAGEFILE must be defined"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_HC32_ROMFS_DEV_MINOR
|
||||
# error "CONFIG_HC32_ROMFS_DEV_MINOR must be defined"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_HC32_ROMFS_MOUNTPOINT
|
||||
# error "CONFIG_HC32_ROMFS_MOUNTPOINT must be defined"
|
||||
#endif
|
||||
|
||||
#define NSECTORS(size) (((size) + ROMFS_SECTOR_SIZE - 1)/ROMFS_SECTOR_SIZE)
|
||||
|
||||
#define STR2(m) #m
|
||||
#define STR(m) STR2(m)
|
||||
|
||||
#define MKMOUNT_DEVNAME(m) "/dev/ram" STR(m)
|
||||
#define MOUNT_DEVNAME MKMOUNT_DEVNAME(CONFIG_HC32_ROMFS_DEV_MINOR)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
__asm__ (
|
||||
".section .rodata\n"
|
||||
".balign 16\n"
|
||||
".globl romfs_data_begin\n"
|
||||
"romfs_data_begin:\n"
|
||||
".incbin " STR(CONFIG_HC32_ROMFS_IMAGEFILE) "\n"\
|
||||
\
|
||||
".balign " STR(ROMFS_SECTOR_SIZE) "\n"
|
||||
".globl romfs_data_end\n"
|
||||
"romfs_data_end:\n"
|
||||
".globl romfs_data_size\n"
|
||||
"romfs_data_size:\n"
|
||||
".word romfs_data_end - romfs_data_begin\n"
|
||||
".previous\n");
|
||||
|
||||
extern const char romfs_data_begin;
|
||||
extern const char romfs_data_end;
|
||||
extern const int romfs_data_size;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hc32_romfs_initialize
|
||||
*
|
||||
* Description:
|
||||
* Registers the aboveincluded binary file as block device.
|
||||
* Then mounts the block device as ROMFS filesystems.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success, a negated errno value on error.
|
||||
*
|
||||
* Assumptions/Limitations:
|
||||
* Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain
|
||||
* ROMFS volume data, as included in the assembly snippet above (l. 84).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int hc32_romfs_initialize(void)
|
||||
{
|
||||
uintptr_t romfs_data_len;
|
||||
int ret;
|
||||
|
||||
/* Create a ROM disk for the /etc filesystem */
|
||||
|
||||
romfs_data_len = (uintptr_t)&romfs_data_end - (uintptr_t)&romfs_data_begin;
|
||||
|
||||
ret = romdisk_register(CONFIG_HC32_ROMFS_DEV_MINOR, &romfs_data_begin,
|
||||
NSECTORS(romfs_data_len), ROMFS_SECTOR_SIZE);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: romdisk_register failed: %d\n", -ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Mount the file system */
|
||||
|
||||
finfo("Mounting ROMFS filesystem at target=%s with source=%s\n",
|
||||
CONFIG_HC32_ROMFS_MOUNTPOINT, MOUNT_DEVNAME);
|
||||
|
||||
ret = nx_mount(MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT,
|
||||
"romfs", MS_RDONLY, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: nx_mount(%s,%s,romfs) failed: %d\n",
|
||||
MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_HC32_ROMFS */
|
|
@ -8,8 +8,8 @@ if ARCH_BOARD_XIDATONG_RISCV64
|
|||
menuconfig BSP_USING_CH376
|
||||
bool "Using CH376 device"
|
||||
default n
|
||||
select K210_16550_UART
|
||||
select K210_16550_UART3
|
||||
select K210_UART
|
||||
select K210_UART3
|
||||
|
||||
if BSP_USING_CH376
|
||||
|
||||
|
@ -40,8 +40,8 @@ menuconfig BSP_USING_TOUCH
|
|||
default n
|
||||
|
||||
menuconfig BSP_USING_CAN
|
||||
select K210_16550_UART
|
||||
select K210_16550_UART1
|
||||
select K210_UART
|
||||
select K210_UART1
|
||||
bool "Using CAN device"
|
||||
default n
|
||||
|
||||
|
|
|
@ -58,17 +58,17 @@ CONFIG_READLINE_TABCOMPLETION=y
|
|||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_DEV_GPIO=y
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_K210_16550_UART=y
|
||||
CONFIG_K210_16550_UART2=y
|
||||
CONFIG_K210_16550_UART2_BASE=0x50220000
|
||||
CONFIG_K210_16550_UART2_CLOCK=195000000
|
||||
CONFIG_K210_16550_UART2_IRQ=39
|
||||
CONFIG_K210_16550_UART2_BAUD=115200
|
||||
CONFIG_K210_16550_UART2_PARITY=0
|
||||
CONFIG_K210_16550_UART2_BITS=8
|
||||
CONFIG_K210_16550_UART2_2STOP=0
|
||||
CONFIG_K210_16550_UART2_RXBUFSIZE=128
|
||||
CONFIG_K210_16550_UART2_TXBUFSIZE=128
|
||||
CONFIG_K210_UART=y
|
||||
CONFIG_K210_UART2=y
|
||||
CONFIG_K210_UART2_BASE=0x50220000
|
||||
CONFIG_K210_UART2_CLOCK=195000000
|
||||
CONFIG_K210_UART2_IRQ=39
|
||||
CONFIG_K210_UART2_BAUD=115200
|
||||
CONFIG_K210_UART2_PARITY=0
|
||||
CONFIG_K210_UART2_BITS=8
|
||||
CONFIG_K210_UART2_2STOP=0
|
||||
CONFIG_K210_UART2_RXBUFSIZE=128
|
||||
CONFIG_K210_UART2_TXBUFSIZE=128
|
||||
CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y
|
||||
CONFIG_CONNECTION_FRAMEWORK_DEBUG=y
|
||||
CONFIG_CONNECTION_ADAPTER_4G=y
|
||||
|
|
|
@ -58,16 +58,16 @@ CONFIG_READLINE_TABCOMPLETION=y
|
|||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_DEV_GPIO=y
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_K210_16550_UART=y
|
||||
CONFIG_K210_16550_UART1=y
|
||||
CONFIG_K210_16550_UART1_BASE=0x50210000
|
||||
CONFIG_K210_16550_UART1_CLOCK=195000000
|
||||
CONFIG_K210_16550_UART1_IRQ=38
|
||||
CONFIG_K210_16550_UART1_BAUD=115200
|
||||
CONFIG_K210_16550_UART1_PARITY=0
|
||||
CONFIG_K210_16550_UART1_BITS=8
|
||||
CONFIG_K210_16550_UART1_2STOP=0
|
||||
CONFIG_K210_16550_UART1_RXBUFSIZE=128
|
||||
CONFIG_K210_16550_UART1_TXBUFSIZE=128
|
||||
CONFIG_K210_UART=y
|
||||
CONFIG_K210_UART1=y
|
||||
CONFIG_K210_UART1_BASE=0x50210000
|
||||
CONFIG_K210_UART1_CLOCK=195000000
|
||||
CONFIG_K210_UART1_IRQ=38
|
||||
CONFIG_K210_UART1_BAUD=115200
|
||||
CONFIG_K210_UART1_PARITY=0
|
||||
CONFIG_K210_UART1_BITS=8
|
||||
CONFIG_K210_UART1_2STOP=0
|
||||
CONFIG_K210_UART1_RXBUFSIZE=128
|
||||
CONFIG_K210_UART1_TXBUFSIZE=128
|
||||
CONFIG_BSP_USING_CAN=y
|
||||
CONFIG_SERIAL_TERMIOS=y
|
||||
|
|
|
@ -58,6 +58,6 @@ CONFIG_READLINE_TABCOMPLETION=y
|
|||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_DEV_GPIO=y
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_K210_16550_UART=y
|
||||
CONFIG_K210_16550_UART3=y
|
||||
CONFIG_K210_UART=y
|
||||
CONFIG_K210_UART3=y
|
||||
CONFIG_BSP_USING_TOUCH=y
|
||||
|
|
|
@ -58,17 +58,17 @@ CONFIG_READLINE_TABCOMPLETION=y
|
|||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_DEV_GPIO=y
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_K210_16550_UART=y
|
||||
CONFIG_K210_16550_UART1=y
|
||||
CONFIG_K210_16550_UART1_BASE=0x50210000
|
||||
CONFIG_K210_16550_UART1_CLOCK=195000000
|
||||
CONFIG_K210_16550_UART1_IRQ=38
|
||||
CONFIG_K210_16550_UART1_BAUD=115200
|
||||
CONFIG_K210_16550_UART1_PARITY=0
|
||||
CONFIG_K210_16550_UART1_BITS=8
|
||||
CONFIG_K210_16550_UART1_2STOP=0
|
||||
CONFIG_K210_16550_UART1_RXBUFSIZE=128
|
||||
CONFIG_K210_16550_UART1_TXBUFSIZE=128
|
||||
CONFIG_K210_UART=y
|
||||
CONFIG_K210_UART1=y
|
||||
CONFIG_K210_UART1_BASE=0x50210000
|
||||
CONFIG_K210_UART1_CLOCK=195000000
|
||||
CONFIG_K210_UART1_IRQ=38
|
||||
CONFIG_K210_UART1_BAUD=115200
|
||||
CONFIG_K210_UART1_PARITY=0
|
||||
CONFIG_K210_UART1_BITS=8
|
||||
CONFIG_K210_UART1_2STOP=0
|
||||
CONFIG_K210_UART1_RXBUFSIZE=128
|
||||
CONFIG_K210_UART1_TXBUFSIZE=128
|
||||
CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y
|
||||
CONFIG_CONNECTION_FRAMEWORK_DEBUG=y
|
||||
CONFIG_CONNECTION_ADAPTER_WIFI=y
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
#include "k210_uart_16550.h"
|
||||
#include "k210_uart.h"
|
||||
#include "k210_fpioa.h"
|
||||
#include "k210_gpiohs.h"
|
||||
#include "k210_gpio_common.h"
|
||||
|
|
|
@ -95,7 +95,7 @@ int k210_bringup(void)
|
|||
board_touch_initialize();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_K210_16550_UART1
|
||||
#ifdef CONFIG_K210_UART1
|
||||
#ifdef CONFIG_ADAPTER_ESP8285_WIFI
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_UART1);
|
||||
sysctl_reset(SYSCTL_RESET_UART1);
|
||||
|
@ -121,7 +121,7 @@ int k210_bringup(void)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_K210_16550_UART2
|
||||
#ifdef CONFIG_K210_UART2
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_UART2);
|
||||
sysctl_reset(SYSCTL_RESET_UART2);
|
||||
|
||||
|
@ -129,7 +129,7 @@ int k210_bringup(void)
|
|||
fpioa_set_function(GPIO_EC200T_TXD, FPOA_USART2_TX);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_K210_16550_UART3
|
||||
#ifdef CONFIG_K210_UART3
|
||||
sysctl_clock_enable(SYSCTL_CLOCK_UART3);
|
||||
sysctl_reset(SYSCTL_RESET_UART3);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <nuttx/ioexpander/gpio.h>
|
||||
#include "k210_uart_16550.h"
|
||||
#include "k210_uart.h"
|
||||
|
||||
#define ERR_USB_UNKNOWN 0xFA
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ cp -rf $current/apps $nuttx
|
|||
cp -rf $nuttx/aiit_board/aiit-arm32-board $nuttx/nuttx/boards/arm/stm32
|
||||
cp -rf $nuttx/aiit_board/aiit-riscv64-board $nuttx/nuttx/boards/risc-v/k210
|
||||
cp -rf $nuttx/aiit_board/xidatong-riscv64 $nuttx/nuttx/boards/risc-v/k210
|
||||
cp -rf $nuttx/aiit_board/edu-riscv64 $nuttx/nuttx/boards/risc-v/k210
|
||||
cp -rf $nuttx/aiit_board/xidatong-arm32 $nuttx/nuttx/boards/arm/imxrt
|
||||
cp -rf $nuttx/aiit_board/hc32f4a0 $nuttx/nuttx/boards/arm/hc32
|
||||
|
||||
|
|
|
@ -172,3 +172,26 @@ config HC32_UART8
|
|||
|
||||
endmenu # HC32 U[S]ART Selection
|
||||
|
||||
config HC32_SPI1
|
||||
bool "SPI1"
|
||||
default n
|
||||
select SPI
|
||||
select HC32_SPI
|
||||
|
||||
config HC32_SPI2
|
||||
bool "SPI2"
|
||||
default n
|
||||
depends on HC32_HAVE_SPI2
|
||||
select SPI
|
||||
select HC32_SPI
|
||||
|
||||
|
||||
config HC32_SPI
|
||||
bool
|
||||
|
||||
config HC32_I2C
|
||||
bool
|
||||
|
||||
config HC32_CAN
|
||||
bool
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ CMN_ASRCS += arm_lazyexception.S
|
|||
else
|
||||
CMN_ASRCS += arm_exception.S
|
||||
endif
|
||||
CMN_CSRCS += arm_vectors.c
|
||||
|
||||
ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
|
||||
CMN_CSRCS += arm_ramvec_initialize.c arm_ramvec_attach.c
|
||||
|
@ -77,12 +76,19 @@ ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
|
|||
CMN_CSRCS += arm_tls.c
|
||||
endif
|
||||
|
||||
CMN_CSRCS += hc32_vectors.c
|
||||
|
||||
CHIP_CSRCS = hc32_allocateheap.c hc32_gpio.c
|
||||
CHIP_CSRCS += hc32_irq.c hc32_idle.c hc32_mpuinit.c
|
||||
CHIP_CSRCS += hc32_rcc.c hc32_start.c hc32_serial.c
|
||||
CHIP_CSRCS += hc32_pm.c hc32_timerisr.c hc32_lowputc.c
|
||||
CHIP_CSRCS += hc32_console.c
|
||||
|
||||
CHIP_CSRCS += hc32f4a0_clk.c hc32f4a0_efm.c hc32f4a0_gpio.c
|
||||
CHIP_CSRCS += hc32f4a0_interrupts.c hc32f4a0_usart.c hc32f4a0_utility.c
|
||||
CHIP_CSRCS += hc32f4a0_sram.c hc32f4a0_pwc.c
|
||||
|
||||
CHIP_CSRCS += hc32f4a0_spi.c
|
||||
|
||||
CHIP_CSRCS += hc32_spiflash.c hc32_spi.c
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ extern "C"
|
|||
#define DDL_RTC_ENABLE (DDL_OFF)
|
||||
#define DDL_SDIOC_ENABLE (DDL_OFF)
|
||||
#define DDL_SMC_ENABLE (DDL_OFF)
|
||||
#define DDL_SPI_ENABLE (DDL_OFF)
|
||||
#define DDL_SPI_ENABLE (DDL_ON)
|
||||
#define DDL_SRAM_ENABLE (DDL_ON)
|
||||
#define DDL_SWDT_ENABLE (DDL_OFF)
|
||||
#define DDL_TMR0_ENABLE (DDL_OFF)
|
||||
|
@ -134,7 +134,7 @@ extern "C"
|
|||
#define BSP_OV5640_ENABLE (BSP_OFF)
|
||||
#define BSP_S29GL064N90TFI03_ENABLE (BSP_OFF)
|
||||
#define BSP_TCA9539_ENABLE (BSP_OFF)
|
||||
#define BSP_W25QXX_ENABLE (BSP_ON)
|
||||
#define BSP_W25QXX_ENABLE (BSP_OFF)
|
||||
#define BSP_WM8731_ENABLE (BSP_OFF)
|
||||
|
||||
/**
|
||||
|
|
|
@ -83,20 +83,20 @@
|
|||
|
||||
/* The HC32 F4A0 have no CCM SRAM */
|
||||
|
||||
# if defined(CONFIG_HC32_HC32F4A0)
|
||||
# if defined(CONFIG_HC32_HC32F4A0)
|
||||
# undef CONFIG_HC32_CCMEXCLUDE
|
||||
# define CONFIG_HC32_CCMEXCLUDE 1
|
||||
# endif
|
||||
|
||||
/* Set the end of system SRAM */
|
||||
|
||||
#define SRAM1_END 0x20073880
|
||||
#define SRAM1_END 0x1FFF0000
|
||||
|
||||
|
||||
/* Set the range of CCM SRAM as well (although we may not use it) */
|
||||
|
||||
#define SRAM2_START 0x1FE00000
|
||||
#define SRAM2_END 0x20073880
|
||||
#define SRAM2_START 0x1FFF0000
|
||||
#define SRAM2_END 0x20070000
|
||||
|
||||
|
||||
/* There are 4 possible SRAM configurations:
|
||||
|
|
|
@ -37,6 +37,15 @@ extern "C"
|
|||
#define HC32F4A0 1
|
||||
#define USE_DDL_DRIVER 1
|
||||
|
||||
#ifdef CONFIG_FS_PROCFS
|
||||
# ifdef CONFIG_NSH_PROC_MOUNTPOINT
|
||||
# define HC32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT
|
||||
# else
|
||||
# define HC32_PROCFS_MOUNTPOINT "/proc"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#define getreg32(a) (*(volatile uint32_t *)(a))
|
||||
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
|
||||
#define getreg16(a) (*(volatile uint16_t *)(a))
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include "chip.h"
|
||||
#include "hc32_uart.h"
|
||||
#include "hc32_spi.h"
|
||||
|
||||
void hc32_test_console(void)
|
||||
{
|
||||
char *dev_str = "/dev/console";
|
||||
char *test_chr = "test";
|
||||
int fd = 0, ret;
|
||||
|
||||
fd = open(dev_str, 0x6);
|
||||
hc32_print("%s: open <%s> ret = %d\n", __func__, dev_str, fd);
|
||||
ret = write(fd, test_chr, strlen(test_chr));
|
||||
hc32_print("%s: open %d ret %d\n", __func__, fd, ret);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void hc32_console_handle(char *buf)
|
||||
{
|
||||
if(strncmp(buf, "console", 7) == 0)
|
||||
{
|
||||
hc32_test_console();
|
||||
}
|
||||
else if(strncmp(buf, "spi", 7) == 0)
|
||||
{
|
||||
hc32_print("start flash test ...\n");
|
||||
hc32_spiflash_test();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef __HC32_CONSOLE_H_
|
||||
#define __HC32_CONSOLE_H_
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.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/fs/ioctl.h>
|
||||
#include <nuttx/serial/serial.h>
|
||||
#include <nuttx/power/pm.h>
|
||||
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include "chip.h"
|
||||
#include "hc32_uart.h"
|
||||
#include "hc32_rcc.h"
|
||||
#include "hc32_gpio.h"
|
||||
#include "arm_internal.h"
|
||||
#include "hc32f4a0.h"
|
||||
#include "hc32f4a0_usart.h"
|
||||
#include "hc32f4a0_gpio.h"
|
||||
#include "hc32f4a0_interrupts.h"
|
||||
#include "hc32f4a0_sram.h"
|
||||
#include "hc32f4a0_pwc.h"
|
||||
#include "hc32f4a0_efm.h"
|
||||
|
||||
void hc32_console_handle(char *buf);
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue