Merge branch 'prepare_for_master' of https://gitlink.org.cn/xuos/xiuos into prepare_for_master
|  | @ -1,3 +1,3 @@ | ||||||
| SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje inovance keyence ab abb | SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje inovance keyence panasonic fatek ab abb | ||||||
| 
 | 
 | ||||||
| include $(KERNEL_ROOT)/compiler.mk | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  |  | ||||||
| After Width: | Height: | Size: 3.0 MiB | 
|  | @ -1,22 +1,48 @@ | ||||||
| # 台达 DVP通信测试 | # 台达 PLC与矽达通ARM通信测试 | ||||||
| 
 | 
 | ||||||
| [TOC] | [TOC] | ||||||
| 
 | 
 | ||||||
| ## 通信接线及参数设置 | ## 台达DVP与矽达通ARM通信处测试 | ||||||
|  | 
 | ||||||
|  | ### 通信接线及参数设置 | ||||||
| 
 | 
 | ||||||
| * 网口 | * 网口 | ||||||
|   * 通过自带 RJ45 网口连接 |   * 通过自带 RJ45 网口连接 | ||||||
|   * 网口参数:IP:192.168.250.27  Port:502 |   * 网口参数:IP:192.168.250.27  Port:502 | ||||||
|   * 测试的协议:Modbus TCP |   * 测试的协议:Modbus TCP | ||||||
| 
 | 
 | ||||||
| ## 存储区 | ### 存储区 | ||||||
| 
 | 
 | ||||||
| - 含M,D,X,Y。台达PLC中 各存储区地址和Modbus地址有明确的对应表,详见台达DVP协议解析测试文档。 | - 含M,D,X,Y。台达PLC中 各存储区地址和Modbus地址有明确的对应表,详见台达DVP协议解析测试文档。 | ||||||
| 
 | 
 | ||||||
| ## 通信测试 | ### 通信测试 | ||||||
| 
 | 
 | ||||||
| -  共测试BOOL,INT16,INT32,FLOAT 共四种类型数据。 | -  共测试BOOL,INT16,INT32,FLOAT 共四种类型数据。 | ||||||
| -  测试D区,M区和Y区。 | -  测试D区,M区和Y区。 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | ## 台达AS332T与矽达通ARM通信处测试 | ||||||
|  | 
 | ||||||
|  | ### 通信接线及参数设置 | ||||||
|  | 
 | ||||||
|  | * 网口 | ||||||
|  |   * 通过自带 RJ45 网口连接 | ||||||
|  |   * 网口参数:IP:192.168.250.5  Port:502 | ||||||
|  |   * 测试的协议:Modbus TCP | ||||||
|  | 
 | ||||||
|  | ### 存储区 | ||||||
|  | 
 | ||||||
|  | - 含M,D,X,Y。台达PLC中 各存储区地址和Modbus地址有明确的对应表,详见台达AS332T协议解析测试文档。 | ||||||
|  | 
 | ||||||
|  | ### 通信测试结果 | ||||||
|  | 
 | ||||||
|  | -  共测试BOOL,INT16,INT32,FLOAT 共四种类型数据。 | ||||||
|  | -  测试D区,M区和Y区。 | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| /*
 | /*
 | ||||||
|  |  * Copyright (c) 2022 AIIT XUOS Lab | ||||||
|  |  /*
 | ||||||
|  * Copyright (c) 2022 AIIT XUOS Lab |  * Copyright (c) 2022 AIIT XUOS Lab | ||||||
|  * XiUOS is licensed under Mulan PSL v2. |  * XiUOS is licensed under Mulan PSL v2. | ||||||
|  * You can use this software according to the terms and conditions of the Mulan PSL v2. |  * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||||||
|  | @ -15,9 +17,53 @@ | ||||||
|  * @brief PLC DELTA AS332T app |  * @brief PLC DELTA AS332T app | ||||||
|  * @version 3.0 |  * @version 3.0 | ||||||
|  * @author AIIT XUOS Lab |  * @author AIIT XUOS Lab | ||||||
|  * @date 2022.9.27 |  * @date 2022.10.10 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <control.h> | ||||||
|  | 
 | ||||||
|  | extern int Adapter4GActive(void); | ||||||
|  | 
 | ||||||
|  | void ControlDeltaas332tTest(void) | ||||||
|  | { | ||||||
|  |     int i, j = 0; | ||||||
|  |     int read_data_length = 0; | ||||||
|  |     uint8_t read_data[128] = {0}; | ||||||
|  | 
 | ||||||
|  | #ifdef CONNECTION_ADAPTER_4G | ||||||
|  |     Adapter4GActive(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ControlProtocolType modbus_tcp_protocol = ControlProtocolFind(); | ||||||
|  |     if (NULL == modbus_tcp_protocol) { | ||||||
|  |         printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol); | ||||||
|  | 
 | ||||||
|  |     if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) { | ||||||
|  |         ControlProtocolOpen(modbus_tcp_protocol); | ||||||
|  | 
 | ||||||
|  |         for (;;) { | ||||||
|  |             read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data)); | ||||||
|  |             printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length); | ||||||
|  |             if (read_data_length) { | ||||||
|  |                 for (j = 0; j < read_data_length; j ++) { | ||||||
|  |                     printf("j %d data 0x%x\n", j, read_data[j]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             i++; | ||||||
|  |             memset(read_data, 0, sizeof(read_data)); | ||||||
|  |             PrivTaskDelay(10000); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //ControlProtocolClose(modbus_tcp_protocol);
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(ControlDeltaas332tTest, Delta as332t Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
| After Width: | Height: | Size: 123 KiB | 
| After Width: | Height: | Size: 171 KiB | 
| After Width: | Height: | Size: 6.8 KiB | 
| After Width: | Height: | Size: 22 KiB | 
| After Width: | Height: | Size: 14 KiB | 
|  | @ -0,0 +1,79 @@ | ||||||
|  | { | ||||||
|  |     "device_id": 1, | ||||||
|  |     "device_name": "DELTA_AS332T_TCP", | ||||||
|  |     "communication_type": 0, | ||||||
|  |     "socket_config": { | ||||||
|  |         "plc_ip": "192.168.250.5", | ||||||
|  |         "local_ip": "192.168.250.233", | ||||||
|  |         "gateway": "192.168.250.1", | ||||||
|  |         "netmask": "255.255.254.0", | ||||||
|  |         "port": 502 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 2, | ||||||
|  |     "read_period": 1000, | ||||||
|  |   "read_item_list": [ | ||||||
|  |     { | ||||||
|  |       "value_name": "M16", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "function_code": 1, | ||||||
|  |       "start_address": 16, | ||||||
|  |       "quantity": 1 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "M17", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "function_code": 1, | ||||||
|  |       "start_address": 17, | ||||||
|  |       "quantity": 1 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "M18", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "function_code": 1, | ||||||
|  |       "start_address": 30, | ||||||
|  |       "quantity": 1 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D300", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "function_code": 3, | ||||||
|  |       "start_address": 300, | ||||||
|  |       "quantity": 1 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D301", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "function_code": 3, | ||||||
|  |       "start_address": 302, | ||||||
|  |       "quantity": 1 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D302", | ||||||
|  |       "value_type": 4, | ||||||
|  |       "function_code": 3, | ||||||
|  |       "start_address": 302, | ||||||
|  |       "quantity": 2 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D304", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "function_code": 3, | ||||||
|  |       "start_address": 304, | ||||||
|  |       "quantity": 2 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y1.0", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "function_code": 1, | ||||||
|  |       "start_address": 40976, | ||||||
|  |       "quantity": 1 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y10", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "function_code": 3, | ||||||
|  |       "start_address": 40970, | ||||||
|  |       "quantity": 1 | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES := fatek_fbs_24mc_uart.c | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,42 @@ | ||||||
|  | # 永宏通信测试 | ||||||
|  | 
 | ||||||
|  | [TOC] | ||||||
|  | 
 | ||||||
|  | ## 永宏FBs-24MCT2-AC通信测试 | ||||||
|  | 
 | ||||||
|  | ### 通信接线及参数设置 | ||||||
|  | 
 | ||||||
|  | * 网口和串口 | ||||||
|  |   * FBS-24MCT2自带圆口232,用于程序的下载。 | ||||||
|  |   * 可本体拓展FBs-CBES用于Modbus TCP,永宏私有协议永宏协议等通信。板卡默认IP:192.168.2.3.端口号500,永宏协议 | ||||||
|  |   * 通过本体拓展FBs-CM22通信模板,可用于Modbus RTU及永宏协议通信。串口接线:+接485A;-接485B。 | ||||||
|  |   * 串口模块MODBUS RTU通信参数配置:通信速率:9600;数据位:8bit;停止位:1bit;校验:偶校验 | ||||||
|  |   * 串口模块永宏协议通信参数配置:通信速率:9600;数据位:8bit;停止位:1bit;校验:偶校验 | ||||||
|  |   * 终端与PLC通信测试,PC编程软件与PLC不能处于联机状态。 | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  | ### 存储区 | ||||||
|  | 
 | ||||||
|  | - 存储区 X,Y,R,D区等。 | ||||||
|  | 
 | ||||||
|  | ### 通信测试 | ||||||
|  | 
 | ||||||
|  | -  共测试BOOL,INT16等类型数据。 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -  测试Y区,R区及D区数据。 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | - 测试截图: | ||||||
|  | 
 | ||||||
|  |   测试PLC环境搭建: | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   解析完成的配方为: | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   测试结果: | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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 fatek_fbs_24mc_uart.c | ||||||
|  |  * @brief PLC fatek fbs app | ||||||
|  |  * @version 3.0 | ||||||
|  |  * @author AIIT XUOS Lab | ||||||
|  |  * @date 2023.11.28 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <control.h> | ||||||
|  | 
 | ||||||
|  | extern int Adapter4GActive(void); | ||||||
|  | 
 | ||||||
|  | void ControlFatekFBsUartTest(void) | ||||||
|  | { | ||||||
|  |     int i, j = 0; | ||||||
|  |     int read_data_length = 0; | ||||||
|  |     uint8_t read_data[128] = {0}; | ||||||
|  | 
 | ||||||
|  | #ifdef CONNECTION_ADAPTER_4G | ||||||
|  |     Adapter4GActive(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ControlProtocolType modbus_rtu_protocol = ControlProtocolFind(); | ||||||
|  |     if (NULL == modbus_rtu_protocol) { | ||||||
|  |         printf("%s get modbus rtu protocol %p failed\n", __func__, modbus_rtu_protocol); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("%s get modbus rtu protocol %p successfull\n", __func__, modbus_rtu_protocol); | ||||||
|  | 
 | ||||||
|  |     if (CONTROL_REGISTERED == modbus_rtu_protocol->protocol_status) { | ||||||
|  |         ControlProtocolOpen(modbus_rtu_protocol); | ||||||
|  | 
 | ||||||
|  |         for (;;) { | ||||||
|  |             read_data_length = ControlProtocolRead(modbus_rtu_protocol, read_data, sizeof(read_data)); | ||||||
|  |             printf("%s read [%d] modbus rtu data %d using receipe file\n", __func__, i, read_data_length); | ||||||
|  |             if (read_data_length) { | ||||||
|  |                 for (j = 0; j < read_data_length; j ++) { | ||||||
|  |                     printf("j %d data 0x%x\n", j, read_data[j]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             i++; | ||||||
|  |             memset(read_data, 0, sizeof(read_data)); | ||||||
|  |             PrivTaskDelay(10000); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //ControlProtocolClose(modbus_rtu_protocol);
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(ControlFatekFBsUartTest, fatek fbs uart Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| After Width: | Height: | Size: 172 KiB | 
|  | @ -0,0 +1,37 @@ | ||||||
|  | { | ||||||
|  |      "device_id": 1, | ||||||
|  |     "device_name": "FATEK_FBSMC24T_RTU", | ||||||
|  |     "communication_type": 1, | ||||||
|  |     "serial_config": { | ||||||
|  |         "station": 1, | ||||||
|  |         "baud_rate": 9600, | ||||||
|  |         "data_bits": 8, | ||||||
|  |         "stop_bits": 1, | ||||||
|  |         "check_mode":3 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 3, | ||||||
|  |     "read_period": 2000, | ||||||
|  |     "read_item_list": [ | ||||||
|  |         { | ||||||
|  |             "value_name": "Y0", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address": 0, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "D0", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 6000, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "R10", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 10, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }           | ||||||
|  |     ] | ||||||
|  | } | ||||||
| After Width: | Height: | Size: 2.1 MiB | 
| After Width: | Height: | Size: 3.1 MiB | 
| After Width: | Height: | Size: 200 KiB | 
|  | @ -1,3 +1,3 @@ | ||||||
| SRC_FILES := mitsubishi_fx3u.c mitsubishi_fx5u.c mitsubishi_fx2n.c mitsubishi_q02u.c | SRC_FILES := mitsubishi_fx3u.c mitsubishi_fx5u.c mitsubishi_fx2n.c mitsubishi_q02u.c mitsubishi_q06h.c mitsubishi_q03udv.c | ||||||
| 
 | 
 | ||||||
| include $(KERNEL_ROOT)/compiler.mk | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  |  | ||||||
|  | @ -1,24 +1,88 @@ | ||||||
| # 三菱 FX2N通信测试 | # 三菱通信测试 | ||||||
| 
 | 
 | ||||||
| [TOC] | [TOC] | ||||||
| 
 | 
 | ||||||
| ## 通信接线及参数设置 | ## 三菱FX2N通信测试 | ||||||
|  | 
 | ||||||
|  | ### 通信接线及参数设置 | ||||||
| 
 | 
 | ||||||
| * 串口 | * 串口 | ||||||
|   * FX2N自带8针圆口422,用于程序的下载。全系列不支持网口,且需购买串口拓展模块FX2N-485-BD用于通信测试。 |   * FX2N自带8针圆口422,用于程序的下载。全系列不支持网口,且需购买串口拓展模块FX2N-485-BD用于通信测试。 | ||||||
|   * 接线:RDA和SDA短接,引出A;RDB与SDB短接,引出B。 |   * 接线:RDA和SDA短接,引出A;RDB与SDB短接,引出B。 | ||||||
|   * 串口模块支持MC-1C协议,通信速率:9600;数据位:7bit;停止位:1bit;校验:偶校验 |   * 串口模块支持MC-1C协议,通信速率:9600;数据位:7bit;停止位:1bit;校验:偶校验 | ||||||
| 
 | 
 | ||||||
| ## 存储区 | ### 存储区 | ||||||
| 
 | 
 | ||||||
| - 存储区 I,Q,M,D区。 | - 存储区 I,Q,M,D区。 | ||||||
| 
 | 
 | ||||||
| ## 通信测试 | ### 通信测试 | ||||||
| 
 | 
 | ||||||
| -  共测试BOOL,INT16,FLOAT共三种类型数据。 | -  共测试BOOL,INT16,FLOAT共三种类型数据。 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| -  测试M区及D区数据。 | -  测试M区及D区数据。 | ||||||
| 
 | 
 | ||||||
|  | ## 三菱Q06H通信测试 | ||||||
|  | 
 | ||||||
|  | ### 通信接线及参数设置 | ||||||
|  | 
 | ||||||
|  | * 接口 | ||||||
|  |   * 首次连接时,可通过CPU自带的串口(打印机方口线)进行程序的下载。 | ||||||
|  |   * 本次测试通过Q06H拓展的模块QJ71E71_100模块的网口模块进行MC—3E通信测试。 | ||||||
|  |   * PLC网口模块IP:192.168.250.21 端口号:4000 | ||||||
|  | 
 | ||||||
|  | ### 存储区 | ||||||
|  | 
 | ||||||
|  | - 存储区 I,Q,M,D区。 | ||||||
|  | 
 | ||||||
|  | ### 通信测试 | ||||||
|  | 
 | ||||||
|  | -  共测试BOOL,INT16,FLOAT共三种类型数据。 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | - 测试M区及D区数据。 | ||||||
|  | 
 | ||||||
|  | - 测试截图: | ||||||
|  | 
 | ||||||
|  |   解析完成的配方为 | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   测试结果: | ||||||
|  |    | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## 三菱Q03UDV通信测试 | ||||||
|  | 
 | ||||||
|  | ### 通信接线及参数设置 | ||||||
|  | 
 | ||||||
|  | * 接口 | ||||||
|  |   * 本次测试通过Q03UDV拓展的模块QJ71E71_100模块的网口模块进行MC—3E通信测试。网口模块IP:192.168.250.21 端口号:4000 | ||||||
|  |   * 本次测试还可通过Q03UDV自身网口进行MC—3E通信测试。网口模块IP:192.168.250.22 端口号:6000 | ||||||
|  | 
 | ||||||
|  | ### 存储区 | ||||||
|  | 
 | ||||||
|  | - 存储区 I,Q,M,D区。 | ||||||
|  | 
 | ||||||
|  | ### 通信测试 | ||||||
|  | 
 | ||||||
|  | -  共测试BOOL,INT16,FLOAT共三种类型数据。 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | - 测试M区及D区数据。 | ||||||
|  | 
 | ||||||
|  | - 测试截图: | ||||||
|  | 
 | ||||||
|  |   扩展模块解析完成的配方为 | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   CPU自带网口解析完成的配方为 | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  |    | ||||||
|  |   测试结果: | ||||||
|  |    | ||||||
|  |    | ||||||
|  |  | ||||||
| After Width: | Height: | Size: 2.8 MiB | 
| After Width: | Height: | Size: 1.4 MiB | 
| After Width: | Height: | Size: 158 KiB | 
| After Width: | Height: | Size: 164 KiB | 
| After Width: | Height: | Size: 6.9 KiB | 
| After Width: | Height: | Size: 156 KiB | 
| After Width: | Height: | Size: 5.6 KiB | 
| After Width: | Height: | Size: 7.0 KiB | 
| After Width: | Height: | Size: 10 KiB | 
| After Width: | Height: | Size: 6.8 KiB | 
|  | @ -0,0 +1,368 @@ | ||||||
|  | { | ||||||
|  |     "device_id": 1, | ||||||
|  |     "device_name": "FX3U_MC_1E", | ||||||
|  |     "communication_type": 0, | ||||||
|  |     "socket_config": { | ||||||
|  |         "plc_ip": "192.168.250.25", | ||||||
|  |         "local_ip": "192.168.250.233", | ||||||
|  |         "gateway": "192.168.250.1", | ||||||
|  |         "netmask": "255.255.254.0", | ||||||
|  |         "port": 2000 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 6, | ||||||
|  |     "read_period": 2000, | ||||||
|  |   "read_item_list": [ | ||||||
|  |     { | ||||||
|  |       "value_name": "启动", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "0", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "停止", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "使能", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "2", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "回零", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "3", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "急停", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "4", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "正限位", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "5", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "负限位", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "6", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "自动运行中", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "20", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "故障", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "21", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "待机", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "22", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "手动模式", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "23", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "自动模式", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "24", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "运行方向", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "25", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "复位", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "26", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "备用1", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "27", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "产量", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "0", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型1", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型2", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "2", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型3", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "3", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型4", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "4", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型5", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "5", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型6", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "50", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型7", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "51", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型8", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "52", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型9", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "53", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "速度", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "200", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "加速度", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "202", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "减速度", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "204", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "起始位置", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "206", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "终点位置", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "208", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "张力值", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "300", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型1", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "302", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型2", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "304", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型3", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "306", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型4", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "308", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y001", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "Y", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y002", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "Y", | ||||||
|  |       "head_device_number_string": "2", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y010", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "Y", | ||||||
|  |       "head_device_number_string": "10", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D400", | ||||||
|  |       "value_type": 4, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "400", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,331 @@ | ||||||
|  | { | ||||||
|  |     "device_id": 769, | ||||||
|  |     "device_name": "Q02UCPU", | ||||||
|  |     "communication_type": 1, | ||||||
|  |     "serial_config": { | ||||||
|  |          "station": 0, | ||||||
|  |         "baud_rate": 19200, | ||||||
|  |         "data_bits": 7, | ||||||
|  |         "stop_bits": 1, | ||||||
|  |         "check_mode": 3 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 10, | ||||||
|  |     "read_period": 1000, | ||||||
|  |     "read_item_list": [ | ||||||
|  |         { | ||||||
|  |             "value_name": "启动", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "0", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "停止", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "1", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "使能", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "2", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "回零", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "3", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "急停", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "4", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "正限位", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "5", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "负限位", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "6", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "自动运行中", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "20", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "故障", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "21", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "待机", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "22", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "手动模式", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "23", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "自动模式", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "24", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "运行方向", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "25", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "复位", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "26", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "备用1", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "device_code": "M", | ||||||
|  |             "head_device_number_string": "27", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 0, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "产量", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "0", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型1", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "1", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型2", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "2", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型3", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "3", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型4", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "4", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型5", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "5", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型6", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "50", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型7", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "51", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型8", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "52", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "整型9", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "53", | ||||||
|  |             "device_points_count": 1, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "速度", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "200", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "加速度", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "202", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "减速度", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "204", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "起始位置", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "206", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "终点位置", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "208", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "张力值", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "300", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "浮点型1", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "302", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "浮点型2", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "304", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "浮点型3", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "306", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "浮点型4", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "device_code": "D", | ||||||
|  |             "head_device_number_string": "308", | ||||||
|  |             "device_points_count": 2, | ||||||
|  |             "command_type": 1, | ||||||
|  |             "monitoring_timer": 100 | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,494 @@ | ||||||
|  | { | ||||||
|  |     "device_id": 1, | ||||||
|  |     "device_name": "Q02UCPU_MC_3E", | ||||||
|  |     "communication_type": 0, | ||||||
|  |     "socket_config": { | ||||||
|  |         "plc_ip": "192.168.250.21", | ||||||
|  |         "local_ip": "192.168.250.233", | ||||||
|  |         "gateway": "192.168.250.1", | ||||||
|  |         "netmask": "255.255.254.0", | ||||||
|  |         "port": 4000 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 7, | ||||||
|  |     "read_period": 2000, | ||||||
|  |   "read_item_list": [ | ||||||
|  |     { | ||||||
|  |       "value_name": "启动", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "0", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "停止", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "使能", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "2", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "回零", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "3", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "急停", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "4", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "正限位", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "5", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "负限位", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "6", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "自动运行中", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "20", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "故障", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "21", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "待机", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "22", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "手动模式", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "23", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "自动模式", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "24", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "运行方向", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "25", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "复位", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "26", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "备用1", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "M", | ||||||
|  |       "head_device_number_string": "27", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "产量", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "0", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型1", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型2", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "2", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型3", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "3", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型4", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "4", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型5", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "5", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型6", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "50", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型7", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "51", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型8", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "52", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "整型9", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "53", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "速度", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "200", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "加速度", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "202", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "减速度", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "204", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "起始位置", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "206", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "终点位置", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "208", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "张力值", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "300", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型1", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "302", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型2", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "304", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型3", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "306", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "浮点型4", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "308", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y001", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "Y", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y002", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "Y", | ||||||
|  |       "head_device_number_string": "2", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y010", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "Y", | ||||||
|  |       "head_device_number_string": "10", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D400", | ||||||
|  |       "value_type": 4, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "400", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D402", | ||||||
|  |       "value_type": 8, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "402", | ||||||
|  |       "device_points_count": 4, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "D406", | ||||||
|  |       "value_type": 8, | ||||||
|  |       "device_code": "D", | ||||||
|  |       "head_device_number_string": "406", | ||||||
|  |       "device_points_count": 4, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "B1", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "B", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "B10", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "B", | ||||||
|  |       "head_device_number_string": "10", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "B20", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "B", | ||||||
|  |       "head_device_number_string": "20", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "W1", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "W", | ||||||
|  |       "head_device_number_string": "1", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "W2", | ||||||
|  |       "value_type": 4, | ||||||
|  |       "device_code": "W", | ||||||
|  |       "head_device_number_string": "2", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "W4", | ||||||
|  |       "value_type": 9, | ||||||
|  |       "device_code": "W", | ||||||
|  |       "head_device_number_string": "4", | ||||||
|  |       "device_points_count": 2, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "W6", | ||||||
|  |       "value_type": 8, | ||||||
|  |       "device_code": "W", | ||||||
|  |       "head_device_number_string": "6", | ||||||
|  |       "device_points_count": 4, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "W22", | ||||||
|  |       "value_type": 3, | ||||||
|  |       "device_code": "W", | ||||||
|  |       "head_device_number_string": "22", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 1, | ||||||
|  |       "monitoring_timer": 100 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "B44", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "B", | ||||||
|  |       "head_device_number_string": "44", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 500 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "B200", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "B", | ||||||
|  |       "head_device_number_string": "200", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 500 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "Y100", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "Y", | ||||||
|  |       "head_device_number_string": "100", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 500 | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "value_name": "X150", | ||||||
|  |       "value_type": 1, | ||||||
|  |       "device_code": "X", | ||||||
|  |       "head_device_number_string": "150", | ||||||
|  |       "device_points_count": 1, | ||||||
|  |       "command_type": 0, | ||||||
|  |       "monitoring_timer": 500 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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 mitsubishi_q03udv.c | ||||||
|  |  * @brief PLC MITSUBISHI Q03udv app | ||||||
|  |  * @version 3.0 | ||||||
|  |  * @author AIIT XUOS Lab | ||||||
|  |  * @date 2023.10.30 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <control.h> | ||||||
|  | 
 | ||||||
|  | extern int Adapter4GActive(void); | ||||||
|  | 
 | ||||||
|  | void ControlQ03udvTest(void) | ||||||
|  | { | ||||||
|  |     int i, j = 0; | ||||||
|  |     int read_data_length = 0; | ||||||
|  |     uint8_t read_data[128] = {0}; | ||||||
|  | 
 | ||||||
|  | #ifdef CONNECTION_ADAPTER_4G | ||||||
|  |     Adapter4GActive(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ControlProtocolType melsec_3e_protocol = ControlProtocolFind(); | ||||||
|  |     if (NULL == melsec_3e_protocol) { | ||||||
|  |         printf("%s get melsec 3e protocol %p failed\n", __func__, melsec_3e_protocol); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("%s get melsec 3e protocol %p successfull\n", __func__, melsec_3e_protocol); | ||||||
|  | 
 | ||||||
|  |     if (CONTROL_REGISTERED == melsec_3e_protocol->protocol_status) { | ||||||
|  |         ControlProtocolOpen(melsec_3e_protocol); | ||||||
|  | 
 | ||||||
|  |         for (;;) { | ||||||
|  |             read_data_length = ControlProtocolRead(melsec_3e_protocol, read_data, sizeof(read_data)); | ||||||
|  |             printf("%s read [%d] melsec 3c data %d using receipe file\n", __func__, i, read_data_length); | ||||||
|  |             if (read_data_length) { | ||||||
|  |                 for (j = 0; j < read_data_length; j ++) { | ||||||
|  |                     printf("j %d data 0x%x\n", j, read_data[j]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             i++; | ||||||
|  |             memset(read_data, 0, sizeof(read_data)); | ||||||
|  |             PrivTaskDelay(10000); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //ControlProtocolClose(melsec_3c_protocol);
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(ControlQ03udvTest, Mitsubishi Q03udv Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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 mitsubishi_q06h.c | ||||||
|  |  * @brief PLC MITSUBISHI Q06H app | ||||||
|  |  * @version 3.0 | ||||||
|  |  * @author AIIT XUOS Lab | ||||||
|  |  * @date 2023.10.30 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <control.h> | ||||||
|  | 
 | ||||||
|  | extern int Adapter4GActive(void); | ||||||
|  | 
 | ||||||
|  | void ControlQ06hTest(void) | ||||||
|  | { | ||||||
|  |     int i, j = 0; | ||||||
|  |     int read_data_length = 0; | ||||||
|  |     uint8_t read_data[128] = {0}; | ||||||
|  | 
 | ||||||
|  | #ifdef CONNECTION_ADAPTER_4G | ||||||
|  |     Adapter4GActive(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ControlProtocolType melsec_3e_protocol = ControlProtocolFind(); | ||||||
|  |     if (NULL == melsec_3e_protocol) { | ||||||
|  |         printf("%s get melsec 3e protocol %p failed\n", __func__, melsec_3e_protocol); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("%s get melsec 3e protocol %p successfull\n", __func__, melsec_3e_protocol); | ||||||
|  | 
 | ||||||
|  |     if (CONTROL_REGISTERED == melsec_3e_protocol->protocol_status) { | ||||||
|  |         ControlProtocolOpen(melsec_3e_protocol); | ||||||
|  | 
 | ||||||
|  |         for (;;) { | ||||||
|  |             read_data_length = ControlProtocolRead(melsec_3e_protocol, read_data, sizeof(read_data)); | ||||||
|  |             printf("%s read [%d] melsec 3c data %d using receipe file\n", __func__, i, read_data_length); | ||||||
|  |             if (read_data_length) { | ||||||
|  |                 for (j = 0; j < read_data_length; j ++) { | ||||||
|  |                     printf("j %d data 0x%x\n", j, read_data[j]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             i++; | ||||||
|  |             memset(read_data, 0, sizeof(read_data)); | ||||||
|  |             PrivTaskDelay(10000); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //ControlProtocolClose(melsec_3c_protocol);
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(ControlQ06hTest, Mitsubishi Q06H Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | { | ||||||
|  |     "device_id": 1, | ||||||
|  |     "device_name": "NJ501", | ||||||
|  |     "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.255.0", | ||||||
|  |         "port": 9600 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 5, | ||||||
|  |     "read_period": 100, | ||||||
|  |     "read_item_list": [ | ||||||
|  |         | ||||||
|  |         { | ||||||
|  |             "value_name": "整型1", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "area_char": "D", | ||||||
|  |             "data_type": 1, | ||||||
|  |             "start_address": 100, | ||||||
|  |             "bit_address": 0, | ||||||
|  |             "data_length": 1 | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | @ -18,6 +18,34 @@ | ||||||
|  * @date 2022.9.27 |  * @date 2022.9.27 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| 
 | #include <control.h> | ||||||
|  | 
 | ||||||
|  | void ControlNj501Test(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(ControlNj501Test, Omron Plc FINS Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | SRC_FILES := panasonic_fpxh_tcp.c panasonic_fpxh_uart.c | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,39 @@ | ||||||
|  | # 松下通信测试 | ||||||
|  | 
 | ||||||
|  | [TOC] | ||||||
|  | 
 | ||||||
|  | ## 松下FPXHC40ET通信测试 | ||||||
|  | 
 | ||||||
|  | ### 通信接线及参数设置 | ||||||
|  | 
 | ||||||
|  | * 网口和串口 | ||||||
|  |   * FPXHC40ET自带miniUSB,用于程序的下载。本体自带的串口为RS232。 | ||||||
|  |   * 本体自带的网口可用于Modbus TCP,Ethernet/IP等通信。目前用于Modbus TCP通信测试,网口IP:192.168.250.51 Port:502 | ||||||
|  |   * 通过本体拓展FPXH-COM3通信模板,可用于Modbus RTU通信。串口接线:S+接485A;S-接485B。 | ||||||
|  |   * 串口模块通信参数配置:通信速率:115200;数据位:8bit;停止位:1bit;校验:偶校验 | ||||||
|  | 
 | ||||||
|  | ### 存储区 | ||||||
|  | 
 | ||||||
|  | - 存储区 X,Y,R,D,L区等。 | ||||||
|  | 
 | ||||||
|  | ### 通信测试 | ||||||
|  | 
 | ||||||
|  | -  共测试BOOL,INT16等类型数据。 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | -  测试Y区,R区及DT区数据。 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | - 测试截图: | ||||||
|  | 
 | ||||||
|  |   测试PLC环境搭建: | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   解析完成的配方为: | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | 
 | ||||||
|  |   测试结果: | ||||||
|  | 
 | ||||||
|  |    | ||||||
| After Width: | Height: | Size: 200 KiB | 
| After Width: | Height: | Size: 182 KiB | 
| After Width: | Height: | Size: 23 KiB | 
| After Width: | Height: | Size: 6.4 KiB | 
|  | @ -0,0 +1,65 @@ | ||||||
|  | { | ||||||
|  |     "device_id": 1, | ||||||
|  |     "device_name": "PANASONIC_FPXH_TCP", | ||||||
|  |     "communication_type": 0, | ||||||
|  |     "socket_config": { | ||||||
|  |         "plc_ip": "192.168.250.51", | ||||||
|  |         "local_ip": "192.168.250.233", | ||||||
|  |         "gateway": "192.168.250.1", | ||||||
|  |         "netmask": "255.255.254.0", | ||||||
|  |         "port": 502 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 2, | ||||||
|  |     "read_period": 1000, | ||||||
|  |     "read_item_list": [ | ||||||
|  |         { | ||||||
|  |             "value_name": "Y0", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address": 0, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "R0", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address":2048, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "R100", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address": 2208, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |        { | ||||||
|  |             "value_name": "R101", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address": 2209, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "DT0", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 0, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "DT1", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 1, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "DT200", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 200, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }     | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,66 @@ | ||||||
|  | { | ||||||
|  |      "device_id": 1, | ||||||
|  |     "device_name": "PANASONIC_FPXH_RTU", | ||||||
|  |     "communication_type": 1, | ||||||
|  |     "serial_config": { | ||||||
|  |         "station": 1, | ||||||
|  |         "baud_rate": 9600, | ||||||
|  |         "data_bits": 8, | ||||||
|  |         "stop_bits": 1, | ||||||
|  |         "check_mode":3 | ||||||
|  |     }, | ||||||
|  |     "protocol_type": 3, | ||||||
|  |     "read_period": 2000, | ||||||
|  |     "read_item_list": [ | ||||||
|  |         { | ||||||
|  |             "value_name": "Y0", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address": 0, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "R0", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address":2048, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "R100", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address": 2208, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |        { | ||||||
|  |             "value_name": "R101", | ||||||
|  |             "value_type": 1, | ||||||
|  |             "function_code": 1, | ||||||
|  |             "start_address": 2209, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "DT0", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 0, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "DT1", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 1, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |             "value_name": "DT200", | ||||||
|  |             "value_type": 3, | ||||||
|  |             "function_code": 3, | ||||||
|  |             "start_address": 200, | ||||||
|  |             "quantity": 1 | ||||||
|  |         }     | ||||||
|  |          | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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 panasonic_fpxh_ethernet.c | ||||||
|  |  * @brief PLC panasonic fpxh app | ||||||
|  |  * @version 3.0 | ||||||
|  |  * @author AIIT XUOS Lab | ||||||
|  |  * @date 2023.11.22 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <control.h> | ||||||
|  | 
 | ||||||
|  | extern int Adapter4GActive(void); | ||||||
|  | 
 | ||||||
|  | void ControlPanasonicFpxhTCPTest(void) | ||||||
|  | { | ||||||
|  |     int i, j = 0; | ||||||
|  |     int read_data_length = 0; | ||||||
|  |     uint8_t read_data[128] = {0}; | ||||||
|  | 
 | ||||||
|  | #ifdef CONNECTION_ADAPTER_4G | ||||||
|  |     Adapter4GActive(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ControlProtocolType modbus_tcp_protocol = ControlProtocolFind(); | ||||||
|  |     if (NULL == modbus_tcp_protocol) { | ||||||
|  |         printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol); | ||||||
|  | 
 | ||||||
|  |     if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) { | ||||||
|  |         ControlProtocolOpen(modbus_tcp_protocol); | ||||||
|  | 
 | ||||||
|  |         for (;;) { | ||||||
|  |             read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data)); | ||||||
|  |             printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length); | ||||||
|  |             if (read_data_length) { | ||||||
|  |                 for (j = 0; j < read_data_length; j ++) { | ||||||
|  |                     printf("j %d data 0x%x\n", j, read_data[j]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             i++; | ||||||
|  |             memset(read_data, 0, sizeof(read_data)); | ||||||
|  |             PrivTaskDelay(10000); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //ControlProtocolClose(modbus_tcp_protocol);
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(ControlPanasonicFpxhTCPTest, panasonic Fpxh TCP Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,64 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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 panasonic_fpxh_uart.c | ||||||
|  |  * @brief PLC panasonic fpxh app | ||||||
|  |  * @version 3.0 | ||||||
|  |  * @author AIIT XUOS Lab | ||||||
|  |  * @date 2023.11.22 | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <control.h> | ||||||
|  | 
 | ||||||
|  | extern int Adapter4GActive(void); | ||||||
|  | 
 | ||||||
|  | void ControlPanasonicFpxhUartTest(void) | ||||||
|  | { | ||||||
|  |     int i, j = 0; | ||||||
|  |     int read_data_length = 0; | ||||||
|  |     uint8_t read_data[128] = {0}; | ||||||
|  | 
 | ||||||
|  | #ifdef CONNECTION_ADAPTER_4G | ||||||
|  |     Adapter4GActive(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     ControlProtocolType modbus_rtu_protocol = ControlProtocolFind(); | ||||||
|  |     if (NULL == modbus_rtu_protocol) { | ||||||
|  |         printf("%s get modbus rtu protocol %p failed\n", __func__, modbus_rtu_protocol); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("%s get modbus rtu protocol %p successfull\n", __func__, modbus_rtu_protocol); | ||||||
|  | 
 | ||||||
|  |     if (CONTROL_REGISTERED == modbus_rtu_protocol->protocol_status) { | ||||||
|  |         ControlProtocolOpen(modbus_rtu_protocol); | ||||||
|  | 
 | ||||||
|  |         for (;;) { | ||||||
|  |             read_data_length = ControlProtocolRead(modbus_rtu_protocol, read_data, sizeof(read_data)); | ||||||
|  |             printf("%s read [%d] modbus rtu data %d using receipe file\n", __func__, i, read_data_length); | ||||||
|  |             if (read_data_length) { | ||||||
|  |                 for (j = 0; j < read_data_length; j ++) { | ||||||
|  |                     printf("j %d data 0x%x\n", j, read_data[j]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             i++; | ||||||
|  |             memset(read_data, 0, sizeof(read_data)); | ||||||
|  |             PrivTaskDelay(10000); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         //ControlProtocolClose(modbus_rtu_protocol);
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(ControlPanasonicFpxhUartTest, panasonic fpxh uart Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -1,3 +1,3 @@ | ||||||
| SRC_FILES := siemens_s7_200_cn.c siemens_s7_200_smart.c siemens_s7_300.c siemens_s7_1200.c siemens_s7_1500.c | SRC_FILES := siemens_s7_200_cn.c siemens_s7_200_smart.c  siemens_s7_1200.c siemens_s7_1500.c | ||||||
| 
 | 
 | ||||||
| include $(KERNEL_ROOT)/compiler.mk | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  |  | ||||||
|  | @ -0,0 +1,25 @@ | ||||||
|  | { | ||||||
|  |     "device_id": 1, | ||||||
|  |     "device_name": "S7-1215", | ||||||
|  |     "communication_type": 0, | ||||||
|  |     "socket_config": { | ||||||
|  |         "plc_ip": "192.168.250.5", | ||||||
|  |         "local_ip": "192.168.250.233", | ||||||
|  |         "gateway": "192.168.250.252", | ||||||
|  |         "netmask": "255.255.255.0", | ||||||
|  |         "port": 102 | ||||||
|  |     }, | ||||||
|  |    "protocol_type": 1, | ||||||
|  |     "read_period": 100, | ||||||
|  |     "read_item_list": [ | ||||||
|  |         { | ||||||
|  |             "value_name": "浮点数", | ||||||
|  |             "value_type": 9, | ||||||
|  |             "area": "DB", | ||||||
|  |             "wordlen": "Real", | ||||||
|  |             "db_number": 10, | ||||||
|  |             "start": 32, | ||||||
|  |             "amount": 1 | ||||||
|  |         } | ||||||
|  |     ] | ||||||
|  | } | ||||||
|  | @ -18,3 +18,28 @@ | ||||||
|  * @date 2023.3.27 |  * @date 2023.3.27 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <control.h> | ||||||
|  | void ControlS71200Test(void) | ||||||
|  | { | ||||||
|  |     int i = 0; | ||||||
|  |     uint16_t read_data_length = 0; | ||||||
|  |     uint8_t read_data[1024] = {0}; | ||||||
|  |     ControlProtocolType s7_protocol = ControlProtocolFind(); | ||||||
|  |     if (NULL == s7_protocol) { | ||||||
|  |         printf("%s get s7 protocol %p failed\n", __func__, s7_protocol); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     printf("%s get s7 protocol %p successfull\n", __func__, s7_protocol); | ||||||
|  |     if (CONTROL_REGISTERED == s7_protocol->protocol_status) { | ||||||
|  |         ControlProtocolOpen(s7_protocol); | ||||||
|  |         for (;;) { | ||||||
|  |             read_data_length = ControlProtocolRead(s7_protocol, read_data, sizeof(read_data)); | ||||||
|  |             printf("%s read [%d] s7 data %d using receipe file\n", __func__, i, read_data_length); | ||||||
|  |             i++; | ||||||
|  |             memset(read_data, 0, sizeof(read_data)); | ||||||
|  |             PrivTaskDelay(10000); | ||||||
|  |         } | ||||||
|  |     }  | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(ControlS71200Test, Siemens Plc S7_1215 Demo, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | @ -1,20 +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 siemens_s7_300.c |  | ||||||
|  * @brief PLC SIEMENS S7-300 app |  | ||||||
|  * @version 3.0 |  | ||||||
|  * @author AIIT XUOS Lab |  | ||||||
|  * @date 2023.3.27 |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
|  | @ -28,6 +28,7 @@ | ||||||
|  * @date 2022-08-08 |  * @date 2022-08-08 | ||||||
|  */ |  */ | ||||||
| #include "ch32v30x.h" | #include "ch32v30x.h" | ||||||
|  | #include "connect_can.h" | ||||||
| #include "connect_ether.h" | #include "connect_ether.h" | ||||||
| #include "connect_uart.h" | #include "connect_uart.h" | ||||||
| #include "core_riscv.h" | #include "core_riscv.h" | ||||||
|  | @ -57,24 +58,27 @@ static uint32_t _SysTick_Config(uint32_t ticks) | ||||||
| /**
 | /**
 | ||||||
|  * This function will initial your board. |  * This function will initial your board. | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
| void InitBoardHardware() | void InitBoardHardware() | ||||||
| { | { | ||||||
|     USART_Printf_Init(115200); |  | ||||||
|     /* System Tick Configuration */ |  | ||||||
|     _SysTick_Config(SystemCoreClock / TICK_PER_SECOND); |     _SysTick_Config(SystemCoreClock / TICK_PER_SECOND); | ||||||
|     /* initialize memory system */ |     /* initialize memory system */ | ||||||
|     InitBoardMemory(MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); |     InitBoardMemory(MEMORY_START_ADDRESS, (void*)MEMORY_END_ADDRESS); | ||||||
|     InitHwUart(); |     InitHwUart(); | ||||||
|     InstallConsole("uart1", "uart1_drv", "uart1_dev1"); | #ifdef BSP_USING_UART4 | ||||||
|  |     InstallConsole("uart4", "uart4_drv", "uart4_dev4"); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef BSP_USING_ETH | #ifdef BSP_USING_ETH | ||||||
|     InitHwEth(); |     InitHwEth(); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef BSP_USING_CAN | ||||||
|  |     InitHwCan(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|     KPrintf("consle init completed.\n"); |     KPrintf("consle init completed.\n"); | ||||||
|     KPrintf("board initialization......\n"); |     KPrintf("board initialization......\n"); | ||||||
|     // KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, gd32vf103_SRAM_SIZE);
 |  | ||||||
|     /* initialize memory system */ |  | ||||||
| 
 | 
 | ||||||
|     KPrintf("board init done.\n"); |     KPrintf("board init done.\n"); | ||||||
|     KPrintf("start okernel...\n"); |     KPrintf("start okernel...\n"); | ||||||
|  |  | ||||||
|  | @ -19,4 +19,23 @@ menuconfig BSP_USING_ETH | ||||||
|     bool "Using Ethernet" |     bool "Using Ethernet" | ||||||
|     default y |     default y | ||||||
|   |   | ||||||
|  | menuconfig BSP_USING_CAN | ||||||
|  |     bool "Using CAN device" | ||||||
|  |     default y | ||||||
|  |     select RESOURCES_CAN | ||||||
|  |     if BSP_USING_CAN | ||||||
|  |         source "$BSP_DIR/third_party_driver/can/Kconfig" | ||||||
|  |     endif | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | menuconfig BSP_USING_USB | ||||||
|  |     bool "Using USB device" | ||||||
|  |     default y | ||||||
|  |     select BSP_USING_USBH | ||||||
|  |     select RESOURCES_USB | ||||||
|  |     select RESOURCES_USB_HOST | ||||||
|  |     select USBH_MSTORAGE | ||||||
|  |     select RESOURCES_USB_DEVICE | ||||||
|  |     if BSP_USING_USB | ||||||
|  |         source "$BSP_DIR/third_party_driver/usb/Kconfig" | ||||||
|  |     endif | ||||||
|  |  | ||||||
|  | @ -13,4 +13,12 @@ ifeq ($(CONFIG_BSP_USING_ETH),y) | ||||||
|   SRC_DIR += ethernet |   SRC_DIR += ethernet | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  | ifeq ($(CONFIG_BSP_USING_CAN),y) | ||||||
|  |   SRC_DIR += can | ||||||
|  | endif | ||||||
|  | 
 | ||||||
|  | ifeq ($(CONFIG_BSP_USING_USB),y) | ||||||
|  |   SRC_DIR += usb | ||||||
|  | endif | ||||||
|  | 
 | ||||||
| include $(KERNEL_ROOT)/compiler.mk | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,11 @@ | ||||||
|  | config CAN_BUS_NAME_1 | ||||||
|  |     string "can bus name" | ||||||
|  |     default "can1" | ||||||
|  | 
 | ||||||
|  | config CAN_DRIVER_NAME | ||||||
|  |     string "can driver name" | ||||||
|  |     default "can1_drv" | ||||||
|  | 
 | ||||||
|  | config CAN_1_DEVICE_NAME_1 | ||||||
|  |     string "can bus 1 device 1 name" | ||||||
|  |     default "can1_dev1" | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | SRC_FILES := connect_can.c | ||||||
|  | SRC_DIR := test | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,249 @@ | ||||||
|  | 
 | ||||||
|  | #include <connect_can.h> | ||||||
|  | #include <ch32v30x_gpio.h> | ||||||
|  | #include <ch32v30x_rcc.h> | ||||||
|  | #include <ch32v30x_misc.h> | ||||||
|  | 
 | ||||||
|  | static struct CanSendConfigure can_send_deconfig =  | ||||||
|  | { | ||||||
|  |     .stdid = 0x12, | ||||||
|  |     .exdid = 0x12, | ||||||
|  |     .ide = 0 , | ||||||
|  |     .rtr = 0, | ||||||
|  |     .data_lenth = 8 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static void CanGPIOInit(void) | ||||||
|  | { | ||||||
|  |     CAN_FilterInitTypeDef  can1_filter; | ||||||
|  |     GPIO_InitTypeDef           gpio_initstructure; | ||||||
|  |     CAN_InitTypeDef             can_initstruction; | ||||||
|  |   | ||||||
|  |     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOB, ENABLE); | ||||||
|  |     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); | ||||||
|  | 
 | ||||||
|  |     GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE); | ||||||
|  | 
 | ||||||
|  |     gpio_initstructure.GPIO_Pin = GPIO_Pin_9; | ||||||
|  | 	gpio_initstructure.GPIO_Mode = GPIO_Mode_AF_PP;		 | ||||||
|  | 	gpio_initstructure.GPIO_Speed = GPIO_Speed_50MHz; | ||||||
|  | 	GPIO_Init( GPIOB, &gpio_initstructure); | ||||||
|  | 
 | ||||||
|  | 	gpio_initstructure.GPIO_Pin = GPIO_Pin_8; | ||||||
|  | 	gpio_initstructure.GPIO_Mode = GPIO_Mode_IPU;	 | ||||||
|  | 	GPIO_Init( GPIOB, &gpio_initstructure); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void Can1NvicConfig(void) | ||||||
|  | { | ||||||
|  |     NVIC_InitTypeDef can_nvic_config; | ||||||
|  | 
 | ||||||
|  |     can_nvic_config.NVIC_IRQChannel = CAN1_RX1_IRQn; | ||||||
|  |     can_nvic_config.NVIC_IRQChannelPreemptionPriority = 2; | ||||||
|  |     can_nvic_config.NVIC_IRQChannelSubPriority = 2; | ||||||
|  |     can_nvic_config.NVIC_IRQChannelCmd = ENABLE; | ||||||
|  |     CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); | ||||||
|  |     NVIC_Init(&can_nvic_config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static uint32 CanModeInit(void *drv, struct BusConfigureInfo *configure_info) | ||||||
|  | { | ||||||
|  |     NULL_PARAM_CHECK(drv); | ||||||
|  |     NULL_PARAM_CHECK(configure_info); | ||||||
|  |     CAN_FilterInitTypeDef can1_filter; | ||||||
|  |     CAN_InitTypeDef     can_initstruction; | ||||||
|  | 
 | ||||||
|  |     struct CanDriverConfigure  *config  = ( struct CanDriverConfigure  *)configure_info->private_data; | ||||||
|  | 
 | ||||||
|  |     can_initstruction.CAN_TTCM  = DISABLE; | ||||||
|  |     can_initstruction.CAN_ABOM = DISABLE; | ||||||
|  |     can_initstruction.CAN_AWUM = DISABLE; | ||||||
|  |     can_initstruction.CAN_NART   = ENABLE; | ||||||
|  |     can_initstruction.CAN_TXFP    = DISABLE; | ||||||
|  |     can_initstruction.CAN_Mode   = config->mode; | ||||||
|  |     can_initstruction.CAN_RFLM   = DISABLE; | ||||||
|  |     can_initstruction.CAN_SJW      = config->tsjw; | ||||||
|  |     can_initstruction.CAN_BS1       = config->tbs1; | ||||||
|  |     can_initstruction.CAN_BS2       = config->tbs2; | ||||||
|  |     can_initstruction.CAN_Prescaler  = config->brp; | ||||||
|  |      | ||||||
|  |     CAN_Init(CAN1, &can_initstruction); | ||||||
|  | 
 | ||||||
|  |     can1_filter.CAN_FilterNumber=0; | ||||||
|  |     can1_filter.CAN_FilterMode=CAN_FilterMode_IdMask; | ||||||
|  |     can1_filter.CAN_FilterScale=CAN_FilterScale_32bit; | ||||||
|  |     can1_filter.CAN_FilterIdHigh=0x0000; | ||||||
|  |     can1_filter.CAN_FilterIdLow=0x0000; | ||||||
|  |     can1_filter.CAN_FilterMaskIdHigh=0x0000; | ||||||
|  |     can1_filter.CAN_FilterMaskIdLow=0x0006; | ||||||
|  |     can1_filter.CAN_FilterFIFOAssignment=CAN_Filter_FIFO1; | ||||||
|  |     can1_filter.CAN_FilterActivation=ENABLE; | ||||||
|  |     CAN_FilterInit(&can1_filter); | ||||||
|  | 
 | ||||||
|  |     #ifdef  CAN_USING_INTERRUPT | ||||||
|  |        Can1NvicConfig(); | ||||||
|  |     #endif | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static uint32 CanSendMsg(void * dev , struct BusBlockWriteParam *write_param ) | ||||||
|  | { | ||||||
|  |     NULL_PARAM_CHECK(write_param); | ||||||
|  | 
 | ||||||
|  |     uint8  *data   = (uint8  * ) write_param->buffer; | ||||||
|  |     u8  messege_box; | ||||||
|  |     u16  i = 0; | ||||||
|  |     u16  timer_count = 1000; | ||||||
|  |     CanTxMsg  tx_data; | ||||||
|  |     tx_data.StdId  = 0x55; | ||||||
|  |     tx_data.ExtId   = 0x00; | ||||||
|  |     tx_data.IDE      =  0; | ||||||
|  |     tx_data.RTR     =  0; | ||||||
|  |     tx_data.DLC     =  write_param->size; | ||||||
|  | 
 | ||||||
|  |     for(i = 0;i < tx_data.DLC;i ++) { | ||||||
|  |         tx_data.Data[i] = data[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     messege_box = CAN_Transmit(CAN1,&tx_data); | ||||||
|  | 
 | ||||||
|  |     while (CAN_TransmitStatus(CAN1,messege_box)==  CAN_TxStatus_Failed &&timer_count) { | ||||||
|  |         timer_count--; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (timer_count<=0) { | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  |     return EOK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static uint32 CanRecvMsg(void *dev , struct BusBlockReadParam *databuf) | ||||||
|  | { | ||||||
|  |     NULL_PARAM_CHECK(dev); | ||||||
|  |     int  i; | ||||||
|  |     uint8  * buf  = (uint8 *)databuf->buffer; | ||||||
|  |     CanRxMsg msg; | ||||||
|  |     if (CAN_MessagePending(CAN1, CAN_FIFO0) == 0) | ||||||
|  |         return 0; | ||||||
|  |     CAN_Receive(CAN1, CAN_FIFO0, &msg); | ||||||
|  |     for(i = 0 ;i < msg.DLC;i ++) | ||||||
|  |          buf[i] = msg.Data[i]; | ||||||
|  |     databuf->size  =  msg.DLC ;  | ||||||
|  | 
 | ||||||
|  |     return msg.DLC; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static struct CanDevDone dev_done =  | ||||||
|  | { | ||||||
|  |     .open  = NONE, | ||||||
|  |     .close  = NONE, | ||||||
|  |     .write  = CanSendMsg, | ||||||
|  |     .read   = CanRecvMsg | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct CanHardwareDevice dev; | ||||||
|  | 
 | ||||||
|  | #ifdef  CAN_USING_INTERRUPT | ||||||
|  | void CAN1_RX0_IRQHandler(void) | ||||||
|  | { | ||||||
|  |     CanRxMsg   rxmsg; | ||||||
|  |     int i = 0; | ||||||
|  |     CAN_Receive(CAN1, 0, &rxmsg); | ||||||
|  |     for (i = 0;i < 8;i ++) | ||||||
|  |           KPrintf("rxbuf [%d] = :%d",i,rxmsg.Data[i]); | ||||||
|  | } | ||||||
|  | DECLARE_HW_IRQ(CAN1_RX0_IRQn, CAN1_RX0_IRQHandler, NONE); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static int BoardCanBusInit(struct CanDev *CanDev_bus, struct CanDriver *can_driver) | ||||||
|  | { | ||||||
|  |     x_err_t ret = EOK; | ||||||
|  | 
 | ||||||
|  |     /*Init the can bus */ | ||||||
|  |     ret = CanBusInit(&CanDev_bus->can_bus, CanDev_bus->bus_name); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("Board_can_init canBusInit error %d\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /*Init the can driver*/ | ||||||
|  |     ret = CanDriverInit(can_driver, CAN_DRIVER_NAME); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("Board_can_init canDriverInit error %d\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /*Attach the can driver to the can bus*/ | ||||||
|  |     ret = CanDriverAttachToBus(CAN_DRIVER_NAME, CanDev_bus->bus_name); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("Board_can_init CanDriverAttachToBus error %d\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     }  | ||||||
|  | 
 | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static x_err_t HwCanDeviceAttach(const char *bus_name, const char *device_name) | ||||||
|  | { | ||||||
|  |     NULL_PARAM_CHECK(bus_name); | ||||||
|  |     NULL_PARAM_CHECK(device_name); | ||||||
|  | 
 | ||||||
|  |     x_err_t result; | ||||||
|  |     struct CanHardwareDevice *can_device; | ||||||
|  | 
 | ||||||
|  |     /* attach the device to can bus*/ | ||||||
|  |     can_device = (struct CanHardwareDevice *)x_malloc(sizeof(struct CanHardwareDevice)); | ||||||
|  |     CHECK(can_device); | ||||||
|  |     memset(can_device, 0, sizeof(struct CanHardwareDevice)); | ||||||
|  |     can_device->dev_done = &dev_done; | ||||||
|  | 
 | ||||||
|  |      result = CanDeviceRegister(can_device, NONE, device_name); | ||||||
|  |     if (EOK != result) { | ||||||
|  |         KPrintf("board_can_init canDeviceInit device %s error %d\n", "can1", result); | ||||||
|  |         return ERROR; | ||||||
|  |     }   | ||||||
|  | 
 | ||||||
|  |     result = CanDeviceAttachToBus(device_name, bus_name); | ||||||
|  |     if (result != EOK) { | ||||||
|  |         SYS_ERR("%s attach to %s faild, %d\n", device_name, bus_name, result); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     CHECK(result == EOK); | ||||||
|  | 
 | ||||||
|  |     KPrintf("%s attach to %s done\n", device_name, bus_name); | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct CanDev can1; | ||||||
|  | 
 | ||||||
|  | int InitHwCan(void) | ||||||
|  | { | ||||||
|  |     x_err_t ret = EOK; | ||||||
|  |     struct CanDev *can_bus; | ||||||
|  | 
 | ||||||
|  |     static struct CanDriver can_driver; | ||||||
|  |     memset(&can_driver, 0, sizeof(struct CanDriver)); | ||||||
|  |     can_driver.configure = CanModeInit; | ||||||
|  | 
 | ||||||
|  |     CanGPIOInit(); | ||||||
|  |     can_bus = &can1; | ||||||
|  |     can_bus->instance = CAN1; | ||||||
|  |     can_bus->bus_name = CAN_BUS_NAME_1; | ||||||
|  |     can_bus->can_bus.private_data = &can1; | ||||||
|  |      | ||||||
|  |     ret = BoardCanBusInit(can_bus, &can_driver); | ||||||
|  |     | ||||||
|  |     if (EOK != ret) { | ||||||
|  |       KPrintf(" can_bus_init %s error ret %u\n", can_bus->bus_name, ret); | ||||||
|  |       return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = HwCanDeviceAttach(CAN_BUS_NAME_1,CAN_1_DEVICE_NAME_1);   | ||||||
|  |     if (EOK != ret) { | ||||||
|  |       KPrintf(" HwCanDeviceAttach %s error ret %u\n", can_bus->bus_name, ret); | ||||||
|  |       return ERROR; | ||||||
|  |     } | ||||||
|  |     return EOK; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | SRC_FILES := can_test.c | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,174 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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 can_test.c | ||||||
|  |  * @brief test ch32v307 can | ||||||
|  |  * @version 1.0 | ||||||
|  |  * @author AIIT XUOS Lab | ||||||
|  |  * @date 2024-03-14 | ||||||
|  |  */ | ||||||
|  | #include "shell.h" | ||||||
|  | #include "ch32v30x.h" | ||||||
|  | #include "connect_can.h" | ||||||
|  | #include <ch32v30x_gpio.h> | ||||||
|  | #include <ch32v30x_rcc.h> | ||||||
|  | #include <ch32v30x_misc.h> | ||||||
|  | 
 | ||||||
|  | static int init_can() | ||||||
|  | { | ||||||
|  |     KPrintf("init can\r\n"); | ||||||
|  | 
 | ||||||
|  |     CAN_FilterInitTypeDef can1_filter; | ||||||
|  |     CAN_InitTypeDef can_initstruction; | ||||||
|  | 
 | ||||||
|  |     can_initstruction.CAN_TTCM = DISABLE; | ||||||
|  |     can_initstruction.CAN_ABOM = DISABLE; | ||||||
|  |     can_initstruction.CAN_AWUM = DISABLE; | ||||||
|  |     can_initstruction.CAN_NART = ENABLE; | ||||||
|  |     can_initstruction.CAN_TXFP = DISABLE; | ||||||
|  |     can_initstruction.CAN_Mode = CAN_Mode_Silent_LoopBack; | ||||||
|  |     can_initstruction.CAN_RFLM = DISABLE; | ||||||
|  |     can_initstruction.CAN_SJW = CAN_SJW_1tq; | ||||||
|  |     can_initstruction.CAN_BS1 = CAN_BS1_6tq; | ||||||
|  |     can_initstruction.CAN_BS2 = CAN_BS2_5tq; | ||||||
|  |     can_initstruction.CAN_Prescaler = 12; | ||||||
|  |     CAN_Init(CAN1, &can_initstruction); | ||||||
|  | 
 | ||||||
|  |     can1_filter.CAN_FilterNumber = 0; | ||||||
|  |     can1_filter.CAN_FilterMode = CAN_FilterMode_IdMask; | ||||||
|  |     can1_filter.CAN_FilterScale = CAN_FilterScale_32bit; | ||||||
|  |     can1_filter.CAN_FilterIdHigh = 0x0000; | ||||||
|  |     can1_filter.CAN_FilterIdLow = 0x0000; | ||||||
|  |     can1_filter.CAN_FilterMaskIdHigh = 0x0000; | ||||||
|  |     can1_filter.CAN_FilterMaskIdLow = 0x0006; | ||||||
|  |     can1_filter.CAN_FilterFIFOAssignment = CAN_Filter_FIFO1; | ||||||
|  |     can1_filter.CAN_FilterActivation = ENABLE; | ||||||
|  |     CAN_FilterInit(&can1_filter); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static u8 CAN_Send_Msg(u8 *msg, u8 len) | ||||||
|  | { | ||||||
|  |     u8 mbox; | ||||||
|  |     u16 i = 0; | ||||||
|  | 
 | ||||||
|  |     CanTxMsg CanTxStructure; | ||||||
|  | 
 | ||||||
|  |     CanTxStructure.StdId = 0x317; | ||||||
|  |     CanTxStructure.IDE = CAN_Id_Standard; | ||||||
|  |     CanTxStructure.RTR = CAN_RTR_Data; | ||||||
|  |     CanTxStructure.DLC = len; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < len; i++) | ||||||
|  |     { | ||||||
|  |         CanTxStructure.Data[i] = msg[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     mbox = CAN_Transmit(CAN1, &CanTxStructure); | ||||||
|  | 
 | ||||||
|  |     i = 0; | ||||||
|  | 
 | ||||||
|  |     while ((CAN_TransmitStatus(CAN1, mbox) != CAN_TxStatus_Ok) && (i < 0xFFF)) | ||||||
|  |     { | ||||||
|  |         i++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (i == 0xFFF) | ||||||
|  |     { | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static u8 CAN_Receive_Msg(u8 *buf) | ||||||
|  | { | ||||||
|  |     u8 i; | ||||||
|  | 
 | ||||||
|  |     CanRxMsg CanRxStructure; | ||||||
|  | 
 | ||||||
|  |     if (CAN_MessagePending(CAN1, CAN_FIFO1) == 0) | ||||||
|  |     { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     CAN_Receive(CAN1, CAN_FIFO1, &CanRxStructure); | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 8; i++) | ||||||
|  |     { | ||||||
|  |         buf[i] = CanRxStructure.Data[i]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return CanRxStructure.DLC; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int test_can(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  |     u8 i; | ||||||
|  |     u8 cnt = 0; | ||||||
|  |     u8 tx, rx; | ||||||
|  |     u8 txbuf[8]; | ||||||
|  |     u8 rxbuf[8]; | ||||||
|  |     init_can(); | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < 8; i++) | ||||||
|  |     { | ||||||
|  |         txbuf[i] = cnt + i; | ||||||
|  |     } | ||||||
|  |     tx = CAN_Send_Msg(txbuf, 8); | ||||||
|  | 
 | ||||||
|  |     if (tx) | ||||||
|  |     { | ||||||
|  |         KPrintf("CAN1 Send Failed\r\n"); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         KPrintf("CAN1 Send Success\r\n"); | ||||||
|  |         KPrintf("CAN1 Send Data:\r\n"); | ||||||
|  | 
 | ||||||
|  |         for (i = 0; i < 8; i++) | ||||||
|  |         { | ||||||
|  |             KPrintf("%02x\r\n", txbuf[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     rx = CAN_Receive_Msg(rxbuf); | ||||||
|  | 
 | ||||||
|  |     if (rx) | ||||||
|  |     { | ||||||
|  |         KPrintf("CAN1 Receive Data:\r\n"); | ||||||
|  | 
 | ||||||
|  |         for (i = 0; i < 8; i++) | ||||||
|  |         { | ||||||
|  |             KPrintf("%02x\r\n", txbuf[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         KPrintf("CAN1 No Receive Data\r\n"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     cnt++; | ||||||
|  |     if (cnt == 0xFF) | ||||||
|  |     { | ||||||
|  |         cnt = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), | ||||||
|  |                  test_can, test_can, test CAN); | ||||||
|  | @ -0,0 +1,55 @@ | ||||||
|  | 
 | ||||||
|  | 0.该测试在Ubiquitous中测试通过(将驱动中静态的收发初始化操作在测试文件中实现),在APP_Framework的测试中BusFind,BusFindDriver,BusFindDevice可找到相应的设备,但无法通过其进行读写等操作 | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | // APP_Framework/Applications/main.c | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <transform.h> | ||||||
|  | #include <bus.h> | ||||||
|  | #define CAN_BUS "can1" | ||||||
|  | 
 | ||||||
|  | #define CAN_DRIVER "can1_drv" | ||||||
|  | 
 | ||||||
|  | #define CAN_DEVICE "can1_dev1" | ||||||
|  | 
 | ||||||
|  | void TestCAN(void) | ||||||
|  | { | ||||||
|  |     KPrintf("Test can start\n"); | ||||||
|  |     struct Bus *bus; | ||||||
|  |     struct HardwareDev *dev; | ||||||
|  |     struct Driver *drv; | ||||||
|  |     char test_str[] = "Hello AIIT!\r\n"; | ||||||
|  |     /* find the serial bus pointer */ | ||||||
|  |     bus = BusFind(CAN_BUS); | ||||||
|  |     if (NONE == bus) | ||||||
|  |     { | ||||||
|  |         KPrintf("BusFind %s failed\n", CAN_BUS); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     /* find the serial driver pointer */ | ||||||
|  |     drv = BusFindDriver(bus, CAN_DRIVER); | ||||||
|  |     if (NONE == drv) | ||||||
|  |     { | ||||||
|  |         KPrintf("BusFindDriver %s failed\n", CAN_DRIVER); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     /* find the serial device pointer */ | ||||||
|  |     dev = BusFindDevice(bus, CAN_DEVICE); | ||||||
|  |     if (NONE == dev) | ||||||
|  |     { | ||||||
|  |         KPrintf("BusFindDevice %s failed\n", CAN_DEVICE); | ||||||
|  |         return; | ||||||
|  |     }  | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(TestCAN, a can test sample, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 1.make BOARD=ch32v307vct6 menuconfig中配置can相关参数 ch32v307vct6 feature  ---> Using CAN device  --->  | ||||||
|  | 
 | ||||||
|  | 2.在can_test.c中can_initstruction.CAN_Mode表示can的收发模式,修改该参数可实现不同的收发方式,有CAN_Mode_Normal,CAN_Mode_LoopBack,CAN_Mode_Silent,CAN_Mode_Silent_LoopBack四种模式,此处用CAN_Mode_Silent_LoopBack该模式,实现自收自发,如果需要通过主机收发可修改为CAN_Mode_Normal | ||||||
|  | 
 | ||||||
|  | 3.编译后将其烧录至开发板上,执行test_can命令,运行can测试。 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,33 @@ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef CONNECT_CAN_H | ||||||
|  | #define CONNECT_CAN_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <bus_can.h> | ||||||
|  | #include <dev_can.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <ch32v30x.h> | ||||||
|  | #include <ch32v30x_can.h> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | struct CanDev | ||||||
|  | { | ||||||
|  |     CAN_TypeDef *instance; | ||||||
|  | 
 | ||||||
|  |     char *bus_name; | ||||||
|  | 
 | ||||||
|  |     // CAN_InitTypeDef init;
 | ||||||
|  | 
 | ||||||
|  |     uint8 can_flag; | ||||||
|  |     struct CanBus can_bus; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | int InitHwCan(void); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,46 @@ | ||||||
|  | /*
 | ||||||
|  | * Copyright (c) 2020 AIIT XUOS Lab | ||||||
|  | * XiUOS is licensed under Mulan PSL v2. | ||||||
|  | * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||||||
|  | * You may obtain a copy of Mulan PSL v2 at: | ||||||
|  | *        http://license.coscl.org.cn/MulanPSL2
 | ||||||
|  | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||||||
|  | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||||||
|  | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||||||
|  | * See the Mulan PSL v2 for more details. | ||||||
|  | */ | ||||||
|  |   | ||||||
|  | /**
 | ||||||
|  | * @file connect_usb.h | ||||||
|  | * @brief define aiit-arm32-board usb function and struct | ||||||
|  | * @version 1.0  | ||||||
|  | * @author AIIT XUOS Lab | ||||||
|  | * @date 2021-04-25 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #ifndef CONNECT_USB_H | ||||||
|  | #define CONNECT_USB_H | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include <bus_usb.h> | ||||||
|  | #include <dev_usb.h> | ||||||
|  | #ifdef RESOURCES_USB_HOST | ||||||
|  | #ifdef BSP_USING_USBH | ||||||
|  | #include <ch32v30x_usbhs_host.h> | ||||||
|  | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | int InitHwUsb(void); | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| menuconfig BSP_USING_UART1 | menuconfig BSP_USING_UART1 | ||||||
|     bool "Enable UART1" |     bool "Enable UART1" | ||||||
|     default y |     default n | ||||||
|     if BSP_USING_UART1 |     if BSP_USING_UART1 | ||||||
|         config SERIAL_BUS_NAME_1 |         config SERIAL_BUS_NAME_1 | ||||||
|             string "serial bus  name" |             string "serial bus  name" | ||||||
|  | @ -12,3 +12,48 @@ menuconfig BSP_USING_UART1 | ||||||
|                 string "serial bus  device name" |                 string "serial bus  device name" | ||||||
|                 default "uart1_dev1"    |                 default "uart1_dev1"    | ||||||
|     endif |     endif | ||||||
|  | 
 | ||||||
|  | menuconfig BSP_USING_UART2 | ||||||
|  |     bool "Enable UART2" | ||||||
|  |     default n | ||||||
|  |     if BSP_USING_UART2 | ||||||
|  |         config SERIAL_BUS_NAME_2 | ||||||
|  |             string "serial bus  name" | ||||||
|  |             default "uart2" | ||||||
|  |         config SERIAL_DRV_NAME_2 | ||||||
|  |             string "serial bus  driver name" | ||||||
|  |             default "uart2_drv" | ||||||
|  |         config SERIAL_2_DEVICE_NAME_0 | ||||||
|  |                 string "serial bus  device name" | ||||||
|  |                 default "uart2_dev2"    | ||||||
|  |     endif | ||||||
|  | 
 | ||||||
|  | menuconfig BSP_USING_UART4 | ||||||
|  |     bool "Enable UART4" | ||||||
|  |     default y | ||||||
|  |     if BSP_USING_UART4 | ||||||
|  |         config SERIAL_BUS_NAME_4 | ||||||
|  |             string "serial bus  name" | ||||||
|  |             default "uart4" | ||||||
|  |         config SERIAL_DRV_NAME_4 | ||||||
|  |             string "serial bus  driver name" | ||||||
|  |             default "uart4_drv" | ||||||
|  |         config SERIAL_4_DEVICE_NAME_0 | ||||||
|  |                 string "serial bus  device name" | ||||||
|  |                 default "uart4_dev4"    | ||||||
|  |     endif | ||||||
|  | 
 | ||||||
|  | menuconfig BSP_USING_UART5 | ||||||
|  |     bool "Enable UART5" | ||||||
|  |     default y | ||||||
|  |     if BSP_USING_UART5 | ||||||
|  |         config SERIAL_BUS_NAME_5 | ||||||
|  |             string "serial bus name" | ||||||
|  |             default "uart5" | ||||||
|  |         config SERIAL_DRV_NAME_5 | ||||||
|  |             string "serial bus  driver name" | ||||||
|  |             default "uart5_drv" | ||||||
|  |         config SERIAL_5_DEVICE_NAME_0 | ||||||
|  |                 string "serial bus  device name" | ||||||
|  |                 default "uart5_dev5"    | ||||||
|  |     endif | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| SRC_FILES := connect_uart.c | SRC_FILES := connect_uart.c test_uart.c | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| include $(KERNEL_ROOT)/compiler.mk | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  |  | ||||||
|  | @ -76,6 +76,7 @@ static void UartIsr(struct SerialDriver* serial_drv, struct SerialHardwareDevice | ||||||
| 
 | 
 | ||||||
| static uint32 SerialInit(struct SerialDriver* serial_drv, struct BusConfigureInfo* configure_info) | static uint32 SerialInit(struct SerialDriver* serial_drv, struct BusConfigureInfo* configure_info) | ||||||
| { | { | ||||||
|  |     KPrintf("Serial init\n"); | ||||||
|     NULL_PARAM_CHECK(serial_drv); |     NULL_PARAM_CHECK(serial_drv); | ||||||
|     struct SerialCfgParam* serial_cfg = (struct SerialCfgParam*)serial_drv->private_data; |     struct SerialCfgParam* serial_cfg = (struct SerialCfgParam*)serial_drv->private_data; | ||||||
|     // struct UsartHwCfg *serial_hw_cfg = (struct UsartHwCfg *)serial_cfg->hw_cfg.private_data;
 |     // struct UsartHwCfg *serial_hw_cfg = (struct UsartHwCfg *)serial_cfg->hw_cfg.private_data;
 | ||||||
|  | @ -95,67 +96,6 @@ static uint32 SerialInit(struct SerialDriver* serial_drv, struct BusConfigureInf | ||||||
|     // config serial receive sem timeout
 |     // config serial receive sem timeout
 | ||||||
|     dev_param->serial_timeout = serial_cfg->data_cfg.serial_timeout; |     dev_param->serial_timeout = serial_cfg->data_cfg.serial_timeout; | ||||||
| 
 | 
 | ||||||
|     // init usart type def
 |  | ||||||
|     GPIO_InitTypeDef GPIO_InitStructure; |  | ||||||
| 
 |  | ||||||
|     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); |  | ||||||
| 
 |  | ||||||
|     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; |  | ||||||
|     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |  | ||||||
|     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; |  | ||||||
|     GPIO_Init(GPIOA, &GPIO_InitStructure); |  | ||||||
| 
 |  | ||||||
|     USART_InitTypeDef USART_InitStructure; |  | ||||||
|     USART_InitStructure.USART_BaudRate = serial_cfg->data_cfg.serial_baud_rate; |  | ||||||
| 
 |  | ||||||
|     switch (serial_cfg->data_cfg.serial_data_bits) { |  | ||||||
|     case DATA_BITS_8: |  | ||||||
|         USART_InitStructure.USART_WordLength = USART_WordLength_8b; |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case DATA_BITS_9: |  | ||||||
|         USART_InitStructure.USART_WordLength = USART_WordLength_9b; |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|         USART_InitStructure.USART_WordLength = USART_WordLength_8b; |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     switch (serial_cfg->data_cfg.serial_stop_bits) { |  | ||||||
|     case STOP_BITS_1: |  | ||||||
|         USART_InitStructure.USART_StopBits = USART_StopBits_1; |  | ||||||
|         break; |  | ||||||
|     case STOP_BITS_2: |  | ||||||
|         USART_InitStructure.USART_StopBits = USART_StopBits_2; |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|         USART_InitStructure.USART_StopBits = USART_StopBits_1; |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     switch (serial_cfg->data_cfg.serial_parity_mode) { |  | ||||||
|     case PARITY_NONE: |  | ||||||
|         USART_InitStructure.USART_Parity = USART_Parity_No; |  | ||||||
|         break; |  | ||||||
|     case PARITY_ODD: |  | ||||||
|         USART_InitStructure.USART_Parity = USART_Parity_Odd; |  | ||||||
|         break; |  | ||||||
|     case PARITY_EVEN: |  | ||||||
|         USART_InitStructure.USART_Parity = USART_Parity_Even; |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|         USART_InitStructure.USART_Parity = USART_Parity_No; |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; |  | ||||||
|     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; |  | ||||||
| 
 |  | ||||||
|     USART_Init(USART1, &USART_InitStructure); |  | ||||||
|     USART_Cmd(USART1, ENABLE); |  | ||||||
|     // usart_hardware_flow_rts_config(serial_cfg->hw_cfg.serial_register_base, USART_RTS_DISABLE);
 |  | ||||||
|     // usart_hardware_flow_cts_config(serial_cfg->hw_cfg.serial_register_base, USART_CTS_DISABLE);
 |  | ||||||
| 
 |  | ||||||
|     return EOK; |     return EOK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -227,6 +167,17 @@ static int SerialGetChar(struct SerialHardwareDevice* serial_dev) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct SerialDataCfg data_cfg_init = { | static const struct SerialDataCfg data_cfg_init = { | ||||||
|  |     .serial_baud_rate = BAUD_RATE_9600, | ||||||
|  |     .serial_data_bits = DATA_BITS_8, | ||||||
|  |     .serial_stop_bits = STOP_BITS_1, | ||||||
|  |     .serial_parity_mode = PARITY_NONE, | ||||||
|  |     .serial_bit_order = BIT_ORDER_LSB, | ||||||
|  |     .serial_invert_mode = NRZ_NORMAL, | ||||||
|  |     .serial_buffer_size = SERIAL_RB_BUFSZ, | ||||||
|  |     .serial_timeout = WAITING_FOREVER, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct SerialDataCfg data_cfg_init_uart3 = { | ||||||
|     .serial_baud_rate = BAUD_RATE_115200, |     .serial_baud_rate = BAUD_RATE_115200, | ||||||
|     .serial_data_bits = DATA_BITS_8, |     .serial_data_bits = DATA_BITS_8, | ||||||
|     .serial_stop_bits = STOP_BITS_1, |     .serial_stop_bits = STOP_BITS_1, | ||||||
|  | @ -317,10 +268,90 @@ void USART1_IRQHandler(void) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | uint16_t UART_ReceiveData(USART_TypeDef* USARTx) | ||||||
|  | { | ||||||
|  |     return (uint16_t)(USARTx->DATAR & (uint16_t)0x01FF); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UART_SendData(USART_TypeDef* USARTx, uint16_t Data) | ||||||
|  | { | ||||||
|  |     USARTx->DATAR = (Data & (uint16_t)0x01FF); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef BSP_USING_UART2 | ||||||
|  | struct SerialDriver serial_driver_2; | ||||||
|  | struct SerialHardwareDevice serial_device_2; | ||||||
|  | 
 | ||||||
|  | #define TxSize2 100 | ||||||
|  | uint16_t RxBuffer2[TxSize2] = { 0 }; | ||||||
|  | uint16_t TxCnt2 = 0, RxCnt2 = 0; | ||||||
|  | 
 | ||||||
|  | void USART3_IRQHandler(void) __attribute__((interrupt())); | ||||||
|  | 
 | ||||||
|  | void USART3_IRQHandler(void) | ||||||
|  | { | ||||||
|  |     if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { | ||||||
|  |         RxBuffer2[RxCnt2++] = UART_ReceiveData(USART3); | ||||||
|  | 
 | ||||||
|  |         if (RxCnt2 == 100) { | ||||||
|  |             USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BSP_USING_UART4 | ||||||
|  | struct SerialDriver serial_driver_4; | ||||||
|  | struct SerialHardwareDevice serial_device_4; | ||||||
|  | 
 | ||||||
|  | #define TxSize2 100 | ||||||
|  | uint16_t RxBuffer4[TxSize2] = { 0 }; | ||||||
|  | uint16_t TxCnt4 = 0, RxCnt4 = 0; | ||||||
|  | 
 | ||||||
|  | void UART4_IRQHandler(void) __attribute__((interrupt())); | ||||||
|  | 
 | ||||||
|  | void UART4_IRQHandler(void) | ||||||
|  | { | ||||||
|  |     GET_INT_SP(); | ||||||
|  |     x_base level; | ||||||
|  |     level = DisableLocalInterrupt(); | ||||||
|  |     isrManager.done->incCounter(); | ||||||
|  |     EnableLocalInterrupt(level); | ||||||
|  |     UartIsr(&serial_driver_4, &serial_device_4); | ||||||
|  |     level = DisableLocalInterrupt(); | ||||||
|  |     isrManager.done->decCounter(); | ||||||
|  |     EnableLocalInterrupt(level); | ||||||
|  |     FREE_INT_SP(); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BSP_USING_UART5 | ||||||
|  | struct SerialDriver serial_driver_5; | ||||||
|  | struct SerialHardwareDevice serial_device_5; | ||||||
|  | 
 | ||||||
|  | #define TxSize5 100 | ||||||
|  | uint16_t RxBuffer5[TxSize5] = { 0 }; | ||||||
|  | uint16_t TxCnt5 = 0, RxCnt5 = 0; | ||||||
|  | 
 | ||||||
|  | void USART5_IRQHandler(void) __attribute__((interrupt())); | ||||||
|  | 
 | ||||||
|  | void USART5_IRQHandler(void) | ||||||
|  | { | ||||||
|  |     if (USART_GetITStatus(UART5, USART_IT_RXNE) != RESET) { | ||||||
|  |         RxBuffer5[RxCnt5++] = UART_ReceiveData(UART5); | ||||||
|  |         if (RxCnt5 == 100) { | ||||||
|  |             USART_ITConfig(UART5, USART_IT_RXNE, DISABLE); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| int InitHwUart(void) | int InitHwUart(void) | ||||||
| { | { | ||||||
|     x_err_t ret = EOK; |     x_err_t ret = EOK; | ||||||
| 
 | 
 | ||||||
|  | #ifdef BSP_USING_UART1 | ||||||
|     static struct SerialBus serial_bus; |     static struct SerialBus serial_bus; | ||||||
|     memset(&serial_bus, 0, sizeof(struct SerialBus)); |     memset(&serial_bus, 0, sizeof(struct SerialBus)); | ||||||
| 
 | 
 | ||||||
|  | @ -340,10 +371,8 @@ int InitHwUart(void) | ||||||
| 
 | 
 | ||||||
|     serial_cfg.data_cfg = data_cfg_init; |     serial_cfg.data_cfg = data_cfg_init; | ||||||
| 
 | 
 | ||||||
| #ifdef BSP_USING_UART1 |  | ||||||
|     serial_cfg.hw_cfg.serial_register_base = (uint32)USART1; |     serial_cfg.hw_cfg.serial_register_base = (uint32)USART1; | ||||||
|     serial_cfg.hw_cfg.serial_irq_interrupt = USART1_IRQn; |     serial_cfg.hw_cfg.serial_irq_interrupt = USART1_IRQn; | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
|     serial_driver_1.private_data = (void*)&serial_cfg; |     serial_driver_1.private_data = (void*)&serial_cfg; | ||||||
| 
 | 
 | ||||||
|  | @ -374,7 +403,7 @@ int InitHwUart(void) | ||||||
|     GPIO_Init(GPIOA, &gpio_init_struct); |     GPIO_Init(GPIOA, &gpio_init_struct); | ||||||
| 
 | 
 | ||||||
|     USART_InitTypeDef usart_init_struct; |     USART_InitTypeDef usart_init_struct; | ||||||
|     usart_init_struct.USART_BaudRate = 115200; |     usart_init_struct.USART_BaudRate = 9600; | ||||||
|     usart_init_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; |     usart_init_struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; | ||||||
|     usart_init_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; |     usart_init_struct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; | ||||||
|     usart_init_struct.USART_WordLength = USART_WordLength_8b; |     usart_init_struct.USART_WordLength = USART_WordLength_8b; | ||||||
|  | @ -382,6 +411,199 @@ int InitHwUart(void) | ||||||
|     usart_init_struct.USART_Parity = USART_Parity_No; |     usart_init_struct.USART_Parity = USART_Parity_No; | ||||||
|     USART_Init((USART_TypeDef*)serial_cfg.hw_cfg.serial_register_base, &usart_init_struct); |     USART_Init((USART_TypeDef*)serial_cfg.hw_cfg.serial_register_base, &usart_init_struct); | ||||||
|     USART_Cmd((USART_TypeDef*)serial_cfg.hw_cfg.serial_register_base, ENABLE); |     USART_Cmd((USART_TypeDef*)serial_cfg.hw_cfg.serial_register_base, ENABLE); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BSP_USING_UART2 | ||||||
|  |     static struct SerialBus serial_bus_2; | ||||||
|  |     memset(&serial_bus_2, 0, sizeof(struct SerialBus)); | ||||||
|  | 
 | ||||||
|  |     memset(&serial_driver_2, 0, sizeof(struct SerialDriver)); | ||||||
|  | 
 | ||||||
|  |     memset(&serial_device_2, 0, sizeof(struct SerialHardwareDevice)); | ||||||
|  | 
 | ||||||
|  |     static struct SerialCfgParam serial_cfg_2; | ||||||
|  |     memset(&serial_cfg_2, 0, sizeof(struct SerialCfgParam)); | ||||||
|  | 
 | ||||||
|  |     static struct SerialDevParam serial_dev_param_2; | ||||||
|  |     memset(&serial_dev_param_2, 0, sizeof(struct SerialDevParam)); | ||||||
|  | 
 | ||||||
|  |     serial_driver_2.drv_done = &drv_done; | ||||||
|  |     serial_driver_2.configure = &SerialDrvConfigure; | ||||||
|  |     serial_device_2.hwdev_done = &hwdev_done; | ||||||
|  | 
 | ||||||
|  |     serial_cfg_2.data_cfg = data_cfg_init; | ||||||
|  | 
 | ||||||
|  |     serial_cfg_2.hw_cfg.serial_register_base = (uint32)USART3; | ||||||
|  |     serial_cfg_2.hw_cfg.serial_irq_interrupt = USART3_IRQn; | ||||||
|  | 
 | ||||||
|  |     serial_driver_2.private_data = (void*)&serial_cfg_2; | ||||||
|  | 
 | ||||||
|  |     serial_dev_param_2.serial_work_mode = SIGN_OPER_INT_RX; | ||||||
|  |     serial_device_2.haldev.private_data = (void*)&serial_dev_param_2; | ||||||
|  | 
 | ||||||
|  |     ret = BoardSerialBusInit(&serial_bus_2, &serial_driver_2, SERIAL_BUS_NAME_2, SERIAL_DRV_NAME_2); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("InitHwUart 2 uarths error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = BoardSerialDevBend(&serial_device_2, (void*)&serial_cfg_2, SERIAL_BUS_NAME_2, SERIAL_2_DEVICE_NAME_0); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("InitHwUart 2 uarths error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     GPIO_InitTypeDef gpio_init_struct_2; | ||||||
|  |     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); | ||||||
|  |     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); | ||||||
|  |     // RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART3 | RCC_APB2Periph_GPIOB, ENABLE);
 | ||||||
|  |     gpio_init_struct_2.GPIO_Pin = GPIO_Pin_10; | ||||||
|  |     gpio_init_struct_2.GPIO_Speed = GPIO_Speed_50MHz; | ||||||
|  |     gpio_init_struct_2.GPIO_Mode = GPIO_Mode_AF_PP; | ||||||
|  |     GPIO_Init(GPIOB, &gpio_init_struct_2); | ||||||
|  |     gpio_init_struct_2.GPIO_Pin = GPIO_Pin_11; | ||||||
|  |     gpio_init_struct_2.GPIO_Speed = GPIO_Speed_50MHz; | ||||||
|  |     gpio_init_struct_2.GPIO_Mode = GPIO_Mode_IN_FLOATING; | ||||||
|  |     GPIO_Init(GPIOB, &gpio_init_struct_2); | ||||||
|  | 
 | ||||||
|  |     USART_InitTypeDef usart_init_struct_2; | ||||||
|  |     usart_init_struct_2.USART_BaudRate = 9600; | ||||||
|  |     usart_init_struct_2.USART_HardwareFlowControl = USART_HardwareFlowControl_None; | ||||||
|  |     usart_init_struct_2.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; | ||||||
|  |     usart_init_struct_2.USART_WordLength = USART_WordLength_8b; | ||||||
|  |     usart_init_struct_2.USART_StopBits = USART_StopBits_1; | ||||||
|  |     usart_init_struct_2.USART_Parity = USART_Parity_No; | ||||||
|  |     USART_Init((USART_TypeDef*)serial_cfg_2.hw_cfg.serial_register_base, &usart_init_struct_2); | ||||||
|  |     USART_Cmd((USART_TypeDef*)serial_cfg_2.hw_cfg.serial_register_base, ENABLE); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BSP_USING_UART4 | ||||||
|  |     static struct SerialBus serial_bus_4; | ||||||
|  |     memset(&serial_bus_4, 0, sizeof(struct SerialBus)); | ||||||
|  | 
 | ||||||
|  |     memset(&serial_driver_4, 0, sizeof(struct SerialDriver)); | ||||||
|  | 
 | ||||||
|  |     memset(&serial_device_4, 0, sizeof(struct SerialHardwareDevice)); | ||||||
|  | 
 | ||||||
|  |     static struct SerialCfgParam serial_cfg_4; | ||||||
|  |     memset(&serial_cfg_4, 0, sizeof(struct SerialCfgParam)); | ||||||
|  | 
 | ||||||
|  |     static struct SerialDevParam serial_dev_param_4; | ||||||
|  |     memset(&serial_dev_param_4, 0, sizeof(struct SerialDevParam)); | ||||||
|  | 
 | ||||||
|  |     serial_driver_4.drv_done = &drv_done; | ||||||
|  |     serial_driver_4.configure = &SerialDrvConfigure; | ||||||
|  |     serial_device_4.hwdev_done = &hwdev_done; | ||||||
|  | 
 | ||||||
|  |     serial_cfg_4.data_cfg = data_cfg_init; | ||||||
|  | 
 | ||||||
|  |     serial_cfg_4.hw_cfg.serial_register_base = (uint32)UART4; | ||||||
|  |     serial_cfg_4.hw_cfg.serial_irq_interrupt = UART4_IRQn; | ||||||
|  | 
 | ||||||
|  |     serial_driver_4.private_data = (void*)&serial_cfg_4; | ||||||
|  | 
 | ||||||
|  |     serial_dev_param_4.serial_work_mode = SIGN_OPER_INT_RX; | ||||||
|  |     serial_device_4.haldev.private_data = (void*)&serial_dev_param_4; | ||||||
|  | 
 | ||||||
|  |     ret = BoardSerialBusInit(&serial_bus_4, &serial_driver_4, SERIAL_BUS_NAME_4, SERIAL_DRV_NAME_4); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("InitHwUart 4 uarths error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = BoardSerialDevBend(&serial_device_4, (void*)&serial_cfg_4, SERIAL_BUS_NAME_4, SERIAL_4_DEVICE_NAME_0); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("InitHwUart 4 uarths error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     GPIO_InitTypeDef gpio_init_struct_4; | ||||||
|  |     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); | ||||||
|  |     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); | ||||||
|  | 
 | ||||||
|  |     gpio_init_struct_4.GPIO_Pin = GPIO_Pin_10; | ||||||
|  |     gpio_init_struct_4.GPIO_Speed = GPIO_Speed_50MHz; | ||||||
|  |     gpio_init_struct_4.GPIO_Mode = GPIO_Mode_AF_PP; | ||||||
|  |     GPIO_Init(GPIOC, &gpio_init_struct_4); | ||||||
|  |     gpio_init_struct_4.GPIO_Pin = GPIO_Pin_11; | ||||||
|  |     gpio_init_struct_4.GPIO_Speed = GPIO_Speed_50MHz; | ||||||
|  |     gpio_init_struct_4.GPIO_Mode = GPIO_Mode_IN_FLOATING; | ||||||
|  |     GPIO_Init(GPIOC, &gpio_init_struct_4); | ||||||
|  | 
 | ||||||
|  |     USART_InitTypeDef usart_init_struct_4; | ||||||
|  |     usart_init_struct_4.USART_BaudRate = 9600; | ||||||
|  |     usart_init_struct_4.USART_HardwareFlowControl = USART_HardwareFlowControl_None; | ||||||
|  |     usart_init_struct_4.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; | ||||||
|  |     usart_init_struct_4.USART_WordLength = USART_WordLength_8b; | ||||||
|  |     usart_init_struct_4.USART_StopBits = USART_StopBits_1; | ||||||
|  |     usart_init_struct_4.USART_Parity = USART_Parity_No; | ||||||
|  |     USART_Init((USART_TypeDef*)serial_cfg_4.hw_cfg.serial_register_base, &usart_init_struct_4); | ||||||
|  |     USART_Cmd((USART_TypeDef*)serial_cfg_4.hw_cfg.serial_register_base, ENABLE); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef BSP_USING_UART5 | ||||||
|  |     static struct SerialBus serial_bus_5; | ||||||
|  |     memset(&serial_bus_5, 0, sizeof(struct SerialBus)); | ||||||
|  | 
 | ||||||
|  |     memset(&serial_driver_5, 0, sizeof(struct SerialDriver)); | ||||||
|  | 
 | ||||||
|  |     memset(&serial_device_5, 0, sizeof(struct SerialHardwareDevice)); | ||||||
|  | 
 | ||||||
|  |     static struct SerialCfgParam serial_cfg_5; | ||||||
|  |     memset(&serial_cfg_5, 0, sizeof(struct SerialCfgParam)); | ||||||
|  | 
 | ||||||
|  |     static struct SerialDevParam serial_dev_param_5; | ||||||
|  |     memset(&serial_dev_param_5, 0, sizeof(struct SerialDevParam)); | ||||||
|  | 
 | ||||||
|  |     serial_driver_5.drv_done = &drv_done; | ||||||
|  |     serial_driver_5.configure = &SerialDrvConfigure; | ||||||
|  |     serial_device_5.hwdev_done = &hwdev_done; | ||||||
|  | 
 | ||||||
|  |     serial_cfg_5.data_cfg = data_cfg_init; | ||||||
|  | 
 | ||||||
|  |     serial_cfg_5.hw_cfg.serial_register_base = (uint32)UART5; | ||||||
|  |     serial_cfg_5.hw_cfg.serial_irq_interrupt = UART5_IRQn; | ||||||
|  | 
 | ||||||
|  |     serial_driver_5.private_data = (void*)&serial_cfg_5; | ||||||
|  | 
 | ||||||
|  |     serial_dev_param_5.serial_work_mode = SIGN_OPER_INT_RX; | ||||||
|  |     serial_device_5.haldev.private_data = (void*)&serial_dev_param_5; | ||||||
|  | 
 | ||||||
|  |     ret = BoardSerialBusInit(&serial_bus_5, &serial_driver_5, SERIAL_BUS_NAME_5, SERIAL_DRV_NAME_5); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("InitHwUart 5 uarths error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = BoardSerialDevBend(&serial_device_5, (void*)&serial_cfg_5, SERIAL_BUS_NAME_5, SERIAL_5_DEVICE_NAME_0); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("InitHwUart 5 uarths error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     GPIO_InitTypeDef gpio_init_struct_5; | ||||||
|  |     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); | ||||||
|  |     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE); | ||||||
|  | 
 | ||||||
|  |     gpio_init_struct_5.GPIO_Pin = GPIO_Pin_12; | ||||||
|  |     gpio_init_struct_5.GPIO_Speed = GPIO_Speed_50MHz; | ||||||
|  |     gpio_init_struct_5.GPIO_Mode = GPIO_Mode_AF_PP; | ||||||
|  |     GPIO_Init(GPIOC, &gpio_init_struct_5); | ||||||
|  |     gpio_init_struct_5.GPIO_Pin = GPIO_Pin_2; | ||||||
|  |     gpio_init_struct_5.GPIO_Speed = GPIO_Speed_50MHz; | ||||||
|  |     gpio_init_struct_5.GPIO_Mode = GPIO_Mode_IN_FLOATING; | ||||||
|  |     GPIO_Init(GPIOD, &gpio_init_struct_5); | ||||||
|  | 
 | ||||||
|  |     USART_InitTypeDef usart_init_struct_5; | ||||||
|  |     usart_init_struct_5.USART_BaudRate = 9600; | ||||||
|  |     usart_init_struct_5.USART_HardwareFlowControl = USART_HardwareFlowControl_None; | ||||||
|  |     usart_init_struct_5.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; | ||||||
|  |     usart_init_struct_5.USART_WordLength = USART_WordLength_8b; | ||||||
|  |     usart_init_struct_5.USART_StopBits = USART_StopBits_1; | ||||||
|  |     usart_init_struct_5.USART_Parity = USART_Parity_No; | ||||||
|  |     USART_Init((USART_TypeDef*)serial_cfg_5.hw_cfg.serial_register_base, &usart_init_struct_5); | ||||||
|  |     USART_Cmd((USART_TypeDef*)serial_cfg_5.hw_cfg.serial_register_base, ENABLE); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  | @ -0,0 +1,76 @@ | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <sys/ioctl.h> | ||||||
|  | #include <termios.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | int main() | ||||||
|  | { | ||||||
|  |     int fd; | ||||||
|  |     struct termios tty; | ||||||
|  |     char buffer[256]; | ||||||
|  | 
 | ||||||
|  |     // 打开串口设备
 | ||||||
|  |     fd = open("/dev/ttySC3", O_RDWR | O_NOCTTY); | ||||||
|  |     if (fd == -1) { | ||||||
|  |         perror("打开串口失败"); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 获取当前串口配置
 | ||||||
|  |     if (tcgetattr(fd, &tty) != 0) { | ||||||
|  |         perror("获取串口配置失败"); | ||||||
|  |         close(fd); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 设置波特率为9600
 | ||||||
|  |     cfsetispeed(&tty, B9600); | ||||||
|  |     cfsetospeed(&tty, B9600); | ||||||
|  | 
 | ||||||
|  |     // 8位数据位,无校验位,1位停止位
 | ||||||
|  |     tty.c_cflag &= ~PARENB; | ||||||
|  |     tty.c_cflag &= ~CSTOPB; | ||||||
|  |     tty.c_cflag &= ~CSIZE; | ||||||
|  |     tty.c_cflag |= CS8; | ||||||
|  | 
 | ||||||
|  |     // 非规范模式,禁止软件流控制
 | ||||||
|  |     tty.c_iflag &= ~(IXON | IXOFF | IXANY); | ||||||
|  |     tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); | ||||||
|  | 
 | ||||||
|  |     // 禁止输出回车换行和换行符的映射
 | ||||||
|  |     tty.c_oflag &= ~OPOST; | ||||||
|  |     tty.c_oflag &= ~ONLCR; | ||||||
|  | 
 | ||||||
|  |     // 设置新的串口配置
 | ||||||
|  |     if (tcsetattr(fd, TCSANOW, &tty) != 0) { | ||||||
|  |         perror("设置串口配置失败"); | ||||||
|  |         close(fd); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 获取待读取数据的字节数
 | ||||||
|  |     int bytes_available; | ||||||
|  |     printf("读取中\n"); | ||||||
|  |     while (1) { | ||||||
|  |         int res = ioctl(fd, TIOCINQ, &bytes_available); | ||||||
|  | 
 | ||||||
|  |         if (res != -1) { | ||||||
|  |             if (bytes_available > 0) { | ||||||
|  |                 // 读取串口数据
 | ||||||
|  |                 printf("read\n"); | ||||||
|  |                 int bytes_read = read(fd, buffer, sizeof(buffer)); | ||||||
|  |                 if (bytes_read > 0) { | ||||||
|  |                     // 在这里处理读取到的数据
 | ||||||
|  |                     printf("读取到的数据: %s\n", buffer); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 关闭串口设备
 | ||||||
|  |     close(fd); | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | SRC_FILES := rs485_test.c | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | @ -0,0 +1,84 @@ | ||||||
|  | 0.该测试在Ubiquitous中测试通过(将驱动中静态的收发操作在测试文件中实现),在APP_Framework的测试中BusFind,BusFindDriver,BusFindDevice可找到相应的设备,但无法通过其进行读写等操作 | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | // APP_Framework/Applications/main.c | ||||||
|  | 
 | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <transform.h> | ||||||
|  | #include <bus.h> | ||||||
|  | #define RS485_UART_BUS "uart5" | ||||||
|  | #define RS485_UART_DRV "uart5_drv" | ||||||
|  | #define RS485_UART_DEV "uart5_dev5" | ||||||
|  | 
 | ||||||
|  | void Test485(void) | ||||||
|  | { | ||||||
|  |     /* | ||||||
|  |     485的驱动,使用UART5,在connect_uart.c中添加UART5的初始化,添加UART5的Kconfig,borad.c中使用InstallConsole用uart5串口正常输出控制台信息;在app_famework中加入app_test的485测试用例后出现 | ||||||
|  | 
 | ||||||
|  |     HardFault_Handler. | ||||||
|  |     mepc  :000f448 | ||||||
|  |     mcause:0000007 | ||||||
|  |     mtval :200100d4 | ||||||
|  |      | ||||||
|  |     报错,控制台停止运行,最后将Test485用例摘出放置main.c中,发现将PrivOpen编译进bin就会报错(没有实际执行) | ||||||
|  |      | ||||||
|  |     试了试busfind,bus,bus_drv,bus_dev都能找到,但是BusDevWriteData(dev, &write_param)编译进去后无法运行(OS无法起来/没有实际执行);Busdevclose导致程序崩溃 | ||||||
|  |      | ||||||
|  |     Test 485 start | ||||||
|  |     [ERR][x_free] Freeing a unallocated address. | ||||||
|  |     HardFault_Handler. | ||||||
|  |     mepc  :0000012 | ||||||
|  |     mcause:0000002 | ||||||
|  |     mtval :0000000 | ||||||
|  |      | ||||||
|  |     在Ubiquitous/XiZi_IIoT/board/ch32v307vct6/third_party_driver/uart/test测试中 | ||||||
|  |     可以通过485串口正常输出接收 | ||||||
|  |      | ||||||
|  |     */ | ||||||
|  |      | ||||||
|  |     KPrintf("Test 485 start\n"); | ||||||
|  |     struct Bus *bus; | ||||||
|  |     struct HardwareDev *dev; | ||||||
|  |     struct Driver *drv; | ||||||
|  |     char test_str[] = "Hello AIIT!\r\n"; | ||||||
|  |     /* find the serial bus pointer */ | ||||||
|  |     bus = BusFind(RS485_UART_BUS); | ||||||
|  |     if (NONE == bus) | ||||||
|  |     { | ||||||
|  |         KPrintf("BusFind %s failed\n", RS485_UART_BUS); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     /* find the serial driver pointer */ | ||||||
|  |     drv = BusFindDriver(bus, RS485_UART_DRV); | ||||||
|  |     if (NONE == drv) | ||||||
|  |     { | ||||||
|  |         KPrintf("BusFindDriver %s failed\n", RS485_UART_DRV); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     /* find the serial device pointer */ | ||||||
|  |     dev = BusFindDevice(bus, RS485_UART_DEV); | ||||||
|  |     if (NONE == dev) | ||||||
|  |     { | ||||||
|  |         KPrintf("BusFindDevice %s failed\n", RS485_UART_DEV); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     struct BusBlockWriteParam write_param; | ||||||
|  |     write_param.pos = 0; | ||||||
|  |     write_param.buffer = (void *)test_str; | ||||||
|  |     write_param.size = sizeof(test_str) - 1; | ||||||
|  |      | ||||||
|  |     // BusDevWriteData(dev, &write_param); | ||||||
|  |     // BusDevClose(dev); | ||||||
|  |      | ||||||
|  |     return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PRIV_SHELL_CMD_FUNCTION(Test485, a 485 test sample, PRIV_SHELL_CMD_MAIN_ATTR); | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 1.make BOARD=ch32v307vct6 menuconfig中配置UART相关参数 ch32v307vct6 feature  ---> Enable UART5  ---> | ||||||
|  | 
 | ||||||
|  | 2.编译后将其烧录至开发板上,连接485转USB硬件至主机,主机使用串口工具打开执行test_rs485命令,运行485收发测试。 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,115 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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 rs485_test.c | ||||||
|  |  * @brief test ch32v307 485 | ||||||
|  |  * @version 1.0 | ||||||
|  |  * @author AIIT XUOS Lab | ||||||
|  |  * @date 2024-03-14 | ||||||
|  |  */ | ||||||
|  | #include "shell.h" | ||||||
|  | #include "ch32v30x.h" | ||||||
|  | #include "ch32v30x_usart.h" | ||||||
|  | #include "connect_uart.h" | ||||||
|  | 
 | ||||||
|  | // UART5发送数据
 | ||||||
|  | static void UART5_SendData(uint8_t data) | ||||||
|  | { | ||||||
|  |     // 等待发送缓冲区为空
 | ||||||
|  |     while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 发送数据
 | ||||||
|  |     USART_SendData(UART5, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // UART5接收数据
 | ||||||
|  | static uint8_t UART5_ReceiveData(void) | ||||||
|  | { | ||||||
|  |     // 等待接收缓冲区非空
 | ||||||
|  |     while (USART_GetFlagStatus(UART5, USART_FLAG_RXNE) == RESET) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // 读取接收数据
 | ||||||
|  |     return USART_ReceiveData(UART5); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void UART5_SendString(const char *buffer) | ||||||
|  | { | ||||||
|  |     size_t len = strlen(buffer); | ||||||
|  |     for (size_t i = 0; i < len; i++) | ||||||
|  |     { | ||||||
|  |         if (buffer[i] != '\r' || buffer[i] != '\n') | ||||||
|  |         { | ||||||
|  |             UART5_SendData(buffer[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void UART5_ReceiveString(char *buffer, size_t bufferSize) | ||||||
|  | { | ||||||
|  |     size_t i = 0; | ||||||
|  | 
 | ||||||
|  |     while (i < bufferSize - 1) | ||||||
|  |     { | ||||||
|  |         char receivedChar = UART5_ReceiveData(); | ||||||
|  | 
 | ||||||
|  |         if (receivedChar == '\n') | ||||||
|  |         { | ||||||
|  |             // 收到回车或换行符,表示字符串接收完毕
 | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         buffer[i] = receivedChar; | ||||||
|  |         i++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     buffer[i] = '\0'; // 在字符串末尾添加空字符,表示字符串结束
 | ||||||
|  | 
 | ||||||
|  |     while (USART_GetFlagStatus(UART5, USART_FLAG_RXNE) != RESET) | ||||||
|  |     { | ||||||
|  |         char dummy = USART_ReceiveData(UART5); | ||||||
|  |         (void)dummy; // 避免编译器警告
 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int test_rs485(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  |     KPrintf("485 Test\r\n"); | ||||||
|  |     char receiveBuffer[100]; | ||||||
|  |     char *sendString = " hello aiit 485\r\n"; | ||||||
|  |     int n = 10; | ||||||
|  |     UART5_SendString(sendString); | ||||||
|  |     while (n--) | ||||||
|  |     { | ||||||
|  |         // 接收字符串
 | ||||||
|  |         UART5_ReceiveString(receiveBuffer, sizeof(receiveBuffer)); | ||||||
|  |         KPrintf("%s\r\n", receiveBuffer); | ||||||
|  |         if (receiveBuffer[0] == 0xfd) | ||||||
|  |         { | ||||||
|  |             UART5_SendString(sendString); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             USART_ClearFlag(UART5, USART_FLAG_TC); | ||||||
|  |             UART5_SendString(receiveBuffer); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), | ||||||
|  |                  test_rs485, test_rs485, test rs485); | ||||||
|  | @ -0,0 +1,34 @@ | ||||||
|  | #include "ch32v30x.h" | ||||||
|  | #include "connect_uart.h" | ||||||
|  | 
 | ||||||
|  | extern RxBuffer2; | ||||||
|  | extern uint16_t UART_ReceiveData(USART_TypeDef* USARTx); | ||||||
|  | extern void UART_SendData(USART_TypeDef* USARTx, uint16_t Data); | ||||||
|  | 
 | ||||||
|  | void send_rensa() | ||||||
|  | { | ||||||
|  |     char* s = "ch uart"; | ||||||
|  |     while (*s) { | ||||||
|  |         UART_SendData(USART3, (uint16_t)*s++); | ||||||
|  |         KPrintf("%c", *s); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void recv_rensa() | ||||||
|  | { | ||||||
|  |     uint16_t ans = 0; | ||||||
|  |     char recv_data = ' '; | ||||||
|  | 
 | ||||||
|  |     int cnt = 0; | ||||||
|  |     while (recv_data != '\n') { | ||||||
|  |         recv_data = (char)UART_ReceiveData(USART3); | ||||||
|  |         KPrintf("%c", recv_data); | ||||||
|  |     } | ||||||
|  |     recv_data = ' '; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), | ||||||
|  |     recv_rensa, recv_rensa, test receive renesa); | ||||||
|  | 
 | ||||||
|  | SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), | ||||||
|  |     send_rensa, send_rensa, test send renesa); | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | 
 | ||||||
|  | menuconfig BSP_USING_USBH | ||||||
|  |     bool "Using usb host" | ||||||
|  |     default y | ||||||
|  |     if BSP_USING_USBH | ||||||
|  |         config USB_BUS_NAME | ||||||
|  |             string "usb bus name" | ||||||
|  |             default "usb" | ||||||
|  |         config USB_DRIVER_NAME | ||||||
|  |             string "usb bus driver name" | ||||||
|  |             default "usb_drv" | ||||||
|  |         config USB_DEVICE_NAME | ||||||
|  |             string "usb bus device name" | ||||||
|  |             default "usb_dev" | ||||||
|  |         config MOUNT_USB_FS | ||||||
|  |             bool "mount usb file system" | ||||||
|  |             default y | ||||||
|  |             select MOUNT_USB | ||||||
|  | 
 | ||||||
|  |         if MOUNT_USB_FS | ||||||
|  |             config MOUNT_USB_FS_TYPE | ||||||
|  |                 int "choose file system type : FATFS(0) LWEXT4(3)" | ||||||
|  |                 default 0  | ||||||
|  |         endif | ||||||
|  |     endif | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | SRC_FILES := connect_usb.c | ||||||
|  | SRC_DIR += usb_drv/src | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,134 @@ | ||||||
|  | /*
 | ||||||
|  | * Copyright (c) 2020 AIIT XUOS Lab | ||||||
|  | * XiUOS is licensed under Mulan PSL v2. | ||||||
|  | * You can use this software according to the terms and conditions of the Mulan PSL v2. | ||||||
|  | * You may obtain a copy of Mulan PSL v2 at: | ||||||
|  | *        http://license.coscl.org.cn/MulanPSL2
 | ||||||
|  | * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||||||
|  | * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||||||
|  | * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||||||
|  | * See the Mulan PSL v2 for more details. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  | * @file connect_usb.c | ||||||
|  | * @brief support aiit-arm32-board usb function and register to bus framework | ||||||
|  | * @version 1.0  | ||||||
|  | * @author AIIT XUOS Lab | ||||||
|  | * @date 2021-04-25 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #include <board.h> | ||||||
|  | #include <ch32v30x_usbhs_host.h> | ||||||
|  | #include <connect_usb.h> | ||||||
|  | 
 | ||||||
|  | uint32 UdiskRead_new_api(void *dev, struct BusBlockReadParam *read_param); | ||||||
|  | uint32 UdiskWirte_new_api(void *dev, struct BusBlockWriteParam *write_param); | ||||||
|  | 
 | ||||||
|  | #ifdef MOUNT_USB | ||||||
|  | #define DISABLE 0 | ||||||
|  | #define ENABLE 1 | ||||||
|  | 
 | ||||||
|  | int MountUsb(void) | ||||||
|  | { | ||||||
|  |     Udisk_USBH_Initialization(); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static uint32 UdiskOpenNewApi(void *dev) | ||||||
|  | { | ||||||
|  |     return EOK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static uint32 UdiskCloseNewApi(void *dev) | ||||||
|  | { | ||||||
|  |     return EOK; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*manage the usb device operations*/ | ||||||
|  | static const struct UsbDevDone dev_done = | ||||||
|  | { | ||||||
|  |     .open = UdiskOpenNewApi, | ||||||
|  |     .close = UdiskCloseNewApi, | ||||||
|  |     .write = UdiskWirte_new_api, | ||||||
|  |     .read = UdiskRead_new_api, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*Init usb bus*/ | ||||||
|  | static int BoardUsbBusInit(struct UsbBus *usb_bus, struct UsbDriver *usb_driver) | ||||||
|  | { | ||||||
|  |     x_err_t ret = EOK; | ||||||
|  | 
 | ||||||
|  |     /*Init the usb bus */ | ||||||
|  |     ret = UsbBusInit(usb_bus, USB_BUS_NAME); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("board_usb_init UsbBusInit error %d\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /*Init the usb driver*/ | ||||||
|  |     ret = UsbDriverInit(usb_driver, USB_DRIVER_NAME); | ||||||
|  |     if (EOK != ret){ | ||||||
|  |         KPrintf("board_usb_init UsbDriverInit error %d\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /*Attach the usb driver to the usb bus*/ | ||||||
|  |     ret = UsbDriverAttachToBus(USB_DRIVER_NAME, USB_BUS_NAME); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("board_usb_init USEDriverAttachToBus error %d\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*Attach the usb device to the usb bus*/ | ||||||
|  | static int BoardUsbDevBend(void) | ||||||
|  | { | ||||||
|  |     x_err_t ret = EOK; | ||||||
|  |     static struct UsbHardwareDevice usb_device1; | ||||||
|  |     memset(&usb_device1, 0, sizeof(struct UsbHardwareDevice)); | ||||||
|  | 
 | ||||||
|  |     usb_device1.dev_done = &dev_done; | ||||||
|  | 
 | ||||||
|  |     ret = USBDeviceRegister(&usb_device1, NONE, USB_DEVICE_NAME); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("board_usb_init USBDeviceInit device %s error %d\n", USB_DEVICE_NAME, ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = USBDeviceAttachToBus(USB_DEVICE_NAME, USB_BUS_NAME); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("board_usb_init USBDeviceAttachToBus device %s error %d\n", USB_DEVICE_NAME, ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*BOARD USB INIT*/ | ||||||
|  | int InitHwUsb(void) | ||||||
|  | { | ||||||
|  |     x_err_t ret = EOK; | ||||||
|  |     static struct UsbBus usb_bus; | ||||||
|  |     memset(&usb_bus, 0, sizeof(struct UsbBus)); | ||||||
|  | 
 | ||||||
|  |     static struct UsbDriver usb_driver; | ||||||
|  |     memset(&usb_driver, 0, sizeof(struct UsbDriver)); | ||||||
|  | 
 | ||||||
|  |     ret = BoardUsbBusInit(&usb_bus, &usb_driver); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("board_usb_Init error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = BoardUsbDevBend(); | ||||||
|  |     if (EOK != ret) { | ||||||
|  |         KPrintf("board_usb_Init error ret %u\n", ret); | ||||||
|  |         return ERROR; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | @ -0,0 +1,366 @@ | ||||||
|  | /* 2014.09.09
 | ||||||
|  | ***************************************** | ||||||
|  | **   Copyright  (C)  W.ch  1999-2019   ** | ||||||
|  | **   Web:      http://wch.cn           **
 | ||||||
|  | ***************************************** | ||||||
|  | **  USB-flash File Interface for CHRV3 ** | ||||||
|  | **  KEIL423, gcc 8.20          ** | ||||||
|  | ***************************************** | ||||||
|  | */ | ||||||
|  | /* CHRV3 U盘主机文件系统接口, 支持: FAT12/FAT16/FAT32 */ | ||||||
|  | 
 | ||||||
|  | //#include "CHRV3BAS.H"
 | ||||||
|  | 
 | ||||||
|  | #ifndef __CHRV3UFI_H__ | ||||||
|  | #define __CHRV3UFI_H__ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #define CHRV3_LIB_VER		0x10 | ||||||
|  | 
 | ||||||
|  | //#define DISK_BASE_BUF_LEN		512	/* 默认的磁盘数据缓冲区大小为512字节(可以选择为2048甚至4096以支持某些大扇区的U盘),为0则禁止在本文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */
 | ||||||
|  | /* 如果需要复用磁盘数据缓冲区以节约RAM,那么可将DISK_BASE_BUF_LEN定义为0以禁止在本文件中定义缓冲区,而由应用程序在调用CHRV3LibInit之前将与其它程序合用的缓冲区起始地址置入pDISK_BASE_BUF变量 */ | ||||||
|  | 
 | ||||||
|  | //#define NO_DEFAULT_ACCESS_SECTOR	    1		/* 禁止默认的磁盘扇区读写子程序,下面用自行编写的程序代替它 */
 | ||||||
|  | //#define NO_DEFAULT_DISK_CONNECT		1		/* 禁止默认的检查磁盘连接子程序,下面用自行编写的程序代替它 */
 | ||||||
|  | //#define NO_DEFAULT_FILE_ENUMER		1		/* 禁止默认的文件名枚举回调程序,下面用自行编写的程序代替它 */
 | ||||||
|  | #define FOR_ROOT_UDISK_ONLY           1 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* ********************************************************************************************************************* */ | ||||||
|  | 
 | ||||||
|  | /* FILE: CHRV3UF.H */ | ||||||
|  | 
 | ||||||
|  | /* 错误码 */ | ||||||
|  | #ifndef ERR_SUCCESS | ||||||
|  | #define ERR_SUCCESS				0x00	/* 操作成功 */ | ||||||
|  | #endif | ||||||
|  | #ifndef ERR_DISK_DISCON | ||||||
|  | #define ERR_CHRV3_ERROR			0x81	/* CHRV3硬件错误,可能需要复位CHRV3 */ | ||||||
|  | //#define ERR_DISK_DISCON			0x82	/* 磁盘尚未连接,可能磁盘已经断开 */
 | ||||||
|  | #define ERR_STATUS_ERR			0x83	/* 磁盘状态错误,可能正在连接或者断开磁盘 */ | ||||||
|  | #define ERR_HUB_PORT_FREE		0x84	/* USB-HUB已经连接但是HUB端口尚未连接磁盘,可能磁盘已经断开 */ | ||||||
|  | #define ERR_MBR_ERROR			0x91	/* 磁盘的主引导记录无效,可能磁盘尚未分区或者尚未格式化 */ | ||||||
|  | #define ERR_TYPE_ERROR			0x92	/* 磁盘分区类型不支持,只支持FAT12/FAT16/BigDOS/FAT32,需要由磁盘管理工具重新分区 */ | ||||||
|  | #define ERR_BPB_ERROR			0xA1	/* 磁盘尚未格式化,或者参数错误,需要由WINDOWS采用默认参数重新格式化 */ | ||||||
|  | #define ERR_TOO_LARGE			0xA2	/* 磁盘非正常格式化并且容量大于4GB,或者容量大于250GB,需要由WINDOWS采用默认参数重新格式化 */ | ||||||
|  | #define ERR_FAT_ERROR			0xA3	/* 磁盘的文件系统不支持,只支持FAT12/FAT16/FAT32,需要由WINDOWS采用默认参数重新格式化 */ | ||||||
|  | #define ERR_DISK_FULL			0xB1	/* 磁盘文件太满,剩余空间太少或者已经没有,需要磁盘整理 */ | ||||||
|  | #define ERR_FDT_OVER			0xB2	/* 目录内文件太多,没有空闲的目录项,FAT12/FAT16根目录下的文件数应该少于500个,需要磁盘整理 */ | ||||||
|  | #define ERR_MISS_DIR			0xB3	/* 指定路径的某个子目录没有找到,可能是目录名称错误 */ | ||||||
|  | #define ERR_FILE_CLOSE			0xB4	/* 文件已经关闭,如果需要使用,应该重新打开文件 */ | ||||||
|  | #define ERR_OPEN_DIR			0x41	/* 指定路径的目录被打开 */ | ||||||
|  | #define ERR_MISS_FILE			0x42	/* 指定路径的文件没有找到,可能是文件名称错误 */ | ||||||
|  | #define ERR_FOUND_NAME			0x43	/* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中,如果需要使用,应该打开该文件 */ | ||||||
|  | #endif | ||||||
|  | /* 代码2XH-3XH用于USB主机方式的通讯失败代码,由CHRV3子程序模仿CH375的返回 */ | ||||||
|  | /* 代码1XH用于USB主机方式的操作状态代码,由CHRV3子程序模仿CH375的返回 */ | ||||||
|  | #ifndef ERR_USB_CONNECT | ||||||
|  | #define	ERR_USB_CONNECT_LS		0x13	/* 检测到低速USB设备连接事件 */ | ||||||
|  | #define	ERR_USB_CONNECT			0x15	/* 检测到USB设备连接事件,磁盘已经连接 */ | ||||||
|  | #define	ERR_USB_DISCON			0x16	/* 检测到USB设备断开事件,磁盘已经断开 */ | ||||||
|  | #define	ERR_USB_BUF_OVER		0x17	/* USB传输的数据有误或者数据太多缓冲区溢出 */ | ||||||
|  | #define	ERR_USB_DISK_ERR		0x1F	/* USB存储器操作失败,在初始化时可能是USB存储器不支持,在读写操作中可能是磁盘损坏或者已经断开 */ | ||||||
|  | #define	ERR_USB_TRANSFER		0x20	/* NAK/STALL等更多错误码在0x20~0x2F */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* 磁盘及文件状态 */ | ||||||
|  | #define DISK_UNKNOWN			0x00	/* 尚未初始化,未知状态 */ | ||||||
|  | #define DISK_DISCONNECT			0x01	/* 磁盘没有连接或者已经断开 */ | ||||||
|  | #define DISK_CONNECT			0x02	/* 磁盘已经连接,但是尚未初始化或者无法识别该磁盘 */ | ||||||
|  | #define DISK_USB_ADDR			0x04	/* 磁盘已经分配USB设备地址,但是尚未配置USB和初始化磁盘 */ | ||||||
|  | #define DISK_MOUNTED			0x05	/* 磁盘已经初始化成功,但是尚未分析文件系统或者文件系统不支持 */ | ||||||
|  | #define DISK_READY				0x10	/* 已经分析磁盘的文件系统并且能够支持 */ | ||||||
|  | #define DISK_OPEN_ROOT			0x12	/* 已经打开根目录,扇区模式,只能以扇区为单位读写目录的内容,使用后必须关闭,注意FAT12/FAT16根目录是固定长度 */ | ||||||
|  | #define DISK_OPEN_DIR			0x13	/* 已经打开子目录,扇区模式,只能以扇区为单位读写目录的内容 */ | ||||||
|  | #define DISK_OPEN_FILE			0x14	/* 已经打开文件,扇区模式,可以以扇区为单位进行数据读写 */ | ||||||
|  | #define DISK_OPEN_FILE_B		0x15	/* 已经打开文件,字节模式,可以以字节为单位进行数据读写 */ | ||||||
|  | 
 | ||||||
|  | /* FAT类型标志 */ | ||||||
|  | #ifndef DISK_FAT16 | ||||||
|  | #define DISK_FS_UNKNOWN			0		/* 未知的文件系统 */ | ||||||
|  | #define DISK_FAT12				1		/* FAT12文件系统 */ | ||||||
|  | #define DISK_FAT16				2		/* FAT16文件系统 */ | ||||||
|  | #define DISK_FAT32				3		/* FAT32文件系统 */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* FAT数据区中文件目录信息 */ | ||||||
|  | typedef struct _FAT_DIR_INFO { | ||||||
|  | 	uint8_t	DIR_Name[11];				/* 00H,文件名,共11字节,不足处填空格 */ | ||||||
|  | 	uint8_t	DIR_Attr;					/* 0BH,文件属性,参考下面的说明 */ | ||||||
|  | 	uint8_t	DIR_NTRes;					/* 0CH */ | ||||||
|  | 	uint8_t	DIR_CrtTimeTenth;			/* 0DH,文件创建的时间,以0.1秒单位计数 */ | ||||||
|  | 	uint16_t	DIR_CrtTime;				/* 0EH,文件创建的时间 */ | ||||||
|  | 	uint16_t	DIR_CrtDate;				/* 10H,文件创建的日期 */ | ||||||
|  | 	uint16_t	DIR_LstAccDate;				/* 12H,最近一次存取操作的日期 */ | ||||||
|  | 	uint16_t	DIR_FstClusHI;				/* 14H */ | ||||||
|  | 	uint16_t	DIR_WrtTime;				/* 16H,文件修改时间,参考宏MAKE_FILE_TIME */ | ||||||
|  | 	uint16_t	DIR_WrtDate;				/* 18H,文件修改日期,参考宏MAKE_FILE_DATA */ | ||||||
|  | 	uint16_t	DIR_FstClusLO;				/* 1AH */ | ||||||
|  | 	uint32_t	DIR_FileSize;				/* 1CH,文件长度 */ | ||||||
|  | } FAT_DIR_INFO;							/* 20H */ | ||||||
|  | 
 | ||||||
|  | typedef FAT_DIR_INFO *PX_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 ) | ||||||
|  | /* 文件属性 uint8_t */ | ||||||
|  | /* bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 */ | ||||||
|  | /*  只   隐   系   卷   目   存   未定义   */ | ||||||
|  | /*  读   藏   统   标   录   档            */ | ||||||
|  | /* 文件时间 uint16_t */ | ||||||
|  | /* Time = (Hour<<11) + (Minute<<5) + (Second>>1) */ | ||||||
|  | #define MAKE_FILE_TIME( h, m, s )	( (h<<11) + (m<<5) + (s>>1) )	/* 生成指定时分秒的文件时间数据 */ | ||||||
|  | /* 文件日期 uint16_t */ | ||||||
|  | /* Date = ((Year-1980)<<9) + (Month<<5) + Day */ | ||||||
|  | #define MAKE_FILE_DATE( y, m, d )	( ((y-1980)<<9) + (m<<5) + d )	/* 生成指定年月日的文件日期数据 */ | ||||||
|  | 
 | ||||||
|  | /* 文件名 */ | ||||||
|  | #define PATH_WILDCARD_CHAR		0x2A	/* 路径名的通配符 '*' */ | ||||||
|  | #define PATH_SEPAR_CHAR1		0x5C	/* 路径名的分隔符 '\' */ | ||||||
|  | #define PATH_SEPAR_CHAR2		0x2F	/* 路径名的分隔符 '/' */ | ||||||
|  | #ifndef MAX_PATH_LEN | ||||||
|  | #define MAX_PATH_LEN			64		/* 最大路径长度,含所有斜杠分隔符和小数点间隔符以及路径结束符00H */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* 外部命令参数 */ | ||||||
|  | typedef union _CMD_PARAM | ||||||
|  | { | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mBuffer[ MAX_PATH_LEN ]; | ||||||
|  |     } Other; | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint32_t mTotalSector;          /* 返回: 当前逻辑盘的总扇区数 */ | ||||||
|  |         uint32_t mFreeSector;           /* 返回: 当前逻辑盘的剩余扇区数 */ | ||||||
|  |         uint32_t mSaveValue; | ||||||
|  |     } Query;                            /* CMD_DiskQuery, 查询磁盘信息 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */ | ||||||
|  |     } Open;                             /* CMD_FileOpen, 打开文件 */ | ||||||
|  | //  struct
 | ||||||
|  | //  {
 | ||||||
|  | //      uint8_t mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名(含通配符*)...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILE*",00H */
 | ||||||
|  | //  } Open;                             /* CMD_FileOpen, 枚举文件, CHRV3vFileSize最高位为1则各调用xFileNameEnumer,为0则返回指定序号的文件名 */
 | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mUpdateLen;             /* 输入参数: 是否允许更新长度: 0禁止,1允许 */ | ||||||
|  |     } Close;                            /* CMD_FileClose, 关闭当前文件 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */ | ||||||
|  |     } Create;                           /* CMD_FileCreate, 新建文件并打开,如果文件已经存在则先删除后再新建 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mPathName[ MAX_PATH_LEN ];  /* 输入参数: 路径: [盘符,冒号,斜杠,目录名或者文件名及扩展名...,结束符00H], 其中盘符和冒号可以省略, 例如"C:\DIR1.EXT\DIR2\FILENAME.EXT",00H */ | ||||||
|  |     } Erase;                            /* CMD_FileErase, 删除文件并关闭 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint32_t mFileSize;             /* 输入参数: 新的文件长度,为0FFFFFFFFH则不修改, 返回: 原长度 */ | ||||||
|  |         uint16_t mFileDate;             /* 输入参数: 新的文件日期,为0FFFFH则不修改, 返回: 原日期 */ | ||||||
|  |         uint16_t mFileTime;             /* 输入参数: 新的文件时间,为0FFFFH则不修改, 返回: 原时间 */ | ||||||
|  |         uint8_t  mFileAttr;             /* 输入参数: 新的文件属性,为0FFH则不修改, 返回: 原属性 */ | ||||||
|  |     } Modify;                           /* CMD_FileQuery, 查询当前文件的信息; CMD_FileModify, 查询或者修改当前文件的信息 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint32_t mSaveCurrClus; | ||||||
|  |         uint32_t mSaveLastClus; | ||||||
|  |     } Alloc;                            /* CMD_FileAlloc, 根据文件长度调整为文件分配的磁盘空间 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint32_t mSectorOffset;      /* 输入参数: 扇区偏移,0则移动到文件头,0FFFFFFFFH则移动到文件尾, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */ | ||||||
|  |         uint32_t mLastOffset; | ||||||
|  |     } Locate;                           /* CMD_FileLocate, 移动当前文件指针 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mSectorCount;           /* 输入参数: 读取扇区数, 返回: 实际读取扇区数 */ | ||||||
|  |         uint8_t mActCnt; | ||||||
|  |         uint8_t mLbaCount; | ||||||
|  |         uint8_t mRemainCnt; | ||||||
|  |         uint8_t *mDataBuffer;           /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */ | ||||||
|  |         uint32_t mLbaStart; | ||||||
|  |     } Read;                             /* CMD_FileRead, 从当前文件读取数据 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mSectorCount;           /* 输入参数: 写入扇区数, 返回: 实际写入扇区数 */ | ||||||
|  |         uint8_t mActCnt; | ||||||
|  |         uint8_t mLbaCount; | ||||||
|  |         uint8_t mAllocCnt; | ||||||
|  |         uint8_t *mDataBuffer;           /* 输入参数: 缓冲区起始地址, 返回: 缓冲区当前地址 */ | ||||||
|  |         uint32_t mLbaStart; | ||||||
|  |         uint32_t mSaveValue; | ||||||
|  |     } Write;                            /* CMD_FileWrite, 向当前文件写入数据 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint32_t mDiskSizeSec;          /* 返回: 整个物理磁盘的总扇区数, 仅首次调用时返回 */ | ||||||
|  |     } DiskReady;                        /* CMD_DiskReady, 查询磁盘就绪 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint32_t mByteOffset;           /* 输入参数: 以字节为单位的偏移量, 以字节为单位的文件指针, 返回: 当前文件指针对应的绝对线性扇区号, 0FFFFFFFFH则已到文件尾 */ | ||||||
|  |         uint32_t mLastOffset; | ||||||
|  |     } ByteLocate;                       /* CMD_ByteLocate, 以字节为单位移动当前文件指针 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint16_t mByteCount;            /* 输入参数: 准备读取的字节数, 返回: 实际读出的字节数 */ | ||||||
|  |         uint8_t *mByteBuffer;           /* 输入参数: 指向存放读出数据块的缓冲区 */ | ||||||
|  |         uint16_t mActCnt; | ||||||
|  |     } ByteRead;                         /* CMD_ByteRead, 以字节为单位从当前文件读取数据块 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint16_t mByteCount;            /* 输入参数: 准备写入的字节数, 返回: 实际写入的字节数 */ | ||||||
|  |         uint8_t *mByteBuffer;           /* 输入参数: 指向存放读出数据块的缓冲区 */ | ||||||
|  |         uint16_t mActCnt; | ||||||
|  |     } ByteWrite;                        /* CMD_ByteWrite, 以字节为单位向当前文件写入数据块 */ | ||||||
|  |     struct | ||||||
|  |     { | ||||||
|  |         uint8_t mSaveVariable;          /* 输入参数: 为0则恢复单个U盘的变量,为0x80则恢复多个U盘的变量,其它值则备份/保存变量 */ | ||||||
|  |         uint8_t mReserved[3]; | ||||||
|  |         uint8_t *mBuffer;               /* 输入参数: 指向子程序库的变量的备份缓冲区,长度不小于80个字节 */ | ||||||
|  |     } SaveVariable;                     /* CMD_SaveVariable, 备份/保存/恢复子程序库的变量 */ | ||||||
|  | } CMD_PARAM; | ||||||
|  | 
 | ||||||
|  | typedef CMD_PARAM CMD_PARAM_I; | ||||||
|  | //typedef CMD_PARAM *P_CMD_PARAM;
 | ||||||
|  | 
 | ||||||
|  | /* SCSI命令码 */ | ||||||
|  | #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 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* FILE: CHRV3UFI.C */ | ||||||
|  | #define EN_DISK_WRITE			1 | ||||||
|  | 
 | ||||||
|  | #ifndef DISK_BASE_BUF_LEN | ||||||
|  | #define DISK_BASE_BUF_LEN		512		/* 默认的磁盘数据缓冲区大小为512字节,建议选择为2048甚至4096以支持某些大扇区的U盘,为0则禁止在.H文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* 子程序库中提供的变量 */ | ||||||
|  | extern  volatile uint8_t CHRV3IntStatus;  /* CHRV3操作的中断状态 */ | ||||||
|  | extern  volatile uint8_t CHRV3DiskStatus; /* 磁盘及文件状态 */ | ||||||
|  | extern  uint8_t  CHRV3vDiskFat;         /* 逻辑盘的FAT标志:1=FAT12,2=FAT16,3=FAT32 */ | ||||||
|  | extern  uint8_t  CHRV3vSecPerClus;      /* 逻辑盘的每簇扇区数 */ | ||||||
|  | extern  uint8_t  CHRV3vSectorSizeB;     /* log2(CHRV3vSectorSize) */ | ||||||
|  | extern  uint32_t CHRV3vStartLba;        /* 逻辑盘的起始绝对扇区号LBA */ | ||||||
|  | extern  uint32_t CHRV3vDiskRoot;        /* 对于FAT16盘为根目录占用扇区数,对于FAT32盘为根目录起始簇号 */ | ||||||
|  | extern  uint32_t CHRV3vDataStart;       /* 逻辑盘的数据区域的起始LBA */ | ||||||
|  | extern  uint32_t CHRV3vStartCluster;    /* 当前文件或者目录的起始簇号 */ | ||||||
|  | extern  uint32_t CHRV3vFileSize;        /* 当前文件的长度 */ | ||||||
|  | extern  uint32_t CHRV3vCurrentOffset;   /* 当前文件指针,当前读写位置的字节偏移 */ | ||||||
|  | extern  uint32_t CHRV3vFdtLba;          /* 当前FDT所在的LBA地址 */ | ||||||
|  | extern  uint32_t CHRV3vLbaCurrent;      /* 当前读写的磁盘起始LBA地址 */ | ||||||
|  | extern  uint16_t CHRV3vFdtOffset;       /* 当前FDT在扇区内的偏移地址 */ | ||||||
|  | extern  uint16_t CHRV3vSectorSize;      /* 磁盘的扇区大小 */ | ||||||
|  | extern  uint8_t  CHRV3vCurrentLun;      /* 磁盘当前操作逻辑单元号 */ | ||||||
|  | extern  uint8_t  CHRV3vSubClassIs6;     /* USB存储类设备的子类为6,0则非6 */ | ||||||
|  | extern  uint8_t  *pDISK_BASE_BUF;       /* 指向外部RAM的磁盘数据缓冲区,缓冲区长度不小于CHRV3vSectorSize,由应用程序初始化 */ | ||||||
|  | extern  uint8_t  *pDISK_FAT_BUF;        /* 指向外部RAM的磁盘FAT数据缓冲区,缓冲区长度不小于CHRV3vSectorSize,由应用程序初始化 */ | ||||||
|  | extern  uint16_t CHRV3vPacketSize;     /* USB存储类设备的最大包长度:64@FS,512@HS/SS,由应用程序初始化 */ | ||||||
|  | extern  uint32_t *pTX_DMA_A_REG;        /* 指向发送DMA地址寄存器,由应用程序初始化 */ | ||||||
|  | extern  uint32_t *pRX_DMA_A_REG;        /* 指向接收DMA地址寄存器,由应用程序初始化 */ | ||||||
|  | extern  uint16_t *pTX_LEN_REG;          /* 指向发送长度寄存器,由应用程序初始化 */ | ||||||
|  | extern  uint16_t *pRX_LEN_REG;          /* 指向接收长度寄存器,由应用程序初始化 */ | ||||||
|  | 
 | ||||||
|  | extern	CMD_PARAM_I	mCmdParam;				/* 命令参数 */ | ||||||
|  | 
 | ||||||
|  | extern	__attribute__ ((aligned(4)))   uint8_t 	RxBuffer[ ];  // IN, must even address
 | ||||||
|  | extern	__attribute__ ((aligned(4)))   uint8_t	TxBuffer[ ];  // OUT, must even address
 | ||||||
|  | 
 | ||||||
|  | //#define		PXUDISK_BOC_CBW	PUDISK_BOC_CBW
 | ||||||
|  | //#define		PXUDISK_BOC_CSW	PUDISK_BOC_CSW
 | ||||||
|  | 
 | ||||||
|  | #ifndef	pSetupReq | ||||||
|  | #define	pSetupReq	((PUSB_SETUP_REQ)TxBuffer) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifndef	pCBW | ||||||
|  | #define	pCBW		((PXUDISK_BOC_CBW)TxBuffer) | ||||||
|  | #define	pCSW		((PXUDISK_BOC_CSW)RxBuffer) | ||||||
|  | #endif | ||||||
|  | #ifndef	pBOC_buf | ||||||
|  | #define	pBOC_buf	(TxBuffer+((USB_BO_CBW_SIZE+4)&0xFE)) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #if		DISK_BASE_BUF_LEN > 0 | ||||||
|  | extern	uint8_t	DISK_BASE_BUF[ DISK_BASE_BUF_LEN ];	/* 外部RAM的磁盘数据缓冲区,缓冲区长度为一个扇区的长度 */ | ||||||
|  | #endif | ||||||
|  | extern	uint8_t	CHRV3ReadSector( uint8_t SectCount, uint8_t * DataBuf );	/* 从磁盘读取多个扇区的数据到缓冲区中 */ | ||||||
|  | #ifdef	EN_DISK_WRITE | ||||||
|  | extern	uint8_t	CHRV3WriteSector( uint8_t SectCount, uint8_t * DataBuf );	/* 将缓冲区中的多个扇区的数据块写入磁盘 */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | extern	uint8_t	CHRV3DiskConnect( void );	/* 检查磁盘是否连接并更新磁盘状态 */ | ||||||
|  | extern	void	xFileNameEnumer( void );	/* 调用外部定义的子程序,文件名枚举回调子程序 */ | ||||||
|  | 
 | ||||||
|  | extern	uint8_t	CHRV3LibInit( void );		/* 初始化CHRV3程序库,操作成功返回0 */ | ||||||
|  | 
 | ||||||
|  | /* 子程序库中提供的子程序 */ | ||||||
|  | /* 下述子程序中, 文件操作子程序CHRV3File*和磁盘查询子程序CHRV3DiskQuery都可能会用到磁盘数据缓冲区pDISK_BASE_BUF,
 | ||||||
|  |    并且有可能在pDISK_BASE_BUF中保存了磁盘信息, 所以必须保证pDISK_BASE_BUF不被用于其它用途, | ||||||
|  |    如果RAM较少, 要将pDISK_BASE_BUF临时用于其它用途, 那么在临时用完后必须调用CHRV3DirtyBuffer清除磁盘缓冲区 */ | ||||||
|  | extern	uint8_t	CHRV3GetVer( void );		/* 获取当前子程序库的版本号 */ | ||||||
|  | extern	void	CHRV3DirtyBuffer( void );	/* 清除磁盘缓冲区 */ | ||||||
|  | extern	uint8_t	CHRV3BulkOnlyCmd( uint8_t * DataBuf );	/* 执行基于BulkOnly协议的命令 */ | ||||||
|  | extern	uint8_t	CHRV3DiskReady( void );		/* 查询磁盘是否准备好 */ | ||||||
|  | extern	uint8_t	CHRV3AnalyzeError( uint8_t iMode );	/* USB操作失败分析CHRV3IntStatus返回错误状态 */ | ||||||
|  | extern	uint8_t	CHRV3FileOpen( void );		/* 打开文件或者枚举文件 */ | ||||||
|  | extern	uint8_t	CHRV3FileClose( void );		/* 关闭当前文件 */ | ||||||
|  | #ifdef	EN_DISK_WRITE | ||||||
|  | extern	uint8_t	CHRV3FileErase( void );		/* 删除文件并关闭 */ | ||||||
|  | extern	uint8_t	CHRV3FileCreate( void );	/* 新建文件并打开,如果文件已经存在则先删除后再新建 */ | ||||||
|  | extern	uint8_t	CHRV3FileAlloc( void );		/* 根据文件长度调整为文件分配的磁盘空间 */ | ||||||
|  | #endif | ||||||
|  | extern	uint8_t	CHRV3FileModify( void );	/* 查询或者修改当前文件的信息 */ | ||||||
|  | extern	uint8_t	CHRV3FileQuery( void );		/* 查询当前文件的信息 */ | ||||||
|  | extern	uint8_t	CHRV3FileLocate( void );	/* 移动当前文件指针 */ | ||||||
|  | extern	uint8_t	CHRV3FileRead( void );		/* 从当前文件读取数据到指定缓冲区 */ | ||||||
|  | #ifdef	EN_DISK_WRITE | ||||||
|  | extern	uint8_t	CHRV3FileWrite( void );		/* 向当前文件写入指定缓冲区的数据 */ | ||||||
|  | #endif | ||||||
|  | extern	uint8_t	CHRV3ByteLocate( void );	/* 以字节为单位移动当前文件指针 */ | ||||||
|  | extern	uint8_t	CHRV3ByteRead( void );		/* 以字节为单位从当前位置读取数据块 */ | ||||||
|  | #ifdef	EN_DISK_WRITE | ||||||
|  | extern	uint8_t	CHRV3ByteWrite( void );		/* 以字节为单位向当前位置写入数据块 */ | ||||||
|  | #endif | ||||||
|  | extern	uint8_t	CHRV3DiskQuery( void );		/* 查询磁盘信息 */ | ||||||
|  | extern	void	CHRV3SaveVariable( void );	/* 备份/保存/恢复子程序库的变量,用于子程序库在多个芯片或者U盘之间进行切换 */ | ||||||
|  | 
 | ||||||
|  | extern	void	mDelayuS( uint16_t n );		// 以uS为单位延时
 | ||||||
|  | extern	void	mDelaymS( uint16_t n );		// 以mS为单位延时
 | ||||||
|  | extern	uint8_t	USBHostTransact( uint8_t endp_pid, uint8_t tog, uint32_t timeout );	// CHRV3传输事务,输入目的端点地址/PID令牌,同步标志,NAK重试时间,返回0成功,超时/出错重试
 | ||||||
|  | extern	uint8_t	HostCtrlTransfer( uint8_t * DataBuf, uint8_t * RetLen );	// 执行控制传输,8字节请求码在pSetupReq中,DataBuf为可选的收发缓冲区,实际收发长度返回在ReqLen指向的变量中
 | ||||||
|  | extern	void	CopySetupReqPkg( const char * pReqPkt );  // 复制控制传输的请求包
 | ||||||
|  | extern	uint8_t	CtrlGetDeviceDescrTB( void );       // 获取设备描述符,返回在TxBuffer中
 | ||||||
|  | extern	uint8_t	CtrlGetConfigDescrTB( void );       // 获取配置描述符,返回在TxBuffer中
 | ||||||
|  | extern	uint8_t	CtrlSetUsbAddress( uint8_t addr );  // 设置USB设备地址
 | ||||||
|  | extern	uint8_t	CtrlSetUsbConfig( uint8_t cfg );    // 设置USB设备配置
 | ||||||
|  | extern	uint8_t	CtrlClearEndpStall( uint8_t endp ); // 清除端点STALL
 | ||||||
|  | #ifndef	FOR_ROOT_UDISK_ONLY | ||||||
|  | //extern	uint8_t	CtrlGetHubDescr( void );  // 获取HUB描述符,返回在TxBuffer中
 | ||||||
|  | extern	uint8_t	HubGetPortStatus( uint8_t HubPortIndex );  // 查询HUB端口状态,返回在TxBuffer中
 | ||||||
|  | //extern	uint8_t	HubSetPortFeature( uint8_t HubPortIndex, uint8_t FeatureSelt );  // 设置HUB端口特性
 | ||||||
|  | extern	uint8_t	HubClearPortFeature( uint8_t HubPortIndex, uint8_t FeatureSelt );  // 清除HUB端口特性
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,78 @@ | ||||||
|  | /********************************** (C) COPYRIGHT  *******************************
 | ||||||
|  | * File Name          : UDisk_Operation.h | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2022/11/20 | ||||||
|  | * Description        : This file contains all the functions prototypes for the Udisk  | ||||||
|  |                        host operation. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #ifndef USER_UDISK_OPERATION_H_ | ||||||
|  | #define USER_UDISK_OPERATION_H_ | ||||||
|  | 
 | ||||||
|  | #include "debug.h" | ||||||
|  | #include "string.h" | ||||||
|  | #include "CHRV3UFI.h" | ||||||
|  | #include "ch32v30x_usbhs_host.h" | ||||||
|  | #include "usb_host_config.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Public Extern Variables */ | ||||||
|  | extern volatile uint8_t          UDisk_Opeation_Flag; | ||||||
|  | extern struct   _ROOT_HUB_DEVICE RootHubDev[ DEF_TOTAL_ROOT_HUB ]; | ||||||
|  | extern struct   __HOST_CTL       HostCtl[ DEF_TOTAL_ROOT_HUB * DEF_ONE_USB_SUP_DEV_TOTAL ]; | ||||||
|  | extern volatile uint8_t          UDisk_Opeation_Flag; | ||||||
|  | extern uint8_t  *pCodeStr; | ||||||
|  | 
 | ||||||
|  | extern __attribute__((aligned(4)))  uint8_t  Com_Buffer[ DEF_COM_BUF_LEN ];     // even address , used for host enumcation and udisk operation
 | ||||||
|  | extern __attribute__((aligned(4)))  uint8_t  DevDesc_Buf[ 18 ];                 // Device Descriptor Buffer
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* 长文件名相关的宏定义极其全局变量 */ | ||||||
|  | // 长文件名缓冲区从(0到20)*26
 | ||||||
|  | #define     LONG_NAME_BUF_LEN       (20*26) | ||||||
|  | #define     UNICODE_ENDIAN          0           // 1为UNICDOE大端编码 0为小端
 | ||||||
|  | // 长文件名存放缓冲区(Unicode编码)
 | ||||||
|  | extern uint8_t LongNameBuf[ ]; | ||||||
|  | // 长文件名(Unicode编码)
 | ||||||
|  | extern uint8_t LongName[ ]; | ||||||
|  | #define     LongName_Len            124 | ||||||
|  | #define     TRUE                    1 | ||||||
|  | #define     FALSE                   0 | ||||||
|  | 
 | ||||||
|  | // 函数返回
 | ||||||
|  | #define     ERR_NO_NAME             0X44        // 此短文件名没有长文件名或错误的长文件
 | ||||||
|  | #define     ERR_BUF_OVER            0X45        // 长文件缓冲区溢出
 | ||||||
|  | #define     ERR_LONG_NAME           0X46        // 错误的长文件名
 | ||||||
|  | #define     ERR_NAME_EXIST          0X47        // 此短文件名存在
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Extern UDisk Operation Functions */ | ||||||
|  | extern void mStopIfError( uint8_t iError ); | ||||||
|  | extern void Udisk_USBH_Initialization( void ); | ||||||
|  | extern uint8_t Udisk_USBH_EnumRootDevice( uint8_t usb_port ); | ||||||
|  | extern uint8_t UDisk_USBH_PreDeal( void ); | ||||||
|  | extern uint8_t UDisk_USBH_DiskReady( void ); | ||||||
|  | 
 | ||||||
|  | /* Extern Long-name Operation Functions */ | ||||||
|  | extern void UDisk_USBH_Longname( void ); | ||||||
|  | extern uint8_t CHRV3GetLongName( void ); | ||||||
|  | extern uint8_t GetUpSectorData( uint32_t *NowSector ); | ||||||
|  | extern uint8_t CHRV3CreateLongName( void ); | ||||||
|  | extern uint8_t AnalyzeLongName( void ); | ||||||
|  | extern uint8_t CheckNameSum( uint8_t *p ); | ||||||
|  | 
 | ||||||
|  | /* Extern Creating Directory Functions */ | ||||||
|  | extern void UDisk_USBH_CreatDirectory( void ); | ||||||
|  | extern uint8_t CreateDirectory( void ); | ||||||
|  | 
 | ||||||
|  | /* Extern Byte/Sector Open/Read/Modify/Delete and File-Enumeration Functions */ | ||||||
|  | extern void UDisk_USBH_ByteOperation( void ); | ||||||
|  | extern void UDisk_USBH_SectorOperation( void ); | ||||||
|  | extern void UDisk_USBH_EnumFiles( void ); | ||||||
|  | 
 | ||||||
|  | #endif /* USER_UDISK_OPERATION_H_ */ | ||||||
|  | @ -0,0 +1,833 @@ | ||||||
|  | /********************************** (C) COPYRIGHT *******************************
 | ||||||
|  | * File Name          : system_ch32v30x.h | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2022/08/20 | ||||||
|  | * Description        : CH32V30x Device Peripheral Access Layer System Header File. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #ifndef __CH32V30x_USB_H | ||||||
|  | #define __CH32V30x_USB_H | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  |  extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Header File */ | ||||||
|  | #include "stdint.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* USB Communication Related Macro Definition */ | ||||||
|  | /* USB Endpoint0 Size */ | ||||||
|  | #ifndef DEFAULT_ENDP0_SIZE | ||||||
|  | #define DEFAULT_ENDP0_SIZE          8          // default maximum packet size for endpoint 0
 | ||||||
|  | #endif | ||||||
|  | #ifndef MAX_PACKET_SIZE | ||||||
|  | #define MAX_PACKET_SIZE             64         // maximum packet size
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB PID */ | ||||||
|  | #ifndef USB_PID_SETUP | ||||||
|  | #define USB_PID_NULL                0x00 | ||||||
|  | #define USB_PID_SOF                 0x05 | ||||||
|  | #define USB_PID_SETUP               0x0D | ||||||
|  | #define USB_PID_IN                  0x09 | ||||||
|  | #define USB_PID_OUT                 0x01 | ||||||
|  | #define USB_PID_NYET                0x06 | ||||||
|  | #define USB_PID_ACK                 0x02 | ||||||
|  | #define USB_PID_NAK                 0x0A | ||||||
|  | #define USB_PID_STALL               0x0E | ||||||
|  | #define USB_PID_DATA0               0x03 | ||||||
|  | #define USB_PID_DATA1               0x0B | ||||||
|  | #define USB_PID_DATA2               0x07 | ||||||
|  | #define USB_PID_MDATA               0x0F | ||||||
|  | #define USB_PID_PRE                 0x0C | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB standard device request code */ | ||||||
|  | #ifndef USB_GET_DESCRIPTOR | ||||||
|  | #define USB_GET_STATUS              0x00 | ||||||
|  | #define USB_CLEAR_FEATURE           0x01 | ||||||
|  | #define USB_SET_FEATURE             0x03 | ||||||
|  | #define USB_SET_ADDRESS             0x05 | ||||||
|  | #define USB_GET_DESCRIPTOR          0x06 | ||||||
|  | #define USB_SET_DESCRIPTOR          0x07 | ||||||
|  | #define USB_GET_CONFIGURATION       0x08 | ||||||
|  | #define USB_SET_CONFIGURATION       0x09 | ||||||
|  | #define USB_GET_INTERFACE           0x0A | ||||||
|  | #define USB_SET_INTERFACE           0x0B | ||||||
|  | #define USB_SYNCH_FRAME             0x0C | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define DEF_STRING_DESC_LANG        0x00 | ||||||
|  | #define DEF_STRING_DESC_MANU        0x01 | ||||||
|  | #define DEF_STRING_DESC_PROD        0x02 | ||||||
|  | #define DEF_STRING_DESC_SERN        0x03 | ||||||
|  | 
 | ||||||
|  | /* USB hub class request code */ | ||||||
|  | #ifndef HUB_GET_DESCRIPTOR | ||||||
|  | #define HUB_GET_STATUS              0x00 | ||||||
|  | #define HUB_CLEAR_FEATURE           0x01 | ||||||
|  | #define HUB_GET_STATE               0x02 | ||||||
|  | #define HUB_SET_FEATURE             0x03 | ||||||
|  | #define HUB_GET_DESCRIPTOR          0x06 | ||||||
|  | #define HUB_SET_DESCRIPTOR          0x07 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB HID class request code */ | ||||||
|  | #ifndef HID_GET_REPORT | ||||||
|  | #define HID_GET_REPORT              0x01 | ||||||
|  | #define HID_GET_IDLE                0x02 | ||||||
|  | #define HID_GET_PROTOCOL            0x03 | ||||||
|  | #define HID_SET_REPORT              0x09 | ||||||
|  | #define HID_SET_IDLE                0x0A | ||||||
|  | #define HID_SET_PROTOCOL            0x0B | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB CDC Class request code */ | ||||||
|  | #ifndef CDC_GET_LINE_CODING | ||||||
|  | #define CDC_GET_LINE_CODING         0x21                                      /* This request allows the host to find out the currently configured line coding */ | ||||||
|  | #define CDC_SET_LINE_CODING         0x20                                      /* Configures DTE rate, stop-bits, parity, and number-of-character */ | ||||||
|  | #define CDC_SET_LINE_CTLSTE         0x22                                      /* This request generates RS-232/V.24 style control signals */ | ||||||
|  | #define CDC_SEND_BREAK              0x23                                      /* Sends special carrier modulation used to specify RS-232 style break */ | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Bit Define for USB Request Type */ | ||||||
|  | #ifndef USB_REQ_TYP_MASK | ||||||
|  | #define USB_REQ_TYP_IN              0x80 | ||||||
|  | #define USB_REQ_TYP_OUT             0x00 | ||||||
|  | #define USB_REQ_TYP_READ            0x80 | ||||||
|  | #define USB_REQ_TYP_WRITE           0x00 | ||||||
|  | #define USB_REQ_TYP_MASK            0x60 | ||||||
|  | #define USB_REQ_TYP_STANDARD        0x00 | ||||||
|  | #define USB_REQ_TYP_CLASS           0x20 | ||||||
|  | #define USB_REQ_TYP_VENDOR          0x40 | ||||||
|  | #define USB_REQ_TYP_RESERVED        0x60 | ||||||
|  | #define USB_REQ_RECIP_MASK          0x1F | ||||||
|  | #define USB_REQ_RECIP_DEVICE        0x00 | ||||||
|  | #define USB_REQ_RECIP_INTERF        0x01 | ||||||
|  | #define USB_REQ_RECIP_ENDP          0x02 | ||||||
|  | #define USB_REQ_RECIP_OTHER         0x03 | ||||||
|  | #define USB_REQ_FEAT_REMOTE_WAKEUP  0x01 | ||||||
|  | #define USB_REQ_FEAT_ENDP_HALT      0x00 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB Descriptor Type */ | ||||||
|  | #ifndef USB_DESCR_TYP_DEVICE | ||||||
|  | #define USB_DESCR_TYP_DEVICE        0x01 | ||||||
|  | #define USB_DESCR_TYP_CONFIG        0x02 | ||||||
|  | #define USB_DESCR_TYP_STRING        0x03 | ||||||
|  | #define USB_DESCR_TYP_INTERF        0x04 | ||||||
|  | #define USB_DESCR_TYP_ENDP          0x05 | ||||||
|  | #define USB_DESCR_TYP_QUALIF        0x06 | ||||||
|  | #define USB_DESCR_TYP_SPEED         0x07 | ||||||
|  | #define USB_DESCR_TYP_OTG           0x09 | ||||||
|  | #define USB_DESCR_TYP_BOS           0X0F | ||||||
|  | #define USB_DESCR_TYP_HID           0x21 | ||||||
|  | #define USB_DESCR_TYP_REPORT        0x22 | ||||||
|  | #define USB_DESCR_TYP_PHYSIC        0x23 | ||||||
|  | #define USB_DESCR_TYP_CS_INTF       0x24 | ||||||
|  | #define USB_DESCR_TYP_CS_ENDP       0x25 | ||||||
|  | #define USB_DESCR_TYP_HUB           0x29 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB Device Class */ | ||||||
|  | #ifndef USB_DEV_CLASS_HUB | ||||||
|  | #define USB_DEV_CLASS_RESERVED      0x00 | ||||||
|  | #define USB_DEV_CLASS_AUDIO         0x01 | ||||||
|  | #define USB_DEV_CLASS_COMMUNIC      0x02 | ||||||
|  | #define USB_DEV_CLASS_HID           0x03 | ||||||
|  | #define USB_DEV_CLASS_MONITOR       0x04 | ||||||
|  | #define USB_DEV_CLASS_PHYSIC_IF     0x05 | ||||||
|  | #define USB_DEV_CLASS_POWER         0x06 | ||||||
|  | #define USB_DEV_CLASS_IMAGE         0x06 | ||||||
|  | #define USB_DEV_CLASS_PRINTER       0x07 | ||||||
|  | #define USB_DEV_CLASS_STORAGE       0x08 | ||||||
|  | #define USB_DEV_CLASS_HUB           0x09 | ||||||
|  | #define USB_DEV_CLASS_VEN_SPEC      0xFF | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB Hub Class Request */ | ||||||
|  | #ifndef HUB_GET_HUB_DESCRIPTOR | ||||||
|  | #define HUB_CLEAR_HUB_FEATURE       0x20 | ||||||
|  | #define HUB_CLEAR_PORT_FEATURE      0x23 | ||||||
|  | #define HUB_GET_BUS_STATE           0xA3 | ||||||
|  | #define HUB_GET_HUB_DESCRIPTOR      0xA0 | ||||||
|  | #define HUB_GET_HUB_STATUS          0xA0 | ||||||
|  | #define HUB_GET_PORT_STATUS         0xA3 | ||||||
|  | #define HUB_SET_HUB_DESCRIPTOR      0x20 | ||||||
|  | #define HUB_SET_HUB_FEATURE         0x20 | ||||||
|  | #define HUB_SET_PORT_FEATURE        0x23 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* Hub Class Feature Selectors */ | ||||||
|  | #ifndef HUB_PORT_RESET | ||||||
|  | #define HUB_C_HUB_LOCAL_POWER       0 | ||||||
|  | #define HUB_C_HUB_OVER_CURRENT      1 | ||||||
|  | #define HUB_PORT_CONNECTION         0 | ||||||
|  | #define HUB_PORT_ENABLE             1 | ||||||
|  | #define HUB_PORT_SUSPEND            2 | ||||||
|  | #define HUB_PORT_OVER_CURRENT       3 | ||||||
|  | #define HUB_PORT_RESET              4 | ||||||
|  | #define HUB_PORT_POWER              8 | ||||||
|  | #define HUB_PORT_LOW_SPEED          9 | ||||||
|  | #define HUB_C_PORT_CONNECTION       16 | ||||||
|  | #define HUB_C_PORT_ENABLE           17 | ||||||
|  | #define HUB_C_PORT_SUSPEND          18 | ||||||
|  | #define HUB_C_PORT_OVER_CURRENT     19 | ||||||
|  | #define HUB_C_PORT_RESET            20 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* USB UDisk */ | ||||||
|  | #ifndef USB_BO_CBW_SIZE | ||||||
|  | #define USB_BO_CBW_SIZE             0x1F | ||||||
|  | #define USB_BO_CSW_SIZE             0x0D | ||||||
|  | #endif | ||||||
|  | #ifndef USB_BO_CBW_SIG0 | ||||||
|  | #define USB_BO_CBW_SIG0             0x55 | ||||||
|  | #define USB_BO_CBW_SIG1             0x53 | ||||||
|  | #define USB_BO_CBW_SIG2             0x42 | ||||||
|  | #define USB_BO_CBW_SIG3             0x43 | ||||||
|  | #define USB_BO_CSW_SIG0             0x55 | ||||||
|  | #define USB_BO_CSW_SIG1             0x53 | ||||||
|  | #define USB_BO_CSW_SIG2             0x42 | ||||||
|  | #define USB_BO_CSW_SIG3             0x53 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /* USBHS Clock Configuration Related Macro Definition */ | ||||||
|  | #define USB_CLK_SRC                 0x80000000 | ||||||
|  | #define USBHS_PLL_ALIVE             0x40000000 | ||||||
|  | #define USBHS_PLL_CKREF_MASK        0x30000000 | ||||||
|  | #define USBHS_PLL_CKREF_3M          0x00000000 | ||||||
|  | #define USBHS_PLL_CKREF_4M          0x10000000 | ||||||
|  | #define USBHS_PLL_CKREF_8M          0x20000000 | ||||||
|  | #define USBHS_PLL_CKREF_5M          0x30000000 | ||||||
|  | #define USBHS_PLL_SRC               0x08000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_MASK      0x07000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV1      0x00000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV2      0x01000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV3      0x02000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV4      0x03000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV5      0x04000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV6      0x05000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV7      0x06000000 | ||||||
|  | #define USBHS_PLL_SRC_PRE_DIV8      0x07000000 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* USBHS Related Register Macro Definition */ | ||||||
|  | 
 | ||||||
|  | /* R8_USB_CTRL */ | ||||||
|  | #define USBHS_UC_HOST_MODE          0x80 | ||||||
|  | #define USBHS_UC_SPEED_TYPE         0x60 | ||||||
|  | #define USBHS_UC_SPEED_LOW          0x40 | ||||||
|  | #define USBHS_UC_SPEED_FULL         0x00 | ||||||
|  | #define USBHS_UC_SPEED_HIGH         0x20 | ||||||
|  | #define USBHS_UC_DEV_PU_EN          0x10 | ||||||
|  | #define USBHS_UC_INT_BUSY           0x08 | ||||||
|  | #define USBHS_UC_RESET_SIE          0x04 | ||||||
|  | #define USBHS_UC_CLR_ALL            0x02 | ||||||
|  | #define USBHS_UC_DMA_EN             0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_INT_EN */ | ||||||
|  | #define USBHS_UIE_DEV_NAK           0x80 | ||||||
|  | #define USBHS_UIE_ISO_ACT           0x40 | ||||||
|  | #define USBHS_UIE_SETUP_ACT         0x20 | ||||||
|  | #define USBHS_UIE_FIFO_OV           0x10 | ||||||
|  | #define USBHS_UIE_SOF_ACT           0x08 | ||||||
|  | #define USBHS_UIE_SUSPEND           0x04 | ||||||
|  | #define USBHS_UIE_TRANSFER          0x02 | ||||||
|  | #define USBHS_UIE_DETECT            0x01 | ||||||
|  | #define USBHS_UIE_BUS_RST           0x01 | ||||||
|  | 
 | ||||||
|  | /* R16_USB_DEV_AD */ | ||||||
|  | #define USBHS_MASK_USB_ADDR         0x7F | ||||||
|  | 
 | ||||||
|  | /* R16_USB_FRAME_NO */ | ||||||
|  | #define USBHS_MICRO_FRAME_NUM       0xE000 | ||||||
|  | #define USBHS_SOF_FRAME_NUM         0x07FF | ||||||
|  | 
 | ||||||
|  | /* R8_USB_SUSPEND */ | ||||||
|  | #define USBHS_USB_LINESTATE         0x30 | ||||||
|  | #define USBHS_USB_WAKEUP_ST         0x04 | ||||||
|  | #define USBHS_USB_SYS_MOD           0x03 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_SPEED_TYPE */ | ||||||
|  | #define USBHS_USB_SPEED_TYPE        0x03 | ||||||
|  | #define USBHS_USB_SPEED_LOW         0x02 | ||||||
|  | #define USBHS_USB_SPEED_FULL        0x00 | ||||||
|  | #define USBHS_USB_SPEED_HIGH        0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_MIS_ST */ | ||||||
|  | #define USBHS_UMS_SOF_PRES          0x80 | ||||||
|  | #define USBHS_UMS_SOF_ACT           0x40 | ||||||
|  | #define USBHS_UMS_SIE_FREE          0x20 | ||||||
|  | #define USBHS_UMS_R_FIFO_RDY        0x10 | ||||||
|  | #define USBHS_UMS_BUS_RESET         0x08 | ||||||
|  | #define USBHS_UMS_SUSPEND           0x04 | ||||||
|  | #define USBHS_UMS_DEV_ATTACH        0x02 | ||||||
|  | #define USBHS_UMS_SPLIT_CAN         0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_INT_FG */ | ||||||
|  | #define USBHS_UIF_ISO_ACT           0x40 | ||||||
|  | #define USBHS_UIF_SETUP_ACT         0x20 | ||||||
|  | #define USBHS_UIF_FIFO_OV           0x10 | ||||||
|  | #define USBHS_UIF_HST_SOF           0x08 | ||||||
|  | #define USBHS_UIF_SUSPEND           0x04 | ||||||
|  | #define USBHS_UIF_TRANSFER          0x02 | ||||||
|  | #define USBHS_UIF_DETECT            0x01 | ||||||
|  | #define USBHS_UIF_BUS_RST           0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_INT_ST */ | ||||||
|  | #define USBHS_UIS_IS_NAK            0x80 | ||||||
|  | #define USBHS_UIS_TOG_OK            0x40 | ||||||
|  | #define USBHS_UIS_TOKEN_MASK        0x30 | ||||||
|  | #define USBHS_UIS_TOKEN_OUT         0x00 | ||||||
|  | #define USBHS_UIS_TOKEN_SOF         0x10 | ||||||
|  | #define USBHS_UIS_TOKEN_IN          0x20 | ||||||
|  | #define USBHS_UIS_TOKEN_SETUP       0x30 | ||||||
|  | #define USBHS_UIS_ENDP_MASK         0x0F | ||||||
|  | #define USBHS_UIS_H_RES_MASK        0x0F | ||||||
|  | 
 | ||||||
|  | /* R16_USB_RX_LEN */ | ||||||
|  | #define USBHS_USB_RX_LEN            0xFFFF | ||||||
|  | 
 | ||||||
|  | /* R32_UEP_CONFIG */ | ||||||
|  | #define USBHS_UEP15_R_EN            0x80000000 | ||||||
|  | #define USBHS_UEP14_R_EN            0x40000000 | ||||||
|  | #define USBHS_UEP13_R_EN            0x20000000 | ||||||
|  | #define USBHS_UEP12_R_EN            0x10000000 | ||||||
|  | #define USBHS_UEP11_R_EN            0x08000000 | ||||||
|  | #define USBHS_UEP10_R_EN            0x04000000 | ||||||
|  | #define USBHS_UEP9_R_EN             0x02000000 | ||||||
|  | #define USBHS_UEP8_R_EN             0x01000000 | ||||||
|  | #define USBHS_UEP7_R_EN             0x00800000 | ||||||
|  | #define USBHS_UEP6_R_EN             0x00400000 | ||||||
|  | #define USBHS_UEP5_R_EN             0x00200000 | ||||||
|  | #define USBHS_UEP4_R_EN             0x00100000 | ||||||
|  | #define USBHS_UEP3_R_EN             0x00080000 | ||||||
|  | #define USBHS_UEP2_R_EN             0x00040000 | ||||||
|  | #define USBHS_UEP1_R_EN             0x00020000 | ||||||
|  | #define USBHS_UEP0_R_EN             0x00010000 | ||||||
|  | #define USBHS_UEP15_T_EN            0x00008000 | ||||||
|  | #define USBHS_UEP14_T_EN            0x00004000 | ||||||
|  | #define USBHS_UEP13_T_EN            0x00002000 | ||||||
|  | #define USBHS_UEP12_T_EN            0x00001000 | ||||||
|  | #define USBHS_UEP11_T_EN            0x00000800 | ||||||
|  | #define USBHS_UEP10_T_EN            0x00000400 | ||||||
|  | #define USBHS_UEP9_T_EN             0x00000200 | ||||||
|  | #define USBHS_UEP8_T_EN             0x00000100 | ||||||
|  | #define USBHS_UEP7_T_EN             0x00000080 | ||||||
|  | #define USBHS_UEP6_T_EN             0x00000040 | ||||||
|  | #define USBHS_UEP5_T_EN             0x00000020 | ||||||
|  | #define USBHS_UEP4_T_EN             0x00000010 | ||||||
|  | #define USBHS_UEP3_T_EN             0x00000008 | ||||||
|  | #define USBHS_UEP2_T_EN             0x00000004 | ||||||
|  | #define USBHS_UEP1_T_EN             0x00000002 | ||||||
|  | #define USBHS_UEP0_T_EN             0x00000001 | ||||||
|  | 
 | ||||||
|  | /* R32_UEP_TYPE */ | ||||||
|  | #define USBHS_UEP15_R_TYPE          0x80000000 | ||||||
|  | #define USBHS_UEP14_R_TYPE          0x40000000 | ||||||
|  | #define USBHS_UEP13_R_TYPE          0x20000000 | ||||||
|  | #define USBHS_UEP12_R_TYPE          0x10000000 | ||||||
|  | #define USBHS_UEP11_R_TYPE          0x08000000 | ||||||
|  | #define USBHS_UEP10_R_TYPE          0x04000000 | ||||||
|  | #define USBHS_UEP9_R_TYPE           0x02000000 | ||||||
|  | #define USBHS_UEP8_R_TYPE           0x01000000 | ||||||
|  | #define USBHS_UEP7_R_TYPE           0x00800000 | ||||||
|  | #define USBHS_UEP6_R_TYPE           0x00400000 | ||||||
|  | #define USBHS_UEP5_R_TYPE           0x00200000 | ||||||
|  | #define USBHS_UEP4_R_TYPE           0x00100000 | ||||||
|  | #define USBHS_UEP3_R_TYPE           0x00080000 | ||||||
|  | #define USBHS_UEP2_R_TYPE           0x00040000 | ||||||
|  | #define USBHS_UEP1_R_TYPE           0x00020000 | ||||||
|  | #define USBHS_UEP0_R_TYPE           0x00010000 | ||||||
|  | #define USBHS_UEP15_T_TYPE          0x00008000 | ||||||
|  | #define USBHS_UEP14_T_TYPE          0x00004000 | ||||||
|  | #define USBHS_UEP13_T_TYPE          0x00002000 | ||||||
|  | #define USBHS_UEP12_T_TYPE          0x00001000 | ||||||
|  | #define USBHS_UEP11_T_TYPE          0x00000800 | ||||||
|  | #define USBHS_UEP10_T_TYPE          0x00000400 | ||||||
|  | #define USBHS_UEP9_T_TYPE           0x00000200 | ||||||
|  | #define USBHS_UEP8_T_TYPE           0x00000100 | ||||||
|  | #define USBHS_UEP7_T_TYPE           0x00000080 | ||||||
|  | #define USBHS_UEP6_T_TYPE           0x00000040 | ||||||
|  | #define USBHS_UEP5_T_TYPE           0x00000020 | ||||||
|  | #define USBHS_UEP4_T_TYPE           0x00000010 | ||||||
|  | #define USBHS_UEP3_T_TYPE           0x00000008 | ||||||
|  | #define USBHS_UEP2_T_TYPE           0x00000004 | ||||||
|  | #define USBHS_UEP1_T_TYPE           0x00000002 | ||||||
|  | #define USBHS_UEP0_T_TYPE           0x00000001 | ||||||
|  | 
 | ||||||
|  | /* R32_UEP_BUF_MOD */ | ||||||
|  | #define USBHS_UEP15_ISO_BUF_MOD     0x80000000 | ||||||
|  | #define USBHS_UEP14_ISO_BUF_MOD     0x40000000 | ||||||
|  | #define USBHS_UEP13_ISO_BUF_MOD     0x20000000 | ||||||
|  | #define USBHS_UEP12_ISO_BUF_MOD     0x10000000 | ||||||
|  | #define USBHS_UEP11_ISO_BUF_MOD     0x08000000 | ||||||
|  | #define USBHS_UEP10_ISO_BUF_MOD     0x04000000 | ||||||
|  | #define USBHS_UEP9_ISO_BUF_MOD      0x02000000 | ||||||
|  | #define USBHS_UEP8_ISO_BUF_MOD      0x01000000 | ||||||
|  | #define USBHS_UEP7_ISO_BUF_MOD      0x00800000 | ||||||
|  | #define USBHS_UEP6_ISO_BUF_MOD      0x00400000 | ||||||
|  | #define USBHS_UEP5_ISO_BUF_MOD      0x00200000 | ||||||
|  | #define USBHS_UEP4_ISO_BUF_MOD      0x00100000 | ||||||
|  | #define USBHS_UEP3_ISO_BUF_MOD      0x00080000 | ||||||
|  | #define USBHS_UEP2_ISO_BUF_MOD      0x00040000 | ||||||
|  | #define USBHS_UEP1_ISO_BUF_MOD      0x00020000 | ||||||
|  | #define USBHS_UEP0_ISO_BUF_MOD      0x00010000 | ||||||
|  | #define USBHS_UEP15_BUF_MOD         0x00008000 | ||||||
|  | #define USBHS_UEP14_BUF_MOD         0x00004000 | ||||||
|  | #define USBHS_UEP13_BUF_MOD         0x00002000 | ||||||
|  | #define USBHS_UEP12_BUF_MOD         0x00001000 | ||||||
|  | #define USBHS_UEP11_BUF_MOD         0x00000800 | ||||||
|  | #define USBHS_UEP10_BUF_MOD         0x00000400 | ||||||
|  | #define USBHS_UEP9_BUF_MOD          0x00000200 | ||||||
|  | #define USBHS_UEP8_BUF_MOD          0x00000100 | ||||||
|  | #define USBHS_UEP7_BUF_MOD          0x00000080 | ||||||
|  | #define USBHS_UEP6_BUF_MOD          0x00000040 | ||||||
|  | #define USBHS_UEP5_BUF_MOD          0x00000020 | ||||||
|  | #define USBHS_UEP4_BUF_MOD          0x00000010 | ||||||
|  | #define USBHS_UEP3_BUF_MOD          0x00000008 | ||||||
|  | #define USBHS_UEP2_BUF_MOD          0x00000004 | ||||||
|  | #define USBHS_UEP1_BUF_MOD          0x00000002 | ||||||
|  | #define USBHS_UEP0_BUF_MOD          0x00000001 | ||||||
|  | 
 | ||||||
|  | /* R32_UEP0_DMA */ | ||||||
|  | #define USBHS_UEP0_DMA              0x0000FFFF | ||||||
|  | 
 | ||||||
|  | /* R32_UEPn_TX_DMA, n=1-15 */ | ||||||
|  | #define USBHS_UEPn_TX_DMA           0x0000FFFF | ||||||
|  | 
 | ||||||
|  | /* R32_UEPn_RX_DMA, n=1-15 */ | ||||||
|  | #define USBHS_UEPn_RX_DMA           0x0000FFFF | ||||||
|  | 
 | ||||||
|  | /* R16_UEPn_MAX_LEN, n=0-15 */ | ||||||
|  | #define USBHS_UEPn_MAX_LEN          0x07FF | ||||||
|  | 
 | ||||||
|  | /* R16_UEPn_T_LEN, n=0-15 */ | ||||||
|  | #define USBHS_UEPn_T_LEN            0x07FF | ||||||
|  | 
 | ||||||
|  | /* R8_UEPn_TX_CTRL, n=0-15 */ | ||||||
|  | #define USBHS_UEP_T_TOG_AUTO        0x20 | ||||||
|  | #define USBHS_UEP_T_TOG_MASK        0x18 | ||||||
|  | #define USBHS_UEP_T_TOG_DATA0       0x00 | ||||||
|  | #define USBHS_UEP_T_TOG_DATA1       0x08 | ||||||
|  | #define USBHS_UEP_T_TOG_DATA2       0x10 | ||||||
|  | #define USBHS_UEP_T_TOG_MDATA       0x18 | ||||||
|  | #define USBHS_UEP_T_RES_MASK        0x03 | ||||||
|  | #define USBHS_UEP_T_RES_ACK         0x00 | ||||||
|  | #define USBHS_UEP_T_RES_NYET        0x01 | ||||||
|  | #define USBHS_UEP_T_RES_NAK         0x02 | ||||||
|  | #define USBHS_UEP_T_RES_STALL       0x03 | ||||||
|  | 
 | ||||||
|  | /* R8_UEPn_TX_CTRL, n=0-15 */ | ||||||
|  | #define USBHS_UEP_R_TOG_AUTO        0x20 | ||||||
|  | #define USBHS_UEP_R_TOG_MASK        0x18 | ||||||
|  | #define USBHS_UEP_R_TOG_DATA0       0x00 | ||||||
|  | #define USBHS_UEP_R_TOG_DATA1       0x08 | ||||||
|  | #define USBHS_UEP_R_TOG_DATA2       0x10 | ||||||
|  | #define USBHS_UEP_R_TOG_MDATA       0x18 | ||||||
|  | #define USBHS_UEP_R_RES_MASK        0x03 | ||||||
|  | #define USBHS_UEP_R_RES_ACK         0x00 | ||||||
|  | #define USBHS_UEP_R_RES_NYET        0x01 | ||||||
|  | #define USBHS_UEP_R_RES_NAK         0x02 | ||||||
|  | #define USBHS_UEP_R_RES_STALL       0x03 | ||||||
|  | 
 | ||||||
|  | /* R8_UHOST_CTRL */ | ||||||
|  | #define USBHS_UH_SOF_EN             0x80 | ||||||
|  | #define USBHS_UH_SOF_FREE           0x40 | ||||||
|  | #define USBHS_UH_PHY_SUSPENDM       0x10 | ||||||
|  | #define USBHS_UH_REMOTE_WKUP        0x08 | ||||||
|  | #define USBHS_UH_TX_BUS_RESUME      0x04 | ||||||
|  | #define USBHS_UH_TX_BUS_SUSPEND     0x02 | ||||||
|  | #define USBHS_UH_TX_BUS_RESET       0x01 | ||||||
|  | 
 | ||||||
|  | /* R32_UH_CONFIG */ | ||||||
|  | #define USBHS_UH_EP_RX_EN           0x00040000 | ||||||
|  | #define USBHS_UH_EP_TX_EN           0x00000008 | ||||||
|  | 
 | ||||||
|  | /* R32_UH_EP_TYPE */ | ||||||
|  | #define USBHS_UH_EP_RX_TYPE         0x00040000 | ||||||
|  | #define USBHS_UH_EP_TX_TYPE         0x00000008 | ||||||
|  | 
 | ||||||
|  | /* R32_UH_RX_DMA */ | ||||||
|  | #define USBHS_UH_RX_DMA             0x0000FFFC | ||||||
|  | 
 | ||||||
|  | /* R32_UH_TX_DMA */ | ||||||
|  | #define USBHS_UH_TX_DMA             0x0000FFFF | ||||||
|  | 
 | ||||||
|  | /* R16_UH_RX_MAX_LEN */ | ||||||
|  | #define USBHS_UH_RX_MAX_LEN         0x07FF | ||||||
|  | 
 | ||||||
|  | /* R8_UH_EP_PID */ | ||||||
|  | #define USBHS_UH_TOKEN_MASK         0xF0 | ||||||
|  | #define USBHS_UH_ENDP_MASK          0x0F | ||||||
|  | 
 | ||||||
|  | /* R8_UH_RX_CTRL */ | ||||||
|  | #define USBHS_UH_R_DATA_NO          0x40 | ||||||
|  | #define USBHS_UH_R_TOG_AUTO         0x20 | ||||||
|  | #define USBHS_UH_R_TOG_MASK         0x18 | ||||||
|  | #define USBHS_UH_R_TOG_DATA0        0x00 | ||||||
|  | #define USBHS_UH_R_TOG_DATA1        0x08 | ||||||
|  | #define USBHS_UH_R_TOG_DATA2        0x10 | ||||||
|  | #define USBHS_UH_R_TOG_MDATA        0x18 | ||||||
|  | #define USBHS_UH_R_RES_NO           0x04 | ||||||
|  | #define USBHS_UH_R_RES_MASK         0x03 | ||||||
|  | #define USBHS_UH_R_RES_ACK          0x00 | ||||||
|  | #define USBHS_UH_R_RES_NYET         0x01 | ||||||
|  | #define USBHS_UH_R_RES_NAK          0x02 | ||||||
|  | #define USBHS_UH_R_RES_STALL        0x03 | ||||||
|  | 
 | ||||||
|  | /* R16_UH_TX_LEN */ | ||||||
|  | #define USBHS_UH_TX_LEN             0x07FF | ||||||
|  | 
 | ||||||
|  | /* R8_UH_TX_CTRL */ | ||||||
|  | #define USBHS_UH_T_DATA_NO          0x40 | ||||||
|  | #define USBHS_UH_T_AUTO_TOG         0x20 | ||||||
|  | #define USBHS_UH_T_TOG_MASK         0x18 | ||||||
|  | #define USBHS_UH_T_TOG_DATA0        0x00 | ||||||
|  | #define USBHS_UH_T_TOG_DATA1        0x08 | ||||||
|  | #define USBHS_UH_T_TOG_DATA2        0x10 | ||||||
|  | #define USBHS_UH_T_TOG_MDATA        0x18 | ||||||
|  | #define USBHS_UH_T_RES_NO           0x04 | ||||||
|  | #define USBHS_UH_T_RES_MASK         0x03 | ||||||
|  | #define USBHS_UH_T_RES_ACK          0x00 | ||||||
|  | #define USBHS_UH_T_RES_NYET         0x01 | ||||||
|  | #define USBHS_UH_T_RES_NAK          0x02 | ||||||
|  | #define USBHS_UH_T_RES_STALL        0x03 | ||||||
|  | 
 | ||||||
|  | /* R16_UH_SPLIT_DATA */ | ||||||
|  | #define USBHS_UH_SPLIT_DATA         0x0FFF | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* USBFS Related Register Macro Definition */ | ||||||
|  | 
 | ||||||
|  | /* R8_USB_CTRL */ | ||||||
|  | #define USBFS_UC_HOST_MODE          0x80 | ||||||
|  | #define USBFS_UC_LOW_SPEED          0x40 | ||||||
|  | #define USBFS_UC_DEV_PU_EN          0x20 | ||||||
|  | #define USBFS_UC_SYS_CTRL_MASK      0x30 | ||||||
|  | #define USBFS_UC_SYS_CTRL0          0x00 | ||||||
|  | #define USBFS_UC_SYS_CTRL1          0x10 | ||||||
|  | #define USBFS_UC_SYS_CTRL2          0x20 | ||||||
|  | #define USBFS_UC_SYS_CTRL3          0x30 | ||||||
|  | #define USBFS_UC_INT_BUSY           0x08 | ||||||
|  | #define USBFS_UC_RESET_SIE          0x04 | ||||||
|  | #define USBFS_UC_CLR_ALL            0x02 | ||||||
|  | #define USBFS_UC_DMA_EN             0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_INT_EN */ | ||||||
|  | #define USBFS_UIE_DEV_SOF           0x80 | ||||||
|  | #define USBFS_UIE_DEV_NAK           0x40 | ||||||
|  | #define USBFS_UIE_FIFO_OV           0x10 | ||||||
|  | #define USBFS_UIE_HST_SOF           0x08 | ||||||
|  | #define USBFS_UIE_SUSPEND           0x04 | ||||||
|  | #define USBFS_UIE_TRANSFER          0x02 | ||||||
|  | #define USBFS_UIE_DETECT            0x01 | ||||||
|  | #define USBFS_UIE_BUS_RST           0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_DEV_AD */ | ||||||
|  | #define USBFS_UDA_GP_BIT            0x80 | ||||||
|  | #define USBFS_USB_ADDR_MASK         0x7F | ||||||
|  | 
 | ||||||
|  | /* R8_USB_MIS_ST */ | ||||||
|  | #define USBFS_UMS_SOF_PRES          0x80 | ||||||
|  | #define USBFS_UMS_SOF_ACT           0x40 | ||||||
|  | #define USBFS_UMS_SIE_FREE          0x20 | ||||||
|  | #define USBFS_UMS_R_FIFO_RDY        0x10 | ||||||
|  | #define USBFS_UMS_BUS_RESET         0x08 | ||||||
|  | #define USBFS_UMS_SUSPEND           0x04 | ||||||
|  | #define USBFS_UMS_DM_LEVEL          0x02 | ||||||
|  | #define USBFS_UMS_DEV_ATTACH        0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_INT_FG */ | ||||||
|  | #define USBFS_U_IS_NAK              0x80    // RO, indicate current USB transfer is NAK received
 | ||||||
|  | #define USBFS_U_TOG_OK              0x40    // RO, indicate current USB transfer toggle is OK
 | ||||||
|  | #define USBFS_U_SIE_FREE            0x20    // RO, indicate USB SIE free status
 | ||||||
|  | #define USBFS_UIF_FIFO_OV           0x10    // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
 | ||||||
|  | #define USBFS_UIF_HST_SOF           0x08    // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
 | ||||||
|  | #define USBFS_UIF_SUSPEND           0x04    // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
 | ||||||
|  | #define USBFS_UIF_TRANSFER          0x02    // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
 | ||||||
|  | #define USBFS_UIF_DETECT            0x01    // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
 | ||||||
|  | #define USBFS_UIF_BUS_RST           0x01    // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
 | ||||||
|  | 
 | ||||||
|  | /* R8_USB_INT_ST */ | ||||||
|  | #define USBFS_UIS_IS_NAK            0x80      // RO, indicate current USB transfer is NAK received for USB device mode
 | ||||||
|  | #define USBFS_UIS_TOG_OK            0x40      // RO, indicate current USB transfer toggle is OK
 | ||||||
|  | #define USBFS_UIS_TOKEN_MASK        0x30      // RO, bit mask of current token PID code received for USB device mode
 | ||||||
|  | #define USBFS_UIS_TOKEN_OUT         0x00 | ||||||
|  | #define USBFS_UIS_TOKEN_SOF         0x10 | ||||||
|  | #define USBFS_UIS_TOKEN_IN          0x20 | ||||||
|  | #define USBFS_UIS_TOKEN_SETUP       0x30 | ||||||
|  | // bUIS_TOKEN1 & bUIS_TOKEN0: current token PID code received for USB device mode
 | ||||||
|  | //   00: OUT token PID received
 | ||||||
|  | //   01: SOF token PID received
 | ||||||
|  | //   10: IN token PID received
 | ||||||
|  | //   11: SETUP token PID received
 | ||||||
|  | #define USBFS_UIS_ENDP_MASK         0x0F      // RO, bit mask of current transfer endpoint number for USB device mode
 | ||||||
|  | #define USBFS_UIS_H_RES_MASK        0x0F      // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
 | ||||||
|  | 
 | ||||||
|  | /* R32_USB_OTG_CR */ | ||||||
|  | #define USBFS_CR_SESS_VTH           0x20 | ||||||
|  | #define USBFS_CR_VBUS_VTH           0x10 | ||||||
|  | #define USBFS_CR_OTG_EN             0x08 | ||||||
|  | #define USBFS_CR_IDPU               0x04 | ||||||
|  | #define USBFS_CR_CHARGE_VBUS        0x02 | ||||||
|  | #define USBFS_CR_DISCHAR_VBUS       0x01 | ||||||
|  | 
 | ||||||
|  | /* R32_USB_OTG_SR */ | ||||||
|  | #define USBFS_SR_ID_DIG             0x08 | ||||||
|  | #define USBFS_SR_SESS_END           0x04 | ||||||
|  | #define USBFS_SR_SESS_VLD           0x02 | ||||||
|  | #define USBFS_SR_VBUS_VLD           0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_UDEV_CTRL */ | ||||||
|  | #define USBFS_UD_PD_DIS             0x80      // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
 | ||||||
|  | #define USBFS_UD_DP_PIN             0x20      // ReadOnly: indicate current UDP pin level
 | ||||||
|  | #define USBFS_UD_DM_PIN             0x10      // ReadOnly: indicate current UDM pin level
 | ||||||
|  | #define USBFS_UD_LOW_SPEED          0x04      // enable USB physical port low speed: 0=full speed, 1=low speed
 | ||||||
|  | #define USBFS_UD_GP_BIT             0x02      // general purpose bit
 | ||||||
|  | #define USBFS_UD_PORT_EN            0x01      // enable USB physical port I/O: 0=disable, 1=enable
 | ||||||
|  | 
 | ||||||
|  | /* R8_UEP4_1_MOD */ | ||||||
|  | #define USBFS_UEP1_RX_EN            0x80      // enable USB endpoint 1 receiving (OUT)
 | ||||||
|  | #define USBFS_UEP1_TX_EN            0x40      // enable USB endpoint 1 transmittal (IN)
 | ||||||
|  | #define USBFS_UEP1_BUF_MOD          0x10      // buffer mode of USB endpoint 1
 | ||||||
|  | #define USBFS_UEP4_RX_EN            0x08      // enable USB endpoint 4 receiving (OUT)
 | ||||||
|  | #define USBFS_UEP4_TX_EN            0x04      // enable USB endpoint 4 transmittal (IN)
 | ||||||
|  | #define USBFS_UEP4_BUF_MOD          0x01 | ||||||
|  | 
 | ||||||
|  | /* R8_UEP2_3_MOD */ | ||||||
|  | #define USBFS_UEP3_RX_EN            0x80      // enable USB endpoint 3 receiving (OUT)
 | ||||||
|  | #define USBFS_UEP3_TX_EN            0x40      // enable USB endpoint 3 transmittal (IN)
 | ||||||
|  | #define USBFS_UEP3_BUF_MOD          0x10      // buffer mode of USB endpoint 3
 | ||||||
|  | #define USBFS_UEP2_RX_EN            0x08      // enable USB endpoint 2 receiving (OUT)
 | ||||||
|  | #define USBFS_UEP2_TX_EN            0x04      // enable USB endpoint 2 transmittal (IN)
 | ||||||
|  | #define USBFS_UEP2_BUF_MOD          0x01      // buffer mode of USB endpoint 2
 | ||||||
|  | 
 | ||||||
|  | /* R8_UEP5_6_MOD */ | ||||||
|  | #define USBFS_UEP6_RX_EN            0x80      // enable USB endpoint 6 receiving (OUT)
 | ||||||
|  | #define USBFS_UEP6_TX_EN            0x40      // enable USB endpoint 6 transmittal (IN)
 | ||||||
|  | #define USBFS_UEP6_BUF_MOD          0x10      // buffer mode of USB endpoint 6
 | ||||||
|  | #define USBFS_UEP5_RX_EN            0x08      // enable USB endpoint 5 receiving (OUT)
 | ||||||
|  | #define USBFS_UEP5_TX_EN            0x04      // enable USB endpoint 5 transmittal (IN)
 | ||||||
|  | #define USBFS_UEP5_BUF_MOD          0x01      // buffer mode of USB endpoint 5
 | ||||||
|  | 
 | ||||||
|  | /* R8_UEP7_MOD */ | ||||||
|  | #define USBFS_UEP7_RX_EN            0x08      // enable USB endpoint 7 receiving (OUT)
 | ||||||
|  | #define USBFS_UEP7_TX_EN            0x04      // enable USB endpoint 7 transmittal (IN)
 | ||||||
|  | #define USBFS_UEP7_BUF_MOD          0x01      // buffer mode of USB endpoint 7
 | ||||||
|  | 
 | ||||||
|  | /* R8_UEPn_TX_CTRL */ | ||||||
|  | #define USBFS_UEP_T_AUTO_TOG        0x08      // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
 | ||||||
|  | #define USBFS_UEP_T_TOG             0x04      // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
 | ||||||
|  | #define USBFS_UEP_T_RES_MASK        0x03      // bit mask of handshake response type for USB endpoint X transmittal (IN)
 | ||||||
|  | #define USBFS_UEP_T_RES_ACK         0x00 | ||||||
|  | #define USBFS_UEP_T_RES_NONE        0x01 | ||||||
|  | #define USBFS_UEP_T_RES_NAK         0x02 | ||||||
|  | #define USBFS_UEP_T_RES_STALL       0x03 | ||||||
|  | // bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
 | ||||||
|  | //   00: DATA0 or DATA1 then expecting ACK (ready)
 | ||||||
|  | //   01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
 | ||||||
|  | //   10: NAK (busy)
 | ||||||
|  | //   11: STALL (error)
 | ||||||
|  | // host aux setup
 | ||||||
|  | 
 | ||||||
|  | /* R8_UEPn_RX_CTRL, n=0-7 */ | ||||||
|  | #define USBFS_UEP_R_AUTO_TOG        0x08      // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
 | ||||||
|  | #define USBFS_UEP_R_TOG             0x04      // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
 | ||||||
|  | #define USBFS_UEP_R_RES_MASK        0x03      // bit mask of handshake response type for USB endpoint X receiving (OUT)
 | ||||||
|  | #define USBFS_UEP_R_RES_ACK         0x00 | ||||||
|  | #define USBFS_UEP_R_RES_NONE        0x01 | ||||||
|  | #define USBFS_UEP_R_RES_NAK         0x02 | ||||||
|  | #define USBFS_UEP_R_RES_STALL       0x03 | ||||||
|  | // RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
 | ||||||
|  | //   00: ACK (ready)
 | ||||||
|  | //   01: no response, time out to host, for non-zero endpoint isochronous transactions
 | ||||||
|  | //   10: NAK (busy)
 | ||||||
|  | //   11: STALL (error)
 | ||||||
|  | 
 | ||||||
|  | /* R8_UHOST_CTRL */ | ||||||
|  | #define USBFS_UH_PD_DIS             0x80      // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
 | ||||||
|  | #define USBFS_UH_DP_PIN             0x20      // ReadOnly: indicate current UDP pin level
 | ||||||
|  | #define USBFS_UH_DM_PIN             0x10      // ReadOnly: indicate current UDM pin level
 | ||||||
|  | #define USBFS_UH_LOW_SPEED          0x04      // enable USB port low speed: 0=full speed, 1=low speed
 | ||||||
|  | #define USBFS_UH_BUS_RESET          0x02      // control USB bus reset: 0=normal, 1=force bus reset
 | ||||||
|  | #define USBFS_UH_PORT_EN            0x01      // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
 | ||||||
|  | 
 | ||||||
|  | /* R32_UH_EP_MOD */ | ||||||
|  | #define USBFS_UH_EP_TX_EN           0x40      // enable USB host OUT endpoint transmittal
 | ||||||
|  | #define USBFS_UH_EP_TBUF_MOD        0x10      // buffer mode of USB host OUT endpoint
 | ||||||
|  | // bUH_EP_TX_EN & bUH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA
 | ||||||
|  | //   0 x:  disable endpoint and disable buffer
 | ||||||
|  | //   1 0:  64 bytes buffer for transmittal (OUT endpoint)
 | ||||||
|  | //   1 1:  dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes
 | ||||||
|  | #define USBFS_UH_EP_RX_EN           0x08      // enable USB host IN endpoint receiving
 | ||||||
|  | #define USBFS_UH_EP_RBUF_MOD        0x01      // buffer mode of USB host IN endpoint
 | ||||||
|  | // bUH_EP_RX_EN & bUH_EP_RBUF_MOD: USB host IN endpoint buffer mode, buffer start address is UH_RX_DMA
 | ||||||
|  | //   0 x:  disable endpoint and disable buffer
 | ||||||
|  | //   1 0:  64 bytes buffer for receiving (IN endpoint)
 | ||||||
|  | //   1 1:  dual 64 bytes buffer by toggle bit bUH_R_TOG selection for receiving (IN endpoint), total=128bytes
 | ||||||
|  | 
 | ||||||
|  | /* R16_UH_SETUP */ | ||||||
|  | #define USBFS_UH_PRE_PID_EN         0x0400      // USB host PRE PID enable for low speed device via hub
 | ||||||
|  | #define USBFS_UH_SOF_EN             0x0004      // USB host automatic SOF enable
 | ||||||
|  | 
 | ||||||
|  | /* R8_UH_EP_PID */ | ||||||
|  | #define USBFS_UH_TOKEN_MASK         0xF0      // bit mask of token PID for USB host transfer
 | ||||||
|  | #define USBFS_UH_ENDP_MASK          0x0F      // bit mask of endpoint number for USB host transfer
 | ||||||
|  | 
 | ||||||
|  | /* R8_UH_RX_CTRL */ | ||||||
|  | #define USBFS_UH_R_AUTO_TOG         0x08      // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
 | ||||||
|  | #define USBFS_UH_R_TOG              0x04      // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
 | ||||||
|  | #define USBFS_UH_R_RES              0x01      // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
 | ||||||
|  | 
 | ||||||
|  | /* R8_UH_TX_CTRL */ | ||||||
|  | #define USBFS_UH_T_AUTO_TOG         0x08      // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
 | ||||||
|  | #define USBFS_UH_T_TOG              0x04      // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
 | ||||||
|  | #define USBFS_UH_T_RES              0x01      // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Struct Definition */ | ||||||
|  | 
 | ||||||
|  | /* USB Setup Request */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_SETUP_REQ | ||||||
|  | { | ||||||
|  |     uint8_t  bRequestType; | ||||||
|  |     uint8_t  bRequest; | ||||||
|  |     uint16_t wValue; | ||||||
|  |     uint16_t wIndex; | ||||||
|  |     uint16_t wLength; | ||||||
|  | } USB_SETUP_REQ, *PUSB_SETUP_REQ; | ||||||
|  | 
 | ||||||
|  | /* USB Device Descriptor */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_DEVICE_DESCR | ||||||
|  | { | ||||||
|  |     uint8_t  bLength; | ||||||
|  |     uint8_t  bDescriptorType; | ||||||
|  |     uint16_t bcdUSB; | ||||||
|  |     uint8_t  bDeviceClass; | ||||||
|  |     uint8_t  bDeviceSubClass; | ||||||
|  |     uint8_t  bDeviceProtocol; | ||||||
|  |     uint8_t  bMaxPacketSize0; | ||||||
|  |     uint16_t idVendor; | ||||||
|  |     uint16_t idProduct; | ||||||
|  |     uint16_t bcdDevice; | ||||||
|  |     uint8_t  iManufacturer; | ||||||
|  |     uint8_t  iProduct; | ||||||
|  |     uint8_t  iSerialNumber; | ||||||
|  |     uint8_t  bNumConfigurations; | ||||||
|  | } USB_DEV_DESCR, *PUSB_DEV_DESCR; | ||||||
|  | 
 | ||||||
|  | /* USB Configuration Descriptor */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_CONFIG_DESCR | ||||||
|  | { | ||||||
|  |     uint8_t  bLength; | ||||||
|  |     uint8_t  bDescriptorType; | ||||||
|  |     uint16_t wTotalLength; | ||||||
|  |     uint8_t  bNumInterfaces; | ||||||
|  |     uint8_t  bConfigurationValue; | ||||||
|  |     uint8_t  iConfiguration; | ||||||
|  |     uint8_t  bmAttributes; | ||||||
|  |     uint8_t  MaxPower; | ||||||
|  | } USB_CFG_DESCR, *PUSB_CFG_DESCR; | ||||||
|  | 
 | ||||||
|  | /* USB Interface Descriptor */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_INTERF_DESCR | ||||||
|  | { | ||||||
|  |     uint8_t  bLength; | ||||||
|  |     uint8_t  bDescriptorType; | ||||||
|  |     uint8_t  bInterfaceNumber; | ||||||
|  |     uint8_t  bAlternateSetting; | ||||||
|  |     uint8_t  bNumEndpoints; | ||||||
|  |     uint8_t  bInterfaceClass; | ||||||
|  |     uint8_t  bInterfaceSubClass; | ||||||
|  |     uint8_t  bInterfaceProtocol; | ||||||
|  |     uint8_t  iInterface; | ||||||
|  | } USB_ITF_DESCR, *PUSB_ITF_DESCR; | ||||||
|  | 
 | ||||||
|  | /* USB Endpoint Descriptor */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_ENDPOINT_DESCR | ||||||
|  | { | ||||||
|  |     uint8_t  bLength; | ||||||
|  |     uint8_t  bDescriptorType; | ||||||
|  |     uint8_t  bEndpointAddress; | ||||||
|  |     uint8_t  bmAttributes; | ||||||
|  |     uint8_t  wMaxPacketSizeL; | ||||||
|  |     uint8_t  wMaxPacketSizeH; | ||||||
|  |     uint8_t  bInterval; | ||||||
|  | } USB_ENDP_DESCR, *PUSB_ENDP_DESCR; | ||||||
|  | 
 | ||||||
|  | /* USB Configuration Descriptor Set */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_CONFIG_DESCR_LONG | ||||||
|  | { | ||||||
|  |     USB_CFG_DESCR  cfg_descr; | ||||||
|  |     USB_ITF_DESCR  itf_descr; | ||||||
|  |     USB_ENDP_DESCR endp_descr[ 1 ]; | ||||||
|  | } USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG; | ||||||
|  | 
 | ||||||
|  | /* USB HUB Descriptor */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_HUB_DESCR | ||||||
|  | { | ||||||
|  |     uint8_t  bDescLength; | ||||||
|  |     uint8_t  bDescriptorType; | ||||||
|  |     uint8_t  bNbrPorts; | ||||||
|  |     uint8_t  wHubCharacteristicsL; | ||||||
|  |     uint8_t  wHubCharacteristicsH; | ||||||
|  |     uint8_t  bPwrOn2PwrGood; | ||||||
|  |     uint8_t  bHubContrCurrent; | ||||||
|  |     uint8_t  DeviceRemovable; | ||||||
|  |     uint8_t  PortPwrCtrlMask; | ||||||
|  | } USB_HUB_DESCR, *PUSB_HUB_DESCR; | ||||||
|  | 
 | ||||||
|  | /* USB HID Descriptor */ | ||||||
|  | typedef struct __attribute__((packed)) _USB_HID_DESCR | ||||||
|  | { | ||||||
|  |     uint8_t  bLength; | ||||||
|  |     uint8_t  bDescriptorType; | ||||||
|  |     uint16_t bcdHID; | ||||||
|  |     uint8_t  bCountryCode; | ||||||
|  |     uint8_t  bNumDescriptors; | ||||||
|  |     uint8_t  bDescriptorTypeX; | ||||||
|  |     uint8_t  wDescriptorLengthL; | ||||||
|  |     uint8_t  wDescriptorLengthH; | ||||||
|  | } USB_HID_DESCR, *PUSB_HID_DESCR; | ||||||
|  | 
 | ||||||
|  | /* USB UDisk */ | ||||||
|  | typedef struct __attribute__((packed)) _UDISK_BOC_CBW | ||||||
|  | { | ||||||
|  |     uint32_t mCBW_Sig; | ||||||
|  |     uint32_t mCBW_Tag; | ||||||
|  |     uint32_t mCBW_DataLen; | ||||||
|  |     uint8_t  mCBW_Flag; | ||||||
|  |     uint8_t  mCBW_LUN; | ||||||
|  |     uint8_t  mCBW_CB_Len; | ||||||
|  |     uint8_t  mCBW_CB_Buf[ 16 ]; | ||||||
|  | } UDISK_BOC_CBW, *PXUDISK_BOC_CBW; | ||||||
|  | 
 | ||||||
|  | /* USB UDisk */ | ||||||
|  | typedef struct __attribute__((packed)) _UDISK_BOC_CSW | ||||||
|  | { | ||||||
|  |     uint32_t mCBW_Sig; | ||||||
|  |     uint32_t mCBW_Tag; | ||||||
|  |     uint32_t mCSW_Residue; | ||||||
|  |     uint8_t  mCSW_Status; | ||||||
|  | } UDISK_BOC_CSW, *PXUDISK_BOC_CSW; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif /* __CH32V30x_USB_H */ | ||||||
|  | @ -0,0 +1,114 @@ | ||||||
|  | /********************************** (C) COPYRIGHT  *******************************
 | ||||||
|  | * File Name          : ch32v30x_usbhs_host.h | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2021/06/06 | ||||||
|  | * Description        : This file contains all the functions prototypes for the USB  | ||||||
|  | *                      Host firmware library. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifndef __CH32V30x_USBHS_HOST_H | ||||||
|  | #define __CH32V30x_USBHS_HOST_H | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Header Files */ | ||||||
|  | #include "ch32v30x.h" | ||||||
|  | #include "ch32v30x_usb.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* USB Setup Request Macro Definition */ | ||||||
|  | #define pUSBHS_SetupRequest        ( (PUSB_SETUP_REQ)USBHS_TX_Buf ) | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Constant Definition */ | ||||||
|  | #ifndef DEF_GET_USB_DEV_DESC | ||||||
|  | #define DEF_GET_USB_DEV_DESC | ||||||
|  | /* Get Device Descriptor Command Packet */ | ||||||
|  | __attribute__((aligned(4))) static const uint8_t  SetupGetDevDesc[ ] = | ||||||
|  | { | ||||||
|  |     USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_DEVICE, 0x00, 0x00, sizeof( USB_DEV_DESCR ), 0x00 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Get Configuration Descriptor Command Packet */ | ||||||
|  | __attribute__((aligned(4))) static const uint8_t SetupGetCfgDesc[ ] = | ||||||
|  | { | ||||||
|  |     USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_CONFIG, 0x00, 0x00, 0x04, 0x00 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Get String Descriptor Command Packet */ | ||||||
|  | __attribute__((aligned(4))) static const uint8_t SetupGetStrDesc[ ] = | ||||||
|  | { | ||||||
|  |     USB_REQ_TYP_IN, USB_GET_DESCRIPTOR, 0x00, USB_DESCR_TYP_STRING, 0x09, 0x04, 0x04, 0x00 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Set USB Address Command Packet */ | ||||||
|  | __attribute__((aligned(4))) static const uint8_t SetupSetAddr[ ] = | ||||||
|  | { | ||||||
|  |     USB_REQ_TYP_OUT, USB_SET_ADDRESS, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Set USB Configuration Command Packet */ | ||||||
|  | __attribute__((aligned(4))) static const uint8_t SetupSetConfig[ ] = | ||||||
|  | { | ||||||
|  |     USB_REQ_TYP_OUT, USB_SET_CONFIGURATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Clear Endpoint STALL Command Packet */ | ||||||
|  | __attribute__((aligned(4))) static const uint8_t SetupClearEndpStall[ ] = | ||||||
|  | { | ||||||
|  |     USB_REQ_TYP_OUT | USB_REQ_RECIP_ENDP, USB_CLEAR_FEATURE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Set Device Interface Command Packet */ | ||||||
|  | __attribute__((aligned(4))) static const uint8_t SetupSetInterface[ ] = | ||||||
|  | { | ||||||
|  |     USB_REQ_RECIP_INTERF, USB_SET_INTERFACE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Variable Declaration */ | ||||||
|  | extern __attribute__((aligned(4))) uint8_t  RxBuffer[ MAX_PACKET_SIZE ]; | ||||||
|  | extern __attribute__((aligned(4))) uint8_t  TxBuffer[ MAX_PACKET_SIZE ]; | ||||||
|  | 
 | ||||||
|  | #define USBHS_RX_Buf RxBuffer | ||||||
|  | #define USBHS_TX_Buf TxBuffer | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Function Declaration */ | ||||||
|  | extern void USBHS_RCC_Init( void ); | ||||||
|  | extern void USBHS_Host_Init( FunctionalState sta ); | ||||||
|  | extern uint8_t USBHSH_CheckRootHubPortStatus( uint8_t status ); | ||||||
|  | extern uint8_t USBHSH_CheckRootHubPortEnable( void ); | ||||||
|  | extern uint8_t USBHSH_CheckRootHubPortSpeed( void ); | ||||||
|  | extern void USBHSH_SetSelfAddr( uint8_t addr ); | ||||||
|  | extern void USBHSH_SetSelfSpeed( uint8_t speed ); | ||||||
|  | extern void USBHSH_ResetRootHubPort( uint8_t mode ); | ||||||
|  | extern uint8_t USBHSH_EnableRootHubPort( uint8_t *pspeed ); | ||||||
|  | extern uint8_t USBHSH_Transact( uint8_t endp_pid, uint8_t endp_tog, uint32_t timeout ); | ||||||
|  | extern uint8_t USBHSH_CtrlTransfer( uint8_t ep0_size, uint8_t *pbuf, uint16_t *plen ); | ||||||
|  | extern uint8_t USBHSH_GetDeviceDescr( uint8_t *pep0_size, uint8_t *pbuf ); | ||||||
|  | extern uint8_t USBHSH_GetConfigDescr( uint8_t ep0_size, uint8_t *pbuf, uint16_t buf_len, uint16_t *pcfg_len ); | ||||||
|  | extern uint8_t USBHSH_GetStrDescr( uint8_t ep0_size, uint8_t str_num, uint8_t *pbuf ); | ||||||
|  | extern uint8_t USBHSH_SetUsbAddress( uint8_t ep0_size, uint8_t addr ); | ||||||
|  | extern uint8_t USBHSH_SetUsbConfig( uint8_t ep0_size, uint8_t cfg_val ); | ||||||
|  | extern uint8_t USBHSH_ClearEndpStall( uint8_t ep0_size, uint8_t endp_num ); | ||||||
|  | extern uint8_t USBHSH_GetEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t *plen ); | ||||||
|  | extern uint8_t USBHSH_SendEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t len ); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif   | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,174 @@ | ||||||
|  | /********************************** (C) COPYRIGHT  *******************************
 | ||||||
|  |  * File Name          : usb_host_config.h | ||||||
|  |  * Author             : WCH | ||||||
|  |  * Version            : V1.0.0 | ||||||
|  |  * Date               : 2022/08/29 | ||||||
|  |  * Description        :  | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | #ifndef __USB_HOST_CONFIG_H | ||||||
|  | #define __USB_HOST_CONFIG_H | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /* Header File */ | ||||||
|  | #include "string.h" | ||||||
|  | #include "debug.h" | ||||||
|  | #include "ch32v30x_usb.h" | ||||||
|  | #include "ch32v30x_usbhs_host.h" | ||||||
|  | 
 | ||||||
|  | /******************************************************************************/ | ||||||
|  | /* USB Host Communication Related Macro Definition */ | ||||||
|  | 
 | ||||||
|  | /* USB Host Port General Control */ | ||||||
|  | /* CH32V303x,  Support USBFS Host/Slave Only */ | ||||||
|  | /* CH32V305FB, Support USBHS Host/Slave Only */ | ||||||
|  | /* CH32V305RB, CH32V307, Support USBHS/USBFS Host/Slave */ | ||||||
|  | #define DEF_TOTAL_ROOT_HUB          2 | ||||||
|  | #define DEF_USB_PORT_FS_EN          0 | ||||||
|  | #define DEF_USB_PORT_HS_EN          1 | ||||||
|  | #define DEF_USB_PORT_FS             0x00                                         | ||||||
|  | #define DEF_USB_PORT_HS             0x01       | ||||||
|  | 
 | ||||||
|  | /* USB Root Device Status */ | ||||||
|  | #define ROOT_DEV_DISCONNECT         0 | ||||||
|  | #define ROOT_DEV_CONNECTED          1 | ||||||
|  | #define ROOT_DEV_FAILED             2 | ||||||
|  | #define ROOT_DEV_SUCCESS            3 | ||||||
|  | 
 | ||||||
|  | /* USB Device Address */ | ||||||
|  | #define USB_DEVICE_ADDR             0x02 | ||||||
|  | 
 | ||||||
|  | /* USB Speed */ | ||||||
|  | #define USB_LOW_SPEED               0x00 | ||||||
|  | #define USB_FULL_SPEED              0x01 | ||||||
|  | #define USB_HIGH_SPEED              0x02 | ||||||
|  | #define USB_SPEED_CHECK_ERR         0xFF | ||||||
|  | 
 | ||||||
|  | /* Configuration Descriptor Type */ | ||||||
|  | #define DEF_DECR_CONFIG             0x02 | ||||||
|  | #define DEF_DECR_INTERFACE          0x04 | ||||||
|  | #define DEF_DECR_ENDPOINT           0x05 | ||||||
|  | #define DEF_DECR_HID                0x21 | ||||||
|  | 
 | ||||||
|  | /* USB Communication Status Code */ | ||||||
|  | #define ERR_SUCCESS                 0x00 | ||||||
|  | #define ERR_USB_CONNECT             0x15 | ||||||
|  | #define ERR_USB_DISCON              0x16 | ||||||
|  | #define ERR_USB_BUF_OVER            0x17 | ||||||
|  | #define ERR_USB_DISK_ERR            0x1F | ||||||
|  | #define ERR_USB_TRANSFER            0x20 | ||||||
|  | #define ERR_USB_UNSUPPORT           0xFB | ||||||
|  | #define ERR_USB_UNAVAILABLE         0xFC | ||||||
|  | #define ERR_USB_UNKNOWN             0xFE | ||||||
|  | 
 | ||||||
|  | /* USB Device Enumeration Status Code */ | ||||||
|  | #define DEF_DEV_DESCR_GETFAIL       0x45 | ||||||
|  | #define DEF_DEV_ADDR_SETFAIL        0x46 | ||||||
|  | #define DEF_CFG_DESCR_GETFAIL       0x47 | ||||||
|  | #define DEF_REP_DESCR_GETFAIL       0x48     | ||||||
|  | #define DEF_DEV_TYPE_UNKNOWN        0xFF | ||||||
|  |                         | ||||||
|  | /* USB Communication Time */ | ||||||
|  | #define DEF_BUS_RESET_TIME          11          // USB bus reset time
 | ||||||
|  | #define DEF_RE_ATTACH_TIMEOUT       100         // Wait for the USB device to reconnect after reset, 100mS timeout
 | ||||||
|  | #define DEF_WAIT_USB_TOUT_200US     1000 | ||||||
|  | #define DEF_CTRL_TRANS_TIMEOVER_CNT 60000       // Control transmission delay timing
 | ||||||
|  | 
 | ||||||
|  | /* General */ | ||||||
|  | #define DEF_ONE_USB_SUP_DEV_TOTAL       1 | ||||||
|  | #define DEF_NEXT_HUB_PORT_NUM_MAX       4 | ||||||
|  | #define DEF_INTERFACE_NUM_MAX           4 | ||||||
|  | #define DEF_COM_BUF_LEN                 255 | ||||||
|  | 
 | ||||||
|  | /* Debug */ | ||||||
|  | #define DEF_DEBUG_PRINTF                1 | ||||||
|  | #if ( DEF_DEBUG_PRINTF == 1 ) | ||||||
|  | #define DUG_PRINTF( format, arg... )    printf( format, ##arg ) | ||||||
|  | #else | ||||||
|  | #define DUG_PRINTF( format, arg... )    do{ if( 0 )printf( format, ##arg ); }while( 0 ); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* HUB Port Device  */ | ||||||
|  | typedef struct _HUB_DEVICE | ||||||
|  | { | ||||||
|  |     uint8_t  bStatus; | ||||||
|  |     uint8_t  bType; | ||||||
|  |     uint8_t  bAddress; | ||||||
|  |     uint8_t  bSpeed; | ||||||
|  |     uint8_t  bEp0MaxPks; | ||||||
|  |     uint8_t  DeviceIndex; | ||||||
|  | }HUB_DEVICE, *PHUB_DEVICE; | ||||||
|  | 
 | ||||||
|  | /* Root HUB Device Structure, Physical Interface */ | ||||||
|  | typedef struct _ROOT_HUB_DEVICE | ||||||
|  | { | ||||||
|  |     uint8_t  bStatus; | ||||||
|  |     uint8_t  bType; | ||||||
|  |     uint8_t  bAddress; | ||||||
|  |     uint8_t  bSpeed; | ||||||
|  |     uint8_t  bEp0MaxPks; | ||||||
|  |     uint8_t  DeviceIndex; | ||||||
|  |     uint8_t  bPortNum; | ||||||
|  |     HUB_DEVICE Device[ DEF_NEXT_HUB_PORT_NUM_MAX ]; | ||||||
|  | } ROOT_HUB_DEVICE, *PROOT_HUB_DEVICE; | ||||||
|  | 
 | ||||||
|  | /* USB Host Control Structure */ | ||||||
|  | struct __HOST_CTL | ||||||
|  | { | ||||||
|  |     uint8_t  InterfaceNum; | ||||||
|  |     uint8_t  ErrorCount; | ||||||
|  | 
 | ||||||
|  |     struct interface | ||||||
|  |     { | ||||||
|  |         uint8_t  Type; | ||||||
|  |         uint16_t HidDescLen; | ||||||
|  |         uint8_t  HidReportID; | ||||||
|  |         uint8_t  Full_KB_Flag; | ||||||
|  | 
 | ||||||
|  |         uint8_t  InEndpNum; | ||||||
|  |         uint8_t  InEndpAddr[ 4 ]; | ||||||
|  |         uint8_t  InEndpType[ 4 ]; | ||||||
|  |         uint16_t InEndpSize[ 4 ]; | ||||||
|  |         uint8_t  InEndpTog[ 4 ]; | ||||||
|  |         uint8_t  InEndpInterval[ 4 ]; | ||||||
|  |         uint8_t  InEndpTimeCount[ 4 ]; | ||||||
|  | 
 | ||||||
|  |         uint8_t  OutEndpNum; | ||||||
|  |         uint8_t  OutEndpAddr[ 4 ]; | ||||||
|  |         uint8_t  OutEndpType[ 4 ]; | ||||||
|  |         uint16_t OutEndpSize[ 4 ]; | ||||||
|  |         uint8_t  OutEndpTog[ 4 ]; | ||||||
|  | 
 | ||||||
|  |         uint8_t  IDFlag; | ||||||
|  |         uint8_t  ReportID; | ||||||
|  | 
 | ||||||
|  |         uint8_t  LED_Usage_Min; | ||||||
|  |         uint8_t  LED_Usage_Max; | ||||||
|  | 
 | ||||||
|  |         uint8_t  SetReport_Swi; | ||||||
|  |         uint8_t  SetReport_Value; | ||||||
|  |         uint8_t  SetReport_Flag; | ||||||
|  | 
 | ||||||
|  |     }Interface[ DEF_INTERFACE_NUM_MAX ]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Variable Declaration */ | ||||||
|  | extern uint8_t  DevDesc_Buf[ ]; | ||||||
|  | extern uint8_t  Com_Buf[ ]; | ||||||
|  | extern struct   _ROOT_HUB_DEVICE RootHubDev[ ]; | ||||||
|  | extern struct   __HOST_CTL HostCtl[ ]; | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -0,0 +1,528 @@ | ||||||
|  | /* 2014.09.09
 | ||||||
|  | ***************************************** | ||||||
|  | **   Copyright  (C)  W.ch  1999-2019   ** | ||||||
|  | **   Web:      http://wch.cn           **
 | ||||||
|  | ***************************************** | ||||||
|  | **  USB-flash File Interface for CHRV3 ** | ||||||
|  | **  KEIL423, gcc 8.20          ** | ||||||
|  | ***************************************** | ||||||
|  | */ | ||||||
|  | /* CHRV3 U盘主机文件系统接口, 支持: FAT12/FAT16/FAT32 */ | ||||||
|  | 
 | ||||||
|  | //#define DISK_BASE_BUF_LEN		512	/* 默认的磁盘数据缓冲区大小为512字节(可以选择为2048甚至4096以支持某些大扇区的U盘),为0则禁止在本文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */
 | ||||||
|  | /* 如果需要复用磁盘数据缓冲区以节约RAM,那么可将DISK_BASE_BUF_LEN定义为0以禁止在本文件中定义缓冲区,而由应用程序在调用CHRV3LibInit之前将与其它程序合用的缓冲区起始地址置入pDISK_BASE_BUF变量 */ | ||||||
|  | 
 | ||||||
|  | //#define NO_DEFAULT_ACCESS_SECTOR	    1		/* 禁止默认的磁盘扇区读写子程序,下面用自行编写的程序代替它 */
 | ||||||
|  | //#define NO_DEFAULT_DISK_CONNECT		1		/* 禁止默认的检查磁盘连接子程序,下面用自行编写的程序代替它 */
 | ||||||
|  | //#define NO_DEFAULT_FILE_ENUMER		1		/* 禁止默认的文件名枚举回调程序,下面用自行编写的程序代替它 */
 | ||||||
|  | //#include "CHRV3SFR.H"
 | ||||||
|  | 
 | ||||||
|  | #include "debug.h" | ||||||
|  | #include "ch32v30x.h" | ||||||
|  | #include "usb_host_config.h" | ||||||
|  | #include "CHRV3UFI.h" | ||||||
|  | 
 | ||||||
|  | uint8_t USBHostTransact( uint8_t endp_pid, uint8_t tog, uint32_t timeout ) | ||||||
|  | { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     uint8_t  r, trans_rerty; | ||||||
|  |     uint16_t i; | ||||||
|  |     USBOTG_H_FS->HOST_TX_CTRL = USBOTG_H_FS->HOST_RX_CTRL = 0; | ||||||
|  |     if( tog & 0x80 ) | ||||||
|  |     { | ||||||
|  |         USBOTG_H_FS->HOST_RX_CTRL = 1<<2; | ||||||
|  |     } | ||||||
|  |     if( tog & 0x40 ) | ||||||
|  |     { | ||||||
|  |         USBOTG_H_FS->HOST_TX_CTRL = 1<<2; | ||||||
|  |     } | ||||||
|  |     trans_rerty = 0; | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |         USBOTG_H_FS->HOST_EP_PID = endp_pid;       // Specify token PID and endpoint number
 | ||||||
|  |         USBOTG_H_FS->INT_FG = USBFS_UIF_TRANSFER;  // Allow transmission
 | ||||||
|  |         for( i = DEF_WAIT_USB_TOUT_200US; ( i != 0 ) && ( ( USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER ) == 0 ); i-- ) | ||||||
|  |         { | ||||||
|  |             Delay_Us( 1 ); | ||||||
|  |         } | ||||||
|  |         USBOTG_H_FS->HOST_EP_PID = 0x00;  // Stop USB transfer
 | ||||||
|  |         if( ( USBOTG_H_FS->INT_FG & USBFS_UIF_TRANSFER ) == 0 ) | ||||||
|  |         { | ||||||
|  |             return ERR_USB_UNKNOWN; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* Complete transfer */ | ||||||
|  |             if( USBOTG_H_FS->INT_ST & USBFS_UIS_TOG_OK ) | ||||||
|  |             { | ||||||
|  |                 return ERR_SUCCESS; | ||||||
|  |             } | ||||||
|  |             r = USBOTG_H_FS->INT_ST & USBFS_UIS_H_RES_MASK;  // USB device answer status
 | ||||||
|  |             if( r == USB_PID_STALL ) | ||||||
|  |             { | ||||||
|  |                 return ( r | ERR_USB_TRANSFER ); | ||||||
|  |             } | ||||||
|  |             if( r == USB_PID_NAK ) | ||||||
|  |             { | ||||||
|  |                 if( timeout == 0 ) | ||||||
|  |                 { | ||||||
|  |                     return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                 } | ||||||
|  |                 if( timeout < 0xFFFF ) | ||||||
|  |                 { | ||||||
|  |                     timeout--; | ||||||
|  |                 } | ||||||
|  |                 --trans_rerty; | ||||||
|  |             } | ||||||
|  |             else switch ( endp_pid >> 4 ) | ||||||
|  |             { | ||||||
|  |                 case USB_PID_SETUP: | ||||||
|  |                 case USB_PID_OUT: | ||||||
|  |                     if( r ) | ||||||
|  |                     { | ||||||
|  |                         return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 case USB_PID_IN: | ||||||
|  |                     if( ( r == USB_PID_DATA0 ) && ( r == USB_PID_DATA1 ) ) | ||||||
|  |                     { | ||||||
|  |                         ; | ||||||
|  |                     } | ||||||
|  |                     else if( r ) | ||||||
|  |                     { | ||||||
|  |                         return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     return ERR_USB_UNKNOWN; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Delay_Us( 15 ); | ||||||
|  |         if( USBOTG_H_FS->INT_FG & USBFS_UIF_DETECT ) | ||||||
|  |         { | ||||||
|  |             Delay_Us( 200 ); | ||||||
|  |             if( USBFSH_CheckRootHubPortEnable( ) == 0 ) | ||||||
|  |             { | ||||||
|  |                 return ERR_USB_DISCON;  // USB device disconnect event
 | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }while( ++trans_rerty < 10 ); | ||||||
|  | 
 | ||||||
|  |     return ERR_USB_TRANSFER; // Reply timeout
 | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     uint8_t   r, trans_retry; | ||||||
|  |     uint16_t  i; | ||||||
|  |     USBHSH->HOST_TX_CTRL = USBHSH->HOST_RX_CTRL = 0; | ||||||
|  |     if( tog & 0x80 ) | ||||||
|  |     { | ||||||
|  |         USBHSH->HOST_RX_CTRL = 1<<3; | ||||||
|  |     } | ||||||
|  |     if( tog & 0x40 ) | ||||||
|  |     { | ||||||
|  |         USBHSH->HOST_TX_CTRL = 1<<3; | ||||||
|  |     } | ||||||
|  |     trans_retry = 0; | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |         USBHSH->HOST_EP_PID = endp_pid; // Set the token for the host to send the packet
 | ||||||
|  |         USBHSH->INT_FG = USBHS_UIF_TRANSFER; | ||||||
|  |         for( i = DEF_WAIT_USB_TOUT_200US; ( i != 0 ) && ( ( USBHSH->INT_FG & USBHS_UIF_TRANSFER ) == 0 ); i-- ) | ||||||
|  |         { | ||||||
|  |             Delay_Us( 1 ); | ||||||
|  |         } | ||||||
|  |         USBHSH->HOST_EP_PID = 0x00; | ||||||
|  |         if( ( USBHSH->INT_FG & USBHS_UIF_TRANSFER ) == 0 ) | ||||||
|  |         { | ||||||
|  |             return ERR_USB_UNKNOWN; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if( USBHSH->INT_FG & USBHS_UIF_DETECT ) | ||||||
|  |         { | ||||||
|  |             USBHSH->INT_FG = USBHS_UIF_DETECT; | ||||||
|  |             Delay_Us( 200 ); | ||||||
|  |             if( USBHSH->MIS_ST & USBHS_UIF_TRANSFER ) | ||||||
|  |             { | ||||||
|  |                 if( USBHSH->HOST_CTRL & USBHS_UH_SOF_EN ) | ||||||
|  |                 { | ||||||
|  |                     return ERR_USB_CONNECT; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 return ERR_USB_DISCON; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if( USBHSH->INT_FG & USBHS_UIF_TRANSFER ) // The packet transmission was successful
 | ||||||
|  |         { | ||||||
|  |             r = USBHSH->INT_ST & USBHS_UIS_H_RES_MASK; | ||||||
|  |             if( ( endp_pid >> 4 ) == USB_PID_IN ) | ||||||
|  |             { | ||||||
|  |                 if( USBHSH->INT_ST & USBHS_UIS_TOG_OK ) | ||||||
|  |                 { | ||||||
|  |                     return ERR_SUCCESS; // Packet token match
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 if( ( r == USB_PID_ACK ) || ( r == USB_PID_NYET ) ) | ||||||
|  |                 { | ||||||
|  |                     return ERR_SUCCESS; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if( r == USB_PID_STALL ) | ||||||
|  |             { | ||||||
|  |                 return ( r | ERR_USB_TRANSFER ); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if( r == USB_PID_NAK ) | ||||||
|  |             { | ||||||
|  |                 if( timeout == 0 ) | ||||||
|  |                 { | ||||||
|  |                     return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                 } | ||||||
|  |                 if( timeout < 0xFFFF ) | ||||||
|  |                 { | ||||||
|  |                     timeout--; | ||||||
|  |                 } | ||||||
|  |                 --trans_retry; | ||||||
|  |             } | ||||||
|  |             else switch( endp_pid >> 4  ) | ||||||
|  |             { | ||||||
|  |                 case USB_PID_SETUP: | ||||||
|  | 
 | ||||||
|  |                 case USB_PID_OUT: | ||||||
|  |                     if( r ) | ||||||
|  |                     { | ||||||
|  |                         return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 case USB_PID_IN: | ||||||
|  |                     if( ( r == USB_PID_DATA0 ) || ( r == USB_PID_DATA1 ) ) | ||||||
|  |                     { | ||||||
|  |                         ; | ||||||
|  |                     } | ||||||
|  |                     else if( r ) | ||||||
|  |                     { | ||||||
|  |                         return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     return ERR_USB_UNKNOWN; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             USBHSH->INT_FG = USBHS_UIF_DETECT | USBHS_UIF_TRANSFER | USBHS_UIF_SUSPEND | USBHS_UIF_HST_SOF | USBHS_UIF_FIFO_OV | USBHS_UIF_SETUP_ACT; | ||||||
|  |         } | ||||||
|  |         Delay_Us( 15 ); | ||||||
|  |     } while( ++trans_retry < 10 ); | ||||||
|  | 
 | ||||||
|  |     return ERR_USB_TRANSFER; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t HostCtrlTransfer( uint8_t *DataBuf, uint8_t *RetLen ) | ||||||
|  | { | ||||||
|  |     uint8_t  ret; | ||||||
|  |     uint16_t retlen; | ||||||
|  |     retlen = (uint16_t)(*RetLen); | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     ret = USBFSH_CtrlTransfer( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, DataBuf, &retlen ); | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     ret = USBHSH_CtrlTransfer( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, DataBuf, &retlen ); | ||||||
|  | #endif | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void CopySetupReqPkg( const char * pReqPkt ) | ||||||
|  | { | ||||||
|  |     uint8_t i; | ||||||
|  |     for(i = 0; i != sizeof(USB_SETUP_REQ); i++) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         ((char *)pUSBFS_SetupRequest)[i] = *pReqPkt; | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |         ((char *)pUSBHS_SetupRequest)[i] = *pReqPkt; | ||||||
|  | #endif | ||||||
|  |         pReqPkt++; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CtrlGetDeviceDescrTB( void ) | ||||||
|  | { | ||||||
|  |     uint8_t ret; | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     ret = USBFSH_GetDeviceDescr( &RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, TxBuffer ); | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     ret = USBHSH_GetDeviceDescr( &RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, TxBuffer ); | ||||||
|  | #endif | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CtrlGetConfigDescrTB( void ) | ||||||
|  | { | ||||||
|  |     uint16_t len; | ||||||
|  |     uint8_t  ret; | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     ret = USBFSH_GetConfigDescr( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, TxBuffer, 256, &len ); | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     ret = USBHSH_GetConfigDescr( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, TxBuffer, 256, &len ); | ||||||
|  | #endif | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CtrlSetUsbConfig( uint8_t cfg ) | ||||||
|  | { | ||||||
|  |     uint8_t ret; | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     ret = USBFSH_SetUsbConfig( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, cfg ); | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     ret = USBHSH_SetUsbConfig( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, cfg ); | ||||||
|  | #endif | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CtrlSetUsbAddress( uint8_t addr ) | ||||||
|  | { | ||||||
|  |     uint8_t ret; | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     ret = USBFSH_SetUsbAddress( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, addr ); | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     ret = USBHSH_SetUsbAddress( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, addr ); | ||||||
|  | #endif | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t CtrlClearEndpStall( uint8_t endp ) | ||||||
|  | { | ||||||
|  |     uint8_t ret; | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     ret = USBFSH_ClearEndpStall( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, endp ); | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     ret = USBHSH_ClearEndpStall( RootHubDev[ DEF_USB_PORT_HS ].bEp0MaxPks, endp ); | ||||||
|  | #endif | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifndef FOR_ROOT_UDISK_ONLY | ||||||
|  | uint8_t CtrlGetHubDescr( void ) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t HubGetPortStatus( uint8_t HubPortIndex ) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t HubSetPortFeature( uint8_t HubPortIndex, uint8_t FeatureSelt ) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8_t HubClearPortFeature( uint8_t HubPortIndex, uint8_t FeatureSelt ) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | CMD_PARAM_I	mCmdParam;						/* 命令参数 */ | ||||||
|  | #if		DISK_BASE_BUF_LEN > 0 | ||||||
|  | //uint8_t	DISK_BASE_BUF[ DISK_BASE_BUF_LEN ] __attribute__((at(BA_RAM+SZ_RAM/2)));	/* 外部RAM的磁盘数据缓冲区,缓冲区长度为一个扇区的长度 */
 | ||||||
|  | uint8_t	DISK_BASE_BUF[ DISK_BASE_BUF_LEN ] __attribute__((aligned (4)));	        /* 外部RAM的磁盘数据缓冲区,缓冲区长度为一个扇区的长度 */ | ||||||
|  | //UINT8	DISK_FAT_BUF[ DISK_BASE_BUF_LEN ] __attribute__((aligned (4)));	            /* 外部RAM的磁盘FAT数据缓冲区,缓冲区长度为一个扇区的长度 */
 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /* 以下程序可以根据需要修改 */ | ||||||
|  | 
 | ||||||
|  | #ifndef	NO_DEFAULT_ACCESS_SECTOR		/* 在应用程序中定义NO_DEFAULT_ACCESS_SECTOR可以禁止默认的磁盘扇区读写子程序,然后用自行编写的程序代替它 */ | ||||||
|  | //if ( use_external_interface ) {  // 替换U盘扇区底层读写子程序
 | ||||||
|  | //    CHRV3vSectorSize=512;  // 设置实际的扇区大小,必须是512的倍数,该值是磁盘的扇区大小
 | ||||||
|  | //    CHRV3vSectorSizeB=9;   // 设置实际的扇区大小的位移数,512则对应9,1024对应10,2048对应11
 | ||||||
|  | //    CHRV3DiskStatus=DISK_MOUNTED;  // 强制块设备连接成功(只差分析文件系统)
 | ||||||
|  | //}
 | ||||||
|  | 
 | ||||||
|  | uint8_t	CHRV3ReadSector( uint8_t SectCount, uint8_t *DataBuf )  /* 从磁盘读取多个扇区的数据到缓冲区中 */ | ||||||
|  | { | ||||||
|  |     uint8_t	retry; | ||||||
|  | //	if ( use_external_interface ) return( extReadSector( CHRV3vLbaCurrent, SectCount, DataBuf ) );  /* 外部接口 */
 | ||||||
|  | 	for( retry = 0; retry < 3; retry ++ ) {  /* 错误重试 */ | ||||||
|  | 		pCBW -> mCBW_DataLen = (uint32_t)SectCount << CHRV3vSectorSizeB;  /* 数据传输长度 */ | ||||||
|  | 		pCBW -> mCBW_Flag = 0x80; | ||||||
|  | 		pCBW -> mCBW_LUN = CHRV3vCurrentLun; | ||||||
|  | 		pCBW -> mCBW_CB_Len = 10; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 0 ] = SPC_CMD_READ10; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 1 ] = 0x00; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 2 ] = (uint8_t)( CHRV3vLbaCurrent >> 24 ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 3 ] = (uint8_t)( CHRV3vLbaCurrent >> 16 ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 4 ] = (uint8_t)( CHRV3vLbaCurrent >> 8 ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 5 ] = (uint8_t)( CHRV3vLbaCurrent ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 6 ] = 0x00; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 7 ] = 0x00; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 8 ] = SectCount; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 9 ] = 0x00; | ||||||
|  | 		CHRV3BulkOnlyCmd( DataBuf );  /* 执行基于BulkOnly协议的命令 */ | ||||||
|  | 		if ( CHRV3IntStatus == ERR_SUCCESS ) { | ||||||
|  | 			return( ERR_SUCCESS ); | ||||||
|  | 		} | ||||||
|  | 		CHRV3IntStatus = CHRV3AnalyzeError( retry ); | ||||||
|  | 		if ( CHRV3IntStatus != ERR_SUCCESS ) { | ||||||
|  | 			return( CHRV3IntStatus ); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return( CHRV3IntStatus = ERR_USB_DISK_ERR );  /* 磁盘操作错误 */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #ifdef	EN_DISK_WRITE | ||||||
|  | uint8_t	CHRV3WriteSector( uint8_t SectCount, uint8_t *DataBuf )  /* 将缓冲区中的多个扇区的数据块写入磁盘 */ | ||||||
|  | { | ||||||
|  |     uint8_t	retry; | ||||||
|  | //	if ( use_external_interface ) return( extWriteSector( CHRV3vLbaCurrent, SectCount, DataBuf ) );  /* 外部接口 */
 | ||||||
|  | 	for( retry = 0; retry < 3; retry ++ ) {  /* 错误重试 */ | ||||||
|  | 		pCBW -> mCBW_DataLen = (uint32_t)SectCount << CHRV3vSectorSizeB;  /* 数据传输长度 */ | ||||||
|  | 		pCBW -> mCBW_Flag = 0x00; | ||||||
|  | 		pCBW -> mCBW_LUN = CHRV3vCurrentLun; | ||||||
|  | 		pCBW -> mCBW_CB_Len = 10; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 0 ] = SPC_CMD_WRITE10; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 1 ] = 0x00; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 2 ] = (uint8_t)( CHRV3vLbaCurrent >> 24 ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 3 ] = (uint8_t)( CHRV3vLbaCurrent >> 16 ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 4 ] = (uint8_t)( CHRV3vLbaCurrent >> 8 ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 5 ] = (uint8_t)( CHRV3vLbaCurrent ); | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 6 ] = 0x00; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 7 ] = 0x00; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 8 ] = SectCount; | ||||||
|  | 		pCBW -> mCBW_CB_Buf[ 9 ] = 0x00; | ||||||
|  | 		CHRV3BulkOnlyCmd( DataBuf );  /* 执行基于BulkOnly协议的命令 */ | ||||||
|  | 		if ( CHRV3IntStatus == ERR_SUCCESS ) { | ||||||
|  | 			Delay_Us( 200 );  /* 写操作后延时 */ | ||||||
|  | 			return( ERR_SUCCESS ); | ||||||
|  | 		} | ||||||
|  | 		CHRV3IntStatus = CHRV3AnalyzeError( retry ); | ||||||
|  | 		if ( CHRV3IntStatus != ERR_SUCCESS ) { | ||||||
|  | 			return( CHRV3IntStatus ); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return( CHRV3IntStatus = ERR_USB_DISK_ERR );  /* 磁盘操作错误 */ | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | #endif  // NO_DEFAULT_ACCESS_SECTOR
 | ||||||
|  | 
 | ||||||
|  | #ifndef	NO_DEFAULT_DISK_CONNECT			/* 在应用程序中定义NO_DEFAULT_DISK_CONNECT可以禁止默认的检查磁盘连接子程序,然后用自行编写的程序代替它 */ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | 约定: USB设备地址分配规则(参考USB_DEVICE_ADDR) | ||||||
|  | 地址值  设备位置 | ||||||
|  | 0x02    内置Root-HUB0下的USB设备或外部HUB | ||||||
|  | 0x03    内置Root-HUB1下的USB设备或外部HUB | ||||||
|  | 0x1x    内置Root-HUB0下的外部HUB的端口x下的USB设备,x为1~n | ||||||
|  | 0x2x    内置Root-HUB1下的外部HUB的端口x下的USB设备,x为1~n | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | #define		UHUB_DEV_ADDR	(USBHSH->DEV_AD) | ||||||
|  | #define		UHUB_MIS_STAT	(USBHSH->MIS_ST) | ||||||
|  | #define		UHUB_HOST_CTRL	(USBHSH->HOST_CTRL) | ||||||
|  | #define		UHUB_INT_FLAG	(USBHSH->INT_FG) | ||||||
|  | #define		bUMS_ATTACH		USBHS_UMS_DEV_ATTACH | ||||||
|  | #define		bUMS_SUSPEND	USBHS_UMS_SUSPEND | ||||||
|  | 
 | ||||||
|  | /* 检查磁盘是否连接 */ | ||||||
|  | uint8_t	CHRV3DiskConnect( void ) | ||||||
|  | { | ||||||
|  |     uint8_t	ums, devaddr; | ||||||
|  | 	UHUB_DEV_ADDR = UHUB_DEV_ADDR & 0x7F; | ||||||
|  | 	ums = UHUB_MIS_STAT; | ||||||
|  | 	devaddr = UHUB_DEV_ADDR; | ||||||
|  | 	if ( devaddr == USB_DEVICE_ADDR+1 ) | ||||||
|  | 	{ | ||||||
|  | 	    /* 内置Root-HUB下的USB设备 */ | ||||||
|  | 		if ( ums & bUMS_ATTACH ) | ||||||
|  | 		{ | ||||||
|  | 		    /* 内置Root-HUB下的USB设备存在 */ | ||||||
|  | 			if ( ( ums & bUMS_SUSPEND ) == 0 ) | ||||||
|  | 			{ | ||||||
|  | 			    /* 内置Root-HUB下的USB设备存在且未插拔 */ | ||||||
|  | 				return( ERR_SUCCESS );  /* USB设备已经连接且未插拔 */ | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 			    /* 内置Root-HUB下的USB设备存在 */ | ||||||
|  | 				CHRV3DiskStatus = DISK_CONNECT;  /* 曾经断开过 */ | ||||||
|  | 				return( ERR_SUCCESS );  /* 外部HUB或USB设备已经连接或者断开后重新连接 */ | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 		    /* USB设备断开 */ | ||||||
|  | mDiskDisconn: | ||||||
|  | 			CHRV3DiskStatus = DISK_DISCONNECT; | ||||||
|  | 			return( ERR_USB_DISCON ); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		goto mDiskDisconn; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | #endif  // NO_DEFAULT_DISK_CONNECT
 | ||||||
|  | 
 | ||||||
|  | #ifndef	NO_DEFAULT_FILE_ENUMER			/* 在应用程序中定义NO_DEFAULT_FILE_ENUMER可以禁止默认的文件名枚举回调程序,然后用自行编写的程序代替它 */ | ||||||
|  | void xFileNameEnumer( void )			/* 文件名枚举回调子程序 */ | ||||||
|  | { | ||||||
|  | /* 如果指定枚举序号CHRV3vFileSize为0xFFFFFFFF后调用FileOpen,那么每搜索到一个文件FileOpen都会调用本回调程序,
 | ||||||
|  |    回调程序xFileNameEnumer返回后,FileOpen递减CHRV3vFileSize并继续枚举直到搜索不到文件或者目录。建议做法是, | ||||||
|  |    在调用FileOpen之前定义一个全局变量为0,当FileOpen回调本程序后,本程序由CHRV3vFdtOffset得到结构FAT_DIR_INFO, | ||||||
|  |    分析结构中的DIR_Attr以及DIR_Name判断是否为所需文件名或者目录名,记录相关信息,并将全局变量计数增量, | ||||||
|  |    当FileOpen返回后,判断返回值如果是ERR_MISS_FILE或ERR_FOUND_NAME都视为操作成功,全局变量为搜索到的有效文件数。 | ||||||
|  |    如果在本回调程序xFileNameEnumer中将CHRV3vFileSize置为1,那么可以通知FileOpen提前结束搜索。以下是回调程序例子 */ | ||||||
|  | #if		0 | ||||||
|  |     uint8_t			i; | ||||||
|  |     uint16_t	    FileCount; | ||||||
|  | 	PX_FAT_DIR_INFO	pFileDir; | ||||||
|  | 	uint8_t			*NameBuf; | ||||||
|  | 	pFileDir = (PX_FAT_DIR_INFO)( pDISK_BASE_BUF + CHRV3vFdtOffset );  /* 当前FDT的起始地址 */ | ||||||
|  | 	FileCount = (UINT16)( 0xFFFFFFFF - CHRV3vFileSize );  /* 当前文件名的枚举序号,CHRV3vFileSize初值是0xFFFFFFFF,找到文件名后递减 */ | ||||||
|  | 	if ( FileCount < sizeof( FILE_DATA_BUF ) / 12 ) {  /* 检查缓冲区是否足够存放,假定每个文件名需占用12个字节存放 */ | ||||||
|  | 		NameBuf = & FILE_DATA_BUF[ FileCount * 12 ];  /* 计算保存当前文件名的缓冲区地址 */ | ||||||
|  | 		for ( i = 0; i < 11; i ++ ) NameBuf[ i ] = pFileDir -> DIR_Name[ i ];  /* 复制文件名,长度为11个字符,未处理空格 */ | ||||||
|  | //		if ( pFileDir -> DIR_Attr & ATTR_DIRECTORY ) NameBuf[ i ] = 1;  /* 判断是目录名 */
 | ||||||
|  | 		NameBuf[ i ] = 0;  /* 文件名结束符 */ | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | #endif  // NO_DEFAULT_FILE_ENUMER
 | ||||||
|  | 
 | ||||||
|  | uint8_t	CHRV3LibInit( void )  /* 初始化CHRV3程序库,操作成功返回0 */ | ||||||
|  | { | ||||||
|  |     uint8_t s; | ||||||
|  |     s = CHRV3GetVer( ); | ||||||
|  | 	if( s < CHRV3_LIB_VER ) | ||||||
|  | 	{ | ||||||
|  |         return( 0xFF );  /* 获取当前子程序库的版本号,版本太低则返回错误 */ | ||||||
|  | 	} | ||||||
|  | 	printf( "lib vision:%02x\r\n",s ); | ||||||
|  | #if		DISK_BASE_BUF_LEN > 0 | ||||||
|  | 	pDISK_BASE_BUF = & DISK_BASE_BUF[0]; /* 指向外部RAM的磁盘数据缓冲区 */ | ||||||
|  | 	pDISK_FAT_BUF = & DISK_BASE_BUF[0];  /* 指向外部RAM的磁盘FAT数据缓冲区,可以与pDISK_BASE_BUF合用以节约RAM */ | ||||||
|  | //	pDISK_FAT_BUF = & DISK_FAT_BUF[0];   /* 指向外部RAM的磁盘FAT数据缓冲区,独立于pDISK_BASE_BUF以提高速度 */
 | ||||||
|  | /* 如果希望提高文件存取速度,那么可以在主程序中调用CHRV3LibInit之后,将pDISK_FAT_BUF重新指向另一个独立分配的与pDISK_BASE_BUF同样大小的缓冲区 */ | ||||||
|  | #endif | ||||||
|  | 	CHRV3DiskStatus = DISK_UNKNOWN;  /* 未知状态 */ | ||||||
|  | 	CHRV3vSectorSizeB = 9;  /* 默认的物理磁盘的扇区是512B */ | ||||||
|  | 	CHRV3vSectorSize = 512; /* 默认的物理磁盘的扇区是512B,该值是磁盘的扇区大小 */ | ||||||
|  | 	CHRV3vStartLba = 0;     /* 默认为自动分析FDD和HDD */ | ||||||
|  | 	CHRV3vPacketSize = 512;  /* USB存储类设备的最大包长度:64@FS,512@HS/SS,由应用程序初始化,枚举U盘后如果是高速或者超速那么及时更新为512 */ | ||||||
|  | 
 | ||||||
|  |     pTX_DMA_A_REG = (uint32_t *)&(USBHSH->HOST_TX_DMA);  /* 指向发送DMA地址寄存器,由应用程序初始化 */ | ||||||
|  |     pRX_DMA_A_REG = (uint32_t *)&(USBHSH->HOST_RX_DMA);  /* 指向接收DMA地址寄存器,由应用程序初始化 */ | ||||||
|  |     pTX_LEN_REG = (uint16_t *)&(USBHSH->HOST_TX_LEN);    /* 指向发送长度寄存器,由应用程序初始化 */ | ||||||
|  |     pRX_LEN_REG = (uint16_t *)&(USBHSH->RX_LEN);         /* 指向接收长度寄存器,由应用程序初始化 */ | ||||||
|  | 
 | ||||||
|  | 	return( ERR_SUCCESS ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void mDelaymS( uint16_t n ) | ||||||
|  | { | ||||||
|  | 	Delay_Ms(n); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | SRC_FILES := ch32v30x_usbhs_host.c Udisk_Func_BasicOp.c UDisk_Func_CreatDir.c UDisk_Func_LongName.c UDisk_HW.c CH32V103UFI.c | ||||||
|  | 
 | ||||||
|  | include $(KERNEL_ROOT)/compiler.mk | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,195 @@ | ||||||
|  | /********************************** (C) COPYRIGHT *******************************
 | ||||||
|  | * File Name          : UDisk_Func_CreatDir.c | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2022/11/22 | ||||||
|  | * Description        : USB full-speed port host operation functions. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Header File */ | ||||||
|  | #include "Udisk_Operation.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************
 | ||||||
|  | * Function Name  : CreateDirectory | ||||||
|  | * Description    : 新建目录并打开,如果目录已经存在则直接打开,目录名在mCmdParam.Create.mPathName中,与文件名规则相同 | ||||||
|  | * Input          : | ||||||
|  | * Output         : None | ||||||
|  | * Return         : ERR_SUCCESS = 打开目录成功或者创建目录成功, | ||||||
|  |                    ERR_FOUND_NAME = 已经存在同名文件, | ||||||
|  |                    ERR_MISS_DIR = 路径名无效或者上级目录不存在 | ||||||
|  | *******************************************************************************/ | ||||||
|  | uint8_t CreateDirectory( void ) | ||||||
|  | { | ||||||
|  |     uint8_t   i, j; | ||||||
|  |     uint32_t  UpDirCluster; | ||||||
|  |     uint8_t * DirXramBuf; | ||||||
|  |     uint8_t  *DirConstData; | ||||||
|  |     j = 0xFF; | ||||||
|  |     for ( i = 0; i != sizeof( mCmdParam.Create.mPathName ); i ++ )    //检查目录路径
 | ||||||
|  |     { | ||||||
|  |         if ( mCmdParam.Create.mPathName[ i ] == 0 ) | ||||||
|  |         { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         if ( mCmdParam.Create.mPathName[ i ] == PATH_SEPAR_CHAR1 || mCmdParam.Create.mPathName[ i ] == PATH_SEPAR_CHAR2 ) | ||||||
|  |         { | ||||||
|  |             j = i;                                                     //记录上级目录
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     i = ERR_SUCCESS; | ||||||
|  |     if ( j == 0 || (j == 2 && mCmdParam.Create.mPathName[1] == ':') ) | ||||||
|  |     { | ||||||
|  |         UpDirCluster = 0;                                              //在根目录下创建子目录
 | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         if ( j != 0xFF )                                               //对于绝对路径应该获取上级目录的起始簇号
 | ||||||
|  |         { | ||||||
|  |             mCmdParam.Create.mPathName[ j ] = 0; | ||||||
|  |             i = CHRV3FileOpen( );                                      //打开上级目录
 | ||||||
|  |             if ( i == ERR_SUCCESS ) | ||||||
|  |             { | ||||||
|  |                 i = ERR_MISS_DIR;                                      //是文件而非目录
 | ||||||
|  |             } | ||||||
|  |             else if ( i == ERR_OPEN_DIR ) | ||||||
|  |             { | ||||||
|  |                 i = ERR_SUCCESS;                                       //成功打开上级目录
 | ||||||
|  |             } | ||||||
|  |             mCmdParam.Create.mPathName[ j ] = PATH_SEPAR_CHAR1;        //恢复目录分隔符
 | ||||||
|  |         } | ||||||
|  |         UpDirCluster = CHRV3vStartCluster;                             //保存上级目录的起始簇号
 | ||||||
|  |     } | ||||||
|  |     if ( i == ERR_SUCCESS )                                            //成功获取上级目录的起始簇号
 | ||||||
|  |     { | ||||||
|  |         i = CHRV3FileOpen( );                                          //打开本级子目录
 | ||||||
|  |         if ( i == ERR_SUCCESS ) | ||||||
|  |         { | ||||||
|  |             i = ERR_FOUND_NAME;                                        //是文件而非目录
 | ||||||
|  |         } | ||||||
|  |         else if ( i == ERR_OPEN_DIR ) | ||||||
|  |         { | ||||||
|  |             i = ERR_SUCCESS;                                           //目录已经存在
 | ||||||
|  |         } | ||||||
|  |         else if ( i == ERR_MISS_FILE )                                 //目录不存在,可以新建
 | ||||||
|  |         { | ||||||
|  |             i = CHRV3FileCreate( );                                    //以创建文件的方法创建目录
 | ||||||
|  |             if ( i == ERR_SUCCESS ) | ||||||
|  |             { | ||||||
|  |                 if ( pDISK_FAT_BUF == pDISK_BASE_BUF ) | ||||||
|  |                 { | ||||||
|  |                     memset(pDISK_FAT_BUF,0,CHRV3vSectorSize);     //如果FILE_DATA_BUF与DISK_BASE_BUF合用则必须清除磁盘缓冲区
 | ||||||
|  |                 } | ||||||
|  |                 DirXramBuf = pDISK_FAT_BUF;                            //文件数据缓冲区
 | ||||||
|  |                 DirConstData = ".          \x10\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x21\x30\x0\x0\x0\x0\x0\x0..         \x10\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x21\x30\x0\x0\x0\x0\x0\x0"; | ||||||
|  |                 for ( i = 0x40; i != 0; i -- )                         //目录的保留单元,分别指向自身和上级目录
 | ||||||
|  |                 { | ||||||
|  |                     *DirXramBuf = *DirConstData; | ||||||
|  |                     DirXramBuf ++; | ||||||
|  |                     DirConstData ++; | ||||||
|  |                 } | ||||||
|  |                 *(pDISK_FAT_BUF+0x1A) = ( (uint8_t *)&CHRV3vStartCluster )[3];//自身的起始簇号
 | ||||||
|  |                 *(pDISK_FAT_BUF+0x1B) = ( (uint8_t *)&CHRV3vStartCluster )[2]; | ||||||
|  |                 *(pDISK_FAT_BUF+0x14) = ( (uint8_t *)&CHRV3vStartCluster )[1]; | ||||||
|  |                 *(pDISK_FAT_BUF+0x15) = ( (uint8_t *)&CHRV3vStartCluster )[0]; | ||||||
|  |                 *(pDISK_FAT_BUF+0x20+0x1A) = ( (uint8_t *)&UpDirCluster )[3];//上级目录的起始簇号
 | ||||||
|  |                 *(pDISK_FAT_BUF+0x20+0x1B) = ( (uint8_t *)&UpDirCluster )[2]; | ||||||
|  |                 *(pDISK_FAT_BUF+0x20+0x14) = ( (uint8_t *)&UpDirCluster )[1]; | ||||||
|  |                 *(pDISK_FAT_BUF+0x20+0x15) = ( (uint8_t *)&UpDirCluster )[0]; | ||||||
|  | //              for ( count = 0x40; count != CHRV3vSectorSizeH*256; count ++ ) {  /* 清空目录区剩余部分 */
 | ||||||
|  | //                  *DirXramBuf = 0;
 | ||||||
|  | //                  DirXramBuf ++;
 | ||||||
|  | //              }
 | ||||||
|  |                 mCmdParam.Write.mSectorCount = 1; | ||||||
|  |                 mCmdParam.Write.mDataBuffer = pDISK_FAT_BUF;                //指向文件数据缓冲区的起始地址
 | ||||||
|  |                 i = CHRV3FileWrite( );                                      //向文件写入数据
 | ||||||
|  |                 if ( i == ERR_SUCCESS ) | ||||||
|  |                 { | ||||||
|  |                     DirXramBuf = pDISK_FAT_BUF; | ||||||
|  |                     for ( i = 0x40; i != 0; i -- )                          //清空目录区
 | ||||||
|  |                     { | ||||||
|  |                         *DirXramBuf = 0; | ||||||
|  |                         DirXramBuf ++; | ||||||
|  |                     } | ||||||
|  |                     for ( j = 1; j != CHRV3vSecPerClus; j ++ ) | ||||||
|  |                     { | ||||||
|  |                         if ( pDISK_FAT_BUF == pDISK_BASE_BUF ) | ||||||
|  |                         { | ||||||
|  |                             memset(pDISK_FAT_BUF,0,CHRV3vSectorSize);   //如果FILE_DATA_BUF与DISK_BASE_BUF合用则必须清除磁盘缓冲区
 | ||||||
|  |                         } | ||||||
|  |                         mCmdParam.Write.mSectorCount = 1; | ||||||
|  |                         mCmdParam.Write.mDataBuffer = pDISK_FAT_BUF;         //指向文件数据缓冲区的起始地址
 | ||||||
|  |                         i = CHRV3FileWrite( );                               //清空目录的剩余扇区
 | ||||||
|  |                         if ( i != ERR_SUCCESS ) | ||||||
|  |                         { | ||||||
|  |                             break; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     if ( j == CHRV3vSecPerClus )                              //成功清空目录
 | ||||||
|  |                     { | ||||||
|  |                         mCmdParam.Modify.mFileSize = 0;                       //目录的长度总是0
 | ||||||
|  |                         mCmdParam.Modify.mFileDate = 0xFFFF; | ||||||
|  |                         mCmdParam.Modify.mFileTime = 0xFFFF; | ||||||
|  |                         mCmdParam.Modify.mFileAttr = 0x10;                    //置目录属性
 | ||||||
|  |                         i = CHRV3FileModify( );                               //将文件信息修改为目录
 | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return( i ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      UDisk_USBH_CreatDirectory | ||||||
|  |  * | ||||||
|  |  * @brief   Demo Function For UDisk Create Directory (EXAM9) | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void UDisk_USBH_CreatDirectory( void ) | ||||||
|  | { | ||||||
|  |     uint8_t  i; | ||||||
|  |     uint8_t  ret; | ||||||
|  | 
 | ||||||
|  |     ret = UDisk_USBH_DiskReady( ); | ||||||
|  |     if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) ) | ||||||
|  |     { | ||||||
|  |         UDisk_Opeation_Flag = 0; | ||||||
|  |         printf("CHRV3DiskStatus:%02x\r\n",CHRV3DiskStatus); | ||||||
|  |         printf( "Create Level 1 Directory /YEAR2004 \r\n" ); | ||||||
|  |         strcpy( mCmdParam.Create.mPathName, "/YEAR2004" );             //目录名,该目录建在根目录下
 | ||||||
|  |         ret = CreateDirectory( );                                      //新建或者打开目录
 | ||||||
|  |         mStopIfError( ret ); | ||||||
|  |         /* 目录新建或者打开成功,下面在这个子目录中新建一个演示文件 */ | ||||||
|  |         printf( "Create New File /YEAR2004/DEMO2004.TXT \r\n" ); | ||||||
|  |         strcpy( mCmdParam.Create.mPathName, "/YEAR2004/DEMO2004.TXT" );//文件名
 | ||||||
|  |         ret = CHRV3FileCreate( );                                      //新建文件并打开,如果文件已经存在则先删除后再新建
 | ||||||
|  |         mStopIfError( ret ); | ||||||
|  |         printf( "Write some data to file DEMO2004.TXT \r\n" ); | ||||||
|  |         i = sprintf( Com_Buffer, "演示文件\xd\xa" ); | ||||||
|  |         mCmdParam.ByteWrite.mByteCount = i;                            //指定本次写入的字节数,单次读写的长度不能超过MAX_BYTE_IO
 | ||||||
|  |         mCmdParam.ByteWrite.mByteBuffer = Com_Buffer;                  //指向缓冲区
 | ||||||
|  |         ret = CHRV3ByteWrite( );                                       //以字节为单位向文件写入数据,单次读写的长度不能超过MAX_BYTE_IO
 | ||||||
|  |         mStopIfError( ret ); | ||||||
|  |         printf( "Close file DEMO2004.TXT \r\n" ); | ||||||
|  |         mCmdParam.Close.mUpdateLen = 1;                                //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度
 | ||||||
|  |         ret = CHRV3FileClose( ); | ||||||
|  |         mStopIfError( ret ); | ||||||
|  |         /* 下面新建二级子目录,方法与前面的一级子目录完全相同 */ | ||||||
|  |         printf( "Create Level 2 Directory /YEAR2004/MONTH05 \r\n" ); | ||||||
|  |         strcpy( mCmdParam.Create.mPathName, "/YEAR2004/MONTH05" );    //目录名,该目录建在YEAR2004子目录下,YEAR2004目录必须事先存在
 | ||||||
|  |         ret = CreateDirectory( );                                     //新建或者打开目录
 | ||||||
|  |         mStopIfError( ret ); | ||||||
|  |         printf( "Close\r\n" ); | ||||||
|  |         mCmdParam.Close.mUpdateLen = 0;                               //对于目录不需要自动更新文件长度
 | ||||||
|  |         ret = CHRV3FileClose( );                                      //关闭目录,目录不需要关闭,关闭只是为了防止下面误操作
 | ||||||
|  |         mStopIfError( ret ); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,596 @@ | ||||||
|  | /********************************** (C) COPYRIGHT *******************************
 | ||||||
|  | * File Name          : Udisk_Func_longname.c | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2022/11/22 | ||||||
|  | * Description        : USB full-speed port host operation functions. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Header File */ | ||||||
|  | #include "Udisk_Operation.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Variable Definition */ | ||||||
|  | uint8_t    LongNameBuf[ LONG_NAME_BUF_LEN ]; | ||||||
|  | /*
 | ||||||
|  | 长文件名示例(UNICODE编码的大小端 必须与UNICODE_ENDIAN定义相同) | ||||||
|  | 以下是LongName里编码内容: | ||||||
|  | 建立长文件名,输入两个参数: 1.采用(unicode 大端),字符串末尾用两个0表示结束;2.ANSI编码短文件名.TXT | ||||||
|  | */ | ||||||
|  | uint8_t LongName[ ] = | ||||||
|  | #if UNICODE_ENDIAN == 1 | ||||||
|  | { | ||||||
|  |     0x5E, 0xFA, 0x7A, 0xCB, 0x95, 0x7F, 0x65, 0x87, 0x4E, 0xF6, 0x54, 0x0D, 0xFF, 0x0C, 0x8F, 0x93, | ||||||
|  |     0x51, 0x65, 0x4E, 0x24, 0x4E, 0x2A, 0x53, 0xC2, 0x65, 0x70, 0xFF, 0x1A, 0x00, 0x20, 0x00, 0x31, | ||||||
|  |     0x00, 0x2E, 0x91, 0xC7, 0x75, 0x28, 0x00, 0x28, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x69, 0x00, 0x63, | ||||||
|  |     0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x59, 0x27, 0x7A, 0xEF, 0x00, 0x29, 0xFF, 0x0C, | ||||||
|  |     0x5B, 0x57, 0x7B, 0x26, 0x4E, 0x32, 0x67, 0x2B, 0x5C, 0x3E, 0x75, 0x28, 0x4E, 0x24, 0x4E, 0x2A, | ||||||
|  |     0x00, 0x30, 0x88, 0x68, 0x79, 0x3A, 0x7E, 0xD3, 0x67, 0x5F, 0x00, 0x3B, 0x00, 0x32, 0x00, 0x2E, | ||||||
|  |     0x00, 0x41, 0x00, 0x4E, 0x00, 0x53, 0x00, 0x49, 0x7F, 0x16, 0x78, 0x01, 0x77, 0xED, 0x65, 0x87, | ||||||
|  |     0x4E, 0xF6, 0x54, 0x0D, 0x00, 0x2E, 0x00, 0x54, 0x00, 0x58, 0x00, 0x54 | ||||||
|  | }; | ||||||
|  | #else | ||||||
|  | { | ||||||
|  |     0xFA, 0x5E, 0xCB, 0x7A, 0x7F, 0x95, 0x87, 0x65, 0xF6, 0x4E, 0x0D, 0x54, 0x0C, 0xFF, 0x93, 0x8F, | ||||||
|  |     0x65, 0x51, 0x24, 0x4E, 0x2A, 0x4E, 0xC2, 0x53, 0x70, 0x65, 0x1A, 0xFF, 0x20, 0x00, 0x31, 0x00, | ||||||
|  |     0x2E, 0x00, 0xC7, 0x91, 0x28, 0x75, 0x28, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x69, 0x00, 0x63, 0x00, | ||||||
|  |     0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x00, 0x27, 0x59, 0xEF, 0x7A, 0x29, 0x00, 0x0C, 0xFF, | ||||||
|  |     0x57, 0x5B, 0x26, 0x7B, 0x32, 0x4E, 0x2B, 0x67, 0x3E, 0x5C, 0x28, 0x75, 0x24, 0x4E, 0x2A, 0x4E, | ||||||
|  |     0x30, 0x00, 0x68, 0x88, 0x3A, 0x79, 0xD3, 0x7E, 0x5F, 0x67, 0x3B, 0x00, 0x32, 0x00, 0x2E, 0x00, | ||||||
|  |     0x41, 0x00, 0x4E, 0x00, 0x53, 0x00, 0x49, 0x00, 0x16, 0x7F, 0x01, 0x78, 0xED, 0x77, 0x87, 0x65, | ||||||
|  |     0xF6, 0x4E, 0x0D, 0x54, 0x2E, 0x00, 0x54, 0x00, 0x58, 0x00, 0x54, 0x00 | ||||||
|  | }; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      UDisk_USBH_Longname | ||||||
|  |  * | ||||||
|  |  * @brief   Demo Function For UDisk long-name Operation(EXAM 13) | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void UDisk_USBH_Longname( void ) | ||||||
|  | { | ||||||
|  |     uint8_t  ret, i, len; | ||||||
|  |     uint16_t j; | ||||||
|  | 
 | ||||||
|  |     ret = UDisk_USBH_DiskReady( ); | ||||||
|  |     if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) ) | ||||||
|  |     { | ||||||
|  |         UDisk_Opeation_Flag = 0; | ||||||
|  |         /*==================== 以下演示创建及读取长文件名 ============================*/ | ||||||
|  |         // 复制长文件名(UNICODE 大端)到LongNameBuf里
 | ||||||
|  |         len = LongName_Len; | ||||||
|  |         memcpy( LongNameBuf, LongName, len ); | ||||||
|  |         // 末尾用两个0表示结束
 | ||||||
|  |         LongNameBuf[len] = 0x00; | ||||||
|  |         LongNameBuf[len + 1] = 0x00; | ||||||
|  |         // 该长文件名的ANSI编码短文件名(8+3格式)
 | ||||||
|  |         strcpy( mCmdParam.Create.mPathName, "\\长文件名.TXT" ); | ||||||
|  |         i = CHRV3CreateLongName( ); | ||||||
|  |         if( i == ERR_SUCCESS ) | ||||||
|  |         { | ||||||
|  |             DUG_PRINTF( "Created Long Name OK!\r\n" ); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* Error code defined in "udisk_operaion.h" */ | ||||||
|  |             DUG_PRINTF( "Error Code: %02X\r\n", (uint16_t)i ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         DUG_PRINTF( "Get long Name#\r\n" ); | ||||||
|  |         strcpy( mCmdParam.Open.mPathName, "\\长文件名.TXT" ); | ||||||
|  |         // 以上需要输入文件名的完整路径
 | ||||||
|  |         i = CHRV3GetLongName( ); | ||||||
|  |         if( i == ERR_SUCCESS ) | ||||||
|  |         { | ||||||
|  |             // 长文件名收集完成,以UNICODE编码方式(按UNICODE_ENDIAN定义)
 | ||||||
|  |             // 存放在LongNameBuf缓冲里,长文件名最后用两个0结束.
 | ||||||
|  |             // 以下显示缓冲区里所有数据
 | ||||||
|  |             DUG_PRINTF( "LongNameBuf: " ); | ||||||
|  |             for( j=0; j!=LONG_NAME_BUF_LEN; j++ ) | ||||||
|  |             { | ||||||
|  |                 DUG_PRINTF( "%02X ", (uint16_t)LongNameBuf[j] ); | ||||||
|  |             } | ||||||
|  |             DUG_PRINTF( "\r\n" ); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* Error code defined in "udisk_operaion.h" */ | ||||||
|  |             DUG_PRINTF( "Error Code: %02X\r\n", (uint16_t)i ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      CheckNameSum | ||||||
|  |  * | ||||||
|  |  * @brief   检查长文件名的短文件名检验和 | ||||||
|  |  * | ||||||
|  |  * @return  计算后的校验和 | ||||||
|  |  */ | ||||||
|  | uint8_t CheckNameSum( uint8_t *p ) | ||||||
|  | { | ||||||
|  | uint8_t FcbNameLen; | ||||||
|  | uint8_t Sum; | ||||||
|  | 
 | ||||||
|  |     Sum = 0; | ||||||
|  |     for (FcbNameLen=0; FcbNameLen!=11; FcbNameLen++) | ||||||
|  |         Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *p++; | ||||||
|  |     return Sum; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      AnalyzeLongName | ||||||
|  |  * | ||||||
|  |  * @brief   整理长文件名 返回有几个的26长度 | ||||||
|  |  * | ||||||
|  |  * @return  返回有多少个26的长度 | ||||||
|  |  */ | ||||||
|  | uint8_t AnalyzeLongName( void ) | ||||||
|  | { | ||||||
|  | uint8_t   i, j; | ||||||
|  | uint16_t  index; | ||||||
|  | 
 | ||||||
|  |     i = FALSE; | ||||||
|  |     for( index=0; index!=LONG_NAME_BUF_LEN; index = index + 2 ) | ||||||
|  |     { | ||||||
|  |         if( ( LongNameBuf[index] == 0 ) && ( LongNameBuf[index+1] == 0 ) ) | ||||||
|  |         { | ||||||
|  |             i = TRUE; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     if( ( i == FALSE ) || ( index == 0) ) | ||||||
|  |         return 0;                   // 返回0表示错误的长文件名
 | ||||||
|  | 
 | ||||||
|  |     i = index % 26; | ||||||
|  |     if( i != 0 ) | ||||||
|  |     { | ||||||
|  |         index += 2; | ||||||
|  |         if( index % 26 != 0 )       // 加0刚好结束
 | ||||||
|  |         { | ||||||
|  |             for( j=i+2; j!=26; j++ )// 把剩余数据填为0XFF
 | ||||||
|  |                 LongNameBuf[index++] = 0xff; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return  (index / 26); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      CHRV3CreateLongName | ||||||
|  |  * | ||||||
|  |  * @brief   创建长文件名,需要输入短文件名的完整路径 | ||||||
|  |  * | ||||||
|  |  * @return  操作状态 | ||||||
|  |  */ | ||||||
|  | uint8_t CHRV3CreateLongName( void ) | ||||||
|  | { | ||||||
|  | // 分析 保留文件路径 创建一个空文件 得到FDT偏移和其所在扇区 删除文件
 | ||||||
|  | // 向后偏移扇区 可能失败 如FAT12/16处在根目录处 填充完毕后再次创建文件
 | ||||||
|  | uint8_t   i; | ||||||
|  | uint8_t   len;                                // 存放路径的长度
 | ||||||
|  | uint16_t  index;                              // 长文件偏移索引
 | ||||||
|  | uint16_t  indexBak;                           // 长文件偏移索引备份
 | ||||||
|  | uint32_t  Secoffset;                          // 扇区偏移
 | ||||||
|  | 
 | ||||||
|  | uint8_t   Fbit;                               // 第一次进入写扇区
 | ||||||
|  | uint8_t   Mult;                               // 长文件名长度26的倍数
 | ||||||
|  | uint8_t   MultBak;                            // 长文件名长度26的倍数备份
 | ||||||
|  | 
 | ||||||
|  | uint16_t  Backoffset;                         // 保存文件偏移备份
 | ||||||
|  | uint16_t  BackoffsetBak;                      // 保存偏移备份的备份
 | ||||||
|  | uint32_t  BackFdtSector;                      // 保寸偏移上一个扇区
 | ||||||
|  | uint8_t   sum;                                // 保存长文件名的校验和
 | ||||||
|  | 
 | ||||||
|  | uint8_t   BackPathBuf[MAX_PATH_LEN];    // 保存文件路径
 | ||||||
|  | 
 | ||||||
|  |     Mult = AnalyzeLongName( );              // 保存长文件名是26的倍数
 | ||||||
|  |     if( Mult == 0 ) | ||||||
|  |         return ERR_LONG_NAME; | ||||||
|  |     MultBak = Mult; | ||||||
|  | 
 | ||||||
|  |     i = CHRV3FileOpen();                    // 短文件名存在则返回错误
 | ||||||
|  |     if( i == ERR_SUCCESS ) | ||||||
|  |         return ERR_NAME_EXIST; | ||||||
|  | 
 | ||||||
|  |     i = CHRV3FileCreate( ); | ||||||
|  |     if( i == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         Backoffset = CHRV3vFdtOffset; | ||||||
|  |         BackoffsetBak = Backoffset; | ||||||
|  |         BackFdtSector = CHRV3vFdtLba; | ||||||
|  |         sum = CheckNameSum( &DISK_BASE_BUF[Backoffset ] ); | ||||||
|  |         for( i=0; i!=MAX_PATH_LEN; i++ )    // 对文件路径进行备份
 | ||||||
|  |             BackPathBuf[i] = mCmdParam.Open.mPathName[i]; | ||||||
|  |         CHRV3FileErase( );                  // 删除此文件
 | ||||||
|  | 
 | ||||||
|  |         Secoffset   = 0;                    // 从0开始偏移
 | ||||||
|  |         index       = Mult*26;              // 得到长文件名的长度
 | ||||||
|  |         indexBak    = index; | ||||||
|  |         Fbit        = FALSE;                // 默认没有进入
 | ||||||
|  |         // 打开上级 进行数据填充数据
 | ||||||
|  |         P_RETRY: | ||||||
|  |         for(len=0; len!=MAX_PATH_LEN; len++) | ||||||
|  |         { | ||||||
|  |             if(mCmdParam.Open.mPathName[len] == 0) | ||||||
|  |                 break;                      // 得到字符串长度
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for(i=len-1; i!=0xff; i--)          // 得到上级目录位置
 | ||||||
|  |         { | ||||||
|  |             if((mCmdParam.Open.mPathName[i] == '\\') || (mCmdParam.Open.mPathName[i] == '/')) | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |         mCmdParam.Open.mPathName[i] = 0x00; | ||||||
|  | 
 | ||||||
|  |         if( i==0 )                          // 打开一级目录注意:处在根目录开始的特殊情况
 | ||||||
|  |         { | ||||||
|  |             mCmdParam.Open.mPathName[0] = '/'; | ||||||
|  |             mCmdParam.Open.mPathName[1] = 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         i = CHRV3FileOpen();                // 打开上级目录
 | ||||||
|  |         if( i == ERR_OPEN_DIR ) | ||||||
|  |         { | ||||||
|  |             while( 1 )                      // 循环填写 直到完成
 | ||||||
|  |             { | ||||||
|  |                 mCmdParam.Locate.mSectorOffset = Secoffset; | ||||||
|  |                 i = CHRV3FileLocate( ); | ||||||
|  |                 if( i == ERR_SUCCESS ) | ||||||
|  |                 { | ||||||
|  |                     if( Fbit )             // 第二次进入次写扇区
 | ||||||
|  |                     { | ||||||
|  |                         if( mCmdParam.Locate.mSectorOffset != 0x0FFFFFFFF ) | ||||||
|  |                         { | ||||||
|  |                             BackFdtSector = mCmdParam.Locate.mSectorOffset; | ||||||
|  |                             Backoffset = 0; | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             for( i=0; i!=MAX_PATH_LEN; i++ )// 还原文件路径
 | ||||||
|  |                                 mCmdParam.Open.mPathName[i] = BackPathBuf[i]; | ||||||
|  |                             i = CHRV3FileCreate( );         // 进行空间扩展
 | ||||||
|  |                             if( i != ERR_SUCCESS ) | ||||||
|  |                                 return i; | ||||||
|  |                             CHRV3FileErase( ); | ||||||
|  |                             goto P_RETRY;                   // 重新打开上级目录
 | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     if( BackFdtSector == mCmdParam.Locate.mSectorOffset ) | ||||||
|  |                     { | ||||||
|  |                         mCmdParam.Read.mSectorCount = 1;   // 读一个扇区到磁盘缓冲区
 | ||||||
|  |                         mCmdParam.Read.mDataBuffer = &DISK_BASE_BUF[0]; | ||||||
|  |                         i = CHRV3FileRead( ); | ||||||
|  |                         CHRV3DirtyBuffer( );                // 清除磁盘缓冲区
 | ||||||
|  |                         if( i!= ERR_SUCCESS ) | ||||||
|  |                             return i; | ||||||
|  | 
 | ||||||
|  |                         i = ( CHRV3vSectorSize - Backoffset ) / 32; | ||||||
|  |                         if( Mult > i ) | ||||||
|  |                             Mult = Mult - i;                // 剩余的倍数
 | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             i = Mult; | ||||||
|  |                             Mult = 0; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         for( len=i; len!=0; len-- ) | ||||||
|  |                         { | ||||||
|  |                             indexBak -= 26; | ||||||
|  |                             index = indexBak; | ||||||
|  |                             for( i=0; i!=5; i++)            // 长文件名的1-5个字符
 | ||||||
|  |                             {                               // 在磁盘上UNICODE用小端方式存放
 | ||||||
|  |                                 #if UNICODE_ENDIAN == 1 | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + i*2 + 2 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + i*2 + 1 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 #else | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + i*2 + 1 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + i*2 + 2 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 #endif | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             for( i =0; i!=6; i++)           // 长文件名的6-11个字符
 | ||||||
|  |                             { | ||||||
|  |                                 #if UNICODE_ENDIAN == 1 | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 14 + i*2 + 1 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 14 + i*2 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 #else | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 14 + i*2 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 14 + i*2 + 1 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 #endif | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             for( i=0; i!=2; i++)            // 长文件名的12-13个字符
 | ||||||
|  |                             { | ||||||
|  |                                 #if UNICODE_ENDIAN == 1 | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 28 + i*2 + 1 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 28 + i*2 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 #else | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 28 + i*2 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 DISK_BASE_BUF[Backoffset + 28 + i*2 + 1 ] = | ||||||
|  |                                     LongNameBuf[index++]; | ||||||
|  |                                 #endif | ||||||
|  |                             } | ||||||
|  | 
 | ||||||
|  |                             DISK_BASE_BUF[Backoffset + 0x0b] = 0x0f; | ||||||
|  |                             DISK_BASE_BUF[Backoffset + 0x0c] = 0x00; | ||||||
|  |                             DISK_BASE_BUF[Backoffset + 0x0d] = sum; | ||||||
|  |                             DISK_BASE_BUF[Backoffset + 0x1a] = 0x00; | ||||||
|  |                             DISK_BASE_BUF[Backoffset + 0x1b] = 0x00; | ||||||
|  |                             DISK_BASE_BUF[Backoffset] = MultBak--; | ||||||
|  |                             Backoffset += 32; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if( !Fbit ) | ||||||
|  |                         { | ||||||
|  |                             Fbit = TRUE; | ||||||
|  |                             DISK_BASE_BUF[ BackoffsetBak ] |= 0x40; | ||||||
|  |                         } | ||||||
|  |                         CHRV3vLbaCurrent = BackFdtSector; | ||||||
|  |                         i = CHRV3WriteSector( 1, DISK_BASE_BUF ); | ||||||
|  |                         if( i!= ERR_SUCCESS ) | ||||||
|  |                             return i; | ||||||
|  | 
 | ||||||
|  |                         if( Mult==0 ) | ||||||
|  |                         {   // 还原文件路径
 | ||||||
|  | 					        CHRV3FileClose( ); | ||||||
|  |                             for( i=0; i!=MAX_PATH_LEN; i++ ) | ||||||
|  |                                 mCmdParam.Open.mPathName[i] = BackPathBuf[i]; | ||||||
|  |                             i = CHRV3FileCreate( ); | ||||||
|  |                             return i; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                     return i; | ||||||
|  |                 Secoffset++; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      GetUpSectorData | ||||||
|  |  * | ||||||
|  |  * @brief   由当前扇区得到上一个扇区的数据,放在磁盘缓冲区 | ||||||
|  |  * | ||||||
|  |  * @return  操作状态 | ||||||
|  |  */ | ||||||
|  | uint8_t GetUpSectorData( uint32_t *NowSector ) | ||||||
|  | { | ||||||
|  | uint8_t  i; | ||||||
|  | uint8_t  len;             // 存放路径的长度
 | ||||||
|  | uint32_t index;           // 目录扇区偏移扇区数
 | ||||||
|  | 
 | ||||||
|  |     index = 0; | ||||||
|  |     for(len=0; len!=MAX_PATH_LEN; len++) | ||||||
|  |     { | ||||||
|  |         if(mCmdParam.Open.mPathName[len] == 0)          // 得到字符串长度
 | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for(i=len-1; i!=0xff; i--)                          // 得到上级目录位置
 | ||||||
|  |     { | ||||||
|  |         if((mCmdParam.Open.mPathName[i] == '\\') || (mCmdParam.Open.mPathName[i] == '/')) | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  |     mCmdParam.Open.mPathName[i] = 0x00; | ||||||
|  | 
 | ||||||
|  |     if( i==0 )  // 打开一级目录注意:处在根目录开始的特殊情况
 | ||||||
|  |     { | ||||||
|  |         mCmdParam.Open.mPathName[0] = '/'; | ||||||
|  |         mCmdParam.Open.mPathName[1] = 0; | ||||||
|  |         i = CHRV3FileOpen(); | ||||||
|  |         if ( i == ERR_OPEN_DIR ) | ||||||
|  |             goto P_NEXT0; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         i = CHRV3FileOpen(); | ||||||
|  |         if ( i == ERR_OPEN_DIR ) | ||||||
|  |         { | ||||||
|  |             while( 1 ) | ||||||
|  |             { | ||||||
|  |                 P_NEXT0: | ||||||
|  |                 mCmdParam.Locate.mSectorOffset = index; | ||||||
|  |                 i = CHRV3FileLocate( ); | ||||||
|  |                 if( i == ERR_SUCCESS ) | ||||||
|  |                 { | ||||||
|  |                     if( *NowSector == mCmdParam.Locate.mSectorOffset ) | ||||||
|  |                     { | ||||||
|  |                         if( index==0 )                          // 处于根目录扇区的开始
 | ||||||
|  |                             return ERR_NO_NAME; | ||||||
|  |                         mCmdParam.Locate.mSectorOffset = --index; | ||||||
|  |                         i = CHRV3FileLocate( );                 // 读上一个扇区的数据
 | ||||||
|  |                         if( i == ERR_SUCCESS ) | ||||||
|  |                         {                                       // 以下保存当前所在扇区数
 | ||||||
|  |                             *NowSector = mCmdParam.Locate.mSectorOffset; | ||||||
|  |                             mCmdParam.Read.mSectorCount = 1;   // 读一个扇区到磁盘缓冲区
 | ||||||
|  |                             mCmdParam.Read.mDataBuffer = &DISK_BASE_BUF[0]; | ||||||
|  |                             i = CHRV3FileRead( ); | ||||||
|  |                             CHRV3DirtyBuffer( );                // 清除磁盘缓冲区
 | ||||||
|  |                             return i; | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                             return i; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                     return i; | ||||||
|  |                 index++; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return i; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      CHRV3GetLongName | ||||||
|  |  * | ||||||
|  |  * @brief   由完整短文件名路径(可以是文件或文件夹)得到相应的长文件名 | ||||||
|  |  * | ||||||
|  |  * @return  操作状态 | ||||||
|  |  */ | ||||||
|  | uint8_t CHRV3GetLongName( void ) | ||||||
|  | { | ||||||
|  | // 需要变量扇区大小
 | ||||||
|  | // 第一步:打开文件是否找到文件,分析文件是否存在,并得到FDT在此扇区的偏移和所在扇区
 | ||||||
|  | // 第二步:分析上面的信息看是否有长文件名存在,是否处于目录的第一个扇区的开始
 | ||||||
|  | // 第三步:实现向后偏移一个扇区?读取长文件名(扇区512字节的U盘)
 | ||||||
|  | uint8_t   i; | ||||||
|  | uint16_t  index;          // 在长文件名缓冲区内的索引
 | ||||||
|  | uint32_t  BackFdtSector;  // 保寸偏移上一个扇区
 | ||||||
|  | uint8_t   sum;            // 保存长文件名的校验和
 | ||||||
|  | //uint16_t  Backoffset;     // 保存文件偏移备份
 | ||||||
|  | uint16_t  offset;         // 扇区内文件偏移32倍数
 | ||||||
|  | uint8_t   FirstBit;       // 长文件名跨越两个扇区标志位
 | ||||||
|  | uint8_t   BackPathBuf[MAX_PATH_LEN]; // 保存文件路径
 | ||||||
|  | 
 | ||||||
|  |     i = CHRV3FileOpen( ); | ||||||
|  |     if( ( i == ERR_SUCCESS ) || ( i == ERR_OPEN_DIR ) ) | ||||||
|  |     { | ||||||
|  |         for( i=0; i!=MAX_PATH_LEN; i++ ) | ||||||
|  |             BackPathBuf[i] = mCmdParam.Open.mPathName[i]; | ||||||
|  |         // 以上完成对路径的备份
 | ||||||
|  | 
 | ||||||
|  |         sum = CheckNameSum( &DISK_BASE_BUF[CHRV3vFdtOffset] ); | ||||||
|  |         index = 0; | ||||||
|  |         FirstBit = FALSE; | ||||||
|  | //        Backoffset = CHRV3vFdtOffset;
 | ||||||
|  |         BackFdtSector = CHRV3vFdtLba; | ||||||
|  |         if( CHRV3vFdtOffset == 0 ) | ||||||
|  |         { | ||||||
|  |             // 先判断是否处于一个扇区开始 是否处于根目录开始 ,否则向后偏移
 | ||||||
|  |             if( FirstBit == FALSE ) | ||||||
|  |                 FirstBit = TRUE; | ||||||
|  |             i = GetUpSectorData( &BackFdtSector ); | ||||||
|  |             if( i == ERR_SUCCESS ) | ||||||
|  |             { | ||||||
|  |                 CHRV3vFdtOffset = CHRV3vSectorSize; | ||||||
|  |                 goto P_NEXT1; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             // 读取偏移后的数据,直到结束。如果不够则向后偏移
 | ||||||
|  |             P_NEXT1: | ||||||
|  |             offset = CHRV3vFdtOffset; | ||||||
|  |             while( 1 ) | ||||||
|  |             { | ||||||
|  |                 if( offset != 0 ) | ||||||
|  |                 { | ||||||
|  |                     offset = offset - 32; | ||||||
|  |                     if( ( DISK_BASE_BUF[offset + 11] == ATTR_LONG_NAME ) | ||||||
|  |                         && (  DISK_BASE_BUF[offset + 13] == sum ) ) | ||||||
|  |                     { | ||||||
|  |                         if( (index + 26) > LONG_NAME_BUF_LEN ) | ||||||
|  |                             return ERR_BUF_OVER; | ||||||
|  | 
 | ||||||
|  |                         for( i=0; i!=5; i++)            // 长文件名的1-5个字符
 | ||||||
|  |                         {                               // 在磁盘上UNICODE用小端方式存放
 | ||||||
|  |                             #if UNICODE_ENDIAN == 1 | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + i*2 + 2]; | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + i*2 + 1]; | ||||||
|  |                             #else | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + i*2 + 1]; | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + i*2 + 2]; | ||||||
|  |                             #endif | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         for( i =0; i!=6; i++)           // 长文件名的6-11个字符
 | ||||||
|  |                         { | ||||||
|  |                             #if UNICODE_ENDIAN == 1 | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + 14 + i*2 + 1]; | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + + 14 + i*2 ]; | ||||||
|  |                             #else | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + + 14 + i*2 ]; | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + 14 + i*2 + 1]; | ||||||
|  |                             #endif | ||||||
|  | 
 | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         for( i=0; i!=2; i++)            // 长文件名的12-13个字符
 | ||||||
|  |                         { | ||||||
|  |                             #if UNICODE_ENDIAN == 1 | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + 28 + i*2 + 1]; | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + 28 + i*2 ]; | ||||||
|  |                             #else | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + 28 + i*2 ]; | ||||||
|  |                             LongNameBuf[index++] = | ||||||
|  |                                 DISK_BASE_BUF[offset + 28 + i*2 + 1]; | ||||||
|  |                             #endif | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if( DISK_BASE_BUF[offset] & 0X40 ) | ||||||
|  |                         { | ||||||
|  |                             if( ! (((LongNameBuf[index -1] ==0x00) | ||||||
|  |                                 && (LongNameBuf[index -2] ==0x00)) | ||||||
|  |                                 || ((LongNameBuf[index -1] ==0xFF) | ||||||
|  |                                 && (LongNameBuf[index -2 ] ==0xFF)))) | ||||||
|  |                             {                           // 处理刚好为26字节长倍数的文件名
 | ||||||
|  |                                 if(index + 52 >LONG_NAME_BUF_LEN ) | ||||||
|  |                                     return ERR_BUF_OVER; | ||||||
|  |                                 LongNameBuf[ index ] = 0x00; | ||||||
|  |                                 LongNameBuf[ index + 1] = 0x00; | ||||||
|  |                             } | ||||||
|  |                             return ERR_SUCCESS;         // 成功完成长文件名收集完成
 | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                         return ERR_NO_NAME;             // 错误的长文件名,程序返回
 | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     if( FirstBit == FALSE ) | ||||||
|  |                         FirstBit = TRUE; | ||||||
|  |                     else                                // 否则第二次进入
 | ||||||
|  |                     { | ||||||
|  |                         for( i=0; i!=MAX_PATH_LEN; i++ )// 还原路径
 | ||||||
|  |                             mCmdParam.Open.mPathName[i] = BackPathBuf[i]; | ||||||
|  |                     } | ||||||
|  |                     i = GetUpSectorData( &BackFdtSector ); | ||||||
|  |                     if( i == ERR_SUCCESS ) | ||||||
|  |                     { | ||||||
|  |                         CHRV3vFdtOffset = CHRV3vSectorSize; | ||||||
|  |                         goto P_NEXT1; | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                         return i; | ||||||
|  |                     // 向后偏移扇区
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return i;                // 返回错误
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,572 @@ | ||||||
|  | /********************************** (C) COPYRIGHT *******************************
 | ||||||
|  | * File Name          : UDisk_HW.c | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2022/09/01 | ||||||
|  | * Description        : USB full-speed port host operation functions. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Header File */ | ||||||
|  | #include "Udisk_Operation.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Variable Definition */ | ||||||
|  | __attribute__((aligned(4)))  uint8_t  Com_Buffer[ DEF_COM_BUF_LEN ];     // even address , used for host enumcation and udisk operation
 | ||||||
|  | __attribute__((aligned(4)))  uint8_t  DevDesc_Buf[ 18 ];                 // Device Descriptor Buffer
 | ||||||
|  | struct   _ROOT_HUB_DEVICE RootHubDev[ DEF_TOTAL_ROOT_HUB ]; | ||||||
|  | struct   __HOST_CTL HostCtl[ DEF_TOTAL_ROOT_HUB * DEF_ONE_USB_SUP_DEV_TOTAL ]; | ||||||
|  | volatile uint8_t  UDisk_Opeation_Flag = 0; | ||||||
|  | 
 | ||||||
|  | /* For Udisk Lib */ | ||||||
|  | uint8_t *pHOST_RX_RAM_Addr; | ||||||
|  | uint8_t *pHOST_TX_RAM_Addr; | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      mStopIfError | ||||||
|  |  * | ||||||
|  |  * @brief   Checking the operation status, displaying the error code and stopping if there is an error | ||||||
|  |  *          input : iError - Error code input | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | // void mStopIfError( uint8_t iError )
 | ||||||
|  | // {
 | ||||||
|  | //     if ( iError == ERR_SUCCESS )
 | ||||||
|  | //     {
 | ||||||
|  | //         /* operation success, return */
 | ||||||
|  | //         return;
 | ||||||
|  | //     }
 | ||||||
|  | //     /* Display the errors */
 | ||||||
|  | //     DUG_PRINTF( "Error:%02x\r\n", iError );
 | ||||||
|  | //     /* After encountering an error, you should analyze the error code and CH103DiskReday status, for example,
 | ||||||
|  | //      * call CH103DiskReday to check whether the current USB disk is connected or not,
 | ||||||
|  | //      * if the disk is disconnected then wait for the disk to be plugged in again and operate again,
 | ||||||
|  | //      * Suggested steps to follow after an error:
 | ||||||
|  | //      *     1,call CH103DiskReday once, if successful, then continue the operation, such as Open, Read/Write, etc.
 | ||||||
|  | //      *     2,If CH103DiskReday is not successful, then the operation will be forced to start from the beginning.
 | ||||||
|  | //      */
 | ||||||
|  | //     while(1)
 | ||||||
|  | //     {  }
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      Udisk_USBH_Initialization | ||||||
|  |  * | ||||||
|  |  * @brief   USB Host Udisk process Initialization, include usb-host initialization | ||||||
|  |  *          usb libs initialization, udisk-related values Initialization  | ||||||
|  |             and the others | ||||||
|  |  * | ||||||
|  |  * @para    none | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void Udisk_USBH_Initialization( void ) | ||||||
|  | { | ||||||
|  |     /* USB Host Initialization */ | ||||||
|  |     printf( "USB Host & UDisk Lib Initialization. \r\n" ); | ||||||
|  |     /* Initialize USBHS host */ | ||||||
|  |     /* Note: Only CH32F205/CH32F207 support USB high-speed port. */ | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |     DUG_PRINTF( "USBHS Host Init\r\n" ); | ||||||
|  |     USBHS_RCC_Init( ); | ||||||
|  |     USBHS_Host_Init( ENABLE ); | ||||||
|  |     /* For Udisk Lib */ | ||||||
|  |     pHOST_TX_RAM_Addr = USBHS_TX_Buf; | ||||||
|  |     pHOST_RX_RAM_Addr = USBHS_RX_Buf; | ||||||
|  |     /* Clear Struct */ | ||||||
|  |     memset( &RootHubDev[ DEF_USB_PORT_HS ].bStatus, 0, sizeof( struct _ROOT_HUB_DEVICE ) ); | ||||||
|  |     memset( &HostCtl[ DEF_USB_PORT_HS ].InterfaceNum, 0, sizeof( struct __HOST_CTL ) ); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* Initialize USBFS host */ | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     DUG_PRINTF( "USBFS Host Init\r\n" ); | ||||||
|  |     USBFS_RCC_Init( ); | ||||||
|  |     USBFS_Host_Init( ENABLE ); | ||||||
|  |     /* For Udisk Lib */ | ||||||
|  |     pHOST_TX_RAM_Addr = USBFS_TX_Buf; | ||||||
|  |     pHOST_RX_RAM_Addr = USBFS_RX_Buf; | ||||||
|  |     /* Clear Struct */ | ||||||
|  |     memset( &RootHubDev[ DEF_USB_PORT_FS ].bStatus, 0, sizeof( struct _ROOT_HUB_DEVICE ) ); | ||||||
|  |     memset( &HostCtl[ DEF_USB_PORT_FS ].InterfaceNum, 0, sizeof( struct __HOST_CTL ) ); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     /* USB Libs Initialization */ | ||||||
|  |     printf( "UDisk library Initialization. \r\n" ); | ||||||
|  |     CHRV3LibInit( ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_CheckRootHubPortStatus | ||||||
|  |  * | ||||||
|  |  * @brief   Check status of USB port. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  The current status of the port. | ||||||
|  |  */ | ||||||
|  | uint8_t USBH_CheckRootHubPortStatus( uint8_t usb_port ) | ||||||
|  | { | ||||||
|  |     uint8_t s = ERR_USB_UNSUPPORT; | ||||||
|  | 
 | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         s = USBFSH_CheckRootHubPortStatus( RootHubDev[ usb_port ].bStatus ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         s = USBHSH_CheckRootHubPortStatus( RootHubDev[ usb_port ].bStatus ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_ResetRootHubPort | ||||||
|  |  * | ||||||
|  |  * @brief   Reset USB port. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  *          mod: Reset host port operating mode. | ||||||
|  |  *               0 -> reset and wait end | ||||||
|  |  *               1 -> begin reset | ||||||
|  |  *               2 -> end reset | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void USBH_ResetRootHubPort( uint8_t usb_port, uint8_t mode ) | ||||||
|  | { | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         USBFSH_ResetRootHubPort( mode ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         USBHSH_ResetRootHubPort( mode ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_EnableRootHubPort | ||||||
|  |  * | ||||||
|  |  * @brief   Enable USB host port. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | uint8_t USBH_EnableRootHubPort( uint8_t usb_port ) | ||||||
|  | { | ||||||
|  |     uint8_t s = ERR_USB_UNSUPPORT; | ||||||
|  | 
 | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         s = USBFSH_EnableRootHubPort( &RootHubDev[ usb_port ].bSpeed ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         s = USBHSH_EnableRootHubPort( &RootHubDev[ usb_port ].bSpeed ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_SetSelfSpeed | ||||||
|  |  * | ||||||
|  |  * @brief   Set USB speed. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void USBH_SetSelfSpeed( uint8_t usb_port ) | ||||||
|  | { | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         USBFSH_SetSelfSpeed( RootHubDev[ usb_port].bSpeed ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         USBHSH_SetSelfSpeed( RootHubDev[ usb_port ].bSpeed ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_GetDeviceDescr | ||||||
|  |  * | ||||||
|  |  * @brief   Get the device descriptor of the USB device. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | uint8_t USBH_GetDeviceDescr( uint8_t usb_port ) | ||||||
|  | { | ||||||
|  |     uint8_t s = ERR_USB_UNSUPPORT; | ||||||
|  | 
 | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         s = USBFSH_GetDeviceDescr( &RootHubDev[ usb_port ].bEp0MaxPks, DevDesc_Buf ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         s = USBHSH_GetDeviceDescr( &RootHubDev[ usb_port ].bEp0MaxPks, DevDesc_Buf ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_SetUsbAddress | ||||||
|  |  * | ||||||
|  |  * @brief   Set USB device address. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | uint8_t USBH_SetUsbAddress( uint8_t usb_port ) | ||||||
|  | { | ||||||
|  |     uint8_t s = ERR_USB_UNSUPPORT; | ||||||
|  | 
 | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         RootHubDev[ usb_port ].bAddress = (uint8_t)( DEF_USB_PORT_FS + USB_DEVICE_ADDR ); | ||||||
|  |         s = USBFSH_SetUsbAddress( RootHubDev[ usb_port ].bEp0MaxPks, RootHubDev[ usb_port ].bAddress ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         RootHubDev[ usb_port ].bAddress = (uint8_t)( DEF_USB_PORT_HS + USB_DEVICE_ADDR ); | ||||||
|  |         s = USBHSH_SetUsbAddress( RootHubDev[ usb_port ].bEp0MaxPks, RootHubDev[ usb_port ].bAddress ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_GetConfigDescr | ||||||
|  |  * | ||||||
|  |  * @brief   Get the configuration descriptor of the USB device. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | uint8_t USBH_GetConfigDescr( uint8_t usb_port, uint16_t *pcfg_len ) | ||||||
|  | { | ||||||
|  |     uint8_t s = ERR_USB_UNSUPPORT; | ||||||
|  | 
 | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         s = USBFSH_GetConfigDescr( RootHubDev[ usb_port ].bEp0MaxPks, Com_Buffer, DEF_COM_BUF_LEN, pcfg_len ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         s = USBHSH_GetConfigDescr( RootHubDev[ usb_port ].bEp0MaxPks, Com_Buffer, DEF_COM_BUF_LEN, pcfg_len ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBFSH_SetUsbConfig | ||||||
|  |  * | ||||||
|  |  * @brief   Set USB configuration. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | uint8_t USBH_SetUsbConfig( uint8_t usb_port, uint8_t cfg_val ) | ||||||
|  | { | ||||||
|  |     uint8_t s = ERR_USB_UNSUPPORT; | ||||||
|  | 
 | ||||||
|  |     if( usb_port == DEF_USB_PORT_FS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |         s = USBFSH_SetUsbConfig( RootHubDev[ usb_port ].bEp0MaxPks, cfg_val ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else if( usb_port == DEF_USB_PORT_HS ) | ||||||
|  |     { | ||||||
|  | #if DEF_USB_PORT_HS_EN | ||||||
|  |         s = USBHSH_SetUsbConfig( RootHubDev[ usb_port ].bEp0MaxPks, cfg_val ); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      Udisk_USBH_EnumRootDevice | ||||||
|  |  * | ||||||
|  |  * @brief   Generally enumerate a device connected to host port. | ||||||
|  |  * | ||||||
|  |  * @para    index: USB host port | ||||||
|  |  * | ||||||
|  |  * @return  Enumeration result | ||||||
|  |  */ | ||||||
|  | uint8_t Udisk_USBH_EnumRootDevice( uint8_t usb_port ) | ||||||
|  | { | ||||||
|  |     uint8_t  s; | ||||||
|  |     uint8_t  enum_cnt; | ||||||
|  |     uint8_t  cfg_val; | ||||||
|  |     uint16_t i; | ||||||
|  |     uint16_t len; | ||||||
|  | 
 | ||||||
|  |     DUG_PRINTF( "Enum:\r\n" ); | ||||||
|  | 
 | ||||||
|  |     enum_cnt = 0; | ||||||
|  | ENUM_START: | ||||||
|  |     /* Delay and wait for the device to stabilize */ | ||||||
|  |     Delay_Ms( 100 ); | ||||||
|  |     enum_cnt++; | ||||||
|  |     Delay_Ms( 8 << enum_cnt ); | ||||||
|  | 
 | ||||||
|  |     /* Reset the USB device and wait for the USB device to reconnect */ | ||||||
|  |     USBH_ResetRootHubPort( usb_port, 0 ); | ||||||
|  |     for( i = 0, s = 0; i < DEF_RE_ATTACH_TIMEOUT; i++ ) | ||||||
|  |     { | ||||||
|  |         if( USBH_EnableRootHubPort( usb_port ) == ERR_SUCCESS ) | ||||||
|  |         { | ||||||
|  |             i = 0; | ||||||
|  |             s++; | ||||||
|  |             if( s > 6 ) | ||||||
|  |             { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Delay_Ms( 1 ); | ||||||
|  |     } | ||||||
|  |     if( i ) | ||||||
|  |     { | ||||||
|  |         /* Determine whether the maximum number of retries has been reached, and retry if not reached */ | ||||||
|  |         if( enum_cnt <= 5 ) | ||||||
|  |         { | ||||||
|  |             goto ENUM_START; | ||||||
|  |         } | ||||||
|  |         return ERR_USB_DISCON; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Select USB speed */ | ||||||
|  |     USBH_SetSelfSpeed( usb_port ); | ||||||
|  | 
 | ||||||
|  |     /* Get USB device device descriptor */ | ||||||
|  |     DUG_PRINTF("Get DevDesc: "); | ||||||
|  |     s = USBH_GetDeviceDescr( usb_port ); | ||||||
|  |     if( s == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         /* Print USB device device descriptor */ | ||||||
|  | #if DEF_DEBUG_PRINTF | ||||||
|  |         for( i = 0; i < 18; i++ ) | ||||||
|  |         { | ||||||
|  |             DUG_PRINTF( "%02x ", DevDesc_Buf[ i ] ); | ||||||
|  |         } | ||||||
|  |         DUG_PRINTF("\n"); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* Determine whether the maximum number of retries has been reached, and retry if not reached */ | ||||||
|  |         DUG_PRINTF( "Err(%02x)\n", s ); | ||||||
|  |         if( enum_cnt <= 5 ) | ||||||
|  |         { | ||||||
|  |             goto ENUM_START; | ||||||
|  |         } | ||||||
|  |         return DEF_DEV_DESCR_GETFAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Set the USB device address */ | ||||||
|  |     DUG_PRINTF("Set DevAddr: "); | ||||||
|  |     s = USBH_SetUsbAddress( usb_port ); | ||||||
|  |     if( s == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         DUG_PRINTF( "OK\n" ); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* Determine whether the maximum number of retries has been reached, and retry if not reached */ | ||||||
|  |         DUG_PRINTF( "Err(%02x)\n", s ); | ||||||
|  |         if( enum_cnt <= 5 ) | ||||||
|  |         { | ||||||
|  |             goto ENUM_START; | ||||||
|  |         } | ||||||
|  |         return DEF_DEV_ADDR_SETFAIL; | ||||||
|  |     } | ||||||
|  |     Delay_Ms( 5 ); | ||||||
|  | 
 | ||||||
|  |     /* Get the USB device configuration descriptor */ | ||||||
|  |     DUG_PRINTF("Get CfgDesc: "); | ||||||
|  |     s = USBH_GetConfigDescr( usb_port, &len ); | ||||||
|  |     if( s == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         cfg_val = ( (PUSB_CFG_DESCR)Com_Buffer )->bConfigurationValue; | ||||||
|  | 
 | ||||||
|  |         /* Print USB device configuration descriptor  */ | ||||||
|  | #if DEF_DEBUG_PRINTF | ||||||
|  |         for( i = 0; i < len; i++ ) | ||||||
|  |         { | ||||||
|  |             DUG_PRINTF( "%02x ", Com_Buffer[ i ] ); | ||||||
|  |         } | ||||||
|  |         DUG_PRINTF("\n"); | ||||||
|  | #endif | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* Determine whether the maximum number of retries has been reached, and retry if not reached */ | ||||||
|  |         DUG_PRINTF( "Err(%02x)\n", s ); | ||||||
|  |         if( enum_cnt <= 5 ) | ||||||
|  |         { | ||||||
|  |             goto ENUM_START; | ||||||
|  |         } | ||||||
|  |         return DEF_CFG_DESCR_GETFAIL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Set USB device configuration value */ | ||||||
|  |     DUG_PRINTF("Set Cfg: "); | ||||||
|  |     s = USBH_SetUsbConfig( usb_port, cfg_val ); | ||||||
|  |     if( s == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         DUG_PRINTF( "OK\n" ); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         /* Determine whether the maximum number of retries has been reached, and retry if not reached */ | ||||||
|  |         DUG_PRINTF( "Err(%02x)\n", s ); | ||||||
|  |         if( enum_cnt <= 5 ) | ||||||
|  |         { | ||||||
|  |             goto ENUM_START; | ||||||
|  |         } | ||||||
|  |         return ERR_USB_UNSUPPORT; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ERR_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      IAP_USBH_PreDeal | ||||||
|  |  * | ||||||
|  |  * @brief   usb host preemption operations,  | ||||||
|  |   *         including detecting device insertion and enumerating device information  | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | uint8_t UDisk_USBH_PreDeal( void ) | ||||||
|  | { | ||||||
|  |     uint8_t usb_port; | ||||||
|  |     uint8_t index; | ||||||
|  |     uint8_t ret; | ||||||
|  | #if DEF_USB_PORT_FS_EN | ||||||
|  |     usb_port = DEF_USB_PORT_FS; | ||||||
|  | #elif DEF_USB_PORT_HS_EN | ||||||
|  |     usb_port = DEF_USB_PORT_HS; | ||||||
|  | #endif | ||||||
|  |     ret = USBH_CheckRootHubPortStatus( usb_port ); | ||||||
|  |     if( ret == ROOT_DEV_CONNECTED ) | ||||||
|  |     { | ||||||
|  |         DUG_PRINTF("USB Dev In.\n"); | ||||||
|  |         USBH_CheckRootHubPortStatus( usb_port ); | ||||||
|  |         RootHubDev[ usb_port ].bStatus = ROOT_DEV_CONNECTED; // Set connection status_
 | ||||||
|  |         RootHubDev[ usb_port ].DeviceIndex = usb_port * DEF_ONE_USB_SUP_DEV_TOTAL; | ||||||
|  | 
 | ||||||
|  |         /* Enumerate root device */ | ||||||
|  |         ret = Udisk_USBH_EnumRootDevice( usb_port ); | ||||||
|  |         if( ret == ERR_SUCCESS ) | ||||||
|  |         { | ||||||
|  |             DUG_PRINTF( "USB Port %02x Device Enumeration Succeed\r\n", usb_port ); | ||||||
|  |             RootHubDev[ usb_port ].bStatus = ROOT_DEV_SUCCESS; | ||||||
|  |             return ERR_SUCCESS; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             DUG_PRINTF( "USB Port %02x Device Enumeration ERR %02x.\r\n", usb_port, ret ); | ||||||
|  |             RootHubDev[ usb_port ].bStatus = ROOT_DEV_FAILED; | ||||||
|  |             return ERR_USB_UNAVAILABLE; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else if( ret == ROOT_DEV_DISCONNECT ) | ||||||
|  |     { | ||||||
|  |         DUG_PRINTF("USB Port %02x Device Out.\r\n", usb_port ); | ||||||
|  |         /* Clear parameters */ | ||||||
|  |         index = RootHubDev[ usb_port ].DeviceIndex; | ||||||
|  |         memset( &RootHubDev[ usb_port ].bStatus, 0, sizeof( struct _ROOT_HUB_DEVICE ) ); | ||||||
|  |         memset( &HostCtl[ index ].InterfaceNum, 0, sizeof( struct __HOST_CTL ) ); | ||||||
|  |         CHRV3DiskStatus = DISK_UNKNOWN; | ||||||
|  |         return ERR_USB_DISCON; | ||||||
|  |     } | ||||||
|  |     return ERR_USB_UNKNOWN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      UDisk_USBH_DiskReady | ||||||
|  |  * | ||||||
|  |  * @brief   Check if UDisk is Ready and update status in 'CHRV3DiskStatus' | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | uint8_t UDisk_USBH_DiskReady( void ) | ||||||
|  | { | ||||||
|  |     uint8_t  ret, i; | ||||||
|  | 
 | ||||||
|  |     /* Detect USB Device & Enumeration processing */ | ||||||
|  |     ret = UDisk_USBH_PreDeal( ); | ||||||
|  |     if( ret == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         /* Wait for uDisk Ready */ | ||||||
|  |         CHRV3DiskStatus = DISK_USB_ADDR; | ||||||
|  |         for ( i = 0; i != 10; i ++ ) | ||||||
|  |         { | ||||||
|  |               DUG_PRINTF( "Wait Disk Ready...\r\n" ); | ||||||
|  |               ret = CHRV3DiskReady( ); | ||||||
|  |               if ( ret == ERR_SUCCESS ) | ||||||
|  |               { | ||||||
|  |                   /* Disk Ready */ | ||||||
|  |                   DUG_PRINTF( "Disk Ready Code:%02x.\r\n", ret ); | ||||||
|  |                   DUG_PRINTF( "CH103DiskStatus:%02x\n", CHRV3DiskStatus); | ||||||
|  |                   UDisk_Opeation_Flag = 1; | ||||||
|  |                   return DISK_READY; | ||||||
|  |               } | ||||||
|  |               else | ||||||
|  |               { | ||||||
|  |                   DUG_PRINTF("Not Ready Code :%02x.\r\n", ret); | ||||||
|  |                   DUG_PRINTF("CH103DiskStatus:%02x.\n", CHRV3DiskStatus); | ||||||
|  |               } | ||||||
|  |               Delay_Ms( 50 ); | ||||||
|  |           } | ||||||
|  |     } | ||||||
|  |     return CHRV3DiskStatus; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -0,0 +1,345 @@ | ||||||
|  | /********************************** (C) COPYRIGHT *******************************
 | ||||||
|  | * File Name          : Udisk_Func_BasicOp.c | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2022/11/22 | ||||||
|  | * Description        : USB full-speed port host operation functions. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Header File */ | ||||||
|  | #include "Udisk_Operation.h" | ||||||
|  | uint8_t  *pCodeStr; | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Variable Definition */ | ||||||
|  | __attribute__((aligned(4)))  uint8_t  MY_DATA_BUF[ DISK_BASE_BUF_LEN ];   /* MY_DATA_BUF指向外部RAM的磁盘数据缓冲区,缓冲区长度为至少一个扇区的长度,用于用户数据缓存 */ | ||||||
|  | uint8_t  *pCodeStr; | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      UDisk_USBH_ByteOperation | ||||||
|  |  * | ||||||
|  |  * @brief   Demo Function For UDisk File Byte-operation | ||||||
|  |  *          including Create\Modify\Read\Erase (EXAM1) | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void UDisk_USBH_ByteOperation( void ) | ||||||
|  | { | ||||||
|  |     uint8_t ret; | ||||||
|  |     uint8_t i,t; | ||||||
|  |     uint16_t TotalCount = 0; | ||||||
|  | 
 | ||||||
|  |     UDisk_USBH_DiskReady( ); | ||||||
|  |     if( (CHRV3DiskStatus >= DISK_MOUNTED)&&( UDisk_Opeation_Flag == 1 ) ) | ||||||
|  |     { | ||||||
|  |         UDisk_Opeation_Flag = 0; | ||||||
|  |         printf("CHRV3DiskStatus:%02x\r\n",CHRV3DiskStatus); | ||||||
|  |         /* 读文件 */ | ||||||
|  |         strcpy( (char *)mCmdParam.Open.mPathName, "/C51/NEWFILE.C" ); //设置将要操作的文件路径和文件名/C51/NEWFILE.C
 | ||||||
|  |         ret = CHRV3FileOpen( );                                       //打开文件
 | ||||||
|  |         if ( ret == ERR_MISS_DIR || ret == ERR_MISS_FILE )            //没有找到文件
 | ||||||
|  |         { | ||||||
|  |             //创建文件演示
 | ||||||
|  |             printf( "Find No File And Create\r\n" ); | ||||||
|  |             strcpy( (char *)mCmdParam.Create.mPathName, "/C51/NEWFILE.C" );  //新文件名,在根目录下,中文文件名
 | ||||||
|  |             ret = CHRV3FileCreate( );                                        //新建文件并打开,如果文件已经存在则先删除后再新建
 | ||||||
|  |             mStopIfError( ret ); | ||||||
|  |             printf( "ByteWrite\r\n" ); | ||||||
|  |             //实际应该判断写数据长度和定义缓冲区长度是否相符,如果大于缓冲区长度则需要多次写入
 | ||||||
|  |             i = sprintf( (char *)Com_Buffer,"Note: \xd\xa这个程序是以字节为单位进行U盘文件读写,简单演示功能。\xd\xa"); | ||||||
|  |             for(t=0; t<10; t++) | ||||||
|  |             { | ||||||
|  |                 mCmdParam.ByteWrite.mByteCount = i;                           //指定本次写入的字节数
 | ||||||
|  |                 mCmdParam.ByteWrite.mByteBuffer = Com_Buffer;                 //指向缓冲区
 | ||||||
|  |                 ret = CHRV3ByteWrite( );                                      //以字节为单位向文件写入数据
 | ||||||
|  |                 mStopIfError( ret ); | ||||||
|  |                 printf("成功写入 %02X次\r\n",(uint16_t)t); | ||||||
|  |             } | ||||||
|  |             //演示修改文件属性
 | ||||||
|  |             printf( "Modify\r\n" ); | ||||||
|  |             mCmdParam.Modify.mFileAttr = 0xff;   //输入参数: 新的文件属性,为0FFH则不修改
 | ||||||
|  |             mCmdParam.Modify.mFileTime = 0xffff;   //输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间
 | ||||||
|  |             mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2015, 5, 18 );  //输入参数: 新的文件日期: 2015.05.18
 | ||||||
|  |             mCmdParam.Modify.mFileSize = 0xffffffff;  // 输入参数: 新的文件长度,以字节为单位写文件应该由程序库关闭文件时自动更新长度,所以此处不修改
 | ||||||
|  |             i = CHRV3FileModify( );   //修改当前文件的信息,修改日期
 | ||||||
|  |             mStopIfError( i ); | ||||||
|  |             printf( "Close\r\n" ); | ||||||
|  |             mCmdParam.Close.mUpdateLen = 1;     //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度
 | ||||||
|  |             i = CHRV3FileClose( ); | ||||||
|  |             mStopIfError( i ); | ||||||
|  | 
 | ||||||
|  |             /* 删除某文件 */ | ||||||
|  | //            printf( "Erase\n" );
 | ||||||
|  | //            strcpy( (char *)mCmdParam.Create.mPathName, "/OLD" );  //将被删除的文件名,在根目录下
 | ||||||
|  | //            i = CHRV3FileErase( );  //删除文件并关闭
 | ||||||
|  | //            if ( i != ERR_SUCCESS ) printf( "Error: %02X\n", (uint16_t)i );  //显示错误
 | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             /* 一、写入文件 */ | ||||||
|  |             printf( "ByteWrite\r\n" ); //如果希望将新数据添加到原文件的尾部,可以移动文件指针
 | ||||||
|  |             mCmdParam.ByteLocate.mByteOffset = 0xffffffff;  //移到文件的尾部
 | ||||||
|  |             CHRV3ByteLocate( );           //实际应该判断写数据长度和定义缓冲区长度是否相符,如果大于缓冲区长度则需要多次写入
 | ||||||
|  |             i = sprintf( (char *)Com_Buffer,"Note: \xd\xa这个程序是以字节为单位进行U盘文件读写,简单演示功能。\xd\xa"); //演示文字
 | ||||||
|  |             for(t=0; t<10; t++) | ||||||
|  |             { | ||||||
|  |                 mCmdParam.ByteWrite.mByteCount = i;               //指定本次写入的字节数
 | ||||||
|  |                 mCmdParam.ByteWrite.mByteBuffer = Com_Buffer;     // 指向缓冲区
 | ||||||
|  |                 ret = CHRV3ByteWrite( );                          // 以字节为单位向文件写入数据
 | ||||||
|  |                 mStopIfError( ret ); | ||||||
|  |                 printf("成功写入 %02X次\r\n",(uint16_t)t); | ||||||
|  |             } | ||||||
|  |             /* 二、读取文件前N字节 */ | ||||||
|  |             TotalCount = 60;                                                  //设置准备读取总长度100字节
 | ||||||
|  |             strcpy( (char *)mCmdParam.Open.mPathName, "/C51/NEWFILE.C" );     //设置将要操作的文件路径和文件名/C51/NEWFILE.C
 | ||||||
|  |             CHRV3FileOpen( );                                                 //打开文件
 | ||||||
|  |             printf( "读出的前%d个字符是:\r\n",TotalCount ); | ||||||
|  |             while ( TotalCount ) | ||||||
|  |             { | ||||||
|  |                 //如果文件比较大,一次读不完,可以再调用CH103ByteRead继续读取,文件指针自动向后移动
 | ||||||
|  |                 if ( TotalCount > (MAX_PATH_LEN-1) ) | ||||||
|  |                 { | ||||||
|  |                     t = MAX_PATH_LEN-1; // 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.Other.mBuffer )
 | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     t = TotalCount; //最后剩余的字节数
 | ||||||
|  |                 } | ||||||
|  |                 mCmdParam.ByteRead.mByteCount = t;                   //请求读出几十字节数据
 | ||||||
|  |                 mCmdParam.ByteRead.mByteBuffer= &Com_Buffer[0]; | ||||||
|  |                 ret = CHRV3ByteRead( );                              //以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读
 | ||||||
|  |                 TotalCount -= mCmdParam.ByteRead.mByteCount;         //计数,减去当前实际已经读出的字符数
 | ||||||
|  |                 for ( i=0; i!=mCmdParam.ByteRead.mByteCount; i++ ) | ||||||
|  |                 { | ||||||
|  |                     printf( "%c", mCmdParam.ByteRead.mByteBuffer[i] ); //显示读出的字符
 | ||||||
|  |                 } | ||||||
|  |                 printf( "\r\n" ); | ||||||
|  | 
 | ||||||
|  |                 if ( mCmdParam.ByteRead.mByteCount < t ) //实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾
 | ||||||
|  |                 { | ||||||
|  |                     printf( "\r\n" ); | ||||||
|  |                     printf( "文件已经结束\r\n" ); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             i = CHRV3FileClose( ); //关闭文件
 | ||||||
|  |             mStopIfError( i ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      UDisk_USBH_SectorOperation | ||||||
|  |  * | ||||||
|  |  * @brief   Demo Function For UDisk File Sector-operation | ||||||
|  |  *          including Create\Modify\Read\Erase (EXAM6) | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void UDisk_USBH_SectorOperation( void ) | ||||||
|  | { | ||||||
|  |     uint8_t  ret, SecCount, s; | ||||||
|  |     uint8_t  i; | ||||||
|  |     uint16_t tmp; | ||||||
|  |     uint8_t  tmpbuf[64]; | ||||||
|  | 
 | ||||||
|  |     ret = UDisk_USBH_DiskReady( ); | ||||||
|  |     if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) ) | ||||||
|  |     { | ||||||
|  |         UDisk_Opeation_Flag = 0; | ||||||
|  |         /* 查询磁盘物理容量 */ | ||||||
|  |         printf( "DiskSize\r\n" ); | ||||||
|  |         i = CHRV3DiskQuery( ); | ||||||
|  |         mStopIfError( i ); | ||||||
|  |         printf( "TotalSize = %u MB \n", (unsigned int)( mCmdParam.Query.mTotalSector * CHRV3vSectorSizeB / 2 ) );  //显示为以MB为单位的容量
 | ||||||
|  | 
 | ||||||
|  |         /* 读取原文件 */ | ||||||
|  |         printf( "Open\r\n" ); | ||||||
|  |         strcpy( mCmdParam.Open.mPathName, "/NEWFILE.TXT" );//文件名,该文件在C51子目录下
 | ||||||
|  |         s = CHRV3FileOpen( );                       //打开文件
 | ||||||
|  |         if ( s == ERR_MISS_DIR || s == ERR_MISS_FILE )//没有找到文件
 | ||||||
|  |         { | ||||||
|  |             printf( "没有找到文件\r\n" ); | ||||||
|  |         } | ||||||
|  |         else                                        //找到文件或者出错
 | ||||||
|  |         { | ||||||
|  |             printf( "Query\r\n" ); | ||||||
|  |             i = CHRV3FileQuery( );                  //查询当前文件的信息
 | ||||||
|  |             mStopIfError( i ); | ||||||
|  |             printf( "Read\r\n" ); | ||||||
|  |             CHRV3vFileSize = CHRV3vFileSize+(sizeof( MY_DATA_BUF )-1);    //原文件的长度
 | ||||||
|  |             SecCount = CHRV3vFileSize/ sizeof( MY_DATA_BUF )  ;//计算文件的扇区数,因为读写是以扇区为单位的,先加CHRV3vSectorSize-1是为了读出文件尾部不足1个扇区的部分
 | ||||||
|  |             printf( "Size=%ld, Sec=%d\r\n", CHRV3vFileSize, (uint16_t)SecCount ); | ||||||
|  |             while(SecCount--) | ||||||
|  |             { | ||||||
|  |                 mCmdParam.Read.mSectorCount = sizeof( MY_DATA_BUF )/512;  //读取全部数据,如果超过2个扇区则只读取2个扇区
 | ||||||
|  |                 mCmdParam.Read.mDataBuffer = &MY_DATA_BUF[0];//指向文件数据缓冲区的起始地址
 | ||||||
|  |                 i = CHRV3FileRead( );                    //从文件读取数据
 | ||||||
|  |                 mStopIfError( i ); | ||||||
|  |                 if(SecCount == 0) break; | ||||||
|  |                 /*
 | ||||||
|  |                 for(tmp=0; tmp<sizeof( MY_DATA_BUF ); tmp++) | ||||||
|  |                 { | ||||||
|  |                 printf("%02X ",(uint16_t)MY_DATA_BUF[tmp]); | ||||||
|  |                 } | ||||||
|  |                 printf("\n"); | ||||||
|  |                 */ | ||||||
|  |             } | ||||||
|  |             tmp = (CHRV3vFileSize-(sizeof( MY_DATA_BUF )-1))%sizeof( MY_DATA_BUF ); | ||||||
|  |             if((tmp == 0)&&(CHRV3vFileSize != 0)) tmp = sizeof( MY_DATA_BUF ); | ||||||
|  |             CHRV3vFileSize = CHRV3vFileSize-(sizeof( MY_DATA_BUF )-1);    //恢复原文件的长度
 | ||||||
|  |             /*
 | ||||||
|  |             for(i=0; i<tmp; i++) | ||||||
|  |             { | ||||||
|  |               printf("%02X ",(uint16_t)MY_DATA_BUF[i]); | ||||||
|  |             } | ||||||
|  |             printf("\n"); | ||||||
|  |             */ | ||||||
|  |             /*
 | ||||||
|  |                          如果文件比较大,一次读不完,可以再调用CHRV3FileRead继续读取,文件指针自动向后移动 | ||||||
|  |              while ( 1 ) | ||||||
|  |              { | ||||||
|  |                c = 4;   每次读取4个扇区,缓冲区定义的越大,一次读取的扇区数越多 | ||||||
|  |                mCmdParam.Read.mSectorCount = c;   指定读取的扇区数 | ||||||
|  |                mCmdParam.Read.mDataBuffer = &MY_DATA_BUF[0];  指向文件数据缓冲区的起始地址 | ||||||
|  |                CHRV3FileRead();   读完后文件指针自动后移 处理数据 | ||||||
|  |                if ( mCmdParam.Read.mSectorCount < c ) break;   实际读出的扇区数较小则说明文件已经结束 | ||||||
|  |              } | ||||||
|  |                                                如果希望从指定位置开始读写,可以移动文件指针 | ||||||
|  |               mCmdParam.Locate.mSectorOffset = 3;  跳过文件的前3个扇区开始读写 | ||||||
|  |               i = CHRV3FileLocate( ); | ||||||
|  |               mCmdParam.Read.mSectorCount = 10; | ||||||
|  |               mCmdParam.Read.mDataBuffer = &MY_DATA_BUF[0];  指向文件数据缓冲区的起始地址 | ||||||
|  |               CHRV3FileRead();   直接读取从文件的第(CHRV3vSectorSizeH*256*3)个字节开始的数据,前3个扇区被跳过 | ||||||
|  |                                                如果希望将新数据添加到原文件的尾部,可以移动文件指针 | ||||||
|  |               i = CHRV3FileOpen( ); | ||||||
|  |               mCmdParam.Locate.mSectorOffset = 0xffffffff;  移到文件的尾部,以扇区为单位,如果原文件是3字节,则从CHRV3vSectorSizeH个字节处开始添加 | ||||||
|  |               i = CHRV3FileLocate( ); | ||||||
|  |               mCmdParam.Write.mSectorCount = 10; | ||||||
|  |               mCmdParam.Write.mDataBuffer = &MY_DATA_BUF[0]; | ||||||
|  |               CHRV3FileWrite();   在原文件的后面添加数据 | ||||||
|  |                                                使用CHRV3FileRead可以自行定义数据缓冲区的起始地址 | ||||||
|  |               mCmdParam.Read.mSectorCount = 2; | ||||||
|  |               mCmdParam.Read.mDataBuffer = 0x50;  将读出的数据放到50H开始的缓冲区中,需要指定缓冲区的起始地址 | ||||||
|  |               CHRV3FileRead();   从文件中读取2个扇区到指定缓冲区 | ||||||
|  |                                                 使用CHRV3FileWrite可以自行定义数据缓冲区的起始地址 | ||||||
|  |               mCmdParam.Wiite.mSectorCount = 2; | ||||||
|  |               mCmdParam.Write.mDataBuffer = 0x50;  将50H开始的缓冲区中的数据写入 | ||||||
|  |               CHRV3FileWrite();   将指定缓冲区中的数据写入2个扇区到文件中 | ||||||
|  |             */ | ||||||
|  |             printf( "Close\r\n" ); | ||||||
|  |             i = CHRV3FileClose( );                            //关闭文件
 | ||||||
|  |             mStopIfError( i ); | ||||||
|  |         } | ||||||
|  |         printf( "Create\r\n" ); | ||||||
|  |         strcpy( mCmdParam.Create.mPathName, "/NEWFILE.TXT" );//新文件名,在根目录下,中文文件名
 | ||||||
|  |         s = CHRV3FileCreate( );                               //新建文件并打开,如果文件已经存在则先删除后再新建 */
 | ||||||
|  |         mStopIfError( s ); | ||||||
|  |         printf( "Write\r\n" ); | ||||||
|  |         strcpy( tmpbuf, "0000ABCDEFGHIJKLMNOPQRSTUVWXYZ\xd\xa" );//准备写文件数据
 | ||||||
|  |         for(i=0; i<(DISK_BASE_BUF_LEN/sizeof(tmpbuf)); i++) | ||||||
|  |         { | ||||||
|  |             tmp=i*sizeof(tmpbuf); | ||||||
|  |             strcpy(&MY_DATA_BUF[tmp],tmpbuf); | ||||||
|  |         } | ||||||
|  |         for(tmp=0; tmp<sizeof(MY_DATA_BUF); tmp++) | ||||||
|  |         { | ||||||
|  |             printf("%02X",(uint16_t)MY_DATA_BUF[tmp]); | ||||||
|  |         } | ||||||
|  |         printf("\r\n"); | ||||||
|  |         for(s=0; s<10; s++) | ||||||
|  |         { | ||||||
|  |             mCmdParam.Write.mSectorCount = 1;                 //写入所有扇区的数据
 | ||||||
|  |             mCmdParam.Write.mDataBuffer = &MY_DATA_BUF[0];    //指向文件数据缓冲区的起始地址
 | ||||||
|  |             i = CHRV3FileWrite( );                            //向文件写入数据
 | ||||||
|  |             mStopIfError( i ); | ||||||
|  |             printf("成功写入 %02X次\r\n",(uint16_t)s); | ||||||
|  |         } | ||||||
|  |         /* printf( "Modify\n" );
 | ||||||
|  |            mCmdParam.Modify.mFileAttr = 0xff;   输入参数: 新的文件属性,为0FFH则不修改 | ||||||
|  |            mCmdParam.Modify.mFileTime = 0xffff;   输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间 | ||||||
|  |            mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2015, 5, 18 );  输入参数: 新的文件日期: 2015.05.18 | ||||||
|  |            mCmdParam.Modify.mFileSize = 0xffffffff;   输入参数: 新的文件长度,以字节为单位写文件应该由程序库关闭文件时自动更新长度,所以此处不修改 | ||||||
|  |            i = CHRV3FileModify( );   修改当前文件的信息,修改日期 | ||||||
|  |            mStopIfError( i ); | ||||||
|  |         */ | ||||||
|  |         printf( "Close\r\n" ); | ||||||
|  |         mCmdParam.Close.mUpdateLen = 1;                        //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度
 | ||||||
|  |         i = CHRV3FileClose( ); | ||||||
|  |         mStopIfError( i ); | ||||||
|  |         /* 删除某文件 */ | ||||||
|  |         /*printf( "Erase\n" );
 | ||||||
|  |           strcpy( mCmdParam.Create.mPathName, "/OLD.TXT" );  将被删除的文件名,在根目录下 | ||||||
|  |           i = CHRV3FileErase( );  删除文件并关闭 | ||||||
|  |           if ( i != ERR_SUCCESS ) printf( "Error File not exist: %02X\n", (uint16_t)i );  显示错误 | ||||||
|  |         */ | ||||||
|  |         printf( "U盘演示完成\r\n" ); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      UDisk_USBH_EnumFiles | ||||||
|  |  * | ||||||
|  |  * @brief   Demo Function For Enumerating files in UDisk(EXAM11) | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void UDisk_USBH_EnumFiles( void ) | ||||||
|  | { | ||||||
|  |     uint8_t  i, s, ret; | ||||||
|  |     uint16_t j; | ||||||
|  | 
 | ||||||
|  |     ret = UDisk_USBH_DiskReady( ); | ||||||
|  |     if( ( ret == DISK_READY )&&( UDisk_Opeation_Flag == 1 ) ) | ||||||
|  |     { | ||||||
|  |         UDisk_Opeation_Flag = 0; | ||||||
|  |         /* 读取原文件 */ | ||||||
|  |         printf( "Open\r\n" ); | ||||||
|  |         strcpy( mCmdParam.Open.mPathName, "/C51/CHRV3HFT.C" );//文件名,该文件在C51子目录下
 | ||||||
|  |         s = CHRV3FileOpen( );                        //打开文件
 | ||||||
|  |         /* 列出文件 */ | ||||||
|  |         if ( s == ERR_MISS_DIR ) | ||||||
|  |         { | ||||||
|  |             printf("不存在该文件则列出所有文件\r\n");  //C51子目录不存在则列出根目录下的所有文件
 | ||||||
|  |             pCodeStr = "/*"; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             pCodeStr = "/C51/*";                     //CHRV3HFT.C文件不存在则列出\C51子目录下的以CHRV3开头的文件
 | ||||||
|  |         } | ||||||
|  |         printf( "List file %s\r\n", pCodeStr ); | ||||||
|  |         for ( j = 0; j < 10000; j ++ )               //最多搜索前10000个文件,实际上没有限制
 | ||||||
|  |         { | ||||||
|  |             strcpy( (char *)mCmdParam.Open.mPathName, pCodeStr );//搜索文件名,*为通配符,适用于所有文件或者子目录
 | ||||||
|  |             i = strlen( mCmdParam.Open.mPathName ); | ||||||
|  |             mCmdParam.Open.mPathName[ i ] = 0xFF;    //根据字符串长度将结束符替换为搜索的序号,从0到254,如果是0xFF即255则说明搜索序号在CHRV3vFileSize变量中
 | ||||||
|  |             CHRV3vFileSize = j;                      //指定搜索/枚举的序号
 | ||||||
|  |             i = CHRV3FileOpen( );                    //打开文件,如果文件名中含有通配符*,则为搜索文件而不打开
 | ||||||
|  |             /* CHRV3FileEnum 与 CHRV3FileOpen 的唯一区别是当后者返回ERR_FOUND_NAME时那么对应于前者返回ERR_SUCCESS */ | ||||||
|  |             if ( i == ERR_MISS_FILE ) | ||||||
|  |             { | ||||||
|  |                 break;                                //再也搜索不到匹配的文件,已经没有匹配的文件名
 | ||||||
|  |             } | ||||||
|  |             if ( i == ERR_FOUND_NAME ) | ||||||
|  |             { | ||||||
|  |                 /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */ | ||||||
|  |                 printf( "  match file %04d#: %s\r\n", (unsigned int)j, mCmdParam.Open.mPathName );//显示序号和搜索到的匹配文件名或者子目录名
 | ||||||
|  |                 continue;                             //继续搜索下一个匹配的文件名,下次搜索时序号会加1
 | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 /* 出错 */ | ||||||
|  |                 mStopIfError( i ); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         printf( "Close\r\n" ); | ||||||
|  |         CHRV3FileClose( );                            //关闭文件
 | ||||||
|  |         printf( "U盘演示完成\r\n" ); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,680 @@ | ||||||
|  | /********************************** (C) COPYRIGHT *******************************
 | ||||||
|  | * File Name          : ch32v30x_usbhs_host.c | ||||||
|  | * Author             : WCH | ||||||
|  | * Version            : V1.0.0 | ||||||
|  | * Date               : 2021/06/06 | ||||||
|  | * Description        : This file provides all the USB firmware functions. | ||||||
|  | ********************************************************************************* | ||||||
|  | * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. | ||||||
|  | * Attention: This software (modified or not) and binary are used for  | ||||||
|  | * microcontroller manufactured by Nanjing Qinheng Microelectronics. | ||||||
|  | *******************************************************************************/ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Header File */ | ||||||
|  | #include "usb_host_config.h" | ||||||
|  | #include "ch32v30x_usb.h" | ||||||
|  | #include "ch32v30x_rcc.h" | ||||||
|  | #include "ch32v30x_usbhs_host.h" | ||||||
|  | 
 | ||||||
|  | /*******************************************************************************/ | ||||||
|  | /* Variable Definition */ | ||||||
|  | __attribute__((aligned(4))) uint8_t  RxBuffer[ MAX_PACKET_SIZE ];           // IN, must even address
 | ||||||
|  | __attribute__((aligned(4))) uint8_t  TxBuffer[ MAX_PACKET_SIZE ];           // OUT, must even address
 | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHS_RCC_Init | ||||||
|  |  * | ||||||
|  |  * @brief   USB RCC initialized | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void USBHS_RCC_Init( void ) | ||||||
|  | { | ||||||
|  |     RCC_USBCLK48MConfig( RCC_USBCLK48MCLKSource_USBPHY ); | ||||||
|  |     RCC_USBHSPLLCLKConfig( RCC_HSBHSPLLCLKSource_HSE ); | ||||||
|  |     RCC_USBHSConfig( RCC_USBPLL_Div2 ); | ||||||
|  |     RCC_USBHSPLLCKREFCLKConfig( RCC_USBHSPLLCKREFCLK_4M ); | ||||||
|  |     RCC_USBHSPHYPLLALIVEcmd( ENABLE ); | ||||||
|  |     RCC_AHBPeriphClockCmd( RCC_AHBPeriph_USBHS, ENABLE ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHS_Host_Init | ||||||
|  |  * | ||||||
|  |  * @brief   USB host mode initialized. | ||||||
|  |  * | ||||||
|  |  * @param   sta - ENABLE or DISABLE | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void USBHS_Host_Init( FunctionalState sta ) | ||||||
|  | { | ||||||
|  |     if( sta ) | ||||||
|  |     { | ||||||
|  |         USBHSH->CONTROL = USBHS_UC_INT_BUSY | USBHS_UC_DMA_EN | USBHS_UC_SPEED_HIGH | USBHS_UC_HOST_MODE; | ||||||
|  |         USBHSH->HOST_CTRL = USBHS_UH_PHY_SUSPENDM | USBHS_UH_SOF_EN; | ||||||
|  |         USBHSH->HOST_EP_CONFIG = USBHS_UH_EP_TX_EN | USBHS_UH_EP_RX_EN;    | ||||||
|  |         USBHSH->HOST_RX_MAX_LEN = 512; | ||||||
|  |         USBHSH->HOST_RX_DMA = (uint32_t)USBHS_RX_Buf; | ||||||
|  |         USBHSH->HOST_TX_DMA = (uint32_t)USBHS_TX_Buf; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         USBHSH->CONTROL = USBHS_UC_RESET_SIE | USBHS_UC_CLR_ALL; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_CheckRootHubPortStatus | ||||||
|  |  * | ||||||
|  |  * @brief   Check status of USB port. | ||||||
|  |  * | ||||||
|  |  * @para    dev_sta: The status of the root device connected to this port. | ||||||
|  |  * | ||||||
|  |  * @return  The current status of the port. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_CheckRootHubPortStatus( uint8_t status ) | ||||||
|  | { | ||||||
|  |     /* Detect USB devices plugged or unplugged */ | ||||||
|  |     if( USBHSH->INT_FG & USBHS_UIF_DETECT ) | ||||||
|  |     { | ||||||
|  |         USBHSH->INT_FG = USBHS_UIF_DETECT; // Clear flag
 | ||||||
|  |         if( USBHSH->MIS_ST & USBHS_UMS_DEV_ATTACH ) // Detect that the USB device has been connected to the port
 | ||||||
|  |         { | ||||||
|  |             if( ( status == ROOT_DEV_DISCONNECT ) || ( ( status != ROOT_DEV_FAILED ) && ( USBHSH_CheckRootHubPortEnable( ) == 0x00 ) ) ) | ||||||
|  |             { | ||||||
|  |                 return ROOT_DEV_CONNECTED; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 return ROOT_DEV_FAILED; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             return ROOT_DEV_DISCONNECT; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         return ROOT_DEV_FAILED; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_CheckRootHubPortEnable | ||||||
|  |  * | ||||||
|  |  * @brief   Check the enable status of the USB port. | ||||||
|  |  * | ||||||
|  |  * @return  The current enable status of the port. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_CheckRootHubPortEnable( void ) | ||||||
|  | { | ||||||
|  |     return ( USBHSH->MIS_ST & USBHS_UMS_DEV_ATTACH ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_CheckRootHubPortSpeed | ||||||
|  |  * | ||||||
|  |  * @brief   Check the speed of the USB port. | ||||||
|  |  * | ||||||
|  |  * @return  The current speed of the port. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_CheckRootHubPortSpeed( void ) | ||||||
|  | { | ||||||
|  |     uint8_t speed; | ||||||
|  |      | ||||||
|  |     speed = USBHSH->SPEED_TYPE & USBHS_USB_SPEED_TYPE; | ||||||
|  |      | ||||||
|  |     if( speed == USBHS_USB_SPEED_LOW ) | ||||||
|  |     { | ||||||
|  |         return USB_LOW_SPEED; | ||||||
|  |     } | ||||||
|  |     else if( speed == USBHS_USB_SPEED_FULL ) | ||||||
|  |     { | ||||||
|  |         return USB_FULL_SPEED; | ||||||
|  |     } | ||||||
|  |     else if( speed == USBHS_USB_SPEED_HIGH ) | ||||||
|  |     { | ||||||
|  |         return USB_HIGH_SPEED; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return USB_SPEED_CHECK_ERR; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_SetSelfAddr | ||||||
|  |  * | ||||||
|  |  * @brief   Set the USB device address. | ||||||
|  |  * | ||||||
|  |  * @para    addr: USB device address. | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void USBHSH_SetSelfAddr( uint8_t addr ) | ||||||
|  | { | ||||||
|  |     USBHSH->DEV_AD = addr & USBHS_MASK_USB_ADDR; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_SetSelfSpeed | ||||||
|  |  * | ||||||
|  |  * @brief   Set USB speed. | ||||||
|  |  * | ||||||
|  |  * @para    speed: USB speed. | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void USBHSH_SetSelfSpeed( uint8_t speed ) | ||||||
|  | { | ||||||
|  |     if( speed == USB_HIGH_SPEED ) | ||||||
|  |     { | ||||||
|  |         USBHSH->CONTROL = ( USBHSH->CONTROL & ~USBHS_UC_SPEED_TYPE ) | USBHS_UC_SPEED_HIGH; | ||||||
|  |     } | ||||||
|  |     else if( speed == USB_FULL_SPEED ) | ||||||
|  |     { | ||||||
|  |         USBHSH->CONTROL = ( USBHSH->CONTROL & ~USBHS_UC_SPEED_TYPE ) | USBHS_UC_SPEED_FULL; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         USBHSH->CONTROL = ( USBHSH->CONTROL & ~USBHS_UC_SPEED_TYPE ) | USBHS_UC_SPEED_LOW; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_ResetRootHubPort | ||||||
|  |  * | ||||||
|  |  * @brief   Reset USB port. | ||||||
|  |  * | ||||||
|  |  * @para    mod: Reset host port operating mode. | ||||||
|  |  *               0 -> reset and wait end | ||||||
|  |  *               1 -> begin reset | ||||||
|  |  *               2 -> end reset | ||||||
|  |  * | ||||||
|  |  * @return  none | ||||||
|  |  */ | ||||||
|  | void USBHSH_ResetRootHubPort( uint8_t mode ) | ||||||
|  | { | ||||||
|  |     USBHSH_SetSelfAddr( 0x00 ); | ||||||
|  |     USBHSH_SetSelfSpeed( USB_HIGH_SPEED ); | ||||||
|  |     if( mode <= 1 ) | ||||||
|  |     { | ||||||
|  |         USBHSH->HOST_CTRL |= USBHS_UH_TX_BUS_RESET; | ||||||
|  |     } | ||||||
|  |     if( mode == 0 ) | ||||||
|  |     { | ||||||
|  |         Delay_Ms( DEF_BUS_RESET_TIME ); | ||||||
|  |     } | ||||||
|  |     if( mode != 1 ) | ||||||
|  |     { | ||||||
|  |         USBHSH->HOST_CTRL &= ~USBHS_UH_TX_BUS_RESET; | ||||||
|  |     } | ||||||
|  |     Delay_Ms( 2 ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_EnableRootHubPort | ||||||
|  |  * | ||||||
|  |  * @brief   Enable USB host port. | ||||||
|  |  * | ||||||
|  |  * @para    *pspeed: USB speed. | ||||||
|  |  * | ||||||
|  |  * @return  Operation result of the enabled port. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_EnableRootHubPort( uint8_t *pspeed ) | ||||||
|  | { | ||||||
|  |     if( USBHSH->MIS_ST & USBHS_UMS_DEV_ATTACH ) | ||||||
|  |     { | ||||||
|  |         *pspeed = USBHSH_CheckRootHubPortSpeed( ); | ||||||
|  |         USBHSH->HOST_CTRL |= USBHS_UH_SOF_EN; | ||||||
|  |          | ||||||
|  |         return ERR_SUCCESS; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ERR_USB_DISCON; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_Transact | ||||||
|  |  * | ||||||
|  |  * @brief   Perform USB transaction. | ||||||
|  |  * | ||||||
|  |  * @para    endp_pid: Token PID. | ||||||
|  |  *          endp_tog: Toggle | ||||||
|  |  *          timeout: Timeout time. | ||||||
|  |  * | ||||||
|  |  * @return  USB transfer result. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_Transact( uint8_t endp_pid, uint8_t endp_tog, uint32_t timeout ) | ||||||
|  | { | ||||||
|  |     uint8_t   r, trans_retry; | ||||||
|  |     uint16_t  i; | ||||||
|  |     USBHSH->HOST_TX_CTRL = USBHSH->HOST_RX_CTRL = endp_tog; | ||||||
|  |     trans_retry = 0; | ||||||
|  |     do | ||||||
|  |     { | ||||||
|  |         USBHSH->HOST_EP_PID = endp_pid; // Set the token for the host to send the packet
 | ||||||
|  |         USBHSH->INT_FG = USBHS_UIF_TRANSFER;  | ||||||
|  |         for( i = DEF_WAIT_USB_TOUT_200US; ( i != 0 ) && ( ( USBHSH->INT_FG & USBHS_UIF_TRANSFER ) == 0 ); i-- ) | ||||||
|  |         { | ||||||
|  |             Delay_Us( 1 );                                                      | ||||||
|  |         } | ||||||
|  |         USBHSH->HOST_EP_PID = 0x00; | ||||||
|  |         if( ( USBHSH->INT_FG & USBHS_UIF_TRANSFER ) == 0 )   | ||||||
|  |         { | ||||||
|  |             return ERR_USB_UNKNOWN; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if( USBHSH->INT_FG & USBHS_UIF_DETECT )  | ||||||
|  |         { | ||||||
|  |             USBHSH->INT_FG = USBHS_UIF_DETECT; | ||||||
|  |             Delay_Us( 200 ); | ||||||
|  |             if( USBHSH->MIS_ST & USBHS_UIF_TRANSFER ) | ||||||
|  |             { | ||||||
|  |                 if( USBHSH->HOST_CTRL & USBHS_UH_SOF_EN ) | ||||||
|  |                 { | ||||||
|  |                     return ERR_USB_CONNECT; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 return ERR_USB_DISCON; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if( USBHSH->INT_FG & USBHS_UIF_TRANSFER ) // The packet transmission was successful
 | ||||||
|  |         { | ||||||
|  |             r = USBHSH->INT_ST & USBHS_UIS_H_RES_MASK; | ||||||
|  |             if( ( endp_pid >> 4 ) == USB_PID_IN ) | ||||||
|  |             { | ||||||
|  |                 if( USBHSH->INT_ST & USBHS_UIS_TOG_OK ) | ||||||
|  |                 { | ||||||
|  |                     return ERR_SUCCESS; // Packet token match
 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 if( ( r == USB_PID_ACK ) || ( r == USB_PID_NYET ) ) | ||||||
|  |                 { | ||||||
|  |                     return ERR_SUCCESS; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if( r == USB_PID_STALL ) | ||||||
|  |             { | ||||||
|  |                 return ( r | ERR_USB_TRANSFER ); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if( r == USB_PID_NAK ) | ||||||
|  |             { | ||||||
|  |                 if( timeout == 0 ) | ||||||
|  |                 { | ||||||
|  |                     return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                 } | ||||||
|  |                 if( timeout < 0xFFFF ) | ||||||
|  |                 { | ||||||
|  |                     timeout--; | ||||||
|  |                 } | ||||||
|  |                 --trans_retry; | ||||||
|  |             } | ||||||
|  |             else switch( endp_pid >> 4  ) | ||||||
|  |             { | ||||||
|  |                 case USB_PID_SETUP: | ||||||
|  | 
 | ||||||
|  |                 case USB_PID_OUT: | ||||||
|  |                     if( r ) | ||||||
|  |                     { | ||||||
|  |                         return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 case USB_PID_IN: | ||||||
|  |                     if( ( r == USB_PID_DATA0 ) || ( r == USB_PID_DATA1 ) ) | ||||||
|  |                     { | ||||||
|  |                         ; | ||||||
|  |                     } | ||||||
|  |                     else if( r ) | ||||||
|  |                     { | ||||||
|  |                         return ( r | ERR_USB_TRANSFER ); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     return ERR_USB_UNKNOWN; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             USBHSH->INT_FG = USBHS_UIF_DETECT | USBHS_UIF_TRANSFER | USBHS_UIF_SUSPEND | USBHS_UIF_HST_SOF | USBHS_UIF_FIFO_OV | USBHS_UIF_SETUP_ACT; | ||||||
|  |         } | ||||||
|  |         Delay_Us( 15 ); | ||||||
|  |     } while( ++trans_retry < 10 ); | ||||||
|  | 
 | ||||||
|  |     return ERR_USB_TRANSFER; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_CtrlTransfer | ||||||
|  |  * | ||||||
|  |  * @brief   Host control transfer. | ||||||
|  |  * | ||||||
|  |  * @brief   USB host control transfer. | ||||||
|  |  * | ||||||
|  |  * @para    ep0_size: Device endpoint 0 size | ||||||
|  |  *          pbuf: Data buffer | ||||||
|  |  *          plen: Data length | ||||||
|  |  * | ||||||
|  |  * @return  USB control transfer result. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_CtrlTransfer( uint8_t ep0_size, uint8_t *pbuf, uint16_t *plen ) | ||||||
|  | { | ||||||
|  |     uint8_t  s, tog = 1; | ||||||
|  |     uint16_t rem_len, rx_len, rx_cnt, tx_cnt; | ||||||
|  | 
 | ||||||
|  |     if( plen ) | ||||||
|  |     { | ||||||
|  |         *plen = 0; | ||||||
|  |     } | ||||||
|  |     USBHSH->HOST_TX_LEN = 8; | ||||||
|  |     s = USBHSH_Transact( ( USB_PID_SETUP << 4 ) | 0x00, 0, 200000 ); | ||||||
|  |     if( s != ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         return s;                     | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     rem_len = pUSBHS_SetupRequest->wLength; | ||||||
|  |     if( rem_len && pbuf ) //data stage
 | ||||||
|  |     { | ||||||
|  |         if( pUSBHS_SetupRequest->bRequestType & USB_REQ_TYP_IN ) //device to host
 | ||||||
|  |         { | ||||||
|  |             while( rem_len ) | ||||||
|  |             { | ||||||
|  |                 s = USBHSH_Transact( ( USB_PID_IN << 4 ) | 0x00, tog << 3, 20000 ); | ||||||
|  |                 if( s != ERR_SUCCESS ) | ||||||
|  |                 { | ||||||
|  |                     return s; | ||||||
|  |                 } | ||||||
|  |                 tog ^=1; | ||||||
|  |                 rx_len = ( USBHSH->RX_LEN < rem_len )? USBHSH->RX_LEN : rem_len; | ||||||
|  |                 rem_len -= rx_len; | ||||||
|  |                 if( plen ) | ||||||
|  |                 { | ||||||
|  |                     *plen += rx_len; | ||||||
|  |                 } | ||||||
|  |                 for( rx_cnt = 0; rx_cnt != rx_len; rx_cnt++ ) | ||||||
|  |                 { | ||||||
|  |                     *pbuf = USBHS_RX_Buf[ rx_cnt ]; | ||||||
|  |                     pbuf++; | ||||||
|  |                 } | ||||||
|  |                 if( ( USBHSH->RX_LEN == 0 ) || ( USBHSH->RX_LEN & ( ep0_size - 1 ) ) ) | ||||||
|  |                 { | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             USBHSH->HOST_TX_LEN = 0; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         {                                                           // host to device
 | ||||||
|  |             while( rem_len ) | ||||||
|  |             { | ||||||
|  |                 USBHSH->HOST_TX_LEN = ( rem_len >= ep0_size )? ep0_size : rem_len; | ||||||
|  |                 for( tx_cnt = 0; tx_cnt != USBHSH->HOST_TX_LEN; tx_cnt++ ) | ||||||
|  |                 { | ||||||
|  |                     USBHS_TX_Buf[ tx_cnt ] = *pbuf; | ||||||
|  |                     pbuf++; | ||||||
|  |                 } | ||||||
|  |                 s = USBHSH_Transact( ( USB_PID_OUT << 4 ) | 0x00, tog << 3, 20000 ); | ||||||
|  |                 if( s != ERR_SUCCESS ) | ||||||
|  |                 { | ||||||
|  |                     return s; | ||||||
|  |                 } | ||||||
|  |                 tog ^=1; | ||||||
|  |                 rem_len -= USBHSH->HOST_TX_LEN; | ||||||
|  |                 if( plen ) | ||||||
|  |                 { | ||||||
|  |                     *plen += USBHSH->HOST_TX_LEN; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     s = USBHSH_Transact( ( USBHSH->HOST_TX_LEN )? ( USB_PID_IN << 4 | 0x00 ) : ( USB_PID_OUT << 4 | 0x00 ), USBHS_UEP_R_TOG_DATA1 | USBHS_UEP_T_TOG_DATA1, 20000 ); | ||||||
|  |     if( s != ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         return s; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if( USBHSH->HOST_TX_LEN == 0 ) | ||||||
|  |     { | ||||||
|  |         return ERR_SUCCESS;    //status stage is out, send a zero-length packet.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if( USBHSH->RX_LEN == 0 ) | ||||||
|  |     { | ||||||
|  |         return ERR_SUCCESS;    //status stage is in, a zero-length packet is returned indicating success.
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return ERR_USB_BUF_OVER; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_GetDeviceDescr | ||||||
|  |  * | ||||||
|  |  * @brief   Get the device descriptor of the USB device. | ||||||
|  |  * | ||||||
|  |  * @para    pep0_size: Device endpoint 0 size | ||||||
|  |  *          pbuf: Data buffer | ||||||
|  |  * | ||||||
|  |  * @return  The result of getting the device descriptor. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_GetDeviceDescr( uint8_t *pep0_size, uint8_t *pbuf ) | ||||||
|  | { | ||||||
|  |     uint8_t  s; | ||||||
|  |     uint16_t len; | ||||||
|  | 
 | ||||||
|  |     *pep0_size = DEFAULT_ENDP0_SIZE; | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupGetDevDesc, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     s = USBHSH_CtrlTransfer( *pep0_size, pbuf, &len ); | ||||||
|  |     if( s != ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         return s; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *pep0_size = ( (PUSB_DEV_DESCR)pbuf )->bMaxPacketSize0; | ||||||
|  |     if( len < ( (PUSB_SETUP_REQ)SetupGetDevDesc )->wLength ) | ||||||
|  |     { | ||||||
|  |         return ERR_USB_BUF_OVER; | ||||||
|  |     } | ||||||
|  |     return ERR_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_GetConfigDescr | ||||||
|  |  * | ||||||
|  |  * @brief   Get the configuration descriptor of the USB device.  | ||||||
|  |  * | ||||||
|  |  * @para    ep0_size: Device endpoint 0 size | ||||||
|  |  *          pbuf: Data buffer | ||||||
|  |  *          buf_len: Data buffer length | ||||||
|  |  *          pcfg_len: The length of the device configuration descriptor | ||||||
|  |  * | ||||||
|  |  * @return  The result of getting the configuration descriptor. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_GetConfigDescr( uint8_t ep0_size, uint8_t *pbuf, uint16_t buf_len, uint16_t *pcfg_len ) | ||||||
|  | { | ||||||
|  |     uint8_t  s; | ||||||
|  | 
 | ||||||
|  |     /* Get the string descriptor of the first 4 bytes */ | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupGetCfgDesc, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     s = USBHSH_CtrlTransfer( ep0_size, pbuf, pcfg_len ); | ||||||
|  |     if( s != ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         return s; | ||||||
|  |     } | ||||||
|  |     if( *pcfg_len < ( (PUSB_SETUP_REQ)SetupGetCfgDesc )->wLength ) | ||||||
|  |     { | ||||||
|  |         return ERR_USB_BUF_OVER; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Get the complete string descriptor */ | ||||||
|  |     *pcfg_len = ((PUSB_CFG_DESCR)pbuf)->wTotalLength; | ||||||
|  |     if( *pcfg_len > buf_len ) | ||||||
|  |     { | ||||||
|  |         *pcfg_len = buf_len; | ||||||
|  |     } | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupGetCfgDesc, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     pUSBHS_SetupRequest->wLength = *pcfg_len; | ||||||
|  |     s = USBHSH_CtrlTransfer( ep0_size, pbuf, pcfg_len ); | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_GetStrDescr | ||||||
|  |  * | ||||||
|  |  * @brief   Get the string descriptor of the USB device. | ||||||
|  |  * | ||||||
|  |  * @para    ep0_size: Device endpoint 0 size | ||||||
|  |  *          str_num: Index of string descriptor   | ||||||
|  |  *          pbuf: Data buffer | ||||||
|  |  * | ||||||
|  |  * @return  The result of getting the string descriptor. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_GetStrDescr( uint8_t ep0_size, uint8_t str_num, uint8_t *pbuf ) | ||||||
|  | { | ||||||
|  |     uint8_t  s; | ||||||
|  |     uint16_t len; | ||||||
|  | 
 | ||||||
|  |     /* Get the string descriptor of the first 4 bytes */ | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupGetStrDesc, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     pUSBHS_SetupRequest->wValue = ( (uint16_t)USB_DESCR_TYP_STRING << 8 ) | str_num; | ||||||
|  |     s = USBHSH_CtrlTransfer( ep0_size, pbuf, &len ); | ||||||
|  |     if( s != ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         return s; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Get the complete string descriptor */ | ||||||
|  |     len = pbuf[ 0 ]; | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupGetStrDesc, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     pUSBHS_SetupRequest->wValue = ( (uint16_t)USB_DESCR_TYP_STRING << 8 ) | str_num; | ||||||
|  |     pUSBHS_SetupRequest->wLength = len; | ||||||
|  |     s = USBHSH_CtrlTransfer( ep0_size, pbuf, &len ); | ||||||
|  |     if( s != ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         return s; | ||||||
|  |     } | ||||||
|  |     return ERR_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_SetUsbAddress | ||||||
|  |  * | ||||||
|  |  * @brief   Set USB device address. | ||||||
|  |  * | ||||||
|  |  * @para    ep0_size: Device endpoint 0 size | ||||||
|  |  *          addr: Device address | ||||||
|  |  * | ||||||
|  |  * @return  The result of setting device address. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_SetUsbAddress( uint8_t ep0_size, uint8_t addr ) | ||||||
|  | { | ||||||
|  |     uint8_t  s; | ||||||
|  | 
 | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupSetAddr, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     pUSBHS_SetupRequest->wValue = (uint16_t)addr; | ||||||
|  |     s = USBHSH_CtrlTransfer( ep0_size, NULL, NULL ); | ||||||
|  |     if( s != ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         return s; | ||||||
|  |     } | ||||||
|  |     USBHSH_SetSelfAddr( addr ); | ||||||
|  |     Delay_Ms( DEF_BUS_RESET_TIME >> 1 ); // Wait for the USB device to complete its operation.
 | ||||||
|  |     return ERR_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_SetUsbConfig | ||||||
|  |  * | ||||||
|  |  * @brief   Set USB configuration. | ||||||
|  |  * | ||||||
|  |  * @para    ep0_size: Device endpoint 0 size | ||||||
|  |  *          cfg: Device configuration value | ||||||
|  |  * | ||||||
|  |  * @return  The result of setting device configuration. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_SetUsbConfig( uint8_t ep0_size, uint8_t cfg_val ) | ||||||
|  | { | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupSetConfig, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     pUSBHS_SetupRequest->wValue = (uint16_t)cfg_val; | ||||||
|  |     return USBHSH_CtrlTransfer( ep0_size, NULL, NULL ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBH_ClearEndpStall | ||||||
|  |  * | ||||||
|  |  * @brief   Clear endpoint stall. | ||||||
|  |  * | ||||||
|  |  * @para    ep0_size: Device endpoint 0 size | ||||||
|  |  *          endp_num: Endpoint number. | ||||||
|  |  * | ||||||
|  |  * @return  The result of clearing endpoint stall. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_ClearEndpStall( uint8_t ep0_size, uint8_t endp_num ) | ||||||
|  | { | ||||||
|  |     memcpy( pUSBHS_SetupRequest, SetupClearEndpStall, sizeof( USB_SETUP_REQ ) ); | ||||||
|  |     pUSBHS_SetupRequest->wIndex = (uint16_t)endp_num; | ||||||
|  |     return ( USBHSH_CtrlTransfer( ep0_size, NULL, NULL ) ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_GetEndpData | ||||||
|  |  * | ||||||
|  |  * @brief   Get data from USB device input endpoint. | ||||||
|  |  * | ||||||
|  |  * @para    endp_num: Endpoint number | ||||||
|  |  *          pendp_tog: Endpoint toggle | ||||||
|  |  *          pbuf: Data Buffer | ||||||
|  |  *          plen: Data length | ||||||
|  |  * | ||||||
|  |  * @return  The result of getting data. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_GetEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t *plen ) | ||||||
|  | { | ||||||
|  |     uint8_t  s; | ||||||
|  |      | ||||||
|  |     s = USBHSH_Transact( ( USB_PID_IN << 4 ) | endp_num, *pendp_tog, 0 ); | ||||||
|  |     if( s == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         *pendp_tog ^= USBHS_UH_T_TOG_DATA1 | USBHS_UH_R_TOG_DATA1; | ||||||
|  |         *plen = USBHSH->RX_LEN; | ||||||
|  |         memcpy( pbuf, USBHS_RX_Buf, *plen ); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*********************************************************************
 | ||||||
|  |  * @fn      USBHSH_SendEndpData | ||||||
|  |  * | ||||||
|  |  * @brief   Send data to the USB device output endpoint. | ||||||
|  |  * | ||||||
|  |  * @para    endp_num: Endpoint number | ||||||
|  |  *          pendp_tog: Endpoint toggle | ||||||
|  |  *          pbuf: Data Buffer | ||||||
|  |  *          plen: Data length | ||||||
|  |  * | ||||||
|  |  * @return  The result of sending data. | ||||||
|  |  */ | ||||||
|  | uint8_t USBHSH_SendEndpData( uint8_t endp_num, uint8_t *pendp_tog, uint8_t *pbuf, uint16_t len ) | ||||||
|  | { | ||||||
|  |     uint8_t  s; | ||||||
|  |      | ||||||
|  |     memcpy( USBHS_TX_Buf, pbuf, len ); | ||||||
|  |     USBHSH->HOST_TX_LEN = len; | ||||||
|  |      | ||||||
|  |     s = USBHSH_Transact( ( USB_PID_OUT << 4 ) | endp_num, *pendp_tog, 0 ); | ||||||
|  |     if( s == ERR_SUCCESS ) | ||||||
|  |     { | ||||||
|  |         *pendp_tog ^= USBHS_UH_T_TOG_DATA1 | USBHS_UH_R_TOG_DATA1; | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     return s; | ||||||
|  | } | ||||||
|  | @ -182,7 +182,7 @@ static uint32 CanReadData(void *dev , struct BusBlockReadParam *databuf) | ||||||
| 
 | 
 | ||||||
|     ret = CAN_GetRxFrame(CAN_X, &frame_received); |     ret = CAN_GetRxFrame(CAN_X, &frame_received); | ||||||
|     if(EOK != ret){ |     if(EOK != ret){ | ||||||
|         // KPrintf("CAN recv frame failed(CODE:%d)!\n",ret);
 |        // KPrintf("CAN recv frame failed(CODE:%d)!\n",ret);
 | ||||||
|         p_can_config->data_lenth = 0; |         p_can_config->data_lenth = 0; | ||||||
|         return ERROR;             |         return ERROR;             | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -285,6 +285,7 @@ KERNELPATHS += \ | ||||||
| 	-I$(KERNEL_ROOT)/arch/risc-v/ch32v307vct6/User \
 | 	-I$(KERNEL_ROOT)/arch/risc-v/ch32v307vct6/User \
 | ||||||
| 	-I$(KERNEL_ROOT)/arch/risc-v/ch32v307vct6 \
 | 	-I$(KERNEL_ROOT)/arch/risc-v/ch32v307vct6 \
 | ||||||
| 	-I$(BSP_ROOT)/third_party_driver/include \
 | 	-I$(BSP_ROOT)/third_party_driver/include \
 | ||||||
|  | 	-I$(BSP_ROOT)/third_party_driver/usb/usb_drv/inc \
 | ||||||
| 	-I$(BSP_ROOT)/third_party_driver/Peripheral/inc \
 | 	-I$(BSP_ROOT)/third_party_driver/Peripheral/inc \
 | ||||||
| 	-I$(BSP_ROOT)/include \
 | 	-I$(BSP_ROOT)/include \
 | ||||||
| 	-I$(KERNEL_ROOT)/include # | 	-I$(KERNEL_ROOT)/include # | ||||||
|  |  | ||||||