diff --git a/hi-sle/Autodesk_Fusion_360_Designs/remote_controller_model.dxf b/hi-sle/Autodesk_Fusion_360_Designs/remote_controller_model.dxf new file mode 100644 index 0000000000000000000000000000000000000000..a33403a3e742340713ed05d755acb08a66ae0c29 --- /dev/null +++ b/hi-sle/Autodesk_Fusion_360_Designs/remote_controller_model.dxf @@ -0,0 +1,620 @@ +0 +SECTION +2 +HEADER +9 +$INSUNITS +70 +4 +9 +$ACADVER +1 +AC1014 +9 +$HANDSEED +5 +FFFF +0 +ENDSEC +0 +SECTION +2 +TABLES +0 +TABLE +2 +VPORT +5 +8 +100 +AcDbSymbolTable +0 +ENDTAB +0 +TABLE +2 +LTYPE +5 +5 +100 +AcDbSymbolTable +0 +LTYPE +5 +14 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord +2 +BYBLOCK +70 +0 +0 +LTYPE +5 +15 +100 +AcDbSymbolTableRecord +100 +AcDbLinetypeTableRecord +2 +BYLAYER +70 +0 +0 +ENDTAB +0 +TABLE +2 +LAYER +5 +2 +100 +AcDbSymbolTable +70 +2 +0 +LAYER +5 +50 +100 +AcDbSymbolTableRecord +100 +AcDbLayerTableRecord +2 +0 +70 +0 +6 +CONTINUOUS +0 +ENDTAB +0 +TABLE +2 +STYLE +5 +3 +100 +AcDbSymbolTable +70 +1 +0 +STYLE +5 +11 +100 +AcDbSymbolTableRecord +100 +AcDbTextStyleTableRecord +2 +STANDARD +70 +0 +0 +ENDTAB +0 +TABLE +2 +VIEW +5 +6 +100 +AcDbSymbolTable +70 +0 +0 +ENDTAB +0 +TABLE +2 +UCS +5 +7 +100 +AcDbSymbolTable +70 +0 +0 +ENDTAB +0 +TABLE +2 +APPID +5 +9 +100 +AcDbSymbolTable +70 +2 +0 +APPID +5 +12 +100 +AcDbSymbolTableRecord +100 +AcDbRegAppTableRecord +2 +ACAD +70 +0 +0 +ENDTAB +0 +TABLE +2 +DIMSTYLE +5 +A +100 +AcDbSymbolTable +70 +1 +0 +ENDTAB +0 +TABLE +2 +BLOCK_RECORD +5 +1 +100 +AcDbSymbolTable +70 +1 +0 +BLOCK_RECORD +5 +1F +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord +2 +*MODEL_SPACE +0 +BLOCK_RECORD +5 +1B +100 +AcDbSymbolTableRecord +100 +AcDbBlockTableRecord +2 +*PAPER_SPACE +0 +ENDTAB +0 +ENDSEC +0 +SECTION +2 +BLOCKS +0 +BLOCK +5 +20 +100 +AcDbEntity +100 +AcDbBlockBegin +2 +*MODEL_SPACE +0 +ENDBLK +5 +21 +100 +AcDbEntity +100 +AcDbBlockEnd +0 +BLOCK +5 +1C +100 +AcDbEntity +100 +AcDbBlockBegin +2 +*PAPER_SPACE +0 +ENDBLK +5 +1D +100 +AcDbEntity +100 +AcDbBlockEnd +0 +ENDSEC +0 +SECTION +2 +ENTITIES +0 +LWPOLYLINE +5 +100 +100 +AcDbEntity +8 +0 +100 +AcDbPolyline +90 +22 +70 +1 +43 +0.0 +10 +40.442226373456592 +20 +23.95073538178648 +42 +0.24171376600242628 +10 +40.024999636689998 +20 +23.138100578409038 +10 +40.024999636689998 +20 +0.37502041741000852 +42 +-0.4142135623730947 +10 +37.824999636690002 +20 +-1.8249795825899942 +10 +-37.824999636692013 +20 +-1.8249795825899922 +42 +-0.4142135623730952 +10 +-40.024999636692009 +20 +0.37502041741000669 +10 +-40.024999636692009 +20 +23.138100578406899 +42 +0.24171376600254765 +10 +-40.442226373458965 +20 +23.9507353817846 +42 +-0.084684859904792825 +10 +-42.100439826245264 +20 +25.627979904149804 +10 +-44.92037124742847 +20 +29.656453362980379 +42 +0.24473544024323177 +10 +-50.64458978696301 +20 +32.636799593589998 +10 +-75.936979930133006 +20 +32.63679959359137 +42 +0.49013302976303491 +10 +-89.482166728216001 +20 +15.160587172 +10 +-80.854252072462955 +20 +-18.336016840902005 +42 +0.34216204865823896 +10 +-61.498714761561999 +20 +-33.337800355600997 +10 +61.498717300760021 +20 +-33.337800355600315 +42 +0.34216204865820105 +10 +80.854252072257879 +20 +-18.336016841682451 +10 +89.482166728211098 +20 +15.160587171999715 +42 +0.49013302976299639 +10 +75.936979930129993 +20 +32.636799593589998 +10 +50.644589786960012 +20 +32.636799593595896 +42 +0.24473544024342697 +10 +44.920371247420007 +20 +29.656453362979999 +10 +42.100439826240276 +20 +25.627979904149814 +42 +-0.084684859904677542 +0 +CIRCLE +5 +101 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +80.000010160020011 +20 +22.855326390649999 +30 +0 +40 +1.5000000000000036 +210 +0 +220 +0 +230 +1 +0 +CIRCLE +5 +102 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +-80.000010160020011 +20 +22.855326390649999 +30 +0 +40 +1.5000000000000036 +210 +0 +220 +0 +230 +1 +0 +CIRCLE +5 +103 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +63.000000000000007 +20 +-25.144673609347002 +30 +0 +40 +1.5000000000000036 +210 +0 +220 +0 +230 +1 +0 +CIRCLE +5 +104 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +-63.000000000000007 +20 +-25.144673609347002 +30 +0 +40 +1.4999999999999947 +210 +0 +220 +0 +230 +1 +0 +CIRCLE +5 +105 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +36.000071120139999 +20 +-11.99997279214376 +30 +0 +40 +6.4999999999999991 +210 +0 +220 +0 +230 +1 +0 +CIRCLE +5 +106 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +-58.800131691628003 +20 +4.2000235642760009 +30 +0 +40 +14.500000000000002 +210 +0 +220 +0 +230 +1 +0 +CIRCLE +5 +107 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +61.200107068841007 +20 +4.2000235642760009 +30 +0 +40 +14.500000000000002 +210 +0 +220 +0 +230 +1 +0 +CIRCLE +5 +108 +100 +AcDbEntity +8 +0 +100 +AcDbCircle +10 +-36.000071120142003 +20 +-11.99997279214376 +30 +0 +40 +6.4999999999999991 +210 +0 +220 +0 +230 +1 +0 +ENDSEC +0 +SECTION +2 +OBJECTS +0 +DICTIONARY +5 +C +100 +AcDbDictionary +3 +ACAD_GROUP +350 +D +3 +ACAD_MLINESTYLE +350 +17 +0 +DICTIONARY +5 +D +100 +AcDbDictionary +0 +DICTIONARY +5 +1A +330 +C +100 +AcDbDictionary +0 +DICTIONARY +5 +17 +100 +AcDbDictionary +0 +ENDSEC +0 +EOF diff --git a/hi-sle/Autodesk_Fusion_360_Designs/remote_controller_model.f3d b/hi-sle/Autodesk_Fusion_360_Designs/remote_controller_model.f3d new file mode 100644 index 0000000000000000000000000000000000000000..1eb17c6f1ccabac51695e83db41e15c179fcf0c5 Binary files /dev/null and b/hi-sle/Autodesk_Fusion_360_Designs/remote_controller_model.f3d differ diff --git a/hi-sle/Bill_of_Materials/material_description.txt b/hi-sle/Bill_of_Materials/material_description.txt new file mode 100644 index 0000000000000000000000000000000000000000..1921d8582f828f4e6c04bf0505880e44db02b5b2 --- /dev/null +++ b/hi-sle/Bill_of_Materials/material_description.txt @@ -0,0 +1,8 @@ +【开源之夏】 +1. 摇杆帽:用于摇杆操控 +2. 亚克力板:用于遥控器整体面板(eulercarboard.dxf轮廓文件) +3. 焊锡膏:用于贴片原件焊料 +4. 704硅橡胶用于PCB电池盒固定 +5. 18650:用于遥控板供电 +6. PCB:用于遥控板整体电路 +7. PCB电子元器件套件:PCB电路BOM表(BOM_Board1_EulerCar.xlsx)所有电子元器件 diff --git a/hi-sle/Bill_of_Materials/material_purchase.xlsx b/hi-sle/Bill_of_Materials/material_purchase.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..cdcea3817b64bc31734437619024c21f3dbf51ce Binary files /dev/null and b/hi-sle/Bill_of_Materials/material_purchase.xlsx differ diff --git a/hi-sle/EulerCar_Host_Computer_EulerPi_Source_Code/ws63_ws73_ros2.c b/hi-sle/EulerCar_Host_Computer_EulerPi_Source_Code/ws63_ws73_ros2.c new file mode 100644 index 0000000000000000000000000000000000000000..b604659df3f93caaf70472c0997461d5f7e19a93 --- /dev/null +++ b/hi-sle/EulerCar_Host_Computer_EulerPi_Source_Code/ws63_ws73_ros2.c @@ -0,0 +1,954 @@ +/** + * Copyright (c) @CompanyNameMagicTag 2022. All rights reserved. + * + * Description: SLE private service register sample of client. + */ +#include "securec.h" +#include "sle_device_discovery.h" +#include "sle_connection_manager.h" +#include "sle_ssap_client.h" +#include "sle_uuid_client.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#undef THIS_FILE_ID +#define THIS_FILE_ID BTH_GLE_SAMPLE_UUID_CLIENT + +// 定义日志前缀 +#define SLE_RCU_DONGLE_LOG "[sle ws73]" + +// 定义默认MTU大小 +#define SLE_MTU_SIZE_DEFAULT 300 + +// 定义默认查找间隔 +#define SLE_SEEK_INTERVAL_DEFAULT 100 + +// 定义默认查找窗口 +#define SLE_SEEK_WINDOW_DEFAULT 100 + +// 定义16位UUID长度 +#define UUID_16BIT_LEN 2 + +// 定义128位UUID长度 +#define UUID_128BIT_LEN 16 + +// 定义键码和键值的全局变量 +char key_code = 0; +char key_value = 0; + +// 定义全局回调结构体 +sle_announce_seek_callbacks_t g_seek_cbk = {0}; +sle_connection_callbacks_t g_connect_cbk = {0}; +ssapc_callbacks_t g_ssapc_cbk = {0}; + +// 定义全局远程地址结构体 +sle_addr_t g_remote_addr = {0}; + +// 定义全局连接ID +uint16_t g_conn_id = 0; + +// 定义全局查找服务结果结构体 +ssapc_find_service_result_t g_find_service_result = {0}; + +// 定义测试套件UART发送函数的宏 +#define test_suite_uart_sendf(fmt, arg...) NULL + +// 定义SLE客户端地址 +#define CONFIG_SLE_MULTICON_CLIENT_ADDR0 0xb0 +#define CONFIG_SLE_MULTICON_CLIENT_ADDR1 0x66 +#define CONFIG_SLE_MULTICON_CLIENT_ADDR2 0x00 +#define CONFIG_SLE_MULTICON_CLIENT_ADDR3 0x00 +#define CONFIG_SLE_MULTICON_CLIENT_ADDR4 0x7A +#define CONFIG_SLE_MULTICON_CLIENT_ADDR5 0x00 + +// 定义USB RCU报告长度 +#define USB_RCU_KEYBOARD_REPORTER_LEN 9 +#define USB_RCU_MOUSE_REPORTER_LEN 5 +#define USB_RCU_CONSUMER_REPORTER_LEN 3 + +// 定义USB HID RCU最大按键长度 +#define USB_HID_RCU_MAX_KEY_LENTH 6 +typedef struct usb_hid_rcu_keyboard_report +{ + uint8_t kind; + uint8_t special_key; /*!< 8bit special key(Lctrl Lshift Lalt Lgui Rctrl Rshift Ralt Rgui) */ + uint8_t reserve; + uint8_t key[USB_HID_RCU_MAX_KEY_LENTH]; /*!< Normal key */ +} usb_hid_rcu_keyboard_report_t; + +void send_data(int fd, char *data) +{ + int bytes_written = write(fd, data, strlen(data)); + if (bytes_written == -1) + { + perror("Error occurred while writing data to the serial port"); + } + else + { + printf("Write %d bytes of data success : %s\n", bytes_written, data); + } +} + +int send_data_to_serial(char *data) +{ + char *serial_port = "/dev/ttyAMA3"; + speed_t baud_rate = B9600; + + int fd = open(serial_port, O_RDWR | O_NOCTTY); + if (fd == -1) + { + perror("Open serial port fail\n"); + return -1; + } + + struct termios options; + if (tcgetattr(fd, &options) != 0) + { + perror("Error from tcgetattr"); + close(fd); + return -1; + } + + // Set baud rate + cfsetispeed(&options, baud_rate); + cfsetospeed(&options, baud_rate); + + // Set serial port parameters + options.c_cflag |= (CLOCAL | CREAD); + options.c_cflag &= ~PARENB; + options.c_cflag &= ~CSTOPB; + options.c_cflag &= ~CSIZE; + options.c_cflag |= CS8; + + options.c_iflag &= ~(INPCK | ISTRIP); + options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); + options.c_oflag &= ~OPOST; + + tcflush(fd, TCIFLUSH); + // Apply settings + if (tcsetattr(fd, TCSANOW, &options) != 0) + { + perror("Error from tcsetattr"); + close(fd); + return -1; + } + send_data(fd, data); + + close(fd); + return 0; +} + +/** + * @brief SLE启用回调函数 + * + * 该函数在SLE启用时被调用。它设置本地地址并启动扫描。 + * + * @param status 启用SLE的状态码。0表示成功,非0表示失败。 + */ +void sle_sample_sle_enable_cbk(errcode_t status) +{ + errcode_t ret; // 定义返回值变量 + uint8_t local_addr[SLE_ADDR_LEN] = {CONFIG_SLE_MULTICON_CLIENT_ADDR0, CONFIG_SLE_MULTICON_CLIENT_ADDR1, + CONFIG_SLE_MULTICON_CLIENT_ADDR2, CONFIG_SLE_MULTICON_CLIENT_ADDR3, + CONFIG_SLE_MULTICON_CLIENT_ADDR4, CONFIG_SLE_MULTICON_CLIENT_ADDR5}; // 定义本地地址数组 + sle_addr_t local_address; // 定义本地地址结构体 + local_address.type = 0; // 设置地址类型为0 + memcpy_s(local_address.addr, SLE_ADDR_LEN, local_addr, SLE_ADDR_LEN); // 将本地地址数组复制到地址结构体中 + + if (status == 0) // 如果SLE启用成功 + { + ret = sle_set_local_addr(&local_address); // 设置本地地址 + printf("sle_set_local_addr %d\n", ret); // 打印设置本地地址的结果 + sle_start_scan(); // 启动扫描 + } +} + +void sle_sample_seek_enable_cbk(errcode_t status) +{ + if (status == 0) + { + return; + } +} + +void sle_sample_seek_disable_cbk(errcode_t status) +{ + if (status == 0) + { + sle_connect_remote_device(&g_remote_addr); + } +} + +/** + * @brief SLE查找结果信息回调函数 + * + * 该函数在SLE查找过程中被调用,用于处理查找结果。当查找结果不为空时, + * 将查找到的设备地址复制到全局变量 `g_remote_addr` 中,并停止查找过程。 + * + * @param seek_result_data 指向查找结果信息结构体的指针 + */ +void sle_sample_seek_result_info_cbk(sle_seek_result_info_t *seek_result_data) +{ + // 检查查找结果是否不为空 + if (seek_result_data != NULL) + { + // 将查找到的设备地址复制到全局变量 g_remote_addr 中 + (void)memcpy_s(&g_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, sizeof(sle_addr_t)); + + // 停止查找过程 + sle_stop_seek(); + } +} + +/** + * @brief 注册样本查找回调函数 + * + * 该函数用于将样本查找相关的回调函数注册到全局回调结构体 `g_seek_cbk` 中。 + * 这些回调函数包括启用SLE、启用查找、禁用查找和查找结果处理。 + */ +void sle_sample_seek_cbk_register(void) +{ + // 注册启用SLE的回调函数 + g_seek_cbk.sle_enable_cb = sle_sample_sle_enable_cbk; + + // 注册启用查找的回调函数 + g_seek_cbk.seek_enable_cb = sle_sample_seek_enable_cbk; + + // 注册禁用查找的回调函数 + g_seek_cbk.seek_disable_cb = sle_sample_seek_disable_cbk; + + // 注册查找结果处理的回调函数 + g_seek_cbk.seek_result_cb = sle_sample_seek_result_info_cbk; +} + +/** + * @brief 连接状态变化回调函数 + * + * 该函数在连接状态变化时被调用。它处理连接状态、配对状态和断开原因。 + * 当连接状态变为已连接时,如果未配对,则启动配对过程,并保存连接ID。 + * + * @param conn_id 连接ID + * @param addr 指向远程设备地址的指针 + * @param conn_state 当前连接状态 + * @param pair_state 当前配对状态 + * @param disc_reason 断开连接的原因 + */ +void sle_sample_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) +{ + // 打印连接状态变化信息,包括连接ID和远程设备地址 + // test_suite_uart_sendf("[ssap client] conn state changed conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + // addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + test_suite_uart_sendf("[ssap client] pair complete conn_id:%d, addr:%02x%02x%02x%02x%02x%02x\n", conn_id, addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], addr->addr[4], addr->addr[5]); + printf("[ssap client] pair complete conn_id:%d, addr:%02x%02x%02x%02x%02x%02x\n", conn_id, addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], addr->addr[4], addr->addr[5]); + + // 打印断开连接的原因 + test_suite_uart_sendf("[ssap client] conn state changed disc_reason:0x%x\n", disc_reason); + + // 如果连接状态为已连接 + if (conn_state == SLE_ACB_STATE_CONNECTED) + { + // 如果配对状态为未配对 + if (pair_state == SLE_PAIR_NONE) + { + // 启动配对过程 + sle_pair_remote_device(&g_remote_addr); + } + // 保存连接ID + g_conn_id = conn_id; + } +} + +/** + * @brief 配对完成回调函数 + * + * 该函数在配对完成时被调用。它处理配对完成后的操作,包括打印配对信息和 + * 发送SSAP交换信息请求。当配对成功时,设置MTU大小和版本信息,并发送交换信息请求。 + * + * @param conn_id 连接ID + * @param addr 指向远程设备地址的指针 + * @param status 配对状态码。0表示成功,非0表示失败。 + */ +void sle_sample_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + // 打印配对完成信息,包括连接ID和远程设备地址 + // test_suite_uart_sendf("[ssap client] pair complete conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + // addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + + test_suite_uart_sendf("[ssap client] pair complete conn_id:%d, addr:%02x%02x%02x%02x%02x%02x\n", conn_id, addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], addr->addr[4], addr->addr[5]); + printf("[ssap client] pair complete conn_id:%d, addr:%02x:%02x:%02x:%02x:%02x:%02x\n", conn_id, addr->addr[0], addr->addr[1], addr->addr[2], addr->addr[3], addr->addr[4], addr->addr[5]); + // 如果配对成功 + if (status == 0) + { + // 定义并初始化SSAP交换信息结构体 + ssap_exchange_info_t info = {0}; + info.mtu_size = SLE_MTU_SIZE_DEFAULT; // 设置MTU大小 + info.version = 1; // 设置版本信息 + // 发送SSAP交换信息请求 + ssapc_exchange_info_req(1, g_conn_id, &info); + } +} + +/** + * @brief 注册样本连接回调函数 + * + * 该函数用于将样本连接相关的回调函数注册到全局回调结构体 `g_connect_cbk` 中。 + * 这些回调函数包括连接状态变化回调函数和配对完成回调函数。 + */ +void sle_sample_connect_cbk_register(void) +{ + // 注册连接状态变化回调函数 + g_connect_cbk.connect_state_changed_cb = sle_sample_connect_state_changed_cbk; + + // 注册配对完成回调函数 + g_connect_cbk.pair_complete_cb = sle_sample_pair_complete_cbk; +} + +/** + * @brief SSAP交换信息回调函数 + * + * 该函数在SSAP交换信息完成时被调用。它处理交换信息的结果,包括打印交换信息和 + * 启动查找结构过程。当交换信息成功时,打印MTU大小和版本信息,并启动查找主服务结构。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param param 指向SSAP交换信息参数结构体的指针 + * @param status 交换信息状态码。0表示成功,非0表示失败。 + */ +void sle_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param, + errcode_t status) +{ + // 打印配对完成信息,包括客户端ID和状态码 + test_suite_uart_sendf("[ssap client] pair complete client id:%d status:%d\n", client_id, status); + + // 打印交换信息,包括MTU大小和版本信息 + test_suite_uart_sendf("[ssap client] exchange mtu, mtu size: %d, version: %d.\n", + param->mtu_size, param->version); + + // 定义并初始化查找结构参数结构体 + ssapc_find_structure_param_t find_param = {0}; + find_param.type = SSAP_FIND_TYPE_PRIMARY_SERVICE; // 设置查找类型为主服务 + find_param.start_hdl = 1; // 设置查找起始句柄 + find_param.end_hdl = 0xFFFF; // 设置查找结束句柄 + + // 启动查找结构过程 + + ssapc_find_structure(0, conn_id, &find_param); +} + +/** + * @brief 查找结构回调函数 + * + * 该函数在查找结构完成时被调用。它处理查找结构的结果,包括打印查找信息和 + * 保存查找结果。当查找结果的UUID长度为16位时,打印16位UUID;否则,打印128位UUID。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param service 指向查找服务结果结构体的指针 + * @param status 查找状态码。0表示成功,非0表示失败。 + */ +void sle_sample_find_structure_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_service_result_t *service, + errcode_t status) +{ + // 打印查找结构回调信息,包括客户端ID、连接ID和状态码 + test_suite_uart_sendf("[ssap client] find structure cbk client: %d conn_id:%d status: %d \n", + client_id, conn_id, status); + + // 打印查找结构的起始句柄、结束句柄和UUID长度 + test_suite_uart_sendf("[ssap client] find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n", + service->start_hdl, service->end_hdl, service->uuid.len); + + // 如果UUID长度为16位 + if (service->uuid.len == UUID_16BIT_LEN) + { + // 打印16位UUID + test_suite_uart_sendf("[ssap client] structure uuid:[0x%02x][0x%02x]\r\n", + service->uuid.uuid[14], service->uuid.uuid[15]); /* 14 15: uuid index */ + } + else + { + // 打印128位UUID + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) + { + test_suite_uart_sendf("[ssap client] structure uuid[%d]:[0x%02x]\r\n", idx, service->uuid.uuid[idx]); + } + } + + // 保存查找结果的起始句柄和结束句柄 + g_find_service_result.start_hdl = service->start_hdl; + g_find_service_result.end_hdl = service->end_hdl; + + // 将查找结果的UUID复制到全局变量 g_find_service_result.uuid 中 + memcpy_s(&g_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t)); +} + +/** + * @brief 查找结构完成回调函数 + * + * 该函数在查找结构完成时被调用。它处理查找结构的结果,包括打印查找信息和 + * 发送写请求。当查找结果的UUID长度为16位时,打印16位UUID;否则,打印128位UUID。 + * 最后,发送写请求,将数据写入查找到的结构中。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param structure_result 指向查找结构结果结构体的指针 + * @param status 查找状态码。0表示成功,非0表示失败。 + */ +void sle_sample_find_structure_cmp_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_structure_result_t *structure_result, errcode_t status) +{ + // 打印查找结构完成回调信息,包括客户端ID、状态码、类型和UUID长度 + test_suite_uart_sendf("[ssap client] find structure cmp cbk client id:%d status:%d type:%d uuid len:%d \r\n", + client_id, status, structure_result->type, structure_result->uuid.len); + + // 如果UUID长度为16位 + if (structure_result->uuid.len == UUID_16BIT_LEN) + { + // 打印16位UUID + test_suite_uart_sendf("[ssap client] find structure cmp cbk structure uuid:[0x%02x][0x%02x]\r\n", + structure_result->uuid.uuid[14], structure_result->uuid.uuid[15]); /* 14 15: uuid index */ + } + else + { + // 打印128位UUID + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) + { + test_suite_uart_sendf("[ssap client] find structure cmp cbk structure uuid[%d]:[0x%02x]\r\n", idx, + structure_result->uuid.uuid[idx]); + } + } + + // 定义要写入的数据 + uint8_t data[] = {0x11, 0x22, 0x33, 0x44}; + uint8_t len = sizeof(data); + + // 定义并初始化写请求参数结构体 + ssapc_write_param_t param = {0}; + param.handle = g_find_service_result.start_hdl; // 设置句柄为查找结果的起始句柄 + param.type = SSAP_PROPERTY_TYPE_VALUE; // 设置属性类型为值 + param.data_len = len; // 设置数据长度 + param.data = data; // 设置数据指针 + + // 发送写请求 + ssapc_write_req(0, conn_id, ¶m); +} + +/** + * @brief SSAP客户端查找属性回调函数 + * + * 该函数在SSAP客户端查找属性操作完成后被调用。它处理查找属性的结果,并将相关信息通过UART发送出去。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param property 指向查找属性结果结构体的指针 + * @param status 操作状态码。0表示成功,非0表示失败。 + */ +void sle_sample_find_property_cbk(uint8_t client_id, uint16_t conn_id, + ssapc_find_property_result_t *property, errcode_t status) +{ + // 通过UART发送查找属性回调的基本信息,包括客户端ID、连接ID、操作指示和描述符数量 + test_suite_uart_sendf("[ssap client] find property cbk, client id: %d, conn id: %d, operate ind: %d, " + "descriptors count: %d status:%d.\n", + client_id, conn_id, property->operate_indication, + property->descriptors_count, status); + + // 遍历所有描述符,并通过UART发送每个描述符的类型 + for (uint16_t idx = 0; idx < property->descriptors_count; idx++) + { + test_suite_uart_sendf("[ssap client] find property cbk, descriptors type [%d]: 0x%02x.\n", + idx, property->descriptors_type[idx]); + } + + // 根据UUID的长度,分别处理16位和128位UUID + if (property->uuid.len == UUID_16BIT_LEN) + { + // 如果UUID长度为16位,通过UART发送UUID的最后两个字节 + test_suite_uart_sendf("[ssap client] find property cbk, uuid: %02x %02x.\n", + property->uuid.uuid[14], property->uuid.uuid[15]); /* 14 15: uuid index */ + } + else if (property->uuid.len == UUID_128BIT_LEN) + { + // 如果UUID长度为128位,遍历UUID的每个字节,并通过UART发送 + for (uint16_t idx = 0; idx < UUID_128BIT_LEN; idx++) + { + test_suite_uart_sendf("[ssap client] find property cbk, uuid [%d]: %02x.\n", + idx, property->uuid.uuid[idx]); + } + } +} + +/** + * @brief 写确认回调函数 + * + * 该函数在写操作完成时被调用。它处理写操作的结果,并发送读请求以读取写入的数据。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param write_result 指向写操作结果结构体的指针 + * @param status 写操作状态码。0表示成功,非0表示失败。 + */ +void sle_sample_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result, + errcode_t status) +{ + // 打印写操作确认信息,包括客户端ID和状态码 + test_suite_uart_sendf("[ssap client] write cfm cbk, client id: %d status:%d.\n", client_id, status); + + // 发送读请求以读取写入的数据 + ssapc_read_req(0, conn_id, write_result->handle, write_result->type); +} + +/** + * @brief 读确认回调函数 + * + * 该函数在读操作完成时被调用。它处理读操作的结果,并打印读取的数据。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param read_data 指向读操作结果结构体的指针 + * @param status 读操作状态码。0表示成功,非0表示失败。 + */ +void sle_sample_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *read_data, + errcode_t status) +{ + // 打印读操作确认信息,包括客户端ID、连接ID和状态码 + test_suite_uart_sendf("[ssap client] read cfm cbk client id: %d conn id: %d status: %d\n", + client_id, conn_id, status); + + // 打印读操作的句柄、类型和数据长度 + test_suite_uart_sendf("[ssap client] read cfm cbk handle: %d, type: %d , len: %d\n", + read_data->handle, read_data->type, read_data->data_len); + + // 打印读取的数据 + for (uint16_t idx = 0; idx < read_data->data_len; idx++) + { + test_suite_uart_sendf("[ssap client] read cfm cbk[%d] 0x%02x\r\n", idx, read_data->data[idx]); + } +} + +char key_code_switch(char key_code) +{ + switch (key_code) + { + case 5: + key_code = 48; + break; + case 7: + key_code = 32; + break; + case 82: + key_code = 103; + break; + case 80: + key_code = 105; + break; + case 40: + key_code = 28; + break; + case 79: + key_code = 106; + break; + case 81: + key_code = 108; + break; + case 41: + key_code = 1; + break; + case 101: + key_code = 127; + break; + case 74: + key_code = 102; + break; + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: + case 42: + key_code = key_code - 28; + break; + default: + break; + } + return key_code; +} + +/** + * @brief 将键码和键值发送到ROS2 + * + * 该函数将键码和键值通过消息队列发送到ROS2。它首先检查键值是否为1,如果是则直接返回。 + * 然后,它创建或打开一个消息队列,并设置消息队列的属性。如果消息队列已满,则接收并删除 + * 一个最旧的消息来腾出空间。最后,它将键码发送到消息队列,并关闭消息队列。 + * + * @param keycode 键码 + * @param keyvalue 键值 + */ +void send_to_ros2(char keycode, char keyvalue) +{ + char recbuffer[2] = {0}; // 定义接收缓冲区 + char sendbuffer[2] = {0}; // 定义发送缓冲区 + mqd_t nearlink_mq = {0}; // 定义消息队列描述符 + unsigned int nearlink_mq_prio = 10; // 定义消息队列优先级 + struct mq_attr nearlink_mq_attr; // 定义消息队列属性结构体 + + // 设置消息队列属性 + nearlink_mq_attr.mq_flags = O_NONBLOCK; // 设置非阻塞标志 + nearlink_mq_attr.mq_maxmsg = 10; // 设置最大消息数 + nearlink_mq_attr.mq_msgsize = 1; // 设置消息大小 + nearlink_mq_attr.mq_curmsgs = 0; // 设置当前消息数 + + // 如果键值为1,直接返回 + if (keyvalue == 1) + { + return; + } + sendbuffer[0] = keycode; // 将键码存入发送缓冲区 + + // 创建或打开消息队列 + nearlink_mq = mq_open("/nearlink_mq", O_CREAT | O_WRONLY, 0644, &nearlink_mq_attr); + if (nearlink_mq == (mqd_t)-1) + { + // 打印消息队列打开失败的错误信息 + printf("%s mq_open nearlink_mq failed,%s\r\n", SLE_RCU_DONGLE_LOG, strerror(errno)); + return; + } + + // 设置消息队列属性 + if (mq_setattr(nearlink_mq, &nearlink_mq_attr, NULL) == -1) + { + // 打印设置消息队列属性失败的错误信息 + printf("%s mq_setattr nearlink_mq failed,%s\r\n", SLE_RCU_DONGLE_LOG, strerror(errno)); + mq_close(nearlink_mq); // 关闭消息队列 + return; + } + + // 获取消息队列属性 + struct mq_attr attr; + if (mq_getattr(nearlink_mq, &attr) == -1) + { + // 打印获取消息队列属性失败的错误信息 + printf("%s mq_getattr nearlink_mq failed,%s\r\n", SLE_RCU_DONGLE_LOG, strerror(errno)); + mq_close(nearlink_mq); // 关闭消息队列 + return; + } + // 打印消息队列属性信息 + printf("%s nearlink_mq attr mq_curmsgs %ld mq_maxmsg %ld \r\n", SLE_RCU_DONGLE_LOG, attr.mq_curmsgs, attr.mq_maxmsg); + + // 如果消息队列已满,接收并删除一个最旧的消息来腾出空间 + if (attr.mq_curmsgs == attr.mq_maxmsg) + { + if (mq_receive(nearlink_mq, recbuffer, nearlink_mq_attr.mq_msgsize, NULL) < 0) + { + // 打印接收消息失败的错误信息 + printf("%s mq_receive nearlink_mq failed,%s\r\n", SLE_RCU_DONGLE_LOG, strerror(errno)); + mq_close(nearlink_mq); // 关闭消息队列 + return; + } + // 打印删除最旧消息的信息 + printf("%s old message dequeued to make space\r\n", SLE_RCU_DONGLE_LOG); + } + + // 发送键码到消息队列 + if (mq_send(nearlink_mq, sendbuffer, nearlink_mq_attr.mq_msgsize, 0) == -1) + { + // 打印发送消息失败的错误信息 + printf("%s mq_send nearlink_mq failed,%s\r\n", SLE_RCU_DONGLE_LOG, strerror(errno)); + mq_close(nearlink_mq); // 关闭消息队列 + return; + } + + // 关闭消息队列 + mq_close(nearlink_mq); +} + +/** + * @brief SLE RCU通知回调函数 + * + * 该函数在接收到SLE RCU通知时被调用。它处理接收到的数据,并根据数据内容 + * 进行相应的操作。如果接收到的是键盘报告数据,则解析并打印键盘报告信息, + * 并将键码和键值发送到ROS2。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param data 指向接收到的数据结构体的指针 + * @param status 接收状态码。0表示成功,非0表示失败。 + */ +static void sle_rcu_notification_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, errcode_t status) +{ + char data_to_send[30]; // 定义要发送的数据缓冲区 + int key_code = 0; // 键码 + int key_value = 0; // 键值 + + // 检查接收到的数据是否为空或数据长度为0 + if (data == NULL || data->data_len == 0 || data->data == NULL) + { + // 如果数据为空或数据长度为0,打印错误信息并返回 + printf("%s sle_rcu_notification_cb fail, recv data is null!\r\n", SLE_RCU_DONGLE_LOG); + return; + } + + // 打印接收成功的信息 + printf("%s sle_rcu_notification_cb ok\n", SLE_RCU_DONGLE_LOG); + + // 检查接收到的数据长度是否为键盘报告长度 + if (data->data_len == USB_RCU_KEYBOARD_REPORTER_LEN) + { + // 定义接收键盘报告的指针 + usb_hid_rcu_keyboard_report_t *recv_usb_hid_rcu_keyboard = NULL; + printf("%s sle rcu recive notification\r\n", SLE_RCU_DONGLE_LOG); + + // 将接收到的数据转换为键盘报告结构体 + recv_usb_hid_rcu_keyboard = (usb_hid_rcu_keyboard_report_t *)data->data; + + // 打印键盘报告的各个字段 + printf("%s recv_usb_hid_rcu_keyboard.kind = [%d]\r\n", SLE_RCU_DONGLE_LOG, + recv_usb_hid_rcu_keyboard->kind); + printf("%s recv_usb_hid_rcu_keyboard.special_key = [%d]\r\n", SLE_RCU_DONGLE_LOG, + recv_usb_hid_rcu_keyboard->special_key); + printf("%s recv_usb_hid_rcu_keyboard.reversed = [%d]\r\n", SLE_RCU_DONGLE_LOG, + recv_usb_hid_rcu_keyboard->reserve); + printf("%s recv_usb_hid_rcu_keyboard.key = ", SLE_RCU_DONGLE_LOG); + + // 打印键盘报告中的按键值 + for (uint8_t i = 0; i < USB_HID_RCU_MAX_KEY_LENTH; i++) + { + printf("0x%02x ", recv_usb_hid_rcu_keyboard->key[i]); + } + + // 根据键盘报告中的按键值设置键码和键值 + if (recv_usb_hid_rcu_keyboard->key[0] != 0) + { + key_code = key_code_switch(recv_usb_hid_rcu_keyboard->key[0]); + key_value = 1; + } + else + { + key_value = 0; + } + printf("\r\n"); + + // 清空数据缓冲区并格式化要发送的数据 + memset(data_to_send, 0, sizeof(char) * 30); + snprintf(data_to_send, 30, "code:%d,value:%d\r\n", key_code, key_value); + printf("code:0x%x,value:%d\r\n", key_code, key_value); + + // 将键码和键值发送到ROS2 + send_to_ros2(key_code, key_value); + sleep(1); + send_to_ros2(0x67, 0); + } + else + { + // 如果接收到的数据不是键盘数据,打印提示信息 + printf("[%s]this is not keyboard data\r\n", __func__); + } +} + +/** + * @brief SLE RCU指示回调函数 + * + * 该函数在接收到SLE RCU指示时被调用。它处理接收到的数据,并根据数据内容 + * 进行相应的操作。如果接收到的是键盘报告数据,则解析并打印键盘报告信息。 + * + * @param client_id 客户端ID + * @param conn_id 连接ID + * @param data 指向接收到的数据结构体的指针 + * @param status 接收状态码。0表示成功,非0表示失败。 + */ + +static void sle_rcu_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, errcode_t status) +{ + // 检查接收到的数据是否为空或数据长度为0 + if (data == NULL || data->data_len == 0 || data->data == NULL) + { + // 如果数据为空或数据长度为0,打印错误信息并返回 + printf("%s sle_rcu_notification_cb fail, recv data is null!\r\n", SLE_RCU_DONGLE_LOG); + return; + } + + // 检查接收到的数据长度是否为键盘报告长度 + if (data->data_len == USB_RCU_KEYBOARD_REPORTER_LEN) + { + // 定义接收键盘报告的指针 + usb_hid_rcu_keyboard_report_t *recv_usb_hid_rcu_keyboard = NULL; + printf("%s sle rcu recive notification\r\n", SLE_RCU_DONGLE_LOG); + + // 将接收到的数据转换为键盘报告结构体 + recv_usb_hid_rcu_keyboard = (usb_hid_rcu_keyboard_report_t *)data->data; + + // 打印键盘报告的各个字段 + printf("%s recv_usb_hid_rcu_keyboard.kind = [%d]\r\n", SLE_RCU_DONGLE_LOG, + recv_usb_hid_rcu_keyboard->kind); + printf("%s recv_usb_hid_rcu_keyboard.special_key = [%d]\r\n", SLE_RCU_DONGLE_LOG, + recv_usb_hid_rcu_keyboard->special_key); + printf("%s recv_usb_hid_rcu_keyboard.reversed = [%d]\r\n", SLE_RCU_DONGLE_LOG, + recv_usb_hid_rcu_keyboard->reserve); + printf("%s recv_usb_hid_rcu_keyboard.key = ", SLE_RCU_DONGLE_LOG); + + // 打印键盘报告中的按键值 + for (uint8_t i = 0; i < USB_HID_RCU_MAX_KEY_LENTH; i++) + { + printf("0x%02x ", recv_usb_hid_rcu_keyboard->key[i]); + } + printf("\r\n"); + } + else + { + // 如果接收到的数据不是键盘数据,打印提示信息 + printf("[%s]this is not keyboard data\r\n", __func__); + } +} + +/** + * @brief 注册SSAP客户端回调函数 + * + * 该函数用于将SSAP客户端相关的回调函数注册到全局回调结构体 `g_ssapc_cbk` 中。 + * 这些回调函数包括交换信息回调、查找结构回调、查找结构完成回调、查找属性回调、 + * 通知回调、指示回调、写确认回调和读确认回调。 + * + * @param notification_cb 通知回调函数 + * @param indication_cb 指示回调函数 + */ +void sle_sample_ssapc_cbk_register(ssapc_notification_callback notification_cb, + ssapc_notification_callback indication_cb) +{ + // 注册交换信息回调函数 + g_ssapc_cbk.exchange_info_cb = sle_sample_exchange_info_cbk; + + // 注册查找结构回调函数 + g_ssapc_cbk.find_structure_cb = sle_sample_find_structure_cbk; + + // 注册查找结构完成回调函数 + g_ssapc_cbk.find_structure_cmp_cb = sle_sample_find_structure_cmp_cbk; + + // 注册查找属性回调函数 + g_ssapc_cbk.ssapc_find_property_cbk = sle_sample_find_property_cbk; + + // 注册通知回调函数 + g_ssapc_cbk.notification_cb = notification_cb; + + // 注册指示回调函数 + g_ssapc_cbk.indication_cb = indication_cb; + + // 注册写确认回调函数 + g_ssapc_cbk.write_cfm_cb = sle_sample_write_cfm_cbk; + + // 注册读确认回调函数 + g_ssapc_cbk.read_cfm_cb = sle_sample_read_cfm_cbk; +} + +/** + * @brief 初始化SLE客户端 + * + * 该函数用于初始化SLE客户端,注册各种回调函数,并启用SLE功能。 + * 它依次调用多个注册函数,将回调函数与相应的事件关联起来。 + */ +void sle_client_init() +{ + // 注册样本查找回调函数 + sle_sample_seek_cbk_register(); + + // 注册样本连接回调函数 + sle_sample_connect_cbk_register(); + + // 注册SSAP客户端回调函数,包括通知和指示回调 + sle_sample_ssapc_cbk_register(sle_rcu_notification_cb, sle_rcu_indication_cb); + + // 注册查找回调函数 + sle_announce_seek_register_callbacks(&g_seek_cbk); + + // 注册连接回调函数 + sle_connection_register_callbacks(&g_connect_cbk); + + // 注册SSAP客户端回调函数 + ssapc_register_callbacks(&g_ssapc_cbk); + + // 启用SLE功能 + enable_sle(); +} + +/** + * @brief 启动SLE扫描 + * + * 该函数用于启动SLE扫描过程。它首先设置扫描参数,然后开始扫描。 + * 扫描参数包括地址类型、重复过滤、扫描过滤策略、扫描物理层、扫描类型、扫描间隔和扫描窗口。 + */ +void sle_start_scan() +{ + // 定义并初始化扫描参数结构体 + sle_seek_param_t param = {0}; + + // 设置扫描参数 + param.own_addr_type = 0; // 本地地址类型 + param.filter_duplicates = 0; // 是否过滤重复设备 + param.seek_filter_policy = 0; // 扫描过滤策略 + param.seek_phys = 1; // 扫描物理层 + param.seek_type[0] = 0; // 扫描类型 + param.seek_interval[0] = SLE_SEEK_INTERVAL_DEFAULT; // 扫描间隔 + param.seek_window[0] = SLE_SEEK_WINDOW_DEFAULT; // 扫描窗口 + + // 设置扫描参数 + sle_set_seek_param(¶m); + + // 开始扫描 + sle_start_seek(); +} +/** + * @brief SIGINT信号处理函数 + * + * 当程序接收到SIGINT信号(如用户按下Ctrl+C)时,该函数会被调用。 + * 该函数用于处理程序的清理工作,例如断开与远程设备的连接。 + * + * @param sig 接收到的信号编号 + */ +void sigintHandler(int sig) +{ + // 避免未使用参数警告 + sig = sig; + + // 关闭与远程设备的连接 + errcode_t ret = sle_disconnect_remote_device(&g_remote_addr); + + // 打印断开连接的结果 + printf("*****sle disconnect remote device(ret %u) ****\n\n", ret); +} + +int main(int argc, char *argv[]) +{ + int ret; + ret = uapi_gle_init(); + if (ret != 0) + { + printf("init fail.\n\n"); + goto mainend; + } + // 创建信号处理函数 + signal(SIGINT, sigintHandler); + // start业务功 + sle_client_init(); + // end业务功能(进入无限循环,保持程序运行) + while (1) + { + send_to_ros2(0x67, 1); + printf("点击小车前进指令\r\n"); + sleep(1); + send_to_ros2(0x67, 0); + printf("释放小车前进指令\r\n"); + sleep(5); + } +mainend: + printf("main start. 00\n\n"); + printf("main end.\n\n"); + return ret; +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/out/target.bin b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/out/target.bin new file mode 100644 index 0000000000000000000000000000000000000000..5518375fe54ac3d4ee2bf11be45a4ff8d9e5f686 Binary files /dev/null and b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/out/target.bin differ diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/adc_demo.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/adc_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..75a32c38b75ff70e88a661e97b17709f8c58613e --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/adc_demo.c @@ -0,0 +1,28 @@ +#include "adc_demo.h" +#include "main.h" +#include "debug.h" + +/** + * @brief ADC single channel sample without DMA and interrupt. + * @param None. + * @retval None. + */ +void ADC_SingleTrigger(void) +{ + DBG_PRINTF("ADC_SingleTrigger begin\r\n"); + + HAL_ADC_SoftTrigSample(&g_adc0, ADC_SOC_NUM0); /* Software trigger ADC sampling */ + + BASE_FUNC_DELAY_MS(10); /* delay 10 ms */ + + if (HAL_ADC_CheckSocFinish(&g_adc0, ADC_SOC_NUM0) == BASE_STATUS_ERROR) { + DBG_PRINTF("ADC did not complete sampling and conversion\r\n"); + return; + } + + unsigned int ret = HAL_ADC_GetConvResult(&g_adc0, ADC_SOC_NUM0); /* Software trigger ADC sampling */ + DBG_PRINTF("Sampling completed, result: %d\r\n", ret); + float voltage = (float)ret / (float)4096 * 3.3; /* 4096 and 3.3 are for Sample Value Conversion */ + DBG_PRINTF("voltage: %f\r\n", voltage); + return; +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/adc_demo.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/adc_demo.h new file mode 100644 index 0000000000000000000000000000000000000000..e485616c19b85df42e0444e9a17722cfc12c653b --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/adc_demo.h @@ -0,0 +1,7 @@ +#ifndef ADC_DEMO_H +#define ADC_DEMO_H + + +void ADC_SingleTrigger(void); + +#endif \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/beep.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/beep.c new file mode 100644 index 0000000000000000000000000000000000000000..c0965f8c0b15a30d9f1ac8ef773c472ff03f8f4b --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/beep.c @@ -0,0 +1,22 @@ +#include "beep.h" +#include "main.h" +#include "debug.h" + +/** + * @brief GPT run and modify period and duty during running. + * @param None. + * @retval None. + */ +void GPT_SampleMain(void) +{ + DBG_PRINTF("GPT Continued Run begin\r\n"); + HAL_GPT_Start(&g_gpt3); + // BASE_FUNC_DelaySeconds(10); /* Delay 10 seconds */ + // DBG_PRINTF("Change the duty to 50%%\r\n"); + + // HAL_GPT_GetConfig(&g_gpt3); + // g_gpt3.period = 59999; /* 59999 is the number of GPT counting cycles. */ + // g_gpt3.refA0.refdot = 20000; /* 20000 is the value of PWM reference point A. */ + // g_gpt3.refB0.refdot = 50000; /* 50000 is the value of PWM reference point A. */ + // HAL_GPT_Config(&g_gpt3); +} diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/beep.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/beep.h new file mode 100644 index 0000000000000000000000000000000000000000..a69aef4b29d46ae4e528dd9a6de7b0f434440908 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/beep.h @@ -0,0 +1,7 @@ +#ifndef BEEP_H +#define BEEP_H + + +void GPT_SampleMain(void); + +#endif diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/button.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/button.c new file mode 100644 index 0000000000000000000000000000000000000000..46b6fa51f37b4fc646b9acffe27282bc53b69da7 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/button.c @@ -0,0 +1,124 @@ +#include "debug.h" +#include "gpio.h" +#include "main.h" +#include "button.h" +#include "user_motor_control.h" + +#define PREVENT_SWIPE_SCREEN_TIME 50 +#define CYCLE_INTERVAL_TIME 500 + +int g_button1State = 0; +int g_button2State = 0; + +//按键滤波计数器 +int g_button1_count = 0; +int g_button2_count = 0; + +unsigned int g_testIndex = 2; +unsigned int g_testAngles = ADJUST_PLUS_90; + +static unsigned int g_angleDate[][2] = { + {1, 76}, + {1, 151}, + {1, 226}, + {1, 301}, + {1, 376} +}; + +void AngleAdjustment(unsigned int index, unsigned int angles) +{ + if (angles > ADJUST_PLUS_90) { + return; + } + + GPT_ReferCfg refer; + refer.refA0.refAction = GPT_ACTION_OUTPUT_HIGH; + refer.refB0.refAction = GPT_ACTION_OUTPUT_LOW; + refer.refA0.refdot = g_angleDate[angles][0]; + refer.refA0.refdot = g_angleDate[angles][1]; + switch (index) { + case 0: + HAL_GPT_SetReferCounterAndAction(&g_gpt0, &refer); + break; + case 1: + HAL_GPT_SetReferCounterAndAction(&g_gpt1, &refer); + break; + case 2: + HAL_GPT_SetReferCounterAndAction(&g_gpt2, &refer); + break; + default: + break; + } +} + +/** + * @brief GPIO register interrupt callback function. + * @param param Value of @ref GPIO_Handle. + * @retval None + */ + + +void GPIO1_0_CallbackFunc(void *param) +{ + BASE_FUNC_UNUSED(param); + if((g_button1State == 0) && (g_button1_count == 0)) + { + //g_button1State = !g_button1State; + g_button1State = 1; + g_button1_count = 1; //在10ms定时中断里处理按键滤波业务逻辑 + } +} + +void GPIO1_1_CallbackFunc(void *param) +{ + BASE_FUNC_UNUSED(param); + if((g_button2State == 0) && (g_button2_count == 0)) + { + //g_button2State = !g_button2State; + g_button2State = 1; + g_button2_count = 1; //在10ms定时中断里处理按键滤波业务逻辑 + } +} + +void InitButtonFunction(void) +{ + HAL_GPT_Start(&g_gpt0); + HAL_GPT_Start(&g_gpt1); + HAL_GPT_Start(&g_gpt2); +} + + +BASE_StatusType ButtonPrintSample(void) +{ + while (1) { + BASE_FUNC_DELAY_MS(1); + if (g_button1State) { + g_button1State = !g_button1State; + DBG_PRINTF("g_button1State Evnet\r\n"); + } + + if (g_button2State) { + g_button2State = !g_button2State; + DBG_PRINTF("g_button2State Evnet\r\n"); + } + } + return BASE_STATUS_OK; +} + +BASE_StatusType GPIO_KeySample(void) +{ + HAL_GPT_Start(&g_gpt0); + HAL_GPT_Start(&g_gpt1); + HAL_GPT_Start(&g_gpt2); + while (1) { + BASE_FUNC_DELAY_MS(100); + if (g_button1State) { + g_button1State = !g_button1State; + startMotor(); + MotorForwardRotation(); + BASE_FUNC_DELAY_MS(3000); + stopMotor(); + } + } + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/button.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/button.h new file mode 100644 index 0000000000000000000000000000000000000000..1cab4a32df33d5a8297d733b9e7edc9cea3b2382 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/button.h @@ -0,0 +1,16 @@ +#ifndef BUTTON_H +#define BUTTON_H + +#define ADJUST_MINUS_90 0 +#define ADJUST_MINUS_45 1 +#define ADJUST_MINUS_0 2 +#define ADJUST_PLUS_45 3 +#define ADJUST_PLUS_90 4 + +void AngleAdjustment(unsigned int index, unsigned int angles); +void AngleAdjuseProcess(void); +void InitButtonFunction(void); +BASE_StatusType GPIO_KeySample(void); +BASE_StatusType ButtonPrintSample(void); + +#endif /* GPIO_KEY_SAMPLE_H */ \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/can_demo.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/can_demo.c new file mode 100644 index 0000000000000000000000000000000000000000..054cd47896129b01e33792101f64c6533ee6cc74 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/can_demo.c @@ -0,0 +1,123 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * @file sample_can_send_receive.c + * @author MCU Driver Team + * @brief can sample module. + * @details This file provides sample code for users to help use + * the filtering function of the CAN. + */ +#include "can_demo.h" +#include "main.h" +#include "debug.h" + +/** + * @brief User-defined read completion callback function. + * @param UART_Handle UART handle. + * @retval None. + */ +void CAN_ReadFinish(void *handle) +{ + CAN_Handle *canHandle = (CAN_Handle *)handle; + DBG_PRINTF("CAN Read Finish\r\n"); + DBG_PRINTF("data[0]: %d \r\n", canHandle->rxFrame->frame[0]); /* frame[0] data */ + DBG_PRINTF("data[1]: %d \r\n", canHandle->rxFrame->frame[1]); /* frame[1] data */ + DBG_PRINTF("data[2]: %d \r\n", canHandle->rxFrame->frame[2]); /* frame[2] data */ + DBG_PRINTF("data[3]: %d \r\n", canHandle->rxFrame->frame[3]); /* frame[3] data */ + DBG_PRINTF("data[4]: %d \r\n", canHandle->rxFrame->frame[4]); /* frame[4] data */ + DBG_PRINTF("data[5]: %d \r\n", canHandle->rxFrame->frame[5]); /* frame[5] data */ + DBG_PRINTF("data[6]: %d \r\n", canHandle->rxFrame->frame[6]); /* frame[6] data */ + DBG_PRINTF("data[7]: %d \r\n", canHandle->rxFrame->frame[7]); /* frame[7] data */ + DBG_PRINTF("ID: 0x%x \r\n", canHandle->rxFrame->CANId); + DBG_PRINTF("len: %d \r\n", canHandle->rxFrame->dataLength); + DBG_PRINTF("type: %d \r\n", canHandle->rxFrame->type); + BASE_FUNC_UNUSED(canHandle); + return; +} + +/** + * @brief User-defined write completion callback function. + * @param CAN_Handle CAN handle. + * @retval None. + */ +void CAN_WriteFinish(void *handle) +{ + BASE_FUNC_UNUSED(handle); + DBG_PRINTF("CAN Write Finish\r\n"); + return; +} +/** + * Sample Note: + * baund rate : 100k Bit/s + * To-be-received data frame : Extended Data Frame, ID = 0x1314 + * + * There are two filtering methods: + * 1. Receive only the specified ID: + * rxFilter.receiveType = CAN_FilterFrame_EXT_DATA; + * rxFilter.filterID = 0x1314; + * rxFilter.filterMask = 0xFFFFFFFF; + * + * 2. Use mask to receive: + * rxFilter.receiveType = CAN_FilterFrame_EXT_DATA; + * rxFilter.filterID = 0x131_; + * rxFilter.filterMask = 0xFFFFFFF0; + * + * rxFilter.receiveType = CAN_FilterFrame_EXT_DATA; + * rxFilter.filterID = 0x13_4; + * rxFilter.filterMask = 0xFFFFFF0F; + * + * rxFilter.receiveType = CAN_FilterFrame_EXT_DATA; + * rxFilter.filterID = 0x1_14; + * rxFilter.filterMask = 0xFFFFF0FF; + * + * rxFilter.receiveType = CAN_FilterFrame_EXT_DATA; + * rxFilter.filterID = 0x_314; + * rxFilter.filterMask = 0xFFFF0FFF; + * + * The value of the ID mask bit, which is not used for filtering. + * + * Do not filter by ID: + * rxFilter.filterMask = 0x00000000; + * + * Both standard frames and extended frames can be received: + * rxFilter.receiveType = CAN_FilterFrame_STD_EXT_DATA; + */ +/** + * @brief CAN sample code for configuring the filtering function and can send and receive packets. + * @param None. + * @retval None. + */ +CANFrame g_sendFrame; +CANFrame g_receiveFrame; +int CAN_ReceiveFilter(void) +{ + SystemInit(); + DBG_PRINTF("CAN Init \r\n"); + CAN_FilterConfigure rxFilter; + g_can.rxFrame = &g_receiveFrame; /* Address for storing received frame data */ + DBG_PRINTF("CAN interrupt register \r\n"); + g_sendFrame.type = CAN_TYPEFRAME_EXT_DATA; /* Transmit extended data frame */ + g_sendFrame.CANId = 0x1314; /* 0x1314 is ID of transmitted data frames */ + g_sendFrame.dataLength = 1; /* 1 is length of the sent frame */ + g_sendFrame.frame[0] = '0'; + HAL_CAN_Write(&g_can, &g_sendFrame); + rxFilter.receiveType = CAN_FILTERFRAME_EXT_DATA; + rxFilter.filterID = 0x1014; /* 0x1014 and 0xFFFFF0FF constitute filtering rules */ + rxFilter.filterMask = 0xFFFFF0FF; /* 0xFFFFF0FF is filter ID mask */ + HAL_CAN_ReadIT(&g_can, &g_receiveFrame, &rxFilter); + return 0; +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/can_demo.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/can_demo.h new file mode 100644 index 0000000000000000000000000000000000000000..b7e0015f6f764a721ab85d4fd8bfc3ad3cc3e085 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/can_demo.h @@ -0,0 +1,8 @@ +#ifndef CAN_DEMO_H +#define CAN_DEMO_H + +int CAN_ReceiveFilter(void); +void CAN_ReadFinish(void *handle); +void CAN_WriteFinish(void *handle); + +#endif /* GPIO_KEY_SAMPLE_H */ \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/encoder.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/encoder.c new file mode 100644 index 0000000000000000000000000000000000000000..2ff7eaca28c1cabd80b73f34e616dc7965487c53 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/encoder.c @@ -0,0 +1,129 @@ +#include "qdm.h" +#include "debug.h" +#include "encoder.h" +#include "main.h" +#include "eulercar_control.h" + + +//系统10ms中断计数器 +extern unsigned int g_TimerInterruptCount; + +/** + * @brief QDM sample use M method + * @param none. + * @retval none. + */ + +//用于pid算法的速度,即MOTOR_PID_CONTROL_PERIOD周期内的速度 +Gear_Motor_handle pidRightMotor; +Gear_Motor_handle pidLeftMotor; + +//用于ODOM里程计的平均速度,即EULER_CAR_DATA_SEND_PERIOD周期内的速度 +Gear_Motor_handle aveRightMotor; +Gear_Motor_handle aveLeftMotor; + +//编码器读取周期内最大差值 +unsigned int g_maxEncodePidDeltaValue; +unsigned int g_maxEncodeAveDeltaValue; + +void InitGearMotor(void) +{ + pidRightMotor.motorSide = MOTOR_RIGHT; + pidRightMotor.curNumber = 0; /* 当前计数器 */ + pidRightMotor.lastNumber = 0; /* 上一次计数器 */ + pidRightMotor.speedRps = 0; /* 电机转速,单位每秒多少圈 */ + pidRightMotor.speed = 0; /* 电机速度,单位mm/s,由转速和轮胎直径计算 */ + pidRightMotor.calPeriod = MOTOR_PID_CONTROL_PERIOD; + + pidLeftMotor.motorSide = MOTOR_LEFT; + pidLeftMotor.curNumber = 0; /* 当前计数器 */ + pidLeftMotor.lastNumber = 0; /* 上一次计数器 */ + pidLeftMotor.speedRps = 0; /* 电机转速,单位每秒多少圈 */ + pidLeftMotor.speed = 0; /* 电机速度,单位mm/s,由转速和轮胎直径计算 */ + pidLeftMotor.calPeriod = MOTOR_PID_CONTROL_PERIOD; + + + aveRightMotor.motorSide = MOTOR_RIGHT; + aveRightMotor.curNumber = 0; /* 当前计数器 */ + aveRightMotor.lastNumber = 0; /* 上一次计数器 */ + aveRightMotor.speedRps = 0; /* 电机转速,单位每秒多少圈 */ + aveRightMotor.speed = 0; /* 电机速度,单位mm/s,由转速和轮胎直径计算 */ + aveRightMotor.calPeriod = EULER_CAR_DATA_SEND_PERIOD; + + aveLeftMotor.motorSide = MOTOR_LEFT; + aveLeftMotor.curNumber = 0; /* 当前计数器 */ + aveLeftMotor.lastNumber = 0; /* 上一次计数器 */ + aveLeftMotor.speedRps = 0; /* 电机转速,单位每秒多少圈 */ + aveLeftMotor.speed = 0; /* 电机速度,单位mm/s,由转速和轮胎直径计算 */ + aveLeftMotor.calPeriod = EULER_CAR_DATA_SEND_PERIOD; + + + //编码器在一个PID周期内最大差值,电机转速的2倍,主要用于容错处理 + g_maxEncodePidDeltaValue = (int)(g_motorMaxSpeed / MOTOR_TIRE_DIAMETER / PI * g_motorLineNum / (1000.0/MOTOR_PID_CONTROL_PERIOD) * 2.0); + //编码器在一个底盘数据上报周期内最大差值,电机转速的2倍,主要用于容错处理 + g_maxEncodeAveDeltaValue = (int)(g_motorMaxSpeed / MOTOR_TIRE_DIAMETER / PI * g_motorLineNum / (1000.0/EULER_CAR_DATA_SEND_PERIOD) * 2.0); + + //DBG_PRINTF("g_maxEncodeDeltaValue = %d\r\n", g_maxEncodeDeltaValue); +} + + + +void QDM_CalMotorSpeed(Gear_Motor_handle *pMotor) +{ + unsigned int qdm_cnt, qdm_dir; + unsigned int deltaValue; + if(pMotor->motorSide == MOTOR_RIGHT ) + HAL_QDM_ReadPosCountAndDir(&g_qdm0, &qdm_cnt, &qdm_dir); + else + HAL_QDM_ReadPosCountAndDir(&g_qdm1, &qdm_cnt, &qdm_dir); + + /* 计算车轮速度 */ + pMotor->curNumber = qdm_cnt; + if(qdm_dir == 1){ //电机正转 + if(pMotor->curNumber >= pMotor->lastNumber) { + deltaValue = pMotor->curNumber - pMotor->lastNumber; + }else{ //过零点后的计算编码器差值 + deltaValue = (pMotor->curNumber +g_motorLineNum) - pMotor->lastNumber; + } + }else{ //电机反转 + if(pMotor->curNumber <= pMotor->lastNumber) { + deltaValue = pMotor->lastNumber - pMotor->curNumber; + }else{ //过零点后的计算编码器差值 + deltaValue = (pMotor->lastNumber + g_motorLineNum) - pMotor->curNumber ; + } + } + + /* 电机正反转切换时,会出现编码器差值计算错误,设置编码器差值为0 */ + if(pMotor->calPeriod == MOTOR_PID_CONTROL_PERIOD){ + if(deltaValue > g_maxEncodePidDeltaValue) { + DBG_PRINTF("===Motor Encode Error = %d, motor side:%d, calculate period %dms===\r\n", deltaValue,pMotor->motorSide,pMotor->calPeriod); + deltaValue = 0; + } + }else{ + if(deltaValue > g_maxEncodeAveDeltaValue) { + DBG_PRINTF("===Motor Encode Error = %d, motor side:%d, calculate period %dms===\r\n", deltaValue,pMotor->motorSide,pMotor->calPeriod); + deltaValue = 0; + } + } + + + /* 计算右轮电机每秒转速 */ + pMotor->speedRps = ((float)deltaValue * (1000.0 / (float)pMotor->calPeriod))/g_motorLineNum; + pMotor->speed = pMotor->speedRps * MOTOR_TIRE_DIAMETER * PI; + pMotor->lastNumber = pMotor->curNumber; + pMotor->deltaValue = deltaValue; + if(qdm_dir == 0){ //电机反转 + pMotor->speed = -pMotor->speed; + } + + /*每10ms打印一次编码器实际数值和计算出来的速度 + if(pMotor->motorSide == MOTOR_LEFT){ + if((g_TimerInterruptCount % 100) == 0) { + if((deltaValue != 0) ) { //编码器数值有变化才进行打印 + DBG_PRINTF("T:%d|qc:%d,d:%d,dr:%d,crs:%.02f,rs:%.01f\r\n", + g_TimerInterruptCount,qdm_cnt,pMotor->deltaValue,qdm_dir,pMotor->speedRps,pMotor->speed); + } + } + }*/ + +} diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/encoder.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/encoder.h new file mode 100644 index 0000000000000000000000000000000000000000..0ee1864fe38014b86825e0fcb41b893c24f32f45 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/encoder.h @@ -0,0 +1,26 @@ +#ifndef ENCODER_H +#define ENCODER_H + +#define PI 3.1415927 + +#define MOTOR_LEFT 0 +#define MOTOR_RIGHT 1 + +#define MOTOR_PID_CONTROL_PERIOD 10 //编码器读取周期,单位ms +#define EULER_CAR_DATA_SEND_PERIOD 200 //底盘数据上报上位机的周期,单位ms + +typedef struct _Gear_Motor_handle { + unsigned int motorSide; /* 当前是那个轮子*/ + unsigned int curNumber; /* 当前计数器 */ + unsigned int lastNumber; /* 上一次计数器 */ + float speedRps; /* 电机转速,单位每秒多少圈 */ + float speed; /* 电机速度,单位mm/s,由转速和轮胎直径计算 */ + unsigned int calPeriod; /* 轮速计算周期, 单位ms */ + unsigned int deltaValue; /* 编码器差值 */ +} Gear_Motor_handle; + + +void InitGearMotor(void); +void QDM_CalMotorSpeed(Gear_Motor_handle *pMotor); + +#endif \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/eulercar_control.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/eulercar_control.c new file mode 100644 index 0000000000000000000000000000000000000000..34198690430bda2dc83e3505ebe9d97d48b4c3b4 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/eulercar_control.c @@ -0,0 +1,457 @@ +#include +#include +#include +#include +#include +#include +#include +#include "user_motor_control.h" +#include "eulercar_control.h" +#include "uart.h" +#include "pid.h" +#include "button.h" +#include "encoder.h" + +unsigned char g_MotorState; //电机状态 + +EulerCarSendData g_SendData; //串口发送数据 +EulerCarRecvData g_ReceiveData; //串口接收数据 +static unsigned char g_ReceiveDataCount = 0; + +extern unsigned int g_pid_count; +extern PidEulerCar g_pidEulerCarRight; +extern PidEulerCar g_pidEulerCarLeft; +extern Gear_Motor_handle pidRightMotor; +extern Gear_Motor_handle pidLeftMotor; +extern Gear_Motor_handle aveRightMotor; +extern Gear_Motor_handle aveLeftMotor; + + +//按键状态 +extern int g_button1State; +extern int g_button2State; + +//按键滤波计数器 +extern int g_button1_count; +extern int g_button2_count; + +//通过按键调整PID参数的步进参数 +extern float g_KP_Step; +extern float g_KI_Step; +extern float g_KD_Step; + +/* 接收完成标志 */ +static volatile bool g_RxInterruptflag = true; +/* 发送完成标志 */ +static volatile bool g_TxInterruptFlag = true; + +/* 定时器中断计数器 */ +unsigned int g_TimerInterruptCount = 0; + +/* 上报数据给上位机计数器 */ +static unsigned int g_SendCount = 0; + +/* 上位机下发命令计数器 */ +static unsigned int g_RecvCount = 0; + +//小车三轴目标运动速度,单位:m/s +float Move_X, Move_Y, Move_Z; + +#define EULERCAR_WHEEL_TRACK 120.0 //EulerCar小车两个轮子之间的轮距,单位mm +float modelCalLeftSpeed = 0.0; //根据两轮差速小车模型计算出的左轮速度 +float modelCalRightSpeed = 0.0; //根据两轮差速小车模型计算出的右轮速度 + +#define IS_SUPPORT_PID 1 + +/* 串口发送的数据进行赋值 */ +static void data_transition(void) +{ + float A_Move_X,A_Move_Z; + + g_SendData.SensorStr.Frame_Header = FRAME_HEADER; //帧头 + g_SendData.SensorStr.Frame_Tail = FRAME_TAIL; //帧尾 + + //从各车轮当前速度求出三轴当前速度 + A_Move_X = (aveRightMotor.speed + aveLeftMotor.speed) / 2.0; //小车x轴速度,单位mm/s + A_Move_Z = (aveRightMotor.speed - aveLeftMotor.speed) / (EULERCAR_WHEEL_TRACK * 2.0) * 1000.0; //小车角速度, 单位mrad/s + + g_SendData.SensorStr.X_speed = (short)(round(A_Move_X)); //小车x轴速度,单位mm/s + g_SendData.SensorStr.Y_speed = 0; + g_SendData.SensorStr.Z_speed = (short)(round(A_Move_Z)); //小车角速度,单位mm/s + +/* + DBG_PRINTF("ActualeftSpeed:%.2fmm/s,ActualRightSpeed:%.2fmm/s,A_Move_X=%.2fmm/s,A_Move_Z=%.2fmrad/s\r\n", + aveLeftMotor.speed,aveRightMotor.speed,A_Move_X,A_Move_Z); +*/ + + //加速度计三轴加速度 + g_SendData.SensorStr.Accelerometer.X_data = 1; //加速度计Y轴转换到ROS坐标X轴 + g_SendData.SensorStr.Accelerometer.Y_data = 1; //加速度计X轴转换到ROS坐标Y轴 + g_SendData.SensorStr.Accelerometer.Z_data = 1; //加速度计Z轴转换到ROS坐标Z轴 + + //角速度计三轴角速度 + g_SendData.SensorStr.Gyroscope.X_data = 2; //角速度计Y轴转换到ROS坐标X轴 + g_SendData.SensorStr.Gyroscope.Y_data = 2; //角速度计X轴转换到ROS坐标Y轴 + if (g_MotorState == 0) + //如果电机控制位使能状态,那么正常发送Z轴角速度 + g_SendData.SensorStr.Gyroscope.Z_data = 1; + else + //如果机器人是静止的(电机控制位失能),那么发送的Z轴角速度为0 + g_SendData.SensorStr.Gyroscope.Z_data = 0; + + //电池电压(这里将浮点数放大一千倍传输,相应的在接收端在接收到数据后也会缩小一千倍) + g_SendData.SensorStr.Power_Voltage = 90; + + g_SendData.buffer[0] = g_SendData.SensorStr.Frame_Header; // 帧头 + g_SendData.buffer[1] = g_MotorState; // 小车软件失能标志位 + + //小车三轴速度,各轴都拆分为两个8位数据再发送 + g_SendData.buffer[2] = g_SendData.SensorStr.X_speed >> 8; + g_SendData.buffer[3] = g_SendData.SensorStr.X_speed; + g_SendData.buffer[4] = g_SendData.SensorStr.Y_speed >> 8; + g_SendData.buffer[5] = g_SendData.SensorStr.Y_speed; + g_SendData.buffer[6] = g_SendData.SensorStr.Z_speed >> 8; + g_SendData.buffer[7] = g_SendData.SensorStr.Z_speed; + + //IMU加速度计三轴加速度,各轴都拆分为两个8位数据再发送 + g_SendData.buffer[8] = g_SendData.SensorStr.Accelerometer.X_data >> 8; + g_SendData.buffer[9] = g_SendData.SensorStr.Accelerometer.X_data; + g_SendData.buffer[10] = g_SendData.SensorStr.Accelerometer.Y_data >> 8; + g_SendData.buffer[11] = g_SendData.SensorStr.Accelerometer.Y_data; + g_SendData.buffer[12] = g_SendData.SensorStr.Accelerometer.Z_data >> 8; + g_SendData.buffer[13] = g_SendData.SensorStr.Accelerometer.Z_data; + + //IMU角速度计三轴角速度,各轴都拆分为两个8位数据再发送 + g_SendData.buffer[14] = g_SendData.SensorStr.Gyroscope.X_data >> 8; + g_SendData.buffer[15] = g_SendData.SensorStr.Gyroscope.X_data; + g_SendData.buffer[16] = g_SendData.SensorStr.Gyroscope.Y_data >> 8; + g_SendData.buffer[17] = g_SendData.SensorStr.Gyroscope.Y_data; + g_SendData.buffer[18] = g_SendData.SensorStr.Gyroscope.Z_data >> 8; + g_SendData.buffer[19] = g_SendData.SensorStr.Gyroscope.Z_data; + + //电池电压,拆分为两个8位数据发送 + g_SendData.buffer[20] = g_SendData.SensorStr.Power_Voltage >> 8; + g_SendData.buffer[21] = g_SendData.SensorStr.Power_Voltage; + + //数据校验位计算 + unsigned char check_sum = 0, k; + for (k = 0; k < 22; k++) { + check_sum = check_sum ^ g_SendData.buffer[k]; + } + g_SendData.buffer[22] = check_sum; + g_SendData.buffer[23] = g_SendData.SensorStr.Frame_Tail; //帧尾 +} + +void debug_send_buffer(unsigned int count) +{ + DBG_PRINTF("-----------------send_count=%u-----------------\r\n", count); + for (size_t i = 0; i < SEND_DATA_SIZE; i++) { + DBG_PRINTF("0x%x ", g_SendData.buffer[i]); + } + DBG_PRINTF(" \r\n"); +} + +void UART3WriteInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + //DBG_PRINTF("\r\nUART Write Finish\r\n"); + g_TxInterruptFlag = true; + return; +} + +void UART3ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + g_RxInterruptflag = 1; + return; +} + +// 定时器10ms产生一个中断 +void TIMER0_InterruptProcess(void *handle) +{ + BASE_StatusType ret; + /* USER CODE BEGIN TIMER0_InterruptProcess */ + TIMER_Handle *timerHandle = (TIMER_Handle *)handle; + BASE_FUNC_UNUSED(timerHandle); + g_TimerInterruptCount++; + + //按键滤波,500毫秒内算一次按键 + if(g_button1_count > 0) + { + g_button1_count ++; + if(g_button1_count > 50){ + g_button1_count = 0; + //DBG_PRINTF("Button1 Count Reset 0\r\n"); + } + } + + if(g_button2_count > 0) + { + g_button2_count ++; + if(g_button2_count > 50){ + g_button2_count = 0; + //DBG_PRINTF("Button2 Count Reset 0\r\n"); + } + } + + //按设置周期上报底盘数据 + if ((g_TimerInterruptCount % (EULER_CAR_DATA_SEND_PERIOD/10)) == 0) { + if (g_TxInterruptFlag) { + g_TxInterruptFlag = false; + //获取小车要发送的数据 + QDM_CalMotorSpeed(&aveLeftMotor); //计算左轮平均速度 + QDM_CalMotorSpeed(&aveRightMotor); //计算右轮平均速度 + data_transition(); + + ret = HAL_UART_WriteIT(&g_uart3, g_SendData.buffer, SEND_DATA_SIZE); + + if(ret == BASE_STATUS_OK) { + //DBG_PRINTF("Data send OK, send count = %d\r\n",g_SendCount); + }else{ + DBG_PRINTF("Data send error, code = %d\r\n",ret); + } + g_SendCount++; + } + } + + //每间隔10毫秒进行一次PID电机控制 + if (g_TimerInterruptCount % (MOTOR_PID_CONTROL_PERIOD / 10) == 0) { + //获取小车运行实际速度 + QDM_CalMotorSpeed(&pidLeftMotor); //计算一个PID周期内左轮速度 + QDM_CalMotorSpeed(&pidRightMotor); //计算一个PID周期内右轮速度 + + g_pidEulerCarLeft.ActualSpeed = pidLeftMotor.speed; + g_pidEulerCarRight.ActualSpeed = pidRightMotor.speed; + + //如果上位机下发速度大于0.1mm/s,则启动PID控制 + if ((fabsf(modelCalLeftSpeed) > 0.1) || (fabsf(modelCalRightSpeed) > 0.1)) { + Pid_Process(); + } + } + +} + +static float XYZ_transition(unsigned char High, unsigned char Low) +{ + short transition = ((High << 8) + Low); //将高8位和低8位整合成一个16位的short型数据 + //return transition / 1000 + (transition % 1000) * 0.001; //单位转换, mm/s->m/s + return (float)transition; +} + +int EulerCarSpeedCtrlLeft(float LeftSpeed) +{ + + unsigned int duty = (abs)((int)(LeftSpeed/g_motorMaxSpeed * 100)); + if (duty > 99) { + duty = 35; + } + //DBG_PRINTF("left wheel duty:%d\r\n", duty); + HAL_APT_SetPWMDutyByNumber(&g_apt1, duty); + + //如果电机小于0.1mm/s,则停止电机转动 + if (fabsf(LeftSpeed) < 0.1) { + HAL_APT_StopModule(RUN_APT1); + return 0; + } + if (LeftSpeed > 0) { + User_APTPwmARecovery(g_apt1.baseAddress); + User_APTForcePWMBOutputLow(g_apt1.baseAddress); + } else { + User_APTPwmBRecovery(g_apt1.baseAddress); + User_APTForcePWMAOutputLow(g_apt1.baseAddress); + } + HAL_APT_StartModule(RUN_APT1); + //DBG_PRINTF("Left wheel set duty:%d, run ok!\r\n",duty); + + return 0; +} + +int EulerCarSpeedCtrlRight(float rightSpeed) +{ + unsigned int duty = (abs)((int)(rightSpeed/g_motorMaxSpeed * 100)); + if (duty > 99) { + duty = 35; + } + HAL_APT_SetPWMDutyByNumber(&g_apt0, duty); + + //如果电机小于0.1mm/s,则停止电机转动 + if (fabsf(rightSpeed) < 0.1) { + HAL_APT_StopModule(RUN_APT0); + return 0; + } + if (rightSpeed > 0) { + User_APTPwmARecovery(g_apt0.baseAddress); + User_APTForcePWMBOutputLow(g_apt0.baseAddress); + } else { + User_APTPwmBRecovery(g_apt0.baseAddress); + User_APTForcePWMAOutputLow(g_apt0.baseAddress); + } + HAL_APT_StartModule(RUN_APT0); + //DBG_PRINTF("Right wheel set duty:%d, run ok!\r\n",duty); + + return 0; +} + +void Pid_Process(void) +{ + float pidTargetSpeed; + g_pid_count++; + + /* 通过PID算法计算右轮目标速度 */ + pidTargetSpeed = Pid_Ctrl(&g_pidEulerCarRight); + EulerCarSpeedCtrlRight(pidTargetSpeed); + + /* 通过PID算法计算左轮目标速度 */ + pidTargetSpeed = Pid_Ctrl(&g_pidEulerCarLeft); + EulerCarSpeedCtrlLeft(pidTargetSpeed); + + /* + //左右轮同时打印 + if((g_TimerInterruptCount % 10) == 0) { + DBG_PRINTF("N=%d,P=%.02f,I=%.02f,D=%.02f|L-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,lr:%.1f,in:%.1f,TS:%.1f,dt:%d|R-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,lr:%.1f,in:%.f,TS:%.1f,dt:%d\r\n", + g_pid_count,g_KP,g_KI,g_KD,g_pidEulerCarRight.SetSpeed,g_pidEulerCarRight.ActualSpeed, + g_pidEulerCarRight.err,g_pidEulerCarRight.err_next,g_pidEulerCarRight.err_last,g_pidEulerCarRight.IncSpeed, + g_pidEulerCarRight.TargetIncSpeed,g_pidEulerCarRight.duty, + g_pidEulerCarLeft.SetSpeed,g_pidEulerCarLeft.ActualSpeed, + g_pidEulerCarLeft.err,g_pidEulerCarLeft.err_next,g_pidEulerCarLeft.err_last,g_pidEulerCarLeft.IncSpeed, + g_pidEulerCarLeft.TargetIncSpeed,g_pidEulerCarLeft.duty); + } + + //打印电机运行情况 + if((g_TimerInterruptCount % 10) == 0) { + DBG_PRINTF("N=%d|L-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,in:%.1f,TS:%.1f,dt:%d|R-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,in:%.f,TS:%.1f,dt:%d\r\n", + g_pid_count,g_pidEulerCarRight.SetSpeed,g_pidEulerCarRight.ActualSpeed, + g_pidEulerCarRight.err,g_pidEulerCarRight.err_next,g_pidEulerCarRight.IncSpeed, + g_pidEulerCarRight.TargetIncSpeed,g_pidEulerCarRight.duty, + g_pidEulerCarLeft.SetSpeed,g_pidEulerCarLeft.ActualSpeed, + g_pidEulerCarLeft.err,g_pidEulerCarLeft.err_next,g_pidEulerCarLeft.IncSpeed, + g_pidEulerCarLeft.TargetIncSpeed,g_pidEulerCarLeft.duty); + } + + + //左右轮同时打印 + if((g_TimerInterruptCount % 10) == 0) { + DBG_PRINTF("N=%d,P=%.02f,I=%.02f,D=%.02f|L-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,lr:%.1f,in:%.1f,TS:%.1f,dt:%d|R-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,lr:%.1f,in:%.f,TS:%.1f,dt:%d\r\n", + g_pid_count,g_KP,g_KI,g_KD,g_pidEulerCarRight.SetSpeed,g_pidEulerCarRight.ActualSpeed, + g_pidEulerCarRight.err,g_pidEulerCarRight.err_next,g_pidEulerCarRight.err_last,g_pidEulerCarRight.IncSpeed, + g_pidEulerCarRight.TargetIncSpeed,g_pidEulerCarRight.duty, + g_pidEulerCarLeft.SetSpeed,g_pidEulerCarLeft.ActualSpeed, + g_pidEulerCarLeft.err,g_pidEulerCarLeft.err_next,g_pidEulerCarLeft.err_last,g_pidEulerCarLeft.IncSpeed, + g_pidEulerCarLeft.TargetIncSpeed,g_pidEulerCarLeft.duty); + } + + //只打印右轮 + if((g_TimerInterruptCount % 10) == 0) { + DBG_PRINTF("N=%d,P=%.02f,I=%.02f,D=%.02f|R-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,lr:%.1f,in:%.1f,TS:%.1f,dt:%d\r\n", + g_pid_count,g_KP,g_KI,g_KD,g_pidEulerCarRight.SetSpeed, + g_pidEulerCarRight.ActualSpeed,g_pidEulerCarRight.err,g_pidEulerCarRight.err_next,g_pidEulerCarRight.err_last, + g_pidEulerCarRight.IncSpeed,g_pidEulerCarRight.TargetIncSpeed,g_pidEulerCarRight.duty); + } + + //只打印左轮 + if((g_TimerInterruptCount % 100) == 0) { + DBG_PRINTF("N=%d,P=%.02f,I=%.02f,D=%.02f|L-SS:%.1f,AS:%.1f,err:%.1f,nr:%.1f,lr:%.1f,in:%.1f,TS:%.1f,dt:%d\r\n", + g_pid_count,g_KP,g_KI,g_KD,g_pidEulerCarLeft.SetSpeed, + g_pidEulerCarLeft.ActualSpeed,g_pidEulerCarLeft.err,g_pidEulerCarLeft.err_next,g_pidEulerCarLeft.err_last, + g_pidEulerCarLeft.IncSpeed,g_pidEulerCarLeft.TargetIncSpeed,g_pidEulerCarLeft.duty); + } */ +} + +void recv_data_cal(void) +{ + float x_linear,z_angular; + + g_ReceiveData.ControlStr.X_speed = Move_X; + g_ReceiveData.ControlStr.Y_speed = Move_Y; + g_ReceiveData.ControlStr.Z_speed = Move_Z; + x_linear = g_ReceiveData.ControlStr.X_speed; + z_angular = g_ReceiveData.ControlStr.Z_speed; + //DBG_PRINTF("x_speed:%.02f, Z_speed:%.02f\r\n", g_ReceiveData.ControlStr.X_speed, g_ReceiveData.ControlStr.Z_speed); + //差分轮运动学模型求解 + modelCalLeftSpeed = x_linear - z_angular * EULERCAR_WHEEL_TRACK / 2.0 / 1000.0; //左轮速度,单位mm/s + modelCalRightSpeed = x_linear + z_angular * EULERCAR_WHEEL_TRACK / 2.0 / 1000.0; //右轮速度,单位mm/s + DBG_PRINTF("modelCalLeftSpeed:%.2fmm/s, modelCalRightSpeed:%.2fmm/s\r\n", modelCalLeftSpeed, modelCalRightSpeed); + + //将上位机设置轮速存到PID控制结构体 + g_pidEulerCarLeft.SetSpeed = modelCalLeftSpeed; + g_pidEulerCarRight.SetSpeed = modelCalRightSpeed; + + //如果上位机下发速度小于0.1mm/s,小车停止运动 + if((fabsf(modelCalLeftSpeed) < 0.1) && (fabsf(modelCalRightSpeed) < 0.1)) + { + EulerCarSpeedCtrlRight(0); + EulerCarSpeedCtrlLeft(0); + //DBG_PRINTF("EulerCar stoped!!!\r\n"); + } +} + +void UART3_INTRxSimultaneously(void) +{ + float tmp_X,tmp_Y,tmp_Z; + unsigned char k,Usart_Receive,check_sum; + + while (1) { + if (g_RxInterruptflag) { + g_RxInterruptflag = false; + HAL_UART_ReadIT(&g_uart3, &Usart_Receive, 1); // 读取数据 + g_ReceiveData.buffer[g_ReceiveDataCount] = Usart_Receive; + //确保数组第一个数据为FRAME_HEADER + if (Usart_Receive == FRAME_HEADER || g_ReceiveDataCount > 0) { + g_ReceiveDataCount++; + } + else { + g_ReceiveDataCount = 0; + } + // 验证数据包的长度 + if (g_ReceiveDataCount == RECEIVE_DATA_SIZE) { + g_ReceiveDataCount = 0; //为串口数据重新填入数组做准备 + //验证数据包的帧尾 + if (g_ReceiveData.buffer[10] == FRAME_TAIL) { + check_sum = 0; + for (k = 0; k < 9; k++) { + check_sum = check_sum ^ g_ReceiveData.buffer[k]; + } + //数据异或位校验计算,模式0是发送数据校验 + if (g_ReceiveData.buffer[9] == check_sum) { + g_RecvCount++; + //从串口数据求三轴目标速度, 单位mm/s + tmp_X = XYZ_transition(g_ReceiveData.buffer[3], g_ReceiveData.buffer[4]); + tmp_Y = XYZ_transition(g_ReceiveData.buffer[5], g_ReceiveData.buffer[6]); + tmp_Z = XYZ_transition(g_ReceiveData.buffer[7], g_ReceiveData.buffer[8]); + //合法性检查,设置速度必须小于当前电机支持的最高速度 + if( (fabsf(tmp_X) < g_motorMaxSpeed) && (fabsf(tmp_Y) < g_motorMaxSpeed) && (fabsf(tmp_Z) < MOTOR_MAX_ANGULAR_SPEED) ) { + Move_X = tmp_X; + Move_Y = tmp_Y; + Move_Z = tmp_Z; + DBG_PRINTF("\r\ng_TimerCount=%d,g_RecvCount=%d,Move_X=%.2fmm/s,Move_Y=%.2fmm/s,Move_Z=%.2fmrad/s\r\n", + g_TimerInterruptCount,g_RecvCount, Move_X, Move_Y, Move_Z); + recv_data_cal(); + } + else{ + DBG_PRINTF("\r\ng_TimerCount=%d,g_RecvCount=%d",g_TimerInterruptCount,g_RecvCount); + if((fabsf(tmp_X) > g_motorMaxSpeed) || (fabsf(tmp_Y) > g_motorMaxSpeed)) + DBG_PRINTF("\r\nLinear speed set error: X=%.2fmm/s Y=%.2fmm/s, must less %.2fmm/s\r\n", tmp_X, tmp_Y,g_motorMaxSpeed); + if((fabsf(tmp_Z) > MOTOR_MAX_ANGULAR_SPEED)) + DBG_PRINTF("\r\nAngular speed set error: Z=%.2fmrad/s, must less %.1fmrad/s\r\n", tmp_Z, MOTOR_MAX_ANGULAR_SPEED); + } + } + } + } + } + + //检测按键是否按下,修改PID参数 + if (g_button1State == 1) { + g_button1State = 0; + g_KP = g_KP + g_KP_Step; + DBG_PRINTF("Button1 Evnet, g_KP + %f\r\n",g_KP_Step); + DBG_PRINTF("g_KP=%f g_KI=%f g_KD=%f\r\n", g_KP, g_KI, g_KD); + } + + if (g_button2State == 1) { + g_button2State = 0; + g_KI = g_KI + g_KI_Step; + DBG_PRINTF("Button2 Evnet, g_KI + %f\r\n",g_KI_Step); + DBG_PRINTF("g_KP=%f g_KI=%f g_KD=%f\r\n", g_KP, g_KI, g_KD); + } + } +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/eulercar_control.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/eulercar_control.h new file mode 100644 index 0000000000000000000000000000000000000000..16d047b35ce76610b58cfa3c69c60be6e5c49b99 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/eulercar_control.h @@ -0,0 +1,67 @@ +#ifndef EULERCAR_TIMER_H +#define EULERCAR_TIMER_H + +#include "debug.h" +#include "timer.h" +#include "main.h" + +#define REQUIRE_TIME_IT 5000 + +#define FRAME_HEADER 0X7B // Frame_header //帧头 +#define FRAME_TAIL 0X7D // Frame_tail //帧尾 + +#define SEND_DATA_SIZE 24 +#define RECEIVE_DATA_SIZE 11 + +/* 用于存放陀螺仪加速度计三轴数据的结构体 */ +typedef struct __Mpu6050_Data_ +{ + short X_data; // 2 bytes //2个字节 + short Y_data; // 2 bytes //2个字节 + short Z_data; // 2 bytes //2个字节 +} Mpu6050_Data; + +typedef struct _EulerCarSendData_ +{ + unsigned char buffer[SEND_DATA_SIZE]; + struct _SensorStr_ + { + unsigned char Frame_Header; // 帧头 + short X_speed; // 运动模型的X轴 + short Y_speed; // 运动模型的Y轴 + short Z_speed; // 运动模型的Z轴 + short Power_Voltage; // 电池电压 + Mpu6050_Data Accelerometer; // 加速度计的三轴加速度 + Mpu6050_Data Gyroscope; // 角速度计的三轴角速度 + unsigned char Frame_Tail; // 帧尾 + } SensorStr; +} EulerCarSendData; + +typedef struct _MotorData_ +{ + float leftSpeed; // 使用M法获取当前左轮的旋转速度 + float rightSpeed; //使用M法获取当前右轮的旋转速度 + unsigned int count; // 当前位置计数器的值 + unsigned int dir;// 和旋转的方向 +} Motor_Data; + +typedef struct _RECEIVE_DATA_ +{ + unsigned char buffer[RECEIVE_DATA_SIZE]; + struct _ControlStr_ + { + unsigned char Frame_Header; // 1 bytes //1个字节 + float X_speed; // 4 bytes //4个字节 + float Y_speed; // 4 bytes //4个字节 + float Z_speed; // Z轴角速度4 bytes //4个字节 + unsigned char Frame_Tail; // 1 bytes //1个字节 + } ControlStr; +} EulerCarRecvData; + +void Pid_Process(void); +void recv_data_cal(void); +int EulerCarSpeedCtrlLeft(float LeftSpeed); +int EulerCarSpeedCtrlRight(float rightSpeed); +void UART3_INTRxSimultaneously(void); +void debug_send_buffer(unsigned int count); +#endif \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/feature.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/feature.h new file mode 100644 index 0000000000000000000000000000000000000000..e8e6b1405e2a2d2ab0bbe44408ad13414ea290a8 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/feature.h @@ -0,0 +1,116 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * @file feature.h + * @author MCU Driver Team + * @brief This file contains macro configurations related to the project. This file is generated by the IDE tool. + */ + +#ifndef McuMagicTag_FEATURE_H +#define McuMagicTag_FEATURE_H + +/* Macro definitions --------------------------------------------------------- */ +#define CHIP_ZDU3061MNPICA MACRO_ENABLE + +#define MACRO_ENABLE 1 +#define MACRO_DISABLE 0 + +/* Macro switch */ +#define BASE_DEFINE_USE_ASSERT MACRO_ENABLE +#ifndef FLASH_CRC_CONFIG +#define FLASH_CRC_CONFIG +#endif /* #ifndef FLASH_CRC_CONFIG */ +#define BASE_MATH_SINCOS_MIDDLE_TABLE MACRO_ENABLE /**< This macro is used to control the table type when the + BASE_MATH_GetSinCos() queries the table. When the value of + this macro is MACRO_ENABLE, the error value obtained by the + BASE_MATH_GetSinCos() is relatively small, and the return + value of the function may be greater than or less than the + actual value. When the value of this macro is MACRO_DISABLE, + the error value obtained by the BASE_MATH_GetSinCos() is + relatively large. However, in the range [0°, 180°) and + [180°, 360°), the return value of the function is either + greater than or less than the actual value. */ + +#define MCS_PARAM_CHECK MACRO_ENABLE +#define APT_PARAM_CHECK MACRO_ENABLE +#define ADC_PARAM_CHECK MACRO_ENABLE +#define CAPM_PARAM_CHECK MACRO_ENABLE +#define CRG_PARAM_CHECK MACRO_ENABLE +#define I2C_PARAM_CHECK MACRO_ENABLE +#define UART_PARAM_CHECK MACRO_ENABLE +#define SPI_PARAM_CHECK MACRO_ENABLE +#define TIMER_PARAM_CHECK MACRO_ENABLE +#define IWDG_PARAM_CHECK MACRO_ENABLE +#define WWDG_PARAM_CHECK MACRO_ENABLE +#define GPIO_PARAM_CHECK MACRO_ENABLE +#define GPT_PARAM_CHECK MACRO_ENABLE +#define DMA_PARAM_CHECK MACRO_ENABLE +#define CRC_PARAM_CHECK MACRO_ENABLE +#define CFD_PARAM_CHECK MACRO_ENABLE +#define CMM_PARAM_CHECK MACRO_ENABLE +#define CAN_PARAM_CHECK MACRO_ENABLE +#define FLASH_PARAM_CHECK MACRO_ENABLE +#define PMC_PARAM_CHECK MACRO_ENABLE +#define ACMP_PARAM_CHECK MACRO_ENABLE +#define DAC_PARAM_CHECK MACRO_ENABLE +#define PGA_PARAM_CHECK MACRO_ENABLE +#define USER_MODE_ENABLE MACRO_ENABLE +#define IOCMG_PARAM_CHECK MACRO_ENABLE +#define QDM_PARAM_CHECK MACRO_ENABLE + +/* Peripheral module macro switch--------------------------------------------- */ +#define BOARD_DIM_NUM 1 /**< Number of dimming handle arrays. */ + +#define BOARD_KEY_NUM 10 /**< Number of key handle arrays. */ +#define BOARD_KEY_PRESS_ON GPIO_HIGH_LEVEL /**< GPIO status corresponding to long press valid. */ +#define BOARD_KEY_PRESS_OFF GPIO_LOW_LEVEL /**< GPIO status corresponding to short press valid. */ + +#define BOARD_LED_SEG_NUM 4 /**< Number of segments. */ +#define BOARD_LED_SEGMENT_ON GPIO_HIGH_LEVEL /**< GPIO level status corresponding to valid segments. */ +#define BOARD_LED_SEGMENT_OFF GPIO_LOW_LEVEL /**< GPIO level status corresponding to invalid segments. */ + +#define BOARD_MKEY_SCHEME_NUMBER BOARD_MKEY_SCHEME_NUMBER_ONE /**< Define the scheme to be adopted. */ +#define BOARD_MKEY_OUT_NUM 4 /**< Number of GPIO pins used as output during scanning. */ +#define BOARD_MKEY_IN_NUM 4 /**< Number of GPIO pins used as input during scanning. */ +#define BOARD_MKEY_OUT_PIN_VALID GPIO_LOW_LEVEL /**< GPIO level status corresponding to the valid \ + status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_OUT_PIN_INVALID GPIO_HIGH_LEVEL /**< GPIO level status corresponding to the \ + invalid status of the output GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_VALID GPIO_LOW_LEVEL /**< Indicates the GPIO level corresponding to the \ + valid status of the input GPIO in the key matrix. */ +#define BOARD_MKEY_IN_PIN_INVALID GPIO_HIGH_LEVEL /**< Indicates the GPIO level corresponding to the \ + invalid status of the input GPIO in the key matrix. */ + +#define BOARD_PULSES_NUM 2 /**< Number of pulse handles. */ + +#define BASE_DEFINE_SLIPAVERAGE_NUM 2 /**< Sliding average array length. */ + +#define LISTNODE_MAX 20 + +#define BASE_DEFINE_DMA_QUICKSTART + +#define XTRAIL_FREQ 30000000U + +#define DBG_USE_NO_PRINTF 0U +#define DBG_USE_UART_PRINTF 1U + +#define DBG_PRINTF_USE DBG_USE_UART_PRINTF +#if (DBG_PRINTF_USE == DBG_USE_UART_PRINTF) +#define DBG_PRINTF_UART_PORT UART2 +#endif + +#endif /* McuMagicTag_FEATURE_H */ \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/main.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/main.h new file mode 100644 index 0000000000000000000000000000000000000000..5fddda212f9fcb30931cac43a22cc674fb1f7aa0 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/main.h @@ -0,0 +1,140 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * @file main.h + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +/* Define to prevent recursive inclusion ------------------------------------- */ +#ifndef McuMagicTag_SYSTEM_INIT_H +#define McuMagicTag_SYSTEM_INIT_H + +#include "adc.h" +#include "adc_ex.h" +#include "apt.h" +#include "uart.h" +#include "uart_ex.h" +#include "i2c.h" +#include "i2c_ex.h" +#include "can.h" +#include "qdm.h" +#include "gpio.h" +#include "gpt.h" +#include "gpt_ex.h" +#include "timer.h" +#include "timer_ex.h" +#include "crg.h" +#include "iocmg.h" + +#define IO_SPEED_FAST 0x00U +#define IO_SPEED_SLOW 0x01U + +#define IO_DRV_LEVEL4 0x00U +#define IO_DRV_LEVEL3 0x01U +#define IO_DRV_LEVEL2 0x02U +#define IO_DRV_LEVEL1 0x03U + +#define XTAL_DRV_LEVEL4 0x03U +#define XTAL_DRV_LEVEL3 0x02U +#define XTAL_DRV_LEVEL2 0x01U +#define XTAL_DRV_LEVEL1 0x00U + +#define MOTOR_TYPE_GEAR_HALL_45 0 +#define MOTOR_TYPE_GEAR_GMR_45 1 +#define MOTOR_TYPE_GEAR_HALL_90 2 +#define MOTOR_TYPE_GEAR_GMR_90 3 + +#define MOTOR_LINE_NUM_HALL_45 585 +#define MOTOR_LINE_NUM_GMR_45 22500 +#define MOTOR_LINE_NUM_HALL_90 1170 +#define MOTOR_LINE_NUM_GMR_90 45000 + +#define MOTOR_TIRE_DIAMETER 67.0 //轮胎直径67mm + +#define MOTOR_MAX_ANGULAR_SPEED 100000.0 //最大角速度,单位mrad/s +#define MOTOR_MAX_SPEED_GEAR_90 650.0 //空载情况下减速比为1:90的电机,带直径为67mm的轮胎,最高速度650mm/s +#define MOTOR_MAX_SPEED_GEAR_45 1280.0 //空载情况下减速比为1:45的电机,带直径为67mm的轮胎,最高速度1280mm/s + +extern GPT_Handle g_gpt0; +extern GPT_Handle g_gpt1; +extern GPT_Handle g_gpt2; +extern GPT_Handle g_gpt3; +extern CAN_Handle g_can; +extern QDM_Handle g_qdm0; +extern QDM_Handle g_qdm1; +extern TIMER_Handle g_timer0; +extern UART_Handle g_uart0; +extern UART_Handle g_uart2; +extern UART_Handle g_uart3; +extern I2C_Handle g_i2c0; +extern I2C_Handle g_i2c1; +extern APT_Handle g_apt0; +extern APT_Handle g_apt1; +extern ADC_Handle g_adc0; + +extern GPIO_Handle g_gpio1; +extern GPIO_Handle g_gpio2; +extern GPIO_Handle g_gpio5; + +extern float g_motorMaxSpeed; //电机最大速度 +extern unsigned int g_curMotorType; //电机类型 +extern unsigned int g_motorLineNum; //电机编码器线数 + +extern unsigned int g_dataSendPeriod; //向上位机发送数据的周期 + +extern float g_KP; +extern float g_KI; +extern float g_KD; + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect); +void SystemInit(void); + +void UART2WriteInterruptCallback(void *handle); +void UART2ReadInterruptCallback(void *handle); +void UART3WriteInterruptCallback(void *handle); +void UART3ReadInterruptCallback(void *handle); + +void UART2InterruptErrorCallback(void *handle); +void UART3InterruptErrorCallback(void *handle); +void QDM1PTUCycleCallback(void *handle); +void QDM1SpeedLoseCallback(void *handle); +void QDM1ZIndexLockedCallback(void *handle); +void QDM1PositionCompareMatchCallback(void *handle); +void QDM1PositionCompareReadyCallback(void *handle); +void QDM1PositionCounterOverflowCallback(void *handle); +void QDM1PositionCounterUnderflowCallback(void *handle); +void QDM1QuadratureDirectionChangeCallback(void *handle); +void QDM1QuadraturePhaseErrorCallback(void *handle); +void QDM1PositionCounterErrorCallback(void *handle); +void TIMER0_InterruptProcess(void *handle); +void TIMER0_DMAOverFlow_InterruptProcess(void *handle); +void QDM0PTUCycleCallback(void *handle); +void QDM0SpeedLoseCallback(void *handle); +void QDM0ZIndexLockedCallback(void *handle); +void QDM0PositionCompareMatchCallback(void *handle); +void QDM0PositionCompareReadyCallback(void *handle); +void QDM0PositionCounterOverflowCallback(void *handle); +void QDM0PositionCounterUnderflowCallback(void *handle); +void QDM0QuadratureDirectionChangeCallback(void *handle); +void QDM0QuadraturePhaseErrorCallback(void *handle); +void QDM0PositionCounterErrorCallback(void *handle); + +void GPIO1_0_CallbackFunc(void *param); +void GPIO1_1_CallbackFunc(void *param); + +#endif /* McuMagicTag_SYSTEM_INIT_H */ \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/system_init.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/system_init.c new file mode 100644 index 0000000000000000000000000000000000000000..aebeb05c405d8ecdec5c3789f96e3d2a95f42a81 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/generatecode/system_init.c @@ -0,0 +1,830 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * @file system_init.c + * @author MCU Driver Team + * @brief This file contains driver init functions. + */ + +#include "main.h" +#include "ioconfig.h" +#include "iocmg_ip.h" +#include "debug.h" + +#define UART0_BAND_RATE 115200 +#define UART2_BAND_RATE 115200 +#define UART3_BAND_RATE 9600 + +BASE_StatusType CRG_Config(CRG_CoreClkSelect *coreClkSelect) +{ + CRG_Handle crg; + crg.baseAddress = CRG; + crg.pllRefClkSelect = CRG_PLL_REF_CLK_SELECT_HOSC; + crg.pllPreDiv = CRG_PLL_PREDIV_4; + crg.pllFbDiv = 48; /* PLL Multiplier 48 */ + crg.pllPostDiv = CRG_PLL_POSTDIV_2; + crg.coreClkSelect = CRG_CORE_CLK_SELECT_PLL; + crg.handleEx.pllPostDiv2 = CRG_PLL_POSTDIV2_3; + crg.handleEx.clk1MSelect = CRG_1M_CLK_SELECT_HOSC; + crg.handleEx.clk1MDiv = (25 - 1); /* The 1 MHz freq is equal to the input clock frequency / (clk_1m_div + 1). */ + + if (HAL_CRG_Init(&crg) != BASE_STATUS_OK) { + return BASE_STATUS_ERROR; + } + *coreClkSelect = crg.coreClkSelect; + return BASE_STATUS_OK; +} + +static void ADC0_Init(void) +{ + HAL_CRG_IpEnableSet(ADC0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(ADC0_BASE, CRG_ADC_CLK_ASYN_PLL_DIV); + HAL_CRG_IpClkDivSet(ADC0_BASE, CRG_ADC_DIV_1); + + g_adc0.baseAddress = ADC0; + g_adc0.socPriority = ADC_PRIMODE_ALL_ROUND; + + HAL_ADC_Init(&g_adc0); + + SOC_Param socParam = {0}; + socParam.adcInput = ADC_CH_ADCINA12; /* PIN10(ADC AIN12) */ + socParam.sampleTotalTime = ADC_SOCSAMPLE_5CLK; /* adc sample total time 5 adc_clk */ + socParam.trigSource = ADC_TRIGSOC_SOFT; + socParam.continueMode = BASE_CFG_DISABLE; + socParam.finishMode = ADC_SOCFINISH_NONE; + HAL_ADC_ConfigureSoc(&g_adc0, ADC_SOC_NUM1, &socParam); +} + +static void APT0_Init(void) +{ + HAL_CRG_IpEnableSet(APT0_BASE, IP_CLK_ENABLE); + + g_apt0.baseAddress = APT0; + + /* Clock Settings */ + g_apt0.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt0.waveform.timerPeriod = 1500; + g_apt0.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt0.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt0.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt0.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt0.waveform.divInitVal = 0; + g_apt0.waveform.cntInitVal = 0; + g_apt0.waveform.cntCmpLeftEdge = 250; + g_apt0.waveform.cntCmpRightEdge = 250; + g_apt0.waveform.cntCmpLoadMode = APT_BUFFER_DISABLE; + g_apt0.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt0.waveform.deadBandCnt = 10; + + HAL_APT_PWMInit(&g_apt0); +} + +static void APT1_Init(void) +{ + HAL_CRG_IpEnableSet(APT1_BASE, IP_CLK_ENABLE); + + g_apt1.baseAddress = APT1; + + /* Clock Settings */ + g_apt1.waveform.dividerFactor = 1 - 1; + /* Timer Settings */ + g_apt1.waveform.timerPeriod = 1500; + g_apt1.waveform.cntMode = APT_COUNT_MODE_UP_DOWN; + + /* Wave Form */ + g_apt1.waveform.basicType = APT_PWM_BASIC_A_HIGH_B_LOW; + g_apt1.waveform.chAOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt1.waveform.chBOutType = APT_PWM_OUT_BASIC_TYPE; + g_apt1.waveform.divInitVal = 0; + g_apt1.waveform.cntInitVal = 0; + g_apt1.waveform.cntCmpLeftEdge = 250; + g_apt1.waveform.cntCmpRightEdge = 250; + g_apt1.waveform.cntCmpLoadMode = APT_BUFFER_DISABLE; + g_apt1.waveform.cntCmpLoadEvt = APT_COMPARE_LOAD_EVENT_ZERO; + g_apt1.waveform.deadBandCnt = 10; + + HAL_APT_PWMInit(&g_apt1); +} + +static void CAN_Init(void){ + HAL_CRG_IpEnableSet(CAN_BASE, IP_CLK_ENABLE); + + g_can.baseAddress = CAN; + + g_can.typeMode = CAN_MODE_NORMAL; + g_can.seg1Phase = CAN_SEG1_6TQ; + g_can.seg2Phase = CAN_SEG2_3TQ; + g_can.sjw = CAN_SJW_2TQ; + g_can.prescalser = 25; /* 25 is frequency division coefficient */ + g_can.rxFIFODepth = 4; /* A maximum of 4 packet objects are in RX FIFO */ + g_can.autoRetrans = BASE_CFG_ENABLE; + HAL_CAN_Init(&g_can); +} + +__weak void GPIO1_0_CallbackFunc(void *param) +{ + GPIO_Handle *handle = (GPIO_Handle *)param; + BASE_FUNC_UNUSED(handle); +} +__weak void GPIO1_1_CallbackFunc(void *param) +{ + GPIO_Handle *handle = (GPIO_Handle *)param; + BASE_FUNC_UNUSED(handle); +} + +static void GPIO_Init(void) +{ + HAL_CRG_IpEnableSet(GPIO1_BASE, IP_CLK_ENABLE); + g_gpio1.baseAddress = GPIO1; + + g_gpio1.pins = GPIO_PIN_0 | GPIO_PIN_1; + HAL_GPIO_Init(&g_gpio1); + HAL_GPIO_SetDirection(&g_gpio1, g_gpio1.pins, GPIO_INPUT_MODE); + HAL_GPIO_SetValue(&g_gpio1, g_gpio1.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio1, g_gpio1.pins, GPIO_INT_TYPE_RISE_EDGE); + + HAL_CRG_IpEnableSet(GPIO2_BASE, IP_CLK_ENABLE); + g_gpio2.baseAddress = GPIO2; + + g_gpio2.pins = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; + HAL_GPIO_Init(&g_gpio2); + HAL_GPIO_SetDirection(&g_gpio2, g_gpio2.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio2, g_gpio2.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio2, g_gpio2.pins, GPIO_INT_TYPE_NONE); + + HAL_CRG_IpEnableSet(GPIO5_BASE, IP_CLK_ENABLE); + g_gpio5.baseAddress = GPIO5; + + g_gpio5.pins = GPIO_PIN_1; + HAL_GPIO_Init(&g_gpio5); + HAL_GPIO_SetDirection(&g_gpio5, g_gpio5.pins, GPIO_OUTPUT_MODE); + HAL_GPIO_SetValue(&g_gpio5, g_gpio5.pins, GPIO_LOW_LEVEL); + HAL_GPIO_SetIrqType(&g_gpio5, g_gpio5.pins, GPIO_INT_TYPE_NONE); + + HAL_GPIO_RegisterCallBack(&g_gpio1, GPIO_PIN_0, GPIO1_0_CallbackFunc); + HAL_GPIO_RegisterCallBack(&g_gpio1, GPIO_PIN_1, GPIO1_1_CallbackFunc); + IRQ_Register(IRQ_GPIO1, HAL_GPIO_IrqHandler, &g_gpio1); + IRQ_SetPriority(IRQ_GPIO1, 1); /* set gpio1 interrupt priority to 1, 1~15 */ + IRQ_EnableN(IRQ_GPIO1); /* gpio interrupt enable */ + + return; +} + +static void GPT0_Init(void) +{ + HAL_CRG_IpEnableSet(GPT0_BASE, IP_CLK_ENABLE); + + g_gpt0.baseAddress = GPT0; + g_gpt0.clockDiv = 1000 - 1; /* 1000 is the internal frequency division of GPT */ + g_gpt0.period = 2996; /* 2996 is the number of GPT counting cycles. */ + g_gpt0.refA0.refdot = 1; /* 1 is the value of PWM reference point A. */ + g_gpt0.refA0.refAction = GPT_ACTION_OUTPUT_HIGH; /* GPT Action High */ + g_gpt0.refB0.refdot = 76; /* 76 is the value of PWM reference point B. */ + g_gpt0.refB0.refAction = GPT_ACTION_OUTPUT_LOW; /* GPT Action Low */ + g_gpt0.bufLoad = BASE_CFG_ENABLE; + g_gpt0.pwmKeep = BASE_CFG_ENABLE; + g_gpt0.handleEx.periodIntEnable = BASE_CFG_DISABLE; + g_gpt0.handleEx.outputFinIntEnable = BASE_CFG_DISABLE; + g_gpt0.triggleAdcOutFinish = BASE_CFG_DISABLE; + g_gpt0.triggleAdcPeriod = BASE_CFG_DISABLE; + + HAL_GPT_Init(&g_gpt0); +} + +static void GPT1_Init(void) +{ + HAL_CRG_IpEnableSet(GPT1_BASE, IP_CLK_ENABLE); + + g_gpt1.baseAddress = GPT1; + g_gpt1.clockDiv = 1000 - 1; /* 1000 is the internal frequency division of GPT */ + g_gpt1.period = 49999; /* 49999 is the number of GPT counting cycles. */ + g_gpt1.refA0.refdot = 10000; /* 10000 is the value of PWM reference point A. */ + g_gpt1.refA0.refAction = GPT_ACTION_OUTPUT_HIGH; /* GPT Action High */ + g_gpt1.refB0.refdot = 30000; /* 30000 is the value of PWM reference point B. */ + g_gpt1.refB0.refAction = GPT_ACTION_OUTPUT_LOW; /* GPT Action Low */ + g_gpt1.bufLoad = BASE_CFG_ENABLE; + g_gpt1.pwmKeep = BASE_CFG_ENABLE; + g_gpt1.handleEx.periodIntEnable = BASE_CFG_DISABLE; + g_gpt1.handleEx.outputFinIntEnable = BASE_CFG_DISABLE; + g_gpt1.triggleAdcOutFinish = BASE_CFG_DISABLE; + g_gpt1.triggleAdcPeriod = BASE_CFG_DISABLE; + + HAL_GPT_Init(&g_gpt1); +} + +static void GPT2_Init(void) +{ + HAL_CRG_IpEnableSet(GPT2_BASE, IP_CLK_ENABLE); + + g_gpt2.baseAddress = GPT2; + g_gpt2.clockDiv = 1000 - 1; /* 1000 is the internal frequency division of GPT */ + g_gpt2.period = 49999; /* 49999 is the number of GPT counting cycles. */ + g_gpt2.refA0.refdot = 10000; /* 10000 is the value of PWM reference point A. */ + g_gpt2.refA0.refAction = GPT_ACTION_OUTPUT_HIGH; /* GPT Action High */ + g_gpt2.refB0.refdot = 30000; /* 30000 is the value of PWM reference point B. */ + g_gpt2.refB0.refAction = GPT_ACTION_OUTPUT_LOW; /* GPT Action Low */ + g_gpt2.bufLoad = BASE_CFG_ENABLE; + g_gpt2.pwmKeep = BASE_CFG_ENABLE; + g_gpt2.handleEx.periodIntEnable = BASE_CFG_DISABLE; + g_gpt2.handleEx.outputFinIntEnable = BASE_CFG_DISABLE; + g_gpt2.triggleAdcOutFinish = BASE_CFG_DISABLE; + g_gpt2.triggleAdcPeriod = BASE_CFG_DISABLE; + + HAL_GPT_Init(&g_gpt2); +} + +static void GPT3_Init(void) +{ + HAL_CRG_IpEnableSet(GPT3_BASE, IP_CLK_ENABLE); + + g_gpt3.baseAddress = GPT3; + g_gpt3.clockDiv = 1000 - 1; /* 1000 is the internal frequency division of GPT */ + g_gpt3.period = 300; /* 300 is the number of GPT counting cycles. */ + g_gpt3.refA0.refdot = 100; /* 100 is the value of PWM reference point A. */ + g_gpt3.refA0.refAction = GPT_ACTION_OUTPUT_HIGH; /* GPT Action High */ + g_gpt3.refB0.refdot = 200; /* 200 is the value of PWM reference point B. */ + g_gpt3.refB0.refAction = GPT_ACTION_OUTPUT_LOW; /* GPT Action Low */ + g_gpt3.bufLoad = BASE_CFG_ENABLE; + g_gpt3.pwmKeep = BASE_CFG_ENABLE; + g_gpt3.handleEx.periodIntEnable = BASE_CFG_DISABLE; + g_gpt3.handleEx.outputFinIntEnable = BASE_CFG_DISABLE; + g_gpt3.triggleAdcOutFinish = BASE_CFG_DISABLE; + g_gpt3.triggleAdcPeriod = BASE_CFG_DISABLE; + + HAL_GPT_Init(&g_gpt3); +} + +static void I2C0_Init(void) +{ + HAL_CRG_IpEnableSet(I2C0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(I2C0_BASE, CRG_AHB_CLK_NO_PREDV); + + g_i2c0.baseAddress = I2C0; + + g_i2c0.functionMode = I2C_MODE_SELECT_MASTER_ONLY; + g_i2c0.addrMode = I2C_7_BITS; + g_i2c0.sdaHoldTime = 10; + g_i2c0.freq = 400000; + g_i2c0.transferBuff = NULL; + g_i2c0.ignoreAckFlag = BASE_CFG_DISABLE; + g_i2c0.handleEx.spikeFilterTime = 0; + g_i2c0.handleEx.sdaDelayTime = 0; + g_i2c0.timeout = 10000; + g_i2c0.state = I2C_STATE_RESET; + HAL_I2C_Init(&g_i2c0); +} + +static void I2C1_Init(void) +{ + HAL_CRG_IpEnableSet(I2C1_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(I2C1_BASE, CRG_AHB_CLK_NO_PREDV); + + g_i2c1.baseAddress = I2C1; + + g_i2c1.functionMode = I2C_MODE_SELECT_MASTER_ONLY; + g_i2c1.addrMode = I2C_7_BITS; + g_i2c1.sdaHoldTime = 10; + g_i2c1.freq = 200000; + g_i2c1.transferBuff = NULL; + g_i2c1.ignoreAckFlag = BASE_CFG_DISABLE; + g_i2c1.handleEx.spikeFilterTime = 0; + g_i2c1.handleEx.sdaDelayTime = 0; + g_i2c1.timeout = 10000; + g_i2c1.state = I2C_STATE_RESET; + HAL_I2C_Init(&g_i2c1); +} + +__weak void QDM0PTUCycleCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM0_TSU_CYCLE */ + /* USER CODE END QDM0_TSU_CYCLE */ +} + +__weak void QDM0ZIndexLockedCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM0_INDEX_LOCKED */ + /* USER CODE END QDM0_INDEX_LOCKED */ +} + +__weak void QDM0QuadraturePhaseErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE QDM0_PHASE_ERROR */ + /* USER CODE QDM0_PHASE_ERROR */ +} + +static void QDM0_Init(void) +{ + HAL_CRG_IpEnableSet(QDM0_BASE, IP_CLK_ENABLE); + + g_qdm0.baseAddress = QDM0_BASE; + + /* emulation config */ + g_qdm0.emuMode = QDM_EMULATION_MODE_STOP_IMMEDIATELY; + /* input config */ + g_qdm0.ctrlConfig.decoderMode = QDM_QUADRATURE_COUNT; + g_qdm0.ctrlConfig.polarity = 0; + g_qdm0.ctrlConfig.resolution = QDM_1X_RESOLUTION; + g_qdm0.ctrlConfig.trgLockMode = QDM_TRG_BY_CYCLE; + g_qdm0.ctrlConfig.swap = QDM_SWAP_DISABLE; + g_qdm0.ctrlConfig.ptuMode = QDM_PTU_MODE_CYCLE; + /* filter config */ + g_qdm0.inputFilter.qdmAFilterLevel = 0; + g_qdm0.inputFilter.qdmBFilterLevel = 0; + g_qdm0.inputFilter.qdmZFilterLevel = 0; + /* other config */ + g_qdm0.lock_mode = QDM_LOCK_RESERVE; + g_qdm0.pcntMode = QDM_PCNT_MODE_BY_DIR; + //g_qdm0.pcntRstMode = QDM_PCNT_RST_BY_PTU; + g_qdm0.pcntRstMode = QDM_PCNT_RST_OVF; // 单独调试脉冲数 + g_qdm0.pcntIdxInitMode = QDM_IDX_INIT_DISABLE; + g_qdm0.qcMax = 4294967295; + g_qdm0.subModeEn = true; + g_qdm0.tsuPrescaler = 0; + g_qdm0.cevtPrescaler = QDM_CEVT_PRESCALER_DIVI1; + //g_qdm0.posMax = 4294967295; + g_qdm0.posMax = g_motorLineNum; + g_qdm0.posInit = 0; + g_qdm0.period = 150000000; + + g_qdm0.motorLineNum = g_motorLineNum; /* 设置编码器线数 */ + //DBG_PRINTF("g_qdm0.motorLineNum:%d\r\n", g_qdm0.motorLineNum); + g_qdm0.interruptEn = QDM_INT_WATCHDOG | + QDM_INT_INDEX_EVNT_LATCH | + QDM_INT_UNIT_TIME_OUT; + + HAL_QDM_Init(&g_qdm0); + + HAL_QDM_RegisterCallback(&g_qdm0, QDM_TSU_CYCLE, QDM0PTUCycleCallback); + HAL_QDM_RegisterCallback(&g_qdm0, QDM_INDEX_LOCKED, QDM0ZIndexLockedCallback); + HAL_QDM_RegisterCallback(&g_qdm0, QDM_PHASE_ERROR, QDM0QuadraturePhaseErrorCallback); + IRQ_Register(IRQ_QDM0, HAL_QDM_IrqHandler, &g_qdm0); + IRQ_SetPriority(IRQ_QDM0, 1); + IRQ_EnableN(IRQ_QDM0); +} + +__weak void QDM1PTUCycleCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM1_TSU_CYCLE */ + /* USER CODE END QDM1_TSU_CYCLE */ +} + +__weak void QDM1ZIndexLockedCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN QDM1_INDEX_LOCKED */ + /* USER CODE END QDM1_INDEX_LOCKED */ +} + +__weak void QDM1QuadraturePhaseErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE QDM1_PHASE_ERROR */ + /* USER CODE QDM1_PHASE_ERROR */ +} + +static void QDM1_Init(void) +{ + HAL_CRG_IpEnableSet(QDM1_BASE, IP_CLK_ENABLE); + + g_qdm1.baseAddress = QDM1_BASE; + + /* emulation config */ + g_qdm1.emuMode = QDM_EMULATION_MODE_STOP_IMMEDIATELY; + /* input config */ + g_qdm1.ctrlConfig.decoderMode = QDM_QUADRATURE_COUNT; + g_qdm1.ctrlConfig.polarity = 0; + g_qdm1.ctrlConfig.resolution = QDM_1X_RESOLUTION; /* 1倍频:只统计A相上升沿,4倍频:统计A、B两项上升沿和下降沿 */ + g_qdm1.ctrlConfig.trgLockMode = QDM_TRG_BY_CYCLE; + g_qdm1.ctrlConfig.swap = QDM_SWAP_DISABLE; + g_qdm1.ctrlConfig.ptuMode = QDM_PTU_MODE_CYCLE; + /* filter config */ + g_qdm1.inputFilter.qdmAFilterLevel = 0; + g_qdm1.inputFilter.qdmBFilterLevel = 0; + g_qdm1.inputFilter.qdmZFilterLevel = 0; + /* other config */ + g_qdm1.lock_mode = QDM_LOCK_RESERVE; + g_qdm1.pcntMode = QDM_PCNT_MODE_BY_DIR; + //g_qdm1.pcntRstMode = QDM_PCNT_RST_BY_PTU; + g_qdm1.pcntRstMode = QDM_PCNT_RST_OVF; + g_qdm1.pcntIdxInitMode = QDM_IDX_INIT_DISABLE; + g_qdm1.qcMax = 4294967295; + g_qdm1.subModeEn = true; + g_qdm1.tsuPrescaler = 0U; + g_qdm1.cevtPrescaler = QDM_CEVT_PRESCALER_DIVI1; + //g_qdm1.posMax = 4294967295; + g_qdm1.posMax = g_motorLineNum; + g_qdm1.posInit = 0; + g_qdm1.period = 150000000; + + g_qdm1.motorLineNum = g_motorLineNum; /* 设置编码器线数 */ + //DBG_PRINTF("g_qdm0.motorLineNum:%d\r\n", g_qdm0.motorLineNum); + + g_qdm1.interruptEn = QDM_INT_WATCHDOG | + QDM_INT_INDEX_EVNT_LATCH | + QDM_INT_UNIT_TIME_OUT; + + HAL_QDM_Init(&g_qdm1); + + HAL_QDM_RegisterCallback(&g_qdm1, QDM_TSU_CYCLE, QDM1PTUCycleCallback); + HAL_QDM_RegisterCallback(&g_qdm1, QDM_INDEX_LOCKED, QDM1ZIndexLockedCallback); + HAL_QDM_RegisterCallback(&g_qdm1, QDM_PHASE_ERROR, QDM1QuadraturePhaseErrorCallback); + IRQ_Register(IRQ_QDM1, HAL_QDM_IrqHandler, &g_qdm1); + IRQ_SetPriority(IRQ_QDM1, 1); + IRQ_EnableN(IRQ_QDM1); +} + +__weak void TIMER0_InterruptProcess(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN TIMER0_InterruptProcess */ + /* USER CODE END TIMER0_InterruptProcess */ +} + +static void TIMER0_Init(void) +{ + + HAL_CRG_IpEnableSet(TIMER0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(TIMER0_BASE, CRG_AHB_CLK_NO_PREDV); + + unsigned int load = (HAL_CRG_GetIpFreq((void *)TIMER0) / (1u << (TIMERPRESCALER_NO_DIV * 4)) / 1000000u) * 10000; + + g_timer0.baseAddress = TIMER0; + g_timer0.load = load - 1; /* Set timer value immediately */ + g_timer0.bgLoad = load - 1; /* Set timer value */ + g_timer0.mode = TIMER_MODE_RUN_PERIODIC; /* Run in period mode */ + g_timer0.prescaler = TIMERPRESCALER_NO_DIV; /* Don't frequency division */ + g_timer0.size = TIMER_SIZE_32BIT; /* 1 for 32bit, 0 for 16bit */ + g_timer0.interruptEn = BASE_CFG_ENABLE; + g_timer0.adcSocReqEnable = BASE_CFG_DISABLE; + g_timer0.dmaReqEnable = BASE_CFG_DISABLE; + HAL_TIMER_Init(&g_timer0); + IRQ_Register(IRQ_TIMER0, HAL_TIMER_IrqHandler, &g_timer0); + + HAL_TIMER_RegisterCallback(&g_timer0, TIMER_PERIOD_FIN, TIMER0_InterruptProcess); + IRQ_SetPriority(IRQ_TIMER0, 1); + IRQ_EnableN(IRQ_TIMER0); +} + +static void UART0_Init(void) +{ + HAL_CRG_IpEnableSet(UART0_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART0_BASE, CRG_AHB_CLK_NO_PREDV); + + g_uart0.baseAddress = UART0; + + g_uart0.baudRate = UART0_BAND_RATE; + g_uart0.dataLength = UART_DATALENGTH_8BIT; + g_uart0.stopBits = UART_STOPBITS_ONE; + g_uart0.parity = UART_PARITY_NONE; + g_uart0.txMode = UART_MODE_BLOCKING; + g_uart0.rxMode = UART_MODE_BLOCKING; + g_uart0.fifoMode = BASE_CFG_ENABLE; + g_uart0.fifoTxThr = UART_FIFODEPTH_SIZE8; + g_uart0.fifoRxThr = UART_FIFODEPTH_SIZE8; + g_uart0.hwFlowCtr = BASE_CFG_DISABLE; + g_uart0.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart0.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart0); +} + +__weak void UART2InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART2_TRNS_IT_ERROR */ + /* USER CODE END UART2_TRNS_IT_ERROR */ +} + +__weak void UART2WriteInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART2_WRITE_IT_FINISH */ + /* USER CODE END UART2_WRITE_IT_FINISH */ +} + +__weak void UART2ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART2_READ_IT_FINISH */ + /* USER CODE END UART2_READ_IT_FINISH */ +} + +static void UART2_Init(void) +{ + HAL_CRG_IpEnableSet(UART2_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART2_BASE, CRG_AHB_CLK_NO_PREDV); + + g_uart2.baseAddress = UART2; + + g_uart2.baudRate = UART2_BAND_RATE; + g_uart2.dataLength = UART_DATALENGTH_8BIT; + g_uart2.stopBits = UART_STOPBITS_ONE; + g_uart2.parity = UART_PARITY_NONE; + g_uart2.txMode = UART_MODE_INTERRUPT; + g_uart2.rxMode = UART_MODE_INTERRUPT; + g_uart2.fifoMode = BASE_CFG_ENABLE; + g_uart2.fifoTxThr = UART_FIFODEPTH_SIZE4; + g_uart2.fifoRxThr = UART_FIFODEPTH_SIZE4; + g_uart2.hwFlowCtr = BASE_CFG_DISABLE; + g_uart2.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart2.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart2); + HAL_UART_RegisterCallBack(&g_uart2, UART_TRNS_IT_ERROR, (UART_CallbackType)UART2InterruptErrorCallback); + HAL_UART_RegisterCallBack(&g_uart2, UART_WRITE_IT_FINISH, (UART_CallbackType)UART2WriteInterruptCallback); + HAL_UART_RegisterCallBack(&g_uart2, UART_READ_IT_FINISH, (UART_CallbackType)UART2ReadInterruptCallback); + + IRQ_Register(IRQ_UART2, HAL_UART_IrqHandler, &g_uart2); + IRQ_SetPriority(IRQ_UART2, 1); + IRQ_EnableN(IRQ_UART2); +} + +__weak void UART3InterruptErrorCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART3InterruptErrorCallback */ + /* USER CODE END UART3InterruptErrorCallback */ +} + +__weak void UART3WriteInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART3WriteInterruptCallback */ + /* USER CODE END UART3WriteInterruptCallback */ +} + +__weak void UART3ReadInterruptCallback(void *handle) +{ + BASE_FUNC_UNUSED(handle); + /* USER CODE BEGIN UART3ReadInterruptCallback */ + /* USER CODE END UART3ReadInterruptCallback */ +} + +static void UART3_Init(void) +{ + HAL_CRG_IpEnableSet(UART3_BASE, IP_CLK_ENABLE); + HAL_CRG_IpClkSelectSet(UART3_BASE, CRG_AHB_CLK_NO_PREDV); + + g_uart3.baseAddress = UART3; + + g_uart3.baudRate = UART3_BAND_RATE; + g_uart3.dataLength = UART_DATALENGTH_8BIT; + g_uart3.stopBits = UART_STOPBITS_ONE; + g_uart3.parity = UART_PARITY_NONE; + g_uart3.txMode = UART_MODE_INTERRUPT; + g_uart3.rxMode = UART_MODE_INTERRUPT; + g_uart3.fifoMode = BASE_CFG_ENABLE; + g_uart3.fifoTxThr = UART_FIFODEPTH_SIZE4; + g_uart3.fifoRxThr = UART_FIFODEPTH_SIZE4; + g_uart3.hwFlowCtr = BASE_CFG_DISABLE; + g_uart3.handleEx.overSampleMultiple = UART_OVERSAMPLING_16X; + g_uart3.handleEx.msbFirst = BASE_CFG_DISABLE; + HAL_UART_Init(&g_uart3); + HAL_UART_RegisterCallBack(&g_uart3, UART_TRNS_IT_ERROR, (UART_CallbackType)UART3InterruptErrorCallback); + HAL_UART_RegisterCallBack(&g_uart3, UART_WRITE_IT_FINISH, (UART_CallbackType)UART3WriteInterruptCallback); + HAL_UART_RegisterCallBack(&g_uart3, UART_READ_IT_FINISH, (UART_CallbackType)UART3ReadInterruptCallback); + + IRQ_Register(IRQ_UART3, HAL_UART_IrqHandler, &g_uart3); + IRQ_SetPriority(IRQ_UART3, 1); + IRQ_EnableN(IRQ_UART3); +} + +static void IOConfig(void) +{ + HAL_IOCMG_SetPinAltFuncMode(GPIO2_2_AS_UART0_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_2_AS_UART0_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_2_AS_UART0_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_2_AS_UART0_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_2_AS_UART0_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO2_3_AS_UART0_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_3_AS_UART0_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_3_AS_UART0_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_3_AS_UART0_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_3_AS_UART0_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO3_0_AS_APT0_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_0_AS_APT0_PWMA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_0_AS_APT0_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_0_AS_APT0_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_0_AS_APT0_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_0_AS_APT0_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_0_AS_APT0_PWMB, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_0_AS_APT0_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_0_AS_APT0_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_0_AS_APT0_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO3_1_AS_APT1_PWMA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_1_AS_APT1_PWMA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_1_AS_APT1_PWMA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_1_AS_APT1_PWMA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_1_AS_APT1_PWMA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_1_AS_APT1_PWMB); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_1_AS_APT1_PWMB, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_1_AS_APT1_PWMB, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_1_AS_APT1_PWMB, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_1_AS_APT1_PWMB, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO2_0_AS_QDM1_A); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_0_AS_QDM1_A, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_0_AS_QDM1_A, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_0_AS_QDM1_A, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_0_AS_QDM1_A, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO2_1_AS_QDM1_B); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_1_AS_QDM1_B, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_1_AS_QDM1_B, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_1_AS_QDM1_B, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_1_AS_QDM1_B, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO5_0_AS_QDM1_INDEX); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_0_AS_QDM1_INDEX, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_0_AS_QDM1_INDEX, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_0_AS_QDM1_INDEX, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_0_AS_QDM1_INDEX, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO1_7_AS_I2C1_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_7_AS_I2C1_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_7_AS_I2C1_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_7_AS_I2C1_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_7_AS_I2C1_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_7_AS_I2C1_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_7_AS_I2C1_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_7_AS_I2C1_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_7_AS_I2C1_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_7_AS_I2C1_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO1_5_AS_UART2_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_5_AS_UART2_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_5_AS_UART2_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_5_AS_UART2_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_5_AS_UART2_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO1_6_AS_UART2_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_6_AS_UART2_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_6_AS_UART2_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_6_AS_UART2_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_6_AS_UART2_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO5_2_AS_GPT2_PWM); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_2_AS_GPT2_PWM, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_2_AS_GPT2_PWM, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_2_AS_GPT2_PWM, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_2_AS_GPT2_PWM, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO0_5_AS_GPT1_PWM); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO0_5_AS_GPT1_PWM, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO0_5_AS_GPT1_PWM, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO0_5_AS_GPT1_PWM, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO0_5_AS_GPT1_PWM, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO2_4_AS_GPT0_PWM); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_4_AS_GPT0_PWM, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_4_AS_GPT0_PWM, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_4_AS_GPT0_PWM, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_4_AS_GPT0_PWM, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO1_0_AS_GPIO1_0); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_0_AS_GPIO1_0, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_0_AS_GPIO1_0, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_0_AS_GPIO1_0, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_0_AS_GPIO1_0, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO1_1_AS_GPIO1_1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_1_AS_GPIO1_1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_1_AS_GPIO1_1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_1_AS_GPIO1_1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_1_AS_GPIO1_1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO2_5_AS_GPIO2_5); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_5_AS_GPIO2_5, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_5_AS_GPIO2_5, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_5_AS_GPIO2_5, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_5_AS_GPIO2_5, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO2_6_AS_GPIO2_6); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_6_AS_GPIO2_6, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_6_AS_GPIO2_6, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_6_AS_GPIO2_6, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_6_AS_GPIO2_6, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO2_7_AS_GPIO2_7); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO2_7_AS_GPIO2_7, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO2_7_AS_GPIO2_7, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO2_7_AS_GPIO2_7, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO2_7_AS_GPIO2_7, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO5_1_AS_GPIO5_1); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_1_AS_GPIO5_1, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_1_AS_GPIO5_1, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_1_AS_GPIO5_1, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_1_AS_GPIO5_1, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO1_4_AS_UART3_RXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_4_AS_UART3_RXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_4_AS_UART3_RXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_4_AS_UART3_RXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_4_AS_UART3_RXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO1_3_AS_UART3_TXD); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO1_3_AS_UART3_TXD, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO1_3_AS_UART3_TXD, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO1_3_AS_UART3_TXD, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO1_3_AS_UART3_TXD, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_2_AS_I2C0_SCL); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_2_AS_I2C0_SCL, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_2_AS_I2C0_SCL, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_2_AS_I2C0_SCL, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_2_AS_I2C0_SCL, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_3_AS_I2C0_SDA); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_3_AS_I2C0_SDA, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_3_AS_I2C0_SDA, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_3_AS_I2C0_SDA, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_3_AS_I2C0_SDA, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO3_7_AS_GPT3_PWM); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_7_AS_GPT3_PWM, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_7_AS_GPT3_PWM, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_7_AS_GPT3_PWM, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_7_AS_GPT3_PWM, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO5_3_AS_ADC_AIN12); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO5_3_AS_ADC_AIN12, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO5_3_AS_ADC_AIN12, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO5_3_AS_ADC_AIN12, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO5_3_AS_ADC_AIN12, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO3_6_AS_CAN_RX); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_6_AS_CAN_RX, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_6_AS_CAN_RX, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_6_AS_CAN_RX, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_6_AS_CAN_RX, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO3_5_AS_CAN_TX); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO3_5_AS_CAN_TX, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO3_5_AS_CAN_TX, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO3_5_AS_CAN_TX, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO3_5_AS_CAN_TX, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_5_AS_QDM0_A); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_5_AS_QDM0_A, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_5_AS_QDM0_A, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_5_AS_QDM0_A, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_5_AS_QDM0_A, DRIVER_RATE_2); /* Output signal edge fast/slow */ + + HAL_IOCMG_SetPinAltFuncMode(GPIO4_6_AS_QDM0_B); /* Check function selection */ + HAL_IOCMG_SetPinPullMode(GPIO4_6_AS_QDM0_B, PULL_NONE); /* Pull-up and pull-down */ + HAL_IOCMG_SetPinSchmidtMode(GPIO4_6_AS_QDM0_B, SCHMIDT_DISABLE); /* Schmitt input on/off */ + HAL_IOCMG_SetPinLevelShiftRate(GPIO4_6_AS_QDM0_B, LEVEL_SHIFT_RATE_SLOW); /* Output drive capability */ + HAL_IOCMG_SetPinDriveRate(GPIO4_6_AS_QDM0_B, DRIVER_RATE_2); /* Output signal edge fast/slow */ + +} + +void SystemInit(void) +{ + IOConfig(); + UART0_Init(); + UART2_Init(); + UART3_Init(); + APT0_Init(); + APT1_Init(); + ADC0_Init(); + CAN_Init(); + GPT0_Init(); + GPT1_Init(); + GPT2_Init(); + GPT3_Init(); + TIMER0_Init(); + I2C0_Init(); + I2C1_Init(); + QDM0_Init(); + QDM1_Init(); + GPIO_Init(); + + /* USER CODE BEGIN system_init */ + /* USER CODE END system_init */ +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/gyro.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/gyro.c new file mode 100644 index 0000000000000000000000000000000000000000..5f6cf916542f7213578e843a55eb7c4300ea5b7d --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/gyro.c @@ -0,0 +1,311 @@ +#include +#include +#include // For memcpy +#include +#include + +#include "main.h" +#include "debug.h" +#include "i2c.h" +#include "ssd1306.h" +#include "ssd1306_fonts.h" +#include "gyro.h" + +#define gyroKp (20.0f) // 比例增益支配率收敛到加速度计/磁强计 +#define gyroKi (0.0004f) // 积分增益支配率的陀螺仪偏见的衔接 +#define gyroHalfT (0.005f) // 采样周期的一半 +#define PAI 3.14 +#define DEGREES 180 + +float q0 = 1, q1 = 0, q2 = 0, q3 = 0; // 四元数的元素,代表估计方向 +float exInt = 0, eyInt = 0, ezInt = 0; // 按比例缩小积分误差 +float g_gyro_yaw, g_gyro_pitch, g_gyro_roll; // 偏航角,俯仰角,翻滚角 +static float yaw_conv = 0.0f; + + +/** + * @berf i2c read + * @param hi_u8 reg_high_8bit_cmd:Transmit register value 8 bits high + * @param hi_u8 reg_low_8bit_cmd:Transmit register value low 8 bits + * @param hi_u8* recv_data:Receive data buff + * @param hi_u8 send_len:Sending data length + * @param hi_u8 read_len:Length of received data +*/ +uint32_t LSM6DS_WriteRead(uint8_t reg_high_8bit_cmd, uint8_t send_len, uint8_t read_len) +{ + uint8_t recvData[12] = {0}; + uint32_t ret = 0; + uint8_t send_user_cmd[1] = {reg_high_8bit_cmd}; + ret= HAL_I2C_MasterWriteBlocking(&g_i2c0, LSM6DS_WRITE_ADDR, send_user_cmd, send_len, 10000); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,write Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Read data from eeprom. */ + ret = HAL_I2C_MasterReadBlocking(&g_i2c0, LSM6DS_READ_ADDR, recvData, read_len, 10000); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + DBG_PRINTF("LSM6DS read ndef data\r\n"); + for (int i = 0; i < read_len; i++) { + DBG_PRINTF("0x%x ", recvData[i]); + } + ret = recvData[0]; + return ret; +} + +uint32_t LSM6DS_ReadCont(uint8_t reg_addr, uint8_t* buffer, uint16_t read_len) +{ + uint32_t ret = 0; + uint8_t send_user_cmd[1] = {reg_addr}; + ret= HAL_I2C_MasterWriteBlocking(&g_i2c0, LSM6DS_WRITE_ADDR, send_user_cmd, 1, 10000); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,write Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + /* Read data from eeprom. */ + ret = HAL_I2C_MasterReadBlocking(&g_i2c0, LSM6DS_READ_ADDR, buffer, read_len, 10000); + if (ret != BASE_STATUS_OK) { + DBG_PRINTF("LINE:%d,Read Data Fail,ret:%d\r\n", __LINE__, ret); + return ret; + } + DBG_PRINTF("LSM6DS read ndef data\r\n"); + for (int i = 0; i < read_len; i++) { + DBG_PRINTF("0x%x ", buffer[i]); + } + return ret; +} + +uint32_t LSM6DS_Write(uint8_t addr, uint8_t writedata, uint32_t buffLen) +{ + uint8_t buffer[2] = {addr, writedata}; + uint32_t retval = HAL_I2C_MasterWriteBlocking(&g_i2c0, LSM6DS_WRITE_ADDR, buffer, buffLen, 10000); + if (retval != BASE_STATUS_OK) { + DBG_PRINTF("LSM6DS_Write: IoTI2cWrite(%02X) failed, %0X!\n", buffer[0], retval); + return retval; + } + DBG_PRINTF("IoTI2cWrite(%02X)\r\n", buffer[0]); + return BASE_STATUS_OK; +} + +void IMU_YAW_CAL(float gyroZ) +{ + int ret = 0; + static char Pitchline[32] = { 0 }; + static char Rollline[32] = { 0 }; + static char Yawline[32] = { 0 }; + static float dt = 0.03; // 0.03代表300ms读取陀螺仪数据 + static float yaw = 0.0f, temp = 0.0f; + // 除去零偏 + #if 0 + static int a = 0; + a++; + if (hi_get_seconds() <= 5) { // 5s + printf("---------times-----------:%d\n", a); + } + #endif + if (fabs(gyroZ) < 0.04) { // 0.04标准值 + temp = 0; + } else { + temp = gyroZ * dt; + } + yaw += temp; + yaw_conv = yaw * 57.32; // 57.32 初始值 + // 360°一个循环 + if (fabs(yaw_conv) > 360.0f) { + if ((yaw_conv) < 0) { + yaw_conv += 360.0f; + } else { + yaw_conv -= 360.0f; + } + } + DBG_PRINTF("Pitch:%.02f, Roll:%.02f, yaw:%.2f\n", g_gyro_pitch, g_gyro_roll, yaw_conv); + ssd1306_SetCursor(0, 15); // 0为横坐标,15为纵坐标 + ret = sprintf(Pitchline, "Pitch: %.2f", g_gyro_pitch); + if (ret < 0) { + printf("Pitch failed\r\n"); + } + ssd1306_DrawString(Pitchline, Font_7x10, White); + ssd1306_SetCursor(0, 30); // 0为横坐标,30为纵坐标 + ret = sprintf(Rollline, "roll: %.2f", g_gyro_roll); + if (ret < 0) { + printf("roll failed\r\n"); + } + ssd1306_DrawString(Rollline, Font_7x10, White); + ssd1306_SetCursor(0, 0); // 0为横坐标,0为纵坐标 + ret = sprintf(Yawline, "roll: %.2f", yaw_conv); + if (ret < 0) { + printf("yaw failed\r\n"); + } + ssd1306_DrawString(Yawline, Font_7x10, White); + ssd1306_UpdateScreen(); +} + +void GetRoll(float atan2x, float atan2y) +{ + float atan2_x = atan2x; + float atan2_y = atan2y; + if (atan2_x > 0) { + g_gyro_roll = atan(atan2_y / atan2_x) * DEGREES / PAI; + } else if (atan2_x < 0 && atan2_y >= 0) { + g_gyro_roll = atan(atan2_y / atan2_x) * DEGREES / PAI + DEGREES; + } else if (atan2_x < 0 && atan2_y < 0) { + g_gyro_roll = atan(atan2_y / atan2_x) * DEGREES / PAI - DEGREES; + } else if (atan2_y > 0 && fabsf(atan2_x) < 0.001) { + g_gyro_roll = 90; // 90° + } else if (atan2_y < 0 && fabsf(atan2_x) < 0.001) { + g_gyro_roll = -90; // -90° + } else { + printf("undefined\n"); + } +} + +void GetPitch(float atan2x, float atan2y) +{ + float atan2_x = atan2x; + float atan2_y_pitch = atan2y; + if (atan2_x > 0) { + g_gyro_pitch = atan(atan2_y_pitch / atan2_x) * DEGREES / PAI; + } else if (atan2_x < 0 && atan2_y_pitch >= 0) { + g_gyro_pitch = atan(atan2_y_pitch / atan2_x) * DEGREES / PAI + DEGREES; + } else if (atan2_x < 0 && atan2_y_pitch < 0) { + g_gyro_pitch = atan(atan2_y_pitch / atan2_x) * DEGREES / PAI - DEGREES; + } else if (atan2_y_pitch > 0 && fabsf(atan2_x) < 0.001) { + g_gyro_pitch = 90; // 90° + } else if (atan2_y_pitch < 0 && fabsf(atan2_x) < 0.001) { + g_gyro_pitch = -90; // -90° + } else { + printf("undefined\n"); + } +} + +void IMU_Attitude_cal(float gcx, float gcy, float gcz, float acx, float acy, float acz) +{ + float norm; + float vx, vy, vz; + float ex, ey, ez; + float atan2_x, atan2_y; + float atan2_y_pitch; + float ax = acx, ay = acy, az = acz; + float gx = gcx, gy = gcy, gz = gcz; + + // 把采集到的三轴加速度转化为单位向量,即向量除以模 + norm = (float)sqrt((float)(ax * ax + ay * ay + az * az)); + if (fabsf(norm) < 0.001) { + printf("norm = 0,failed\n"); + } + ax = ax / norm; + ay = ay / norm; + az = az / norm; + + // 把四元素换算成方向余弦中的第三行的三个元素 + // vx、vy、vz其实就是上一次的欧拉角(四元数)机体参考坐标系换算出来的重力的单位向量 + vx = 2 * (q1 * q3 - q0 * q2); // 2计算系数 + vy = 2 * (q0 * q1 + q2 * q3); // 2计算系数 + vz = q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3; + + // 对向量叉乘,求出姿态误差 + // ex、ey、ez为三轴误差元素 + ex = (ay * vz - az * vy); + ey = (az * vx - ax * vz); + ez = (ax * vy - ay * vx); + + // 叉乘向量仍旧是机体坐标系上的,而陀螺仪积分误差也是机体坐标系 + // 而且叉积的大小与陀螺仪误差成正比,正好拿来纠正陀螺 + exInt = exInt + ex * gyroKi; + eyInt = eyInt + ey * gyroKi; + ezInt = ezInt + ez * gyroKi; + + // 调整后的陀螺仪测量 + gx = gx + gyroKp * ex + exInt; + gy = gy + gyroKp * ey + eyInt; + gz = gz + gyroKp * ez + ezInt; + + // 使用一阶龙格库塔解四元数微分方程 + q0 = q0 + (-q1 * gx - q2 * gy - q3 * gz) * gyroHalfT; + q1 = q1 + (q0 * gx + q2 * gz - q3 * gy) * gyroHalfT; + q2 = q2 + (q0 * gy - q1 * gz + q3 * gx) * gyroHalfT; + q3 = q3 + (q0 * gz + q1 * gy - q2 * gx) * gyroHalfT; + + // 四元数归一化 + norm = sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3); + if (fabsf(norm) < 0.001) { + printf("norm = 0,failed\n"); + } + q0 = q0 / norm; + q1 = q1 / norm; + q2 = q2 / norm; + q3 = q3 / norm; + + // 计算姿态角,本文Roll为横滚角,Pitch为俯仰角 + atan2_x = -2 * q1 * q1 - 2 * q2 * q2 + 1; // 2 计算参数 + atan2_y = 2 * q2 * q3 + 2 * q0 * q1; // 2 计算参数 + GetRoll(atan2_x, atan2_y); + // 俯仰角 + atan2_y_pitch = -2 * q1 * q3 + 2 * q0 * q2; // 2 计算参数 + GetPitch(atan2_x, atan2_y_pitch); +} + +void Lsm_Get_RawAcc(void) +{ + uint8_t buf[12] = {0}; + int16_t acc_x = 0, acc_y = 0, acc_z = 0; + float acc_x_conv = 0, acc_y_conv = 0, acc_z_conv = 0; + int16_t ang_rate_x = 0, ang_rate_y = 0, ang_rate_z = 0; + float ang_rate_x_conv = 0, ang_rate_y_conv = 0, ang_rate_z_conv = 0; + + if ((LSM6DS_WriteRead(LSM6DSL_STATUS_REG, 1, 1) & 0x03)!=0) { + if (BASE_STATUS_OK != LSM6DS_ReadCont(LSM6DSL_OUTX_L_G, buf, 12)) { + DBG_PRINTF("i2c read error!\n"); + } + else { + ang_rate_x = (buf[1] << 8) + buf[0]; + ang_rate_y = (buf[3] << 8) + buf[2]; + ang_rate_z = (buf[5] << 8) + buf[4]; + acc_x = (buf[7] << 8) + buf[6]; + acc_y = (buf[9] << 8) + buf[8]; + acc_z = (buf[11] << 8) + buf[10]; + + // DBG_PRINTF("lsm acc: %d, %d, %d \n ang: %d, %d, %d\n ", + // acc_x, acc_y, acc_z, ang_rate_x, ang_rate_y, ang_rate_z); + ang_rate_x_conv = 3.14 / 180.0 * ang_rate_x / 14.29; + ang_rate_y_conv = 3.14 / 180.0 * ang_rate_y / 14.29; + ang_rate_z_conv = 3.14 / 180.0 * ang_rate_z / 14.29; + + acc_x_conv = acc_x / 4098.36; + acc_y_conv = acc_y / 4098.36; + acc_z_conv = acc_z / 4098.36; + // DBG_PRINTF("lsm trans acc: %.2f, %.2f, %.2f \n ang: %.2f, %.2f, %.2f\n ", + // acc_x_conv, acc_y_conv, acc_z_conv, ang_rate_x_conv, ang_rate_y_conv, ang_rate_z_conv); + IMU_Attitude_cal(ang_rate_x_conv, ang_rate_y_conv, ang_rate_z_conv, acc_x_conv, acc_y_conv, acc_z_conv); + IMU_YAW_CAL(ang_rate_z_conv); + } + } +} + +void LSM6DS_Init() +{ + LSM6DS_Write(LSM6DSL_CTRL3_C, 0x34, 2); + LSM6DS_Write(LSM6DSL_CTRL2_G , 0X4C, 2); // 角速度陀螺仪配置2000dps ,104Hz + LSM6DS_Write(LSM6DSL_CTRL10_C, 0x38, 2); // timer en, pedo en, tilt en ?? + LSM6DS_Write(LSM6DSL_CTRL1_XL, 0x4F, 2); // 加速度配置量程为8g,104Hz, lpf1_bw_sel=1, bw0_xl=1; + + LSM6DS_Write(LSM6DSL_TAP_CFG, 0x10, 2); + LSM6DS_Write(LSM6DSL_WAKE_UP_DUR, 0x00, 2); + LSM6DS_Write(LSM6DSL_WAKE_UP_THS, 0x02, 2); + LSM6DS_Write(LSM6DSL_TAP_THS_6D, 0x40, 2); + LSM6DS_Write(LSM6DSL_CTRL8_XL, 0x01, 2); +} + +void InitGyro(void) +{ + uint32_t ret; + ret = LSM6DS_WriteRead(LSM6DSL_WHO_AM_I, 1, 1); + DBG_PRINTF("who am i: %X\n", ret); + LSM6DS_Init(); + while (1) { + Lsm_Get_RawAcc(); + BASE_FUNC_DELAY_MS(10); // 延时10ms + } +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/gyro.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/gyro.h new file mode 100644 index 0000000000000000000000000000000000000000..140111b4e68e65470c92b0ef3d709b94248b2aae --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/gyro.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef GYRO_H +#define GYRO_H + +#define LSM6DS_WRITE_ADDR (0XD6) +#define LSM6DS_READ_ADDR (0XD7) +#define WRITELEN 2 + +/* sensor output data */ +#define LSM6DSL_OUTX_L_G 0X22 +#define LSM6DSL_OUTX_H_G 0X23 +#define LSM6DSL_OUTY_L_G 0X24 +#define LSM6DSL_OUTY_H_G 0X25 +#define LSM6DSL_OUTZ_L_G 0X26 +#define LSM6DSL_OUTZ_H_G 0X27 + +#define LSM6DSL_OUTX_L_XL 0X28 +#define LSM6DSL_OUTX_H_XL 0X29 +#define LSM6DSL_OUTY_L_XL 0X2A +#define LSM6DSL_OUTY_H_XL 0X2B +#define LSM6DSL_OUTZ_L_XL 0X2C +#define LSM6DSL_OUTZ_H_XL 0X2D +/* sensor control reg */ +#define LSM6DSL_CTRL1_XL 0X10 +#define LSM6DSL_CTRL2_G 0X11 +#define LSM6DSL_CTRL3_C 0X12 +#define LSM6DSL_CTRL8_XL 0X17 +#define LSM6DSL_CTRL9_XL 0X18 +#define LSM6DSL_CTRL10_C 0X19 +#define LSM6DSL_INT2_CTRL 0X0E +#define LSM6DSL_WHO_AM_I 0x0F // get id +#define LSM6DSL_STATUS_REG 0x1E + +#define LSM6DSL_SENSORHUB11_REG 0X38 +#define LSM6DSL_TAP_CFG 0X58 +#define LSM6DSL_TAP_THS_6D 0X59 +#define LSM6DSL_INT_DUR2 0X5A +#define LSM6DSL_WAKE_UP_THS 0X5B +#define LSM6DSL_WAKE_UP_DUR 0X5C +#define LSM6DSL_FREE_FALL 0X5D +#define LSM6DSL_MD1_CFG 0X5E +#define PAI 3.14 +#define DEGREES 180 + +void InitGyro(void); +void Lsm_Get_RawAcc(void); +void LSM6DS_Init(void); +float GetPitchValue(void); + +void IMU_YAW_CAL(float gyroZ); +void GetRoll(float atan2x, float atan2y); +void GetPitch(float atan2x, float atan2y); +void IMU_Attitude_cal(float gcx, float gcy, float gcz, float acx, float acy, float acz); + +uint32_t LSM6DS_ReadCont(uint8_t reg_addr, uint8_t* buffer, uint16_t read_len); +uint32_t LSM6DS_Write(uint8_t addr, uint8_t writedata, uint32_t buffLen); +uint32_t LSM6DS_WriteRead(uint8_t reg_high_8bit_cmd, uint8_t send_len, uint8_t read_len); + +#endif // AHT20_H \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/led.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/led.c new file mode 100644 index 0000000000000000000000000000000000000000..0147324670cc704c0896095fdd3da0ef8ada2792 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/led.c @@ -0,0 +1,29 @@ +#include "debug.h" +#include "gpio.h" +#include "main.h" +#include "led.h" + +#define CYCLE_INTERVAL_TIME 500 + +/* ---------------------------------- Sample Parameters -------------------------------- */ +/** + * @brief Test GPIO PIN control LED. + * @param None + * @retval Value of @ref BASE_StatusType. + */ +BASE_StatusType GPIO_LedSample(void) +{ + /* Cycle control LED on and off. */ + while (1) { + BASE_FUNC_DELAY_MS(2000); + HAL_GPIO_TogglePin(&g_gpio2, GPIO_PIN_5); + BASE_FUNC_DELAY_MS(2000); + HAL_GPIO_TogglePin(&g_gpio2, GPIO_PIN_6); + BASE_FUNC_DELAY_MS(2000); + HAL_GPIO_TogglePin(&g_gpio2, GPIO_PIN_7); + BASE_FUNC_DELAY_MS(2000); + HAL_GPIO_TogglePin(&g_gpio5, GPIO_PIN_1); + DBG_PRINTF("LED Stata reverse! \r\n"); + } + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/led.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/led.h new file mode 100644 index 0000000000000000000000000000000000000000..9537887fea0ac3710e07d16f1c6e493f43594c42 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/led.h @@ -0,0 +1,6 @@ +#ifndef LED_H +#define LED_H + +BASE_StatusType GPIO_LedSample(void); + +#endif /* GPIO_LED_SAMPLE_H */ \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/main.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/main.c new file mode 100644 index 0000000000000000000000000000000000000000..a77cad1513681a37373189a418e60e3e93426cc1 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/main.c @@ -0,0 +1,129 @@ +/** + * @copyright Copyright (c) 2022, HiSilicon (Shanghai) Technologies Co., Ltd. All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * @file main.c + * @author MCU Driver Team + * @brief Main program body. + */ + +#include "typedefs.h" +#include "feature.h" +#include "main.h" +/* USER CODE BEGIN 0 */ +/* USER CODE 区域内代码不会被覆盖,区域外会被生成的默认代码覆盖(其余USER CODE 区域同理) */ +#include "debug.h" +#include "ssd1306.h" +#include "ssd1306_fonts.h" +#include "uart.h" +#include "user_motor_control.h" +#include "button.h" +#include "adc_demo.h" +#include "beep.h" +#include "gyro.h" +#include "encoder.h" +#include "eulercar_control.h" +#include "debug.h" +#include "pid.h" +/* 建议用户放置头文件 */ +/* USER CODE END 0 */ + +/* USER CODE BEGIN 1 */ +CAN_Handle g_can; +QDM_Handle g_qdm0; +QDM_Handle g_qdm1; +GPT_Handle g_gpt0; +GPT_Handle g_gpt1; +GPT_Handle g_gpt2; +GPT_Handle g_gpt3; +TIMER_Handle g_timer0; +UART_Handle g_uart0; +UART_Handle g_uart2; +UART_Handle g_uart3; +I2C_Handle g_i2c0; +I2C_Handle g_i2c1; +APT_Handle g_apt0; +APT_Handle g_apt1; +ADC_Handle g_adc0; +GPIO_Handle g_gpio1; +GPIO_Handle g_gpio2; +GPIO_Handle g_gpio5; + +char g_motorTypeStr[4][20] = { + "1:45 HALL", + "1:45 GMR", + "1:90 HALL", + "1:90 GMR", +}; + +/* +//减速比为1:90的霍尔传感器电机 +float g_motorMaxSpeed = MOTOR_MAX_SPEED_GEAR_90; +unsigned int g_curMotorType = MOTOR_TYPE_GEAR_HALL_90; +unsigned int g_motorLineNum = MOTOR_LINE_NUM_HALL_90; + +//减速比为1:90的GMR传感器电机 +float g_motorMaxSpeed = MOTOR_MAX_SPEED_GEAR_90; +unsigned int g_curMotorType = MOTOR_TYPE_GEAR_GMR_90; +unsigned int g_motorLineNum = MOTOR_LINE_NUM_GMR_90; + +//减速比为1:45的霍尔传感器电机 +float g_motorMaxSpeed = MOTOR_MAX_SPEED_GEAR_45; +unsigned int g_curMotorType = MOTOR_TYPE_GEAR_HALL_45; +unsigned int g_motorLineNum = MOTOR_LINE_NUM_HALL_45; + +//减速比为1:45的GMR传感器电机 +float g_motorMaxSpeed = MOTOR_MAX_SPEED_GEAR_45; +unsigned int g_curMotorType = MOTOR_TYPE_GEAR_GMR_45; +unsigned int g_motorLineNum = MOTOR_LINE_NUM_GMR_45; +*/ + +//减速比为1:90的GMR传感器电机 +float g_motorMaxSpeed = MOTOR_MAX_SPEED_GEAR_90; +unsigned int g_curMotorType = MOTOR_TYPE_GEAR_GMR_90; +unsigned int g_motorLineNum = MOTOR_LINE_NUM_GMR_90; + +/* 建议用户定义全局变量、结构体、宏定义或函数声明等 */ +/* USER CODE END 1 */ + +int main(void) +{ + SystemInit(); + InitGearMotor(); + Pid_Init(); + DBG_PRINTF("==============================================================\r\n"); + DBG_PRINTF(" • EulerCar Controller 1.0 • \r\n"); + DBG_PRINTF(" \r\n"); + DBG_PRINTF(" ➤ System Information: \r\n"); + DBG_PRINTF(" • Motor Type:%s\r\n",g_motorTypeStr[g_curMotorType]); + DBG_PRINTF(" • Motor Encode Line Number:%05d\r\n",g_motorLineNum); + DBG_PRINTF(" • Motor Max Speed:%.02fmm/s\r\n", g_motorMaxSpeed); + DBG_PRINTF(" • EulerCar Data Send Period:%dms,%dHZ\r\n", EULER_CAR_DATA_SEND_PERIOD, 1000/EULER_CAR_DATA_SEND_PERIOD); + DBG_PRINTF(" \r\n"); + DBG_PRINTF(" ➤ PID Information: \r\n"); + DBG_PRINTF(" • KP:%.02f • KI:%.02f • KD:%.02f\r\n",g_KP,g_KI,g_KD); + DBG_PRINTF(" • PID Control Period:%dms\r\n",MOTOR_PID_CONTROL_PERIOD); + DBG_PRINTF("==============================================================\r\n"); + DBG_PRINTF("EulerCar MCU init success!!!\r\n"); + HAL_TIMER_Start(&g_timer0); + DBG_PRINTF("TIMER start\r\n"); + InitButtonFunction(); + + UART3_INTRxSimultaneously(); + + /* USER CODE END 5 */ + return BASE_STATUS_OK; +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/pid.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/pid.c new file mode 100644 index 0000000000000000000000000000000000000000..5bec0f05558481a98eb38aa4cdd3ae11dfeff0a9 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/pid.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include +#include +#include +#include "debug.h" +#include "gpio.h" +#include "main.h" +#include "pid.h" + +extern unsigned int g_TimerInterruptCount; +unsigned int g_pid_count =0; + +/* 增量式PID控制结构体 */ +PidEulerCar g_pidEulerCarRight; +PidEulerCar g_pidEulerCarLeft; + +//增量式PID参数 +float g_KP = 1.2; +float g_KI = 15.0; +float g_KD = 0.0; + +//通过按键调整PID参数的步进增量参数 +float g_KP_Step = 0.1; +float g_KI_Step = 0.1; +float g_KD_Step = 0; + +void Pid_Init(void) +{ + g_pidEulerCarRight.SetSpeed = 0; + g_pidEulerCarRight.ActualSpeed = 0; + g_pidEulerCarRight.duty = 0; + g_pidEulerCarRight.err = 0; + g_pidEulerCarRight.err_next = 0; + g_pidEulerCarRight.err_last = 0; + g_pidEulerCarRight.IncSpeed = 0; + g_pidEulerCarRight.TargetIncSpeed = 0; + //DBG_PRINTF("pid right init success\r\n"); + + g_pidEulerCarLeft.SetSpeed = 0; + g_pidEulerCarLeft.ActualSpeed = 0; + g_pidEulerCarLeft.duty = 0; + g_pidEulerCarLeft.err = 0; + g_pidEulerCarLeft.err_next = 0; + g_pidEulerCarLeft.err_last = 0; + g_pidEulerCarLeft.IncSpeed = 0; + g_pidEulerCarLeft.TargetIncSpeed = 0; + //DBG_PRINTF("pid left init success\r\n"); +} + + +float Pid_Ctrl(PidEulerCar *pMotor) +{ + float IncrementSpeed; + unsigned int duty; + + //计算当前误差 + pMotor->err = pMotor->SetSpeed - pMotor->ActualSpeed; + + //增量式PID算法计算出增量,越接近目标速度,增量越接近零 + //增量式PID算法参数设定策略,先确定KI,再调KP,最后式KD + IncrementSpeed = g_KP * (pMotor->err - pMotor->err_next) + + g_KI * pMotor->err + + g_KD * (pMotor->err - 2 * pMotor->err_next + pMotor->err_last); + pMotor->TargetIncSpeed = pMotor->TargetIncSpeed + IncrementSpeed; + + +/* + err = state.target - state.actual;; + integral += (err * time_delta); + derivative = (error - previous_error) / time_delta; + state.output = ( (kp * err) + (ki * integral) + (kd * derivative) ); + state.previous_error = error; + return state; +*/ + + + pMotor->IncSpeed = IncrementSpeed; + + + //限制幅度 + if(pMotor->SetSpeed > 0){ + if (pMotor->TargetIncSpeed > g_motorMaxSpeed){ + pMotor->TargetIncSpeed = g_motorMaxSpeed; + } + if (pMotor->TargetIncSpeed < 0){ + pMotor->TargetIncSpeed = 0; + } + } + + if(pMotor->SetSpeed < 0){ + if (pMotor->TargetIncSpeed < -g_motorMaxSpeed){ + pMotor->TargetIncSpeed = -g_motorMaxSpeed; + } + if (pMotor->TargetIncSpeed > 0){ + pMotor->TargetIncSpeed = 0; + } + } + + //电机需要设置的占空比 + duty = (abs)((int)(pMotor->TargetIncSpeed/g_motorMaxSpeed * 100.0)); + if (duty > 99) { + duty = 99; + } + pMotor->duty = duty; + + pMotor->err_last = pMotor->err_next; + pMotor->err_next = pMotor->err; + + + return pMotor->TargetIncSpeed; +} diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/pid.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/pid.h new file mode 100644 index 0000000000000000000000000000000000000000..6521d1d2ad78720b6679981dc26b83df841a632a --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/pid.h @@ -0,0 +1,19 @@ +#ifndef PID_H +#define PID_H + +//增量式PID控制算法结构体 +typedef struct { + float SetSpeed; //上位机设定速度 + float ActualSpeed; //编码器实际测试速度 + float err; //偏差值 + float err_next; //上一个偏差值 + float err_last; //上上一个偏差值 + float IncSpeed; //增量式PID算法计算出的增量速度 + float TargetIncSpeed; //增量式PID算法目标增量速度 + unsigned int duty; //电机PWM占空比 +} PidEulerCar; + +void Pid_Init(void); +float Pid_Ctrl(PidEulerCar *pMotor); + +#endif \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306.c new file mode 100644 index 0000000000000000000000000000000000000000..c9cd0317e0210ab07379122fe083a1a741a0a461 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306.c @@ -0,0 +1,560 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include // For memcpy +#include +#include +#include +#include +#include "i2c.h" +#include "main.h" +#include "debug.h" +#include "ssd1306.h" + +#define I2C_SLAVE2_ADDR 0x78 +#define SSD1306_CTRL_CMD 0x00 +#define SSD1306_CTRL_DATA 0x40 +#define SSD1306_MASK_CONT (0x1 << 7) +#define DOUBLE 2 + + +void ssd1306_Reset(void) +{ + /* for I2C - do nothing */ +} + +static uint32_t ssd1306_SendData(uint8_t* buffer, uint32_t size) +{ + uint16_t dev_addr = I2C_SLAVE2_ADDR; + uint32_t retval = HAL_I2C_MasterWriteBlocking(&g_i2c1, dev_addr, buffer, size, 10000); + if (retval != BASE_STATUS_OK) { + DBG_PRINTF("I2cWrite(0x%X) failed, 0x%X!\n", buffer[1], retval); + return retval; + } + return 0; +} + +static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte) +{ + uint8_t buffer[] = {regAddr, byte}; + return ssd1306_SendData(buffer, sizeof(buffer)); +} + +// Send a byte to the command register +void ssd1306_WriteCommand(uint8_t byte) +{ + ssd1306_WiteByte(SSD1306_CTRL_CMD, byte); +} + +// Send data +void ssd1306_WriteData(uint8_t* buffer, uint32_t buff_size) +{ + uint8_t data[SSD1306_WIDTH * DOUBLE] = {0}; + for (uint32_t i = 0; i < buff_size; i++) { + data[i * DOUBLE] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT; + data[i * DOUBLE + 1] = buffer[i]; + } + data[(buff_size - 1) * DOUBLE] = SSD1306_CTRL_DATA; + ssd1306_SendData(data, sizeof(data)); +} + +// Screenbuffer +static uint8_t SSD1306_Buffer[SSD1306_BUFFER_SIZE]; + +// Screen object +static SSD1306_t SSD1306; + +/* Fills the Screenbuffer with values from a given buffer of a fixed length */ +SSD1306_Error_t ssd1306_FillBuffer(uint8_t* buf, uint32_t len) +{ + SSD1306_Error_t ret = SSD1306_ERR; + if (len <= SSD1306_BUFFER_SIZE) { + memcpy_s(SSD1306_Buffer, len + 1, buf, len); + ret = SSD1306_OK; + } + return ret; +} + +void ssd1306_Init_CMD(void) +{ + ssd1306_WriteCommand(0xA4); // 0xa4,Output follows RAM content;0xa5,Output ignores RAM content + + ssd1306_WriteCommand(0xD3); // -set display offset - CHECK + ssd1306_WriteCommand(0x00); // -not offset + + ssd1306_WriteCommand(0xD5); // --set display clock divide ratio/oscillator frequency + ssd1306_WriteCommand(0xF0); // --set divide ratio + + ssd1306_WriteCommand(0xD9); // --set pre-charge period + ssd1306_WriteCommand(0x11); // 0x22 by default + + ssd1306_WriteCommand(0xDA); // --set com pins hardware configuration - CHECK +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x02); +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x12); +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x12); +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + + ssd1306_WriteCommand(0xDB); // --set vcomh + ssd1306_WriteCommand(0x30); // 0x20,0.77xVcc, 0x30,0.83xVcc + + ssd1306_WriteCommand(0x8D); // --set DC-DC enable + ssd1306_WriteCommand(0x14); // + ssd1306_SetDisplayOn(1); // --turn on SSD1306 panel +} + +// Initialize the oled screen +void ssd1306_Init(void) +{ + // Reset OLED + ssd1306_Reset(); + + // Wait for the screen to boot + BASE_FUNC_DELAY_MS(10); // 10000us The delay here is very important + + // Init OLED + ssd1306_SetDisplayOn(0); // display off + + ssd1306_WriteCommand(0x20); // Set Memory Addressing Mode + ssd1306_WriteCommand(0x00); // 00b,Horizontal Addressing Mode; 01b,Vertical Addressing Mode; + // 10b,Page Addressing Mode (RESET); 11b,Invalid + + ssd1306_WriteCommand(0xB0); // Set Page Start Address for Page Addressing Mode,0-7 + +#ifdef SSD1306_MIRROR_VERT + ssd1306_WriteCommand(0xC0); // Mirror vertically +#else + ssd1306_WriteCommand(0xC8); // Set COM Output Scan Direction +#endif + + ssd1306_WriteCommand(0x00); // ---set low column address + ssd1306_WriteCommand(0x10); // ---set high column address + + ssd1306_WriteCommand(0x40); // --set start line address - CHECK + + ssd1306_SetContrast(0xFF); + +#ifdef SSD1306_MIRROR_HORIZ + ssd1306_WriteCommand(0xA0); // Mirror horizontally +#else + ssd1306_WriteCommand(0xA1); // --set segment re-map 0 to 127 - CHECK +#endif + +#ifdef SSD1306_INVERSE_COLOR + ssd1306_WriteCommand(0xA7); // --set inverse color +#else + ssd1306_WriteCommand(0xA6); // --set normal color +#endif + +// Set multiplex ratio. +#if (SSD1306_HEIGHT == 128) + // Found in the Luma Python lib for SH1106. + ssd1306_WriteCommand(0xFF); +#else + ssd1306_WriteCommand(0xA8); // --set multiplex ratio(1 to 64) - CHECK +#endif + +#if (SSD1306_HEIGHT == 32) + ssd1306_WriteCommand(0x1F); // +#elif (SSD1306_HEIGHT == 64) + ssd1306_WriteCommand(0x3F); // +#elif (SSD1306_HEIGHT == 128) + ssd1306_WriteCommand(0x3F); // Seems to work for 128px high displays too. +#else +#error "Only 32, 64, or 128 lines of height are supported!" +#endif + ssd1306_Init_CMD(); + // Clear screen + ssd1306_Fill(Black); + + // Flush buffer to screen + ssd1306_UpdateScreen(); + + // Set default values for screen object + SSD1306.CurrentX = 0; + SSD1306.CurrentY = 0; + + SSD1306.Initialized = 1; +} + +// Fill the whole screen with the given color +void ssd1306_Fill(SSD1306_COLOR color) +{ + /* Set memory */ + uint32_t i; + + for (i = 0; i < sizeof(SSD1306_Buffer); i++) { + SSD1306_Buffer[i] = (color == Black) ? 0x00 : 0xFF; + } +} + +// Write the screenbuffer with changed to the screen +void ssd1306_UpdateScreen(void) +{ + // Write data to each page of RAM. Number of pages + // depends on the screen height: + // + // * 32px == 4 pages + // * 64px == 8 pages + // * 128px == 16 pages + + uint8_t cmd[] = { + 0X21, // 设置列起始和结束地址 + 0X00, // 列起始地址 0 + 0X7F, // 列终止地址 127 + 0X22, // 设置页起始和结束地址 + 0X00, // 页起始地址 0 + 0X07, // 页终止地址 7 + }; + uint32_t count = 0; + uint8_t data[sizeof(cmd) * DOUBLE + SSD1306_BUFFER_SIZE + 1] = {}; + + // copy cmd + for (uint32_t i = 0; i < sizeof(cmd) / sizeof(cmd[0]); i++) { + data[count++] = SSD1306_CTRL_CMD | SSD1306_MASK_CONT; + data[count++] = cmd[i]; + } + + // copy frame data + data[count++] = SSD1306_CTRL_DATA; + memcpy_s(&data[count], SSD1306_BUFFER_SIZE + 1, SSD1306_Buffer, SSD1306_BUFFER_SIZE); + count += sizeof(SSD1306_Buffer); + + // send to i2c bus + uint32_t retval = ssd1306_SendData(data, count); + if (retval != 0) { + DBG_PRINTF("ssd1306_UpdateScreen send frame data filed: %d!\r\n", retval); + } +} + +// Draw one pixel in the screenbuffer +// X => X Coordinate +// Y => Y Coordinate +// color => Pixel color +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) +{ + if (x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) { + // Don't write outside the buffer + return; + } + SSD1306_COLOR color1 = color; + // Check if pixel should be inverted + if (SSD1306.Inverted) { + color1 = (SSD1306_COLOR)!color1; + } + + // Draw in the right color + uint32_t c = 8; // 8 + if (color == White) { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] |= 1 << (y % c); + } else { + SSD1306_Buffer[x + (y / c) * SSD1306_WIDTH] &= ~(1 << (y % c)); + } +} + +// Draw 1 char to the screen buffer +// ch => char om weg te schrijven +// Font => Font waarmee we gaan schrijven +// color => Black or White +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color) +{ + uint32_t i, b, j; + + // Check if character is valid + uint32_t ch_min = 32; // 32 + uint32_t ch_max = 126; // 126 + if ((uint32_t)ch < ch_min || (uint32_t)ch > ch_max) { + return 0; + } + + // Check remaining space on current line + if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) || + SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight)) { + // Not enough space on current line + return 0; + } + + // Use the font to write + for (i = 0; i < Font.FontHeight; i++) { + b = Font.data[(ch - ch_min) * Font.FontHeight + i]; + for (j = 0; j < Font.FontWidth; j++) { + if ((b << j) & 0x8000) { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR) color); + } else { + ssd1306_DrawPixel(SSD1306.CurrentX + j, (SSD1306.CurrentY + i), (SSD1306_COLOR)!color); + } + } + } + + // The current space is now taken + SSD1306.CurrentX += Font.FontWidth; + + // Return written char for validation + return ch; +} + +// Write full string to screenbuffer +char ssd1306_DrawString(char* str, FontDef Font, SSD1306_COLOR color) +{ + // Write until null-byte + char* str1 = str; + while (*str1) { + if (ssd1306_DrawChar(*str1, Font, color) != *str1) { + // Char could not be written + return *str1; + } + // Next char + str1++; + } + + // Everything ok + return *str1; +} + +// Position the cursor +void ssd1306_SetCursor(uint8_t x, uint8_t y) +{ + SSD1306.CurrentX = x; + SSD1306.CurrentY = y; +} + +// Draw line by Bresenhem's algorithm +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + uint8_t x = x1; + uint8_t y = y1; + int32_t deltaX = abs(x2 - x1); + int32_t deltaY = abs(y2 - y1); + int32_t signX = ((x1 < x2) ? 1 : -1); + int32_t signY = ((y1 < y2) ? 1 : -1); + int32_t error = deltaX - deltaY; + int32_t error2; + ssd1306_DrawPixel(x2, y2, color); + while ((x1 != x2) || (y1 != y2)) { + ssd1306_DrawPixel(x1, y1, color); + error2 = error * DOUBLE; + if (error2 > -deltaY) { + error -= deltaY; + x += signX; + } else { + /* nothing to do */ + } + if (error2 < deltaX) { + error += deltaX; + y += signY; + } else { + /* nothing to do */ + } + } +} + +// Draw polyline +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color) +{ + uint16_t i; + if (par_vertex != 0) { + for (i = 1; i < par_size; i++) { + ssd1306_DrawLine(par_vertex[i - 1].x, par_vertex[i - 1].y, par_vertex[i].x, par_vertex[i].y, color); + } + } else { + /* nothing to do */ + } + return; +} + +// Draw circle by Bresenhem's algorithm +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color) +{ + int32_t x = -par_r; + int32_t y = 0; + int32_t b = 2; + int32_t err = b - b * par_r; + int32_t e2; + + if (par_x >= SSD1306_WIDTH || par_y >= SSD1306_HEIGHT) { + return; + } + + do { + ssd1306_DrawPixel(par_x - x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y + y, par_color); + ssd1306_DrawPixel(par_x + x, par_y - y, par_color); + ssd1306_DrawPixel(par_x - x, par_y - y, par_color); + e2 = err; + if (e2 <= y) { + y++; + err = err + (y * b + 1); + if (-x == y && e2 <= x) { + e2 = 0; + } else { + /* nothing to do */ + } + } else { + /* nothing to do */ + } + if (e2 > x) { + x++; + err = err + (x * b + 1); + } else { + /* nothing to do */ + } + } while (x <= 0); + + return; +} + +// Draw rectangle +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color) +{ + ssd1306_DrawLine(x1, y1, x2, y1, color); + ssd1306_DrawLine(x2, y1, x2, y2, color); + ssd1306_DrawLine(x2, y2, x1, y2, color); + ssd1306_DrawLine(x1, y2, x1, y1, color); +} + +void ssd1306_DrawBitmap(const uint8_t* bitmap, uint32_t size) +{ + unsigned int c = 8; + uint8_t rows = size * c / SSD1306_WIDTH; + if (rows > SSD1306_HEIGHT) { + rows = SSD1306_HEIGHT; + } + for (uint8_t y = 0; y < rows; y++) { + for (uint8_t x = 0; x < SSD1306_WIDTH; x++) { + uint8_t byte = bitmap[(y * SSD1306_WIDTH / c) + (x / c)]; + uint8_t bit = byte & (0x80 >> (x % c)); + ssd1306_DrawPixel(x, y, bit ? White : Black); + } + } +} + +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t* data, uint32_t size) +{ + uint32_t stride = w; + uint8_t h = w; // 字体宽高一样 + uint8_t width = w; + if (x + w > SSD1306_WIDTH || y + h > SSD1306_HEIGHT || w * h == 0) { + DBG_PRINTF("%dx%d @ %d,%d out of range or invalid!\r\n", w, h, x, y); + return; + } + + width = (width <= SSD1306_WIDTH ? width : SSD1306_WIDTH); + h = (h <= SSD1306_HEIGHT ? h : SSD1306_HEIGHT); + stride = (stride == 0 ? w : stride); + unsigned int c = 8; + + uint8_t rows = size * c / stride; + for (uint8_t i = 0; i < rows; i++) { + uint32_t base = i * stride / c; + for (uint8_t j = 0; j < width; j++) { + uint32_t idx = base + (j / c); + uint8_t byte = idx < size ? data[idx] : 0; + uint8_t bit = byte & (0x80 >> (j % c)); + ssd1306_DrawPixel(x + j, y + i, bit ? White : Black); + } + } +} + +void ssd1306_SetContrast(const uint8_t value) +{ + const uint8_t kSetContrastControlRegister = 0x81; + ssd1306_WriteCommand(kSetContrastControlRegister); + ssd1306_WriteCommand(value); +} + +void ssd1306_SetDisplayOn(const uint8_t on) +{ + uint8_t value; + if (on) { + value = 0xAF; // Display on + SSD1306.DisplayOn = 1; + } else { + value = 0xAE; // Display off + SSD1306.DisplayOn = 0; + } + ssd1306_WriteCommand(value); +} + +uint8_t ssd1306_GetDisplayOn(void) +{ + return SSD1306.DisplayOn; +} + +void *memcpy_custom(void *dest, const void *src, size_t n) +{ + char *d = (char *)dest; + const char *s = (const char *)src; + + // 逐字节复制源字符串到目标字符串 + for (size_t i = 0; i < n; i++) { + d[i] = s[i]; + } + + return dest; +} + +#define SSD_MAX_LENGTH 12 +void ssd1306_print(char *str) // 每行最多11个字节,最多三行,Y轴20 +{ + int str_length = strlen(str); + if (str_length > 33) + { + DBG_PRINTF("ssd1306_print len %d \r\n",str_length); + return; + } + ssd1306_Fill(Black); + + if (str_length <= 11) //1行 + { + ssd1306_SetCursor(1, 0); + ssd1306_DrawString(str, Font_11x18, White); + ssd1306_UpdateScreen(); + return; + } + + if ((str_length > 11) && (str_length <= 22)) //2行 + { + ssd1306_SetCursor(1, 0); + char buff[SSD_MAX_LENGTH] = {0}; + memcpy_custom(buff,str,11); + ssd1306_DrawString(buff, Font_11x18, White); + ssd1306_SetCursor(1, 20); + ssd1306_DrawString(str+11, Font_11x18, White); + ssd1306_UpdateScreen(); + return; + } + + if (str_length > 22) //3行 + { + ssd1306_SetCursor(1, 0); + char buff[SSD_MAX_LENGTH] = {0}; + memcpy_custom(buff,str,11); + ssd1306_DrawString(buff, Font_11x18, White); + ssd1306_SetCursor(1, 20); + memcpy_custom(buff,str+11,11); + ssd1306_DrawString(buff, Font_11x18, White); + + ssd1306_SetCursor(1, 40); + ssd1306_DrawString(str+22, Font_11x18, White); + ssd1306_UpdateScreen(); + return; + } +} diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306.h new file mode 100644 index 0000000000000000000000000000000000000000..bf6f82874848b74b4a87c62a2469210f725eecfb --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SSD1306_H +#define SSD1306_H + +#include +#include +#include "ssd1306_fonts.h" + +/* vvv I2C config vvv */ + +#define SSD1306_USE_I2C +#ifndef SSD1306_I2C_PORT +#define SSD1306_I2C_PORT hi2c1 +#endif + +// #ifndef SSD1306_I2C_ADDR +// #define SSD1306_I2C_ADDR (0x3C << 1) +// #endif + +/* ^^^ I2C config ^^^ */ + +/* vvv SPI config vvv */ + +#ifndef SSD1306_SPI_PORT +#define SSD1306_SPI_PORT hspi2 +#endif + +#ifndef SSD1306_CS_Port +#define SSD1306_CS_Port GPIOB +#endif +#ifndef SSD1306_CS_Pin +#define SSD1306_CS_Pin GPIO_PIN_12 +#endif + +#ifndef SSD1306_DC_Port +#define SSD1306_DC_Port GPIOB +#endif +#ifndef SSD1306_DC_Pin +#define SSD1306_DC_Pin GPIO_PIN_14 +#endif + +#ifndef SSD1306_Reset_Port +#define SSD1306_Reset_Port GPIOA +#endif +#ifndef SSD1306_Reset_Pin +#define SSD1306_Reset_Pin GPIO_PIN_8 +#endif + +/* ^^^ SPI config ^^^ */ + +#if defined(SSD1306_USE_I2C) +#elif defined(SSD1306_USE_SPI) +extern SPI_HandleTypeDef SSD1306_SPI_PORT; +#else +#error "You should define SSD1306_USE_SPI or SSD1306_USE_I2C macro!" +#endif + +// SSD1306 OLED height in pixels +#ifndef SSD1306_HEIGHT +#define SSD1306_HEIGHT 64 +#endif + +// SSD1306 width in pixels +#ifndef SSD1306_WIDTH +#define SSD1306_WIDTH 128 +#endif + +// some LEDs don't display anything in first two columns + +#ifndef SSD1306_BUFFER_SIZE +#define SSD1306_BUFFER_SIZE (SSD1306_WIDTH * SSD1306_HEIGHT / 8) +#endif + +// Enumeration for screen colors +typedef enum { + Black = 0x00, // Black color, no pixel + White = 0x01 // Pixel is set. Color depends on OLED +} SSD1306_COLOR; + +typedef enum { + SSD1306_OK = 0x00, + SSD1306_ERR = 0x01 // Generic error. +} SSD1306_Error_t; + +// Struct to store transformations +typedef struct { + uint16_t CurrentX; + uint16_t CurrentY; + uint8_t Inverted; + uint8_t Initialized; + uint8_t DisplayOn; +} SSD1306_t; +typedef struct { + uint8_t x; + uint8_t y; +} SSD1306_VERTEX; + +// Procedure definitions +void ssd1306_Init(void); +void ssd1306_Fill(SSD1306_COLOR color); +void ssd1306_SetCursor(uint8_t x, uint8_t y); +void ssd1306_UpdateScreen(void); + +char ssd1306_DrawChar(char ch, FontDef Font, SSD1306_COLOR color); +char ssd1306_DrawString(char* str, FontDef Font, SSD1306_COLOR color); + +void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color); +void ssd1306_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawPolyline(const SSD1306_VERTEX *par_vertex, uint16_t par_size, SSD1306_COLOR color); +void ssd1306_DrawRectangle(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color); +void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR par_color); +void ssd1306_DrawBitmap(const uint8_t* bitmap, uint32_t size); +void ssd1306_DrawRegion(uint8_t x, uint8_t y, uint8_t w, const uint8_t* data, uint32_t size); +void *memcpy_custom(void *dest, const void *src, size_t n); + +/** + * @brief Sets the contrast of the display. + * @param[in] value contrast to set. + * @note Contrast increases as the value increases. + * @note RESET = 7Fh. + */ +void ssd1306_SetContrast(const uint8_t value); +/** + * @brief Set Display ON/OFF. + * @param[in] on 0 for OFF, any for ON. + */ +void ssd1306_SetDisplayOn(const uint8_t on); +/** + * @brief Reads DisplayOn state. + * @return 0: OFF. + * 1: ON. + */ +uint8_t ssd1306_GetDisplayOn(void); + +void HAL_Delay(uint32_t ms); + +uint32_t HAL_GetTick(void); // in ms + +// Low-level procedures +void ssd1306_Init_CMD(void); +void ssd1306_Reset(void); +void ssd1306_WriteCommand(uint8_t byte); +void ssd1306_WriteData(uint8_t* buffer, size_t buff_size); +SSD1306_Error_t ssd1306_FillBuffer(uint8_t* buf, uint32_t len); +void ssd1306_ClearOLED(void); +void ssd1306_printf(char *fmt, ...); +void ssd1306_print(char *str); + +#endif // __SSD1306_H__ \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306_fonts.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306_fonts.c new file mode 100644 index 0000000000000000000000000000000000000000..725489259f7eef0f72ae7a71269ea9311f798eaf --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306_fonts.c @@ -0,0 +1,915 @@ +/* + MIT License + + Copyright (c) 2018-2019, Alexey Dynda + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +/* + * ssd1306xled_font6x8 is by Neven Boyanov + * ssd1306xled_font8x16 is by Neven Boyanov + * + * @created: 2014-08-12 + * @author: Neven Boyanov + * + * Copyright (c) 2015 Neven Boyanov, Tinusaur Team. All Rights Reserved. + * Distributed as open source software under MIT License, see LICENSE.txt file. + * Please, as a favour, retain the link http://tinusaur.org to The Tinusaur Project. + * + * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled + * + */ + +#include "ssd1306_fonts.h" + +/************************************6*8的点阵************************************/ +const unsigned char g_f6X8[][6] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp + { 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! + { 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 }, // " + { 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # + { 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ + { 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 }, // % + { 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 }, // & + { 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' + { 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( + { 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) + { 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * + { 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + + { 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 }, // , + { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 }, // - + { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, // . + { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 }, // / + { 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 + { 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 + { 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 + { 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 + { 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 + { 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 + { 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 + { 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 + { 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 + { 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 + { 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // : + { 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;号 + { 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, // < + { 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 }, // = + { 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 }, // > + { 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? + { 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ + { 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A + { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B + { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C + { 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D + { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E + { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F + { 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G + { 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H + { 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I + { 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J + { 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K + { 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L + { 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M + { 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N + { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O + { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P + { 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q + { 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R + { 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }, // S + { 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T + { 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U + { 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V + { 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W + { 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }, // X + { 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y + { 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z + { 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ + { 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55 + { 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] + { 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ + { 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ + { 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' + { 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 }, // a + { 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b + { 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 }, // c + { 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F }, // d + { 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 }, // e + { 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f + { 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g + { 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h + { 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i + { 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j + { 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k + { 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l + { 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m + { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n + { 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 }, // o + { 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p + { 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC }, // q + { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r + { 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 }, // s + { 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t + { 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u + { 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v + { 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w + { 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 }, // x + { 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y + { 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z + { 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 }, // horiz lines +}; + +/****************************************8*16的点阵************************************/ +const unsigned char g_f8X16[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, // ! 1 + 0x00, 0x10, 0x0C, 0x06, 0x10, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " 2 + 0x40, 0xC0, 0x78, 0x40, 0xC0, 0x78, 0x40, 0x00, 0x04, 0x3F, 0x04, 0x04, 0x3F, 0x04, 0x04, 0x00, // # 3 + 0x00, 0x70, 0x88, 0xFC, 0x08, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0xFF, 0x21, 0x1E, 0x00, 0x00, // $ 4 + 0xF0, 0x08, 0xF0, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x00, 0x21, 0x1C, 0x03, 0x1E, 0x21, 0x1E, 0x00, // % 5 + 0x00, 0xF0, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x21, 0x23, 0x24, 0x19, 0x27, 0x21, 0x10, // & 6 + 0x10, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' 7 + 0x00, 0x00, 0x00, 0xE0, 0x18, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x00, // ( 8 + 0x00, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, // ) 9 + 0x40, 0x40, 0x80, 0xF0, 0x80, 0x40, 0x40, 0x00, 0x02, 0x02, 0x01, 0x0F, 0x01, 0x02, 0x02, 0x00, // * 10 + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x1F, 0x01, 0x01, 0x01, 0x00, // + 11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xB0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, // , 12 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // - 13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, // . 14 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x04, 0x00, 0x60, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, // / 15 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x10, 0x0F, 0x00, // 0 16 + 0x00, 0x10, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // 1 17 + 0x00, 0x70, 0x08, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x30, 0x28, 0x24, 0x22, 0x21, 0x30, 0x00, // 2 18 + 0x00, 0x30, 0x08, 0x88, 0x88, 0x48, 0x30, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // 3 19 + 0x00, 0x00, 0xC0, 0x20, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x07, 0x04, 0x24, 0x24, 0x3F, 0x24, 0x00, // 4 20 + 0x00, 0xF8, 0x08, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00, 0x19, 0x21, 0x20, 0x20, 0x11, 0x0E, 0x00, // 5 21 + 0x00, 0xE0, 0x10, 0x88, 0x88, 0x18, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // 6 22 + 0x00, 0x38, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // 7 23 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x1C, 0x22, 0x21, 0x21, 0x22, 0x1C, 0x00, // 8 24 + 0x00, 0xE0, 0x10, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x00, 0x00, 0x31, 0x22, 0x22, 0x11, 0x0F, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, // ;号 27 + 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, // < 28 + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, // = 29 + 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, // > 30 + 0x00, 0x70, 0x48, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x36, 0x01, 0x00, 0x00, // ? 31 + 0xC0, 0x30, 0xC8, 0x28, 0xE8, 0x10, 0xE0, 0x00, 0x07, 0x18, 0x27, 0x24, 0x23, 0x14, 0x0B, 0x00, // @ 32 + 0x00, 0x00, 0xC0, 0x38, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x3C, 0x23, 0x02, 0x02, 0x27, 0x38, 0x20, // A 33 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x70, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x11, 0x0E, 0x00, // B 34 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x07, 0x18, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, // C 35 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // D 36 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x23, 0x20, 0x18, 0x00, // E 37 + 0x08, 0xF8, 0x88, 0x88, 0xE8, 0x08, 0x10, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, // F 38 + 0xC0, 0x30, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x07, 0x18, 0x20, 0x20, 0x22, 0x1E, 0x02, 0x00, // G 39 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x21, 0x3F, 0x20, // H 40 + 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // I 41 + 0x00, 0x00, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, 0x00, // J 42 + 0x08, 0xF8, 0x88, 0xC0, 0x28, 0x18, 0x08, 0x00, 0x20, 0x3F, 0x20, 0x01, 0x26, 0x38, 0x20, 0x00, // K 43 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x30, 0x00, // L 44 + 0x08, 0xF8, 0xF8, 0x00, 0xF8, 0xF8, 0x08, 0x00, 0x20, 0x3F, 0x00, 0x3F, 0x00, 0x3F, 0x20, 0x00, // M 45 + 0x08, 0xF8, 0x30, 0xC0, 0x00, 0x08, 0xF8, 0x08, 0x20, 0x3F, 0x20, 0x00, 0x07, 0x18, 0x3F, 0x00, // N 46 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x10, 0x20, 0x20, 0x20, 0x10, 0x0F, 0x00, // O 47 + 0x08, 0xF8, 0x08, 0x08, 0x08, 0x08, 0xF0, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x01, 0x01, 0x00, 0x00, // P 48 + 0xE0, 0x10, 0x08, 0x08, 0x08, 0x10, 0xE0, 0x00, 0x0F, 0x18, 0x24, 0x24, 0x38, 0x50, 0x4F, 0x00, // Q 49 + 0x08, 0xF8, 0x88, 0x88, 0x88, 0x88, 0x70, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x03, 0x0C, 0x30, 0x20, // R 50 + 0x00, 0x70, 0x88, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x38, 0x20, 0x21, 0x21, 0x22, 0x1C, 0x00, // S 51 + 0x18, 0x08, 0x08, 0xF8, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // T 52 + 0x08, 0xF8, 0x08, 0x00, 0x00, 0x08, 0xF8, 0x08, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // U 53 + 0x08, 0x78, 0x88, 0x00, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x07, 0x38, 0x0E, 0x01, 0x00, 0x00, // V 54 + 0xF8, 0x08, 0x00, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x03, 0x3C, 0x07, 0x00, 0x07, 0x3C, 0x03, 0x00, // W 55 + 0x08, 0x18, 0x68, 0x80, 0x80, 0x68, 0x18, 0x08, 0x20, 0x30, 0x2C, 0x03, 0x03, 0x2C, 0x30, 0x20, // X 56 + 0x08, 0x38, 0xC8, 0x00, 0xC8, 0x38, 0x08, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x00, 0x00, // Y 57 + 0x10, 0x08, 0x08, 0x08, 0xC8, 0x38, 0x08, 0x00, 0x20, 0x38, 0x26, 0x21, 0x20, 0x20, 0x18, 0x00, // Z 58 + 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x00, // [ 59 + 0x00, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0xC0, 0x00, // \ 60 + 0x00, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x7F, 0x00, 0x00, 0x00, // ] 61 + 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // _ 63 + 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x19, 0x24, 0x22, 0x22, 0x22, 0x3F, 0x20, // a 65 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x11, 0x20, 0x20, 0x11, 0x0E, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x20, 0x11, 0x00, // c 67 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x88, 0xF8, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0x10, 0x3F, 0x20, // d 68 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x22, 0x22, 0x22, 0x22, 0x13, 0x00, // e 69 + 0x00, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x18, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x6B, 0x94, 0x94, 0x94, 0x93, 0x60, 0x00, // g 71 + 0x08, 0xF8, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // h 72 + 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // i 73 + 0x00, 0x00, 0x00, 0x80, 0x98, 0x98, 0x00, 0x00, 0x00, 0xC0, 0x80, 0x80, 0x80, 0x7F, 0x00, 0x00, // j 74 + 0x08, 0xF8, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x24, 0x02, 0x2D, 0x30, 0x20, 0x00, // k 75 + 0x00, 0x08, 0x08, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x3F, 0x20, 0x20, 0x00, 0x00, // l 76 + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x20, 0x3F, 0x20, 0x00, 0x3F, 0x20, 0x00, 0x3F, // m 77 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x00, 0x00, 0x20, 0x3F, 0x20, // n 78 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, // o 79 + 0x80, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xA1, 0x20, 0x20, 0x11, 0x0E, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0E, 0x11, 0x20, 0x20, 0xA0, 0xFF, 0x80, // q 81 + 0x80, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x20, 0x20, 0x3F, 0x21, 0x20, 0x00, 0x01, 0x00, // r 82 + 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x33, 0x24, 0x24, 0x24, 0x24, 0x19, 0x00, // s 83 + 0x00, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x00, 0x00, // t 84 + 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x1F, 0x20, 0x20, 0x20, 0x10, 0x3F, 0x20, // u 85 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x01, 0x0E, 0x30, 0x08, 0x06, 0x01, 0x00, // v 86 + 0x80, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, 0x0F, 0x30, 0x0C, 0x03, 0x0C, 0x30, 0x0F, 0x00, // w 87 + 0x00, 0x80, 0x80, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x31, 0x2E, 0x0E, 0x31, 0x20, 0x00, // x 88 + 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x81, 0x8E, 0x70, 0x18, 0x06, 0x01, 0x00, // y 89 + 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x21, 0x30, 0x2C, 0x22, 0x21, 0x30, 0x00, // z 90 + 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x40, 0x40, // { 91 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // | 92 + 0x00, 0x02, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, // } 93 + 0x00, 0x06, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ~ 94 +}; + + +static const unsigned short Font7x10 [] = { +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp +0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ! +0x2800, 0x2800, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " +0x2400, 0x2400, 0x7C00, 0x2400, 0x4800, 0x7C00, 0x4800, 0x4800, 0x0000, 0x0000, // # +0x3800, 0x5400, 0x5000, 0x3800, 0x1400, 0x5400, 0x5400, 0x3800, 0x1000, 0x0000, // $ +0x2000, 0x5400, 0x5800, 0x3000, 0x2800, 0x5400, 0x1400, 0x0800, 0x0000, 0x0000, // % +0x1000, 0x2800, 0x2800, 0x1000, 0x3400, 0x4800, 0x4800, 0x3400, 0x0000, 0x0000, // & +0x1000, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' +0x0800, 0x1000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x1000, 0x0800, // ( +0x2000, 0x1000, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x1000, 0x2000, // ) +0x1000, 0x3800, 0x1000, 0x2800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * +0x0000, 0x0000, 0x1000, 0x1000, 0x7C00, 0x1000, 0x1000, 0x0000, 0x0000, 0x0000, // + +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // , +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3800, 0x0000, 0x0000, 0x0000, 0x0000, // - +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // . +0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x0000, 0x0000, // / +0x3800, 0x4400, 0x4400, 0x5400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 0 +0x1000, 0x3000, 0x5000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // 1 +0x3800, 0x4400, 0x4400, 0x0400, 0x0800, 0x1000, 0x2000, 0x7C00, 0x0000, 0x0000, // 2 +0x3800, 0x4400, 0x0400, 0x1800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 3 +0x0800, 0x1800, 0x2800, 0x2800, 0x4800, 0x7C00, 0x0800, 0x0800, 0x0000, 0x0000, // 4 +0x7C00, 0x4000, 0x4000, 0x7800, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 5 +0x3800, 0x4400, 0x4000, 0x7800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 6 +0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000, // 7 +0x3800, 0x4400, 0x4400, 0x3800, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // 8 +0x3800, 0x4400, 0x4400, 0x4400, 0x3C00, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // 9 +0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, // : +0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x1000, 0x1000, 0x1000, // ; +0x0000, 0x0000, 0x0C00, 0x3000, 0x4000, 0x3000, 0x0C00, 0x0000, 0x0000, 0x0000, // < +0x0000, 0x0000, 0x0000, 0x7C00, 0x0000, 0x7C00, 0x0000, 0x0000, 0x0000, 0x0000, // = +0x0000, 0x0000, 0x6000, 0x1800, 0x0400, 0x1800, 0x6000, 0x0000, 0x0000, 0x0000, // > +0x3800, 0x4400, 0x0400, 0x0800, 0x1000, 0x1000, 0x0000, 0x1000, 0x0000, 0x0000, // ? +0x3800, 0x4400, 0x4C00, 0x5400, 0x5C00, 0x4000, 0x4000, 0x3800, 0x0000, 0x0000, // @ +0x1000, 0x2800, 0x2800, 0x2800, 0x2800, 0x7C00, 0x4400, 0x4400, 0x0000, 0x0000, // A +0x7800, 0x4400, 0x4400, 0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x0000, 0x0000, // B +0x3800, 0x4400, 0x4000, 0x4000, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // C +0x7000, 0x4800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4800, 0x7000, 0x0000, 0x0000, // D +0x7C00, 0x4000, 0x4000, 0x7C00, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // E +0x7C00, 0x4000, 0x4000, 0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // F +0x3800, 0x4400, 0x4000, 0x4000, 0x5C00, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // G +0x4400, 0x4400, 0x4400, 0x7C00, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // H +0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3800, 0x0000, 0x0000, // I +0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // J +0x4400, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // K +0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7C00, 0x0000, 0x0000, // L +0x4400, 0x6C00, 0x6C00, 0x5400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // M +0x4400, 0x6400, 0x6400, 0x5400, 0x5400, 0x4C00, 0x4C00, 0x4400, 0x0000, 0x0000, // N +0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // O +0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // P +0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x5400, 0x3800, 0x0400, 0x0000, // Q +0x7800, 0x4400, 0x4400, 0x4400, 0x7800, 0x4800, 0x4800, 0x4400, 0x0000, 0x0000, // R +0x3800, 0x4400, 0x4000, 0x3000, 0x0800, 0x0400, 0x4400, 0x3800, 0x0000, 0x0000, // S +0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // T +0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // U +0x4400, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x1000, 0x0000, 0x0000, // V +0x4400, 0x4400, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // W +0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, // X +0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // Y +0x7C00, 0x0400, 0x0800, 0x1000, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // Z +0x1800, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1800, // [ +0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x0000, 0x0000, /* \ */ +0x3000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x3000, // ] +0x1000, 0x2800, 0x2800, 0x4400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFE00, // _ +0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` +0x0000, 0x0000, 0x3800, 0x4400, 0x3C00, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // a +0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x0000, 0x0000, // b +0x0000, 0x0000, 0x3800, 0x4400, 0x4000, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // c +0x0400, 0x0400, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // d +0x0000, 0x0000, 0x3800, 0x4400, 0x7C00, 0x4000, 0x4400, 0x3800, 0x0000, 0x0000, // e +0x0C00, 0x1000, 0x7C00, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // f +0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x7800, // g +0x4000, 0x4000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // h +0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // i +0x1000, 0x0000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0xE000, // j +0x4000, 0x4000, 0x4800, 0x5000, 0x6000, 0x5000, 0x4800, 0x4400, 0x0000, 0x0000, // k +0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000, // l +0x0000, 0x0000, 0x7800, 0x5400, 0x5400, 0x5400, 0x5400, 0x5400, 0x0000, 0x0000, // m +0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x4400, 0x4400, 0x0000, 0x0000, // n +0x0000, 0x0000, 0x3800, 0x4400, 0x4400, 0x4400, 0x4400, 0x3800, 0x0000, 0x0000, // o +0x0000, 0x0000, 0x5800, 0x6400, 0x4400, 0x4400, 0x6400, 0x5800, 0x4000, 0x4000, // p +0x0000, 0x0000, 0x3400, 0x4C00, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0400, 0x0400, // q +0x0000, 0x0000, 0x5800, 0x6400, 0x4000, 0x4000, 0x4000, 0x4000, 0x0000, 0x0000, // r +0x0000, 0x0000, 0x3800, 0x4400, 0x3000, 0x0800, 0x4400, 0x3800, 0x0000, 0x0000, // s +0x2000, 0x2000, 0x7800, 0x2000, 0x2000, 0x2000, 0x2000, 0x1800, 0x0000, 0x0000, // t +0x0000, 0x0000, 0x4400, 0x4400, 0x4400, 0x4400, 0x4C00, 0x3400, 0x0000, 0x0000, // u +0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x2800, 0x1000, 0x0000, 0x0000, // v +0x0000, 0x0000, 0x5400, 0x5400, 0x5400, 0x6C00, 0x2800, 0x2800, 0x0000, 0x0000, // w +0x0000, 0x0000, 0x4400, 0x2800, 0x1000, 0x1000, 0x2800, 0x4400, 0x0000, 0x0000, // x +0x0000, 0x0000, 0x4400, 0x4400, 0x2800, 0x2800, 0x1000, 0x1000, 0x1000, 0x6000, // y +0x0000, 0x0000, 0x7C00, 0x0800, 0x1000, 0x2000, 0x4000, 0x7C00, 0x0000, 0x0000, // z +0x1800, 0x1000, 0x1000, 0x1000, 0x2000, 0x2000, 0x1000, 0x1000, 0x1000, 0x1800, // { +0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, // | +0x3000, 0x1000, 0x1000, 0x1000, 0x0800, 0x0800, 0x1000, 0x1000, 0x1000, 0x3000, // } +0x0000, 0x0000, 0x0000, 0x7400, 0x4C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +static const unsigned short Font11x18 [] = { +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp +0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ! +0x0000, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " +0x0000, 0x1980, 0x1980, 0x1980, 0x1980, 0x7FC0, 0x7FC0, 0x1980, 0x3300, +0x7FC0, 0x7FC0, 0x3300, 0x3300, 0x3300, 0x3300, 0x0000, 0x0000, 0x0000, // # +0x0000, 0x1E00, 0x3F00, 0x7580, 0x6580, 0x7400, 0x3C00, 0x1E00, 0x0700, +0x0580, 0x6580, 0x6580, 0x7580, 0x3F00, 0x1E00, 0x0400, 0x0400, 0x0000, // $ +0x0000, 0x7000, 0xD800, 0xD840, 0xD8C0, 0xD980, 0x7300, 0x0600, 0x0C00, +0x1B80, 0x36C0, 0x66C0, 0x46C0, 0x06C0, 0x0380, 0x0000, 0x0000, 0x0000, // % +0x0000, 0x1E00, 0x3F00, 0x3300, 0x3300, 0x3300, 0x1E00, 0x0C00, 0x3CC0, +0x66C0, 0x6380, 0x6180, 0x6380, 0x3EC0, 0x1C80, 0x0000, 0x0000, 0x0000, // & +0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ' +0x0080, 0x0100, 0x0300, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0300, 0x0100, 0x0080, // ( +0x2000, 0x1000, 0x1800, 0x0C00, 0x0C00, 0x0400, 0x0600, 0x0600, 0x0600, +0x0600, 0x0600, 0x0600, 0x0400, 0x0C00, 0x0C00, 0x1800, 0x1000, 0x2000, // ) +0x0000, 0x0C00, 0x2D00, 0x3F00, 0x1E00, 0x3300, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // * +0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0xFFC0, 0xFFC0, +0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // + +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // , +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // - +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // . +0x0000, 0x0300, 0x0300, 0x0300, 0x0600, 0x0600, 0x0600, 0x0600, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // / +0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6D80, 0x6D80, +0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 0 +0x0000, 0x0600, 0x0E00, 0x1E00, 0x3600, 0x2600, 0x0600, 0x0600, 0x0600, +0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 1 +0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, 0x6180, 0x0180, 0x0300, 0x0600, +0x0C00, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // 2 +0x0000, 0x1C00, 0x3E00, 0x6300, 0x6300, 0x0300, 0x0E00, 0x0E00, 0x0300, +0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 3 +0x0000, 0x0600, 0x0E00, 0x0E00, 0x1E00, 0x1E00, 0x1600, 0x3600, 0x3600, +0x6600, 0x7F80, 0x7F80, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // 4 +0x0000, 0x7F00, 0x7F00, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x6380, +0x0180, 0x0180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 5 +0x0000, 0x1E00, 0x3F00, 0x3380, 0x6180, 0x6000, 0x6E00, 0x7F00, 0x7380, +0x6180, 0x6180, 0x6180, 0x3380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 6 +0x0000, 0x7F80, 0x7F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0600, 0x0C00, +0x0C00, 0x0C00, 0x0800, 0x1800, 0x1800, 0x1800, 0x0000, 0x0000, 0x0000, // 7 +0x0000, 0x1E00, 0x3F00, 0x6380, 0x6180, 0x6180, 0x2100, 0x1E00, 0x3F00, +0x6180, 0x6180, 0x6180, 0x6180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 8 +0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, +0x1D80, 0x0180, 0x6180, 0x7300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // 9 +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // : +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0C00, 0x0C00, 0x0400, 0x0400, 0x0800, // ; +0x0000, 0x0000, 0x0000, 0x0000, 0x0080, 0x0380, 0x0E00, 0x3800, 0x6000, +0x3800, 0x0E00, 0x0380, 0x0080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // < +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7F80, 0x7F80, 0x0000, 0x0000, +0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // = +0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x7000, 0x1C00, 0x0700, 0x0180, +0x0700, 0x1C00, 0x7000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // > +0x0000, 0x1F00, 0x3F80, 0x71C0, 0x60C0, 0x00C0, 0x01C0, 0x0380, 0x0700, +0x0E00, 0x0C00, 0x0C00, 0x0000, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // ? +0x0000, 0x1E00, 0x3F00, 0x3180, 0x7180, 0x6380, 0x6F80, 0x6D80, 0x6D80, +0x6F80, 0x6780, 0x6000, 0x3200, 0x3E00, 0x1C00, 0x0000, 0x0000, 0x0000, // @ +0x0000, 0x0E00, 0x0E00, 0x1B00, 0x1B00, 0x1B00, 0x1B00, 0x3180, 0x3180, +0x3F80, 0x3F80, 0x3180, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // A +0x0000, 0x7C00, 0x7E00, 0x6300, 0x6300, 0x6300, 0x6300, 0x7E00, 0x7E00, +0x6300, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, 0x0000, 0x0000, 0x0000, // B +0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6000, +0x6000, 0x6000, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // C +0x0000, 0x7C00, 0x7F00, 0x6300, 0x6380, 0x6180, 0x6180, 0x6180, 0x6180, +0x6180, 0x6180, 0x6300, 0x6300, 0x7E00, 0x7C00, 0x0000, 0x0000, 0x0000, // D +0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, +0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // E +0x0000, 0x7F80, 0x7F80, 0x6000, 0x6000, 0x6000, 0x6000, 0x7F00, 0x7F00, +0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // F +0x0000, 0x1E00, 0x3F00, 0x3180, 0x6180, 0x6000, 0x6000, 0x6000, 0x6380, +0x6380, 0x6180, 0x6180, 0x3180, 0x3F80, 0x1E00, 0x0000, 0x0000, 0x0000, // G +0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x7F80, 0x7F80, +0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // H +0x0000, 0x3F00, 0x3F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3F00, 0x3F00, 0x0000, 0x0000, 0x0000, // I +0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, +0x0180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // J +0x0000, 0x60C0, 0x6180, 0x6300, 0x6600, 0x6600, 0x6C00, 0x7800, 0x7C00, +0x6600, 0x6600, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // K +0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, +0x6000, 0x6000, 0x6000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // L +0x0000, 0x71C0, 0x71C0, 0x7BC0, 0x7AC0, 0x6AC0, 0x6AC0, 0x6EC0, 0x64C0, +0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x60C0, 0x0000, 0x0000, 0x0000, // M +0x0000, 0x7180, 0x7180, 0x7980, 0x7980, 0x7980, 0x6D80, 0x6D80, 0x6D80, +0x6580, 0x6780, 0x6780, 0x6780, 0x6380, 0x6380, 0x0000, 0x0000, 0x0000, // N +0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, +0x6180, 0x6180, 0x6180, 0x3300, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // O +0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6180, 0x6380, 0x7F00, +0x7E00, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x0000, 0x0000, 0x0000, // P +0x0000, 0x1E00, 0x3F00, 0x3300, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, +0x6180, 0x6580, 0x6780, 0x3300, 0x3F80, 0x1E40, 0x0000, 0x0000, 0x0000, // Q +0x0000, 0x7E00, 0x7F00, 0x6380, 0x6180, 0x6180, 0x6380, 0x7F00, 0x7E00, +0x6600, 0x6300, 0x6300, 0x6180, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // R +0x0000, 0x0E00, 0x1F00, 0x3180, 0x3180, 0x3000, 0x3800, 0x1E00, 0x0700, +0x0380, 0x6180, 0x6180, 0x3180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // S +0x0000, 0xFFC0, 0xFFC0, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // T +0x0000, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, +0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // U +0x0000, 0x60C0, 0x60C0, 0x60C0, 0x3180, 0x3180, 0x3180, 0x1B00, 0x1B00, +0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x0400, 0x0000, 0x0000, 0x0000, // V +0x0000, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xCCC0, 0x4C80, 0x4C80, +0x5E80, 0x5280, 0x5280, 0x7380, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // W +0x0000, 0xC0C0, 0x6080, 0x6180, 0x3300, 0x3B00, 0x1E00, 0x0C00, 0x0C00, +0x1E00, 0x1F00, 0x3B00, 0x7180, 0x6180, 0xC0C0, 0x0000, 0x0000, 0x0000, // X +0x0000, 0xC0C0, 0x6180, 0x6180, 0x3300, 0x3300, 0x1E00, 0x1E00, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // Y +0x0000, 0x3F80, 0x3F80, 0x0180, 0x0300, 0x0300, 0x0600, 0x0C00, 0x0C00, +0x1800, 0x1800, 0x3000, 0x6000, 0x7F80, 0x7F80, 0x0000, 0x0000, 0x0000, // Z +0x0F00, 0x0F00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0F00, 0x0F00, // [ +0x0000, 0x1800, 0x1800, 0x1800, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0600, +0x0600, 0x0600, 0x0600, 0x0300, 0x0300, 0x0300, 0x0000, 0x0000, 0x0000, /* \ */ +0x1E00, 0x1E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, +0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x1E00, 0x1E00, // ] +0x0000, 0x0C00, 0x0C00, 0x1E00, 0x1200, 0x3300, 0x3300, 0x6180, 0x6180, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFE0, 0x0000, // _ +0x0000, 0x3800, 0x1800, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ` +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F00, 0x3F80, 0x6180, 0x0180, +0x1F80, 0x3F80, 0x6180, 0x6380, 0x7F80, 0x38C0, 0x0000, 0x0000, 0x0000, // a +0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6E00, 0x7F00, 0x7380, 0x6180, +0x6180, 0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x0000, 0x0000, 0x0000, // b +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, +0x6000, 0x6000, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // c +0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x1D80, 0x3F80, 0x7380, 0x6180, +0x6180, 0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0000, 0x0000, 0x0000, // d +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7300, 0x6180, +0x7F80, 0x7F80, 0x6000, 0x7180, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // e +0x0000, 0x07C0, 0x0FC0, 0x0C00, 0x0C00, 0x7F80, 0x7F80, 0x0C00, 0x0C00, +0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0000, 0x0000, 0x0000, // f +0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, +0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x6380, 0x7F00, 0x3E00, // g +0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6F00, 0x7F80, 0x7180, 0x6180, +0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // h +0x0000, 0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, +0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // i +0x0600, 0x0600, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, +0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x4600, 0x7E00, 0x3C00, // j +0x0000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6180, 0x6300, 0x6600, 0x6C00, +0x7C00, 0x7600, 0x6300, 0x6300, 0x6180, 0x60C0, 0x0000, 0x0000, 0x0000, // k +0x0000, 0x3E00, 0x3E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, +0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000, 0x0000, // l +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xFFC0, 0xCEC0, 0xCCC0, +0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0xCCC0, 0x0000, 0x0000, 0x0000, // m +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6F00, 0x7F80, 0x7180, 0x6180, +0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x6180, 0x0000, 0x0000, 0x0000, // n +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F00, 0x7380, 0x6180, +0x6180, 0x6180, 0x6180, 0x7380, 0x3F00, 0x1E00, 0x0000, 0x0000, 0x0000, // o +0x0000, 0x0000, 0x0000, 0x0000, 0x6E00, 0x7F00, 0x7380, 0x6180, 0x6180, +0x6180, 0x6180, 0x7380, 0x7F00, 0x6E00, 0x6000, 0x6000, 0x6000, 0x6000, // p +0x0000, 0x0000, 0x0000, 0x0000, 0x1D80, 0x3F80, 0x7380, 0x6180, 0x6180, +0x6180, 0x6180, 0x7380, 0x3F80, 0x1D80, 0x0180, 0x0180, 0x0180, 0x0180, // q +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6700, 0x3F80, 0x3900, 0x3000, +0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x3000, 0x0000, 0x0000, 0x0000, // r +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1E00, 0x3F80, 0x6180, 0x6000, +0x7F00, 0x3F80, 0x0180, 0x6180, 0x7F00, 0x1E00, 0x0000, 0x0000, 0x0000, // s +0x0000, 0x0000, 0x0800, 0x1800, 0x1800, 0x7F00, 0x7F00, 0x1800, 0x1800, +0x1800, 0x1800, 0x1800, 0x1800, 0x1F80, 0x0F80, 0x0000, 0x0000, 0x0000, // t +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x6180, 0x6180, +0x6180, 0x6180, 0x6180, 0x6380, 0x7F80, 0x3D80, 0x0000, 0x0000, 0x0000, // u +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x60C0, 0x3180, 0x3180, 0x3180, +0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0600, 0x0000, 0x0000, 0x0000, // v +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD80, 0xDD80, 0xDD80, 0x5500, +0x5500, 0x5500, 0x7700, 0x7700, 0x2200, 0x2200, 0x0000, 0x0000, 0x0000, // w +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x3300, 0x3300, 0x1E00, +0x0C00, 0x0C00, 0x1E00, 0x3300, 0x3300, 0x6180, 0x0000, 0x0000, 0x0000, // x +0x0000, 0x0000, 0x0000, 0x0000, 0x6180, 0x6180, 0x3180, 0x3300, 0x3300, +0x1B00, 0x1B00, 0x1B00, 0x0E00, 0x0E00, 0x0E00, 0x1C00, 0x7C00, 0x7000, // y +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FC0, 0x7FC0, 0x0180, 0x0300, +0x0600, 0x0C00, 0x1800, 0x3000, 0x7FC0, 0x7FC0, 0x0000, 0x0000, 0x0000, // z +0x0380, 0x0780, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0E00, 0x1C00, +0x1C00, 0x0E00, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0780, 0x0380, // { +0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, +0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, 0x0600, // | +0x3800, 0x3C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0E00, 0x0700, +0x0700, 0x0E00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x0C00, 0x3C00, 0x3800, // } +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3880, 0x7F80, +0x4700, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; +static const unsigned short Font16x26 [] = { +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [ ] +0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, +0x03C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, +0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [!] +0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x1E3C, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ["] +0x01CE, 0x03CE, 0x03DE, 0x039E, 0x039C, 0x079C, 0x3FFF, 0x7FFF, 0x0738, +0x0F38, 0x0F78, 0x0F78, 0x0E78, 0xFFFF, 0xFFFF, 0x1EF0, 0x1CF0, 0x1CE0, +0x3CE0, 0x3DE0, 0x39E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [#] +0x03FC, 0x0FFE, 0x1FEE, 0x1EE0, 0x1EE0, 0x1EE0, 0x1EE0, 0x1FE0, 0x0FE0, +0x07E0, 0x03F0, 0x01FC, 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x01FE, 0x01FE, +0x3DFE, 0x3FFC, 0x0FF0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, // Ascii = [$] +0x3E03, 0xF707, 0xE78F, 0xE78E, 0xE39E, 0xE3BC, 0xE7B8, 0xE7F8, 0xF7F0, +0x3FE0, 0x01C0, 0x03FF, 0x07FF, 0x07F3, 0x0FF3, 0x1EF3, 0x3CF3, 0x38F3, +0x78F3, 0xF07F, 0xE03F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [%] +0x07E0, 0x0FF8, 0x0F78, 0x1F78, 0x1F78, 0x1F78, 0x0F78, 0x0FF0, 0x0FE0, +0x1F80, 0x7FC3, 0xFBC3, 0xF3E7, 0xF1F7, 0xF0F7, 0xF0FF, 0xF07F, 0xF83E, +0x7C7F, 0x3FFF, 0x1FEF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [&] +0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03C0, 0x01C0, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = ['] +0x003F, 0x007C, 0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x0780, 0x0780, 0x0F80, +0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F00, 0x0F80, 0x0780, 0x0780, +0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x007C, 0x003F, 0x000F, 0x0000, // Ascii = [(] +0x7E00, 0x1F00, 0x07C0, 0x03C0, 0x01E0, 0x01F0, 0x00F0, 0x00F0, 0x00F8, +0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x0078, 0x00F8, 0x00F0, 0x00F0, +0x01F0, 0x01E0, 0x03C0, 0x07C0, 0x1F00, 0x7E00, 0x7800, 0x0000, // Ascii = [)] +0x03E0, 0x03C0, 0x01C0, 0x39CE, 0x3FFF, 0x3F7F, 0x0320, 0x0370, 0x07F8, +0x0F78, 0x1F3C, 0x0638, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [*] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01C0, 0x01C0, 0x01C0, +0x01C0, 0x01C0, 0x01C0, 0x01C0, 0xFFFF, 0xFFFF, 0x01C0, 0x01C0, 0x01C0, +0x01C0, 0x01C0, 0x01C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [+] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x0380, // Ascii = [,] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [-] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [.] +0x000F, 0x000F, 0x001E, 0x001E, 0x003C, 0x003C, 0x0078, 0x0078, 0x00F0, +0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x0780, 0x0780, 0x0F00, 0x0F00, +0x1E00, 0x1E00, 0x3C00, 0x3C00, 0x7800, 0x7800, 0xF000, 0x0000, // Ascii = [/] +0x07F0, 0x0FF8, 0x1F7C, 0x3E3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x780F, 0x780F, +0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x7C1F, 0x7C1F, 0x3C1E, 0x3E3E, +0x1F7C, 0x0FF8, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [0] +0x00F0, 0x07F0, 0x3FF0, 0x3FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, +0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, +0x01F0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [1] +0x0FE0, 0x3FF8, 0x3C7C, 0x003C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, +0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, 0x0780, 0x0F00, 0x1E00, 0x3E00, +0x3C00, 0x3FFE, 0x3FFE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [2] +0x0FF0, 0x1FF8, 0x1C7C, 0x003E, 0x003E, 0x003E, 0x003C, 0x003C, 0x00F8, +0x0FF0, 0x0FF8, 0x007C, 0x003E, 0x001E, 0x001E, 0x001E, 0x001E, 0x003E, +0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [3] +0x0078, 0x00F8, 0x00F8, 0x01F8, 0x03F8, 0x07F8, 0x07F8, 0x0F78, 0x1E78, +0x1E78, 0x3C78, 0x7878, 0x7878, 0xFFFF, 0xFFFF, 0x0078, 0x0078, 0x0078, +0x0078, 0x0078, 0x0078, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [4] +0x1FFC, 0x1FFC, 0x1FFC, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1FE0, +0x1FF8, 0x00FC, 0x007C, 0x003E, 0x003E, 0x001E, 0x003E, 0x003E, 0x003C, +0x1C7C, 0x1FF8, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [5] +0x01FC, 0x07FE, 0x0F8E, 0x1F00, 0x1E00, 0x3E00, 0x3C00, 0x3C00, 0x3DF8, +0x3FFC, 0x7F3E, 0x7E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3E0F, 0x1E1F, +0x1F3E, 0x0FFC, 0x03F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [6] +0x3FFF, 0x3FFF, 0x3FFF, 0x000F, 0x001E, 0x001E, 0x003C, 0x0038, 0x0078, +0x00F0, 0x00F0, 0x01E0, 0x01E0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x0F80, +0x0F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [7] +0x07F8, 0x0FFC, 0x1F3E, 0x1E1E, 0x3E1E, 0x3E1E, 0x1E1E, 0x1F3C, 0x0FF8, +0x07F0, 0x0FF8, 0x1EFC, 0x3E3E, 0x3C1F, 0x7C1F, 0x7C0F, 0x7C0F, 0x3C1F, +0x3F3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [8] +0x07F0, 0x0FF8, 0x1E7C, 0x3C3E, 0x3C1E, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, +0x3C1F, 0x3E3F, 0x1FFF, 0x07EF, 0x001F, 0x001E, 0x001E, 0x003E, 0x003C, +0x38F8, 0x3FF0, 0x1FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [9] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, +0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [:] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x03E0, +0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x03C0, 0x0380, // Ascii = [;] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x000F, 0x003F, +0x00FC, 0x03F0, 0x0FC0, 0x3F00, 0xFE00, 0x3F00, 0x0FC0, 0x03F0, 0x00FC, +0x003F, 0x000F, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [<] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [=] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE000, 0xF800, 0x7E00, +0x1F80, 0x07E0, 0x01F8, 0x007E, 0x001F, 0x007E, 0x01F8, 0x07E0, 0x1F80, +0x7E00, 0xF800, 0xE000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [>] +0x1FF0, 0x3FFC, 0x383E, 0x381F, 0x381F, 0x001E, 0x001E, 0x003C, 0x0078, +0x00F0, 0x01E0, 0x03C0, 0x03C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, +0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [?] +0x03F8, 0x0FFE, 0x1F1E, 0x3E0F, 0x3C7F, 0x78FF, 0x79EF, 0x73C7, 0xF3C7, +0xF38F, 0xF38F, 0xF38F, 0xF39F, 0xF39F, 0x73FF, 0x7BFF, 0x79F7, 0x3C00, +0x1F1C, 0x0FFC, 0x03F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [@] +0x0000, 0x0000, 0x0000, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x07F0, 0x0F78, +0x0F78, 0x0E7C, 0x1E3C, 0x1E3C, 0x3C3E, 0x3FFE, 0x3FFF, 0x781F, 0x780F, +0xF00F, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [A] +0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FFC, 0x3C3E, 0x3C1E, 0x3C1E, 0x3C1E, +0x3C3E, 0x3C7C, 0x3FF0, 0x3FF8, 0x3C7E, 0x3C1F, 0x3C1F, 0x3C0F, 0x3C0F, +0x3C1F, 0x3FFE, 0x3FF8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [B] +0x0000, 0x0000, 0x0000, 0x01FF, 0x07FF, 0x1F87, 0x3E00, 0x3C00, 0x7C00, +0x7800, 0x7800, 0x7800, 0x7800, 0x7800, 0x7C00, 0x7C00, 0x3E00, 0x3F00, +0x1F83, 0x07FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [C] +0x0000, 0x0000, 0x0000, 0x7FF0, 0x7FFC, 0x787E, 0x781F, 0x781F, 0x780F, +0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x781F, 0x781E, +0x787E, 0x7FF8, 0x7FE0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [D] +0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x3E00, 0x3E00, 0x3E00, 0x3E00, +0x3E00, 0x3E00, 0x3FFE, 0x3FFE, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, +0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [E] +0x0000, 0x0000, 0x0000, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, +0x1E00, 0x1E00, 0x1FFF, 0x1FFF, 0x1E00, 0x1E00, 0x1E00, 0x1E00, 0x1E00, +0x1E00, 0x1E00, 0x1E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [F] +0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, 0x3E00, 0x7C00, 0x7C00, +0x7800, 0xF800, 0xF800, 0xF87F, 0xF87F, 0x780F, 0x7C0F, 0x7C0F, 0x3E0F, +0x1F8F, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [G] +0x0000, 0x0000, 0x0000, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, +0x7C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x7C1F, +0x7C1F, 0x7C1F, 0x7C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [H] +0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, +0x03E0, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [I] +0x0000, 0x0000, 0x0000, 0x1FFC, 0x1FFC, 0x007C, 0x007C, 0x007C, 0x007C, +0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x007C, 0x0078, 0x0078, +0x38F8, 0x3FF0, 0x3FC0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [J] +0x0000, 0x0000, 0x0000, 0x3C1F, 0x3C1E, 0x3C3C, 0x3C78, 0x3CF0, 0x3DE0, +0x3FE0, 0x3FC0, 0x3F80, 0x3FC0, 0x3FE0, 0x3DF0, 0x3CF0, 0x3C78, 0x3C7C, +0x3C3E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [K] +0x0000, 0x0000, 0x0000, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, +0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, 0x3E00, +0x3E00, 0x3FFF, 0x3FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [L] +0x0000, 0x0000, 0x0000, 0xF81F, 0xFC1F, 0xFC1F, 0xFE3F, 0xFE3F, 0xFE3F, +0xFF7F, 0xFF77, 0xFF77, 0xF7F7, 0xF7E7, 0xF3E7, 0xF3E7, 0xF3C7, 0xF007, +0xF007, 0xF007, 0xF007, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [M] +0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7E0F, 0x7F0F, 0x7F0F, 0x7F8F, +0x7F8F, 0x7FCF, 0x7BEF, 0x79EF, 0x79FF, 0x78FF, 0x78FF, 0x787F, 0x783F, +0x783F, 0x781F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [N] +0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, +0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0x780F, 0x780F, 0x7C1F, +0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [O] +0x0000, 0x0000, 0x0000, 0x3FFC, 0x3FFF, 0x3E1F, 0x3E0F, 0x3E0F, 0x3E0F, +0x3E0F, 0x3E1F, 0x3E3F, 0x3FFC, 0x3FF0, 0x3E00, 0x3E00, 0x3E00, 0x3E00, +0x3E00, 0x3E00, 0x3E00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [P] +0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, 0x7C1F, 0x780F, 0x780F, +0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0xF80F, 0x780F, 0x780F, 0x7C1F, +0x3E3E, 0x1FFC, 0x07F8, 0x007C, 0x003F, 0x000F, 0x0003, 0x0000, // Ascii = [Q] +0x0000, 0x0000, 0x0000, 0x3FF0, 0x3FFC, 0x3C7E, 0x3C3E, 0x3C1E, 0x3C1E, +0x3C3E, 0x3C3C, 0x3CFC, 0x3FF0, 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, 0x3C3E, +0x3C1E, 0x3C1F, 0x3C0F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [R] +0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x3E0E, 0x3C00, 0x3C00, 0x3C00, +0x3E00, 0x1FC0, 0x0FF8, 0x03FE, 0x007F, 0x001F, 0x000F, 0x000F, 0x201F, +0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [S] +0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x03E0, 0x03E0, 0x03E0, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [T] +0x0000, 0x0000, 0x0000, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, +0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x7C0F, 0x3C1E, 0x3C1E, +0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [U] +0x0000, 0x0000, 0x0000, 0xF007, 0xF007, 0xF807, 0x780F, 0x7C0F, 0x3C1E, +0x3C1E, 0x3E1E, 0x1E3C, 0x1F3C, 0x1F78, 0x0F78, 0x0FF8, 0x07F0, 0x07F0, +0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [V] +0x0000, 0x0000, 0x0000, 0xE003, 0xF003, 0xF003, 0xF007, 0xF3E7, 0xF3E7, +0xF3E7, 0x73E7, 0x7BF7, 0x7FF7, 0x7FFF, 0x7F7F, 0x7F7F, 0x7F7E, 0x3F7E, +0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [W] +0x0000, 0x0000, 0x0000, 0xF807, 0x7C0F, 0x3E1E, 0x3E3E, 0x1F3C, 0x0FF8, +0x07F0, 0x07E0, 0x03E0, 0x03E0, 0x07F0, 0x0FF8, 0x0F7C, 0x1E7C, 0x3C3E, +0x781F, 0x780F, 0xF00F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [X] +0x0000, 0x0000, 0x0000, 0xF807, 0x7807, 0x7C0F, 0x3C1E, 0x3E1E, 0x1F3C, +0x0F78, 0x0FF8, 0x07F0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, 0x03E0, +0x03E0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Y] +0x0000, 0x0000, 0x0000, 0x7FFF, 0x7FFF, 0x000F, 0x001F, 0x003E, 0x007C, +0x00F8, 0x00F0, 0x01E0, 0x03E0, 0x07C0, 0x0F80, 0x0F00, 0x1E00, 0x3E00, +0x7C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [Z] +0x07FF, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, +0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, +0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x07FF, 0x07FF, 0x0000, // Ascii = [[] +0x7800, 0x7800, 0x3C00, 0x3C00, 0x1E00, 0x1E00, 0x0F00, 0x0F00, 0x0780, +0x0780, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x00F0, 0x00F0, 0x0078, 0x0078, +0x003C, 0x003C, 0x001E, 0x001E, 0x000F, 0x000F, 0x0007, 0x0000, // Ascii = [\] +0x7FF0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, +0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, +0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x00F0, 0x7FF0, 0x7FF0, 0x0000, // Ascii = []] +0x00C0, 0x01C0, 0x01C0, 0x03E0, 0x03E0, 0x07F0, 0x07F0, 0x0778, 0x0F78, +0x0F38, 0x1E3C, 0x1E3C, 0x3C1E, 0x3C1E, 0x380F, 0x780F, 0x7807, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [^] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, // Ascii = [_] +0x00F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [`] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0FF8, 0x3FFC, 0x3C7C, +0x003E, 0x003E, 0x003E, 0x07FE, 0x1FFE, 0x3E3E, 0x7C3E, 0x783E, 0x7C3E, +0x7C7E, 0x3FFF, 0x1FCF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [a] +0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DF8, 0x3FFE, 0x3F3E, +0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3C1E, +0x3F3E, 0x3FFC, 0x3BF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [b] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FE, 0x0FFF, 0x1F87, +0x3E00, 0x3E00, 0x3C00, 0x7C00, 0x7C00, 0x7C00, 0x3C00, 0x3E00, 0x3E00, +0x1F87, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [c] +0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x001F, 0x07FF, 0x1FFF, 0x3E3F, +0x3C1F, 0x7C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, +0x3E7F, 0x1FFF, 0x0FDF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [d] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03F8, 0x0FFC, 0x1F3E, +0x3E1E, 0x3C1F, 0x7C1F, 0x7FFF, 0x7FFF, 0x7C00, 0x7C00, 0x3C00, 0x3E00, +0x1F07, 0x0FFF, 0x03FE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [e] +0x01FF, 0x03E1, 0x03C0, 0x07C0, 0x07C0, 0x07C0, 0x7FFF, 0x7FFF, 0x07C0, +0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, 0x07C0, +0x07C0, 0x07C0, 0x07C0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [f] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EF, 0x1FFF, 0x3E7F, +0x3C1F, 0x7C1F, 0x7C1F, 0x781F, 0x781F, 0x781F, 0x7C1F, 0x7C1F, 0x3C3F, +0x3E7F, 0x1FFF, 0x0FDF, 0x001E, 0x001E, 0x001E, 0x387C, 0x3FF8, // Ascii = [g] +0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3DFC, 0x3FFE, 0x3F9E, +0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, +0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [h] +0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x7FE0, 0x7FE0, 0x01E0, +0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, +0x01E0, 0x01E0, 0x01E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [i] +0x00F8, 0x00F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FF8, 0x3FF8, 0x00F8, +0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, +0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F8, 0x00F0, 0x71F0, 0x7FE0, // Ascii = [j] +0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C1F, 0x3C3E, 0x3C7C, +0x3CF8, 0x3DF0, 0x3DE0, 0x3FC0, 0x3FC0, 0x3FE0, 0x3DF0, 0x3CF8, 0x3C7C, +0x3C3E, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [k] +0x7FF0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, +0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, 0x01F0, +0x01F0, 0x01F0, 0x01F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [l] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF79E, 0xFFFF, 0xFFFF, +0xFFFF, 0xFBE7, 0xF9E7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, 0xF1C7, +0xF1C7, 0xF1C7, 0xF1C7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [m] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DFC, 0x3FFE, 0x3F9E, +0x3F1F, 0x3E1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, 0x3C1F, +0x3C1F, 0x3C1F, 0x3C1F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [n] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07F0, 0x1FFC, 0x3E3E, +0x3C1F, 0x7C1F, 0x780F, 0x780F, 0x780F, 0x780F, 0x780F, 0x7C1F, 0x3C1F, +0x3E3E, 0x1FFC, 0x07F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [o] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3DF8, 0x3FFE, 0x3F3E, +0x3E1F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C0F, 0x3C1F, 0x3E1E, +0x3F3E, 0x3FFC, 0x3FF8, 0x3C00, 0x3C00, 0x3C00, 0x3C00, 0x3C00, // Ascii = [p] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07EE, 0x1FFE, 0x3E7E, +0x3C1E, 0x7C1E, 0x781E, 0x781E, 0x781E, 0x781E, 0x781E, 0x7C1E, 0x7C3E, +0x3E7E, 0x1FFE, 0x0FDE, 0x001E, 0x001E, 0x001E, 0x001E, 0x001E, // Ascii = [q] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1F7F, 0x1FFF, 0x1FE7, +0x1FC7, 0x1F87, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, 0x1F00, +0x1F00, 0x1F00, 0x1F00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [r] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07FC, 0x1FFE, 0x1E0E, +0x3E00, 0x3E00, 0x3F00, 0x1FE0, 0x07FC, 0x00FE, 0x003E, 0x001E, 0x001E, +0x3C3E, 0x3FFC, 0x1FF0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [s] +0x0000, 0x0000, 0x0000, 0x0780, 0x0780, 0x0780, 0x7FFF, 0x7FFF, 0x0780, +0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, 0x0780, +0x07C0, 0x03FF, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [t] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3C1E, 0x3C1E, 0x3C1E, +0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C1E, 0x3C3E, 0x3C7E, +0x3EFE, 0x1FFE, 0x0FDE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [u] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF007, 0x780F, 0x780F, +0x3C1E, 0x3C1E, 0x3E1E, 0x1E3C, 0x1E3C, 0x0F78, 0x0F78, 0x0FF0, 0x07F0, +0x07F0, 0x03E0, 0x03E0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [v] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF003, 0xF1E3, 0xF3E3, +0xF3E7, 0xF3F7, 0xF3F7, 0x7FF7, 0x7F77, 0x7F7F, 0x7F7F, 0x7F7F, 0x3E3E, +0x3E3E, 0x3E3E, 0x3E3E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [w] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7C0F, 0x3E1E, 0x3E3C, +0x1F3C, 0x0FF8, 0x07F0, 0x07F0, 0x03E0, 0x07F0, 0x07F8, 0x0FF8, 0x1E7C, +0x3E3E, 0x3C1F, 0x781F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [x] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xF807, 0x780F, 0x7C0F, +0x3C1E, 0x3C1E, 0x1E3C, 0x1E3C, 0x1F3C, 0x0F78, 0x0FF8, 0x07F0, 0x07F0, +0x03E0, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x0780, 0x0F80, 0x7F00, // Ascii = [y] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3FFF, 0x3FFF, 0x001F, +0x003E, 0x007C, 0x00F8, 0x01F0, 0x03E0, 0x07C0, 0x0F80, 0x1F00, 0x1E00, +0x3C00, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [z] +0x01FE, 0x03E0, 0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x01E0, 0x01E0, 0x01E0, +0x01C0, 0x03C0, 0x3F80, 0x3F80, 0x03C0, 0x01C0, 0x01E0, 0x01E0, 0x01E0, +0x03C0, 0x03C0, 0x03C0, 0x03C0, 0x03E0, 0x01FE, 0x007E, 0x0000, // Ascii = [{] +0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, +0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, +0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x01C0, 0x0000, // Ascii = [|] +0x3FC0, 0x03E0, 0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x01C0, 0x03C0, 0x03C0, +0x01C0, 0x01E0, 0x00FE, 0x00FE, 0x01E0, 0x01C0, 0x03C0, 0x03C0, 0x01C0, +0x01E0, 0x01E0, 0x01E0, 0x01E0, 0x03E0, 0x3FC0, 0x3F00, 0x0000, // Ascii = [}] +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x3F07, 0x7FC7, 0x73E7, 0xF1FF, 0xF07E, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // Ascii = [~] +}; +static const unsigned short Font6x8 [] = { +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // sp +0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x0000, // ! +0x5000, 0x5000, 0x5000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // " +0x5000, 0x5000, 0xf800, 0x5000, 0xf800, 0x5000, 0x5000, 0x0000, // # +0x2000, 0x7800, 0xa000, 0x7000, 0x2800, 0xf000, 0x2000, 0x0000, // $ +0xc000, 0xc800, 0x1000, 0x2000, 0x4000, 0x9800, 0x1800, 0x0000, // % +0x4000, 0xa000, 0xa000, 0x4000, 0xa800, 0x9000, 0x6800, 0x0000, // & +0x3000, 0x3000, 0x2000, 0x4000, 0x0000, 0x0000, 0x0000, 0x0000, // ' +0x1000, 0x2000, 0x4000, 0x4000, 0x4000, 0x2000, 0x1000, 0x0000, // ( +0x4000, 0x2000, 0x1000, 0x1000, 0x1000, 0x2000, 0x4000, 0x0000, // ) +0x2000, 0xa800, 0x7000, 0xf800, 0x7000, 0xa800, 0x2000, 0x0000, // * +0x0000, 0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x0000, 0x0000, // + +0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x2000, 0x0000, // , +0x0000, 0x0000, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, 0x0000, // - +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x3000, 0x0000, // . +0x0000, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, 0x0000, // / +0x7000, 0x8800, 0x9800, 0xa800, 0xc800, 0x8800, 0x7000, 0x0000, // 0 +0x2000, 0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // 1 +0x7000, 0x8800, 0x0800, 0x7000, 0x8000, 0x8000, 0xf800, 0x0000, // 2 +0xf800, 0x0800, 0x1000, 0x3000, 0x0800, 0x8800, 0x7000, 0x0000, // 3 +0x1000, 0x3000, 0x5000, 0x9000, 0xf800, 0x1000, 0x1000, 0x0000, // 4 +0xf800, 0x8000, 0xf000, 0x0800, 0x0800, 0x8800, 0x7000, 0x0000, // 5 +0x3800, 0x4000, 0x8000, 0xf000, 0x8800, 0x8800, 0x7000, 0x0000, // 6 +0xf800, 0x0800, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x0000, // 7 +0x7000, 0x8800, 0x8800, 0x7000, 0x8800, 0x8800, 0x7000, 0x0000, // 8 +0x7000, 0x8800, 0x8800, 0x7800, 0x0800, 0x1000, 0xe000, 0x0000, // 9 +0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x0000, 0x0000, 0x0000, // : +0x0000, 0x0000, 0x2000, 0x0000, 0x2000, 0x2000, 0x4000, 0x0000, // ; +0x0800, 0x1000, 0x2000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, // < +0x0000, 0x0000, 0xf800, 0x0000, 0xf800, 0x0000, 0x0000, 0x0000, // = +0x4000, 0x2000, 0x1000, 0x0800, 0x1000, 0x2000, 0x4000, 0x0000, // > +0x7000, 0x8800, 0x0800, 0x3000, 0x2000, 0x0000, 0x2000, 0x0000, // ? +0x7000, 0x8800, 0xa800, 0xb800, 0xb000, 0x8000, 0x7800, 0x0000, // @ +0x2000, 0x5000, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x0000, // A +0xf000, 0x8800, 0x8800, 0xf000, 0x8800, 0x8800, 0xf000, 0x0000, // B +0x7000, 0x8800, 0x8000, 0x8000, 0x8000, 0x8800, 0x7000, 0x0000, // C +0xf000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0xf000, 0x0000, // D +0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0xf800, 0x0000, // E +0xf800, 0x8000, 0x8000, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // F +0x7800, 0x8800, 0x8000, 0x8000, 0x9800, 0x8800, 0x7800, 0x0000, // G +0x8800, 0x8800, 0x8800, 0xf800, 0x8800, 0x8800, 0x8800, 0x0000, // H +0x7000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // I +0x3800, 0x1000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // J +0x8800, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x8800, 0x0000, // K +0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0xf800, 0x0000, // L +0x8800, 0xd800, 0xa800, 0xa800, 0xa800, 0x8800, 0x8800, 0x0000, // M +0x8800, 0x8800, 0xc800, 0xa800, 0x9800, 0x8800, 0x8800, 0x0000, // N +0x7000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // O +0xf000, 0x8800, 0x8800, 0xf000, 0x8000, 0x8000, 0x8000, 0x0000, // P +0x7000, 0x8800, 0x8800, 0x8800, 0xa800, 0x9000, 0x6800, 0x0000, // Q +0xf000, 0x8800, 0x8800, 0xf000, 0xa000, 0x9000, 0x8800, 0x0000, // R +0x7000, 0x8800, 0x8000, 0x7000, 0x0800, 0x8800, 0x7000, 0x0000, // S +0xf800, 0xa800, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // T +0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // U +0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // V +0x8800, 0x8800, 0x8800, 0xa800, 0xa800, 0xa800, 0x5000, 0x0000, // W +0x8800, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x8800, 0x0000, // X +0x8800, 0x8800, 0x5000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, // Y +0xf800, 0x0800, 0x1000, 0x7000, 0x4000, 0x8000, 0xf800, 0x0000, // Z +0x7800, 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, 0x7800, 0x0000, // [ +0x0000, 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0000, 0x0000, /* \ */ +0x7800, 0x0800, 0x0800, 0x0800, 0x0800, 0x0800, 0x7800, 0x0000, // ] +0x2000, 0x5000, 0x8800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ^ +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf800, 0x0000, // _ +0x6000, 0x6000, 0x2000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, // ` +0x0000, 0x0000, 0x6000, 0x1000, 0x7000, 0x9000, 0x7800, 0x0000, // a +0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0xc800, 0xb000, 0x0000, // b +0x0000, 0x0000, 0x7000, 0x8800, 0x8000, 0x8800, 0x7000, 0x0000, // c +0x0800, 0x0800, 0x6800, 0x9800, 0x8800, 0x9800, 0x6800, 0x0000, // d +0x0000, 0x0000, 0x7000, 0x8800, 0xf800, 0x8000, 0x7000, 0x0000, // e +0x1000, 0x2800, 0x2000, 0x7000, 0x2000, 0x2000, 0x2000, 0x0000, // f +0x0000, 0x0000, 0x7000, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // g +0x8000, 0x8000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // h +0x2000, 0x0000, 0x6000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // i +0x1000, 0x0000, 0x1000, 0x1000, 0x1000, 0x9000, 0x6000, 0x0000, // j +0x8000, 0x8000, 0x9000, 0xa000, 0xc000, 0xa000, 0x9000, 0x0000, // k +0x6000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x7000, 0x0000, // l +0x0000, 0x0000, 0xd000, 0xa800, 0xa800, 0xa800, 0xa800, 0x0000, // m +0x0000, 0x0000, 0xb000, 0xc800, 0x8800, 0x8800, 0x8800, 0x0000, // n +0x0000, 0x0000, 0x7000, 0x8800, 0x8800, 0x8800, 0x7000, 0x0000, // o +0x0000, 0x0000, 0xb000, 0xc800, 0xc800, 0xb000, 0x8000, 0x0000, // p +0x0000, 0x0000, 0x6800, 0x9800, 0x9800, 0x6800, 0x0800, 0x0000, // q +0x0000, 0x0000, 0xb000, 0xc800, 0x8000, 0x8000, 0x8000, 0x0000, // r +0x0000, 0x0000, 0x7800, 0x8000, 0x7000, 0x0800, 0xf000, 0x0000, // s +0x2000, 0x2000, 0xf800, 0x2000, 0x2000, 0x2800, 0x1000, 0x0000, // t +0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x9800, 0x6800, 0x0000, // u +0x0000, 0x0000, 0x8800, 0x8800, 0x8800, 0x5000, 0x2000, 0x0000, // v +0x0000, 0x0000, 0x8800, 0x8800, 0xa800, 0xa800, 0x5000, 0x0000, // w +0x0000, 0x0000, 0x8800, 0x5000, 0x2000, 0x5000, 0x8800, 0x0000, // x +0x0000, 0x0000, 0x8800, 0x8800, 0x7800, 0x0800, 0x8800, 0x0000, // y +0x0000, 0x0000, 0xf800, 0x1000, 0x2000, 0x4000, 0xf800, 0x0000, // z +0x1000, 0x2000, 0x2000, 0x4000, 0x2000, 0x2000, 0x1000, 0x0000, // { +0x2000, 0x2000, 0x2000, 0x0000, 0x2000, 0x2000, 0x2000, 0x0000, // | +0x4000, 0x2000, 0x2000, 0x1000, 0x2000, 0x2000, 0x4000, 0x0000, // } +0x4000, 0xa800, 0x1000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // ~ +}; + +FontDef Font_7x10 = {7,10,Font7x10}; +FontDef Font_6x8 = {6, 8, Font6x8}; +FontDef Font_11x18 = {11, 18, Font11x18}; +FontDef Font_16x26 = {16, 26, Font16x26}; \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306_fonts.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306_fonts.h new file mode 100644 index 0000000000000000000000000000000000000000..9d26f31adbfca2c5d03d7d041b07a3b465bfebc7 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/ssd1306_fonts.h @@ -0,0 +1,58 @@ +/* + MIT License + + Copyright (c) 2018, Alexey Dynda + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +/** + * @file ssd1306_fonts.h Fonts for monochrome/rgb oled display + */ + +#ifndef SSD1306_FONTS_H +#define SSD1306_FONTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup LCD_FONTS FONTS: Supported LCD fonts + * @{ + */ + +extern const unsigned char g_f6X8[][6]; +extern const unsigned char g_f8X16[]; + +typedef struct { + const unsigned char FontWidth; /*!< Font width in pixels */ + unsigned char FontHeight; /*!< Font height in pixels */ + const unsigned short *data; /*!< Pointer to data font data array */ +} FontDef; + +extern FontDef Font_7x10; +extern FontDef Font_6x8; +extern FontDef Font_11x18; +extern FontDef Font_16x26; + +#ifdef __cplusplus +} +#endif + +#endif // SSD1306_FONTS_H \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/user_motor_control.c b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/user_motor_control.c new file mode 100644 index 0000000000000000000000000000000000000000..0425d3c4716fb92a1749a6fec2d86e40db8d1151 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/user_motor_control.c @@ -0,0 +1,170 @@ +#include "main.h" +#include "debug.h" +#include "user_motor_control.h" + +unsigned int g_aptDutyCur = 50; +unsigned int g_aptDutySet = 50; +unsigned int g_aptFreqCntCur =1500; +unsigned int g_aptFreqCntSet =1500; +unsigned int g_rotationDirectionStatus = 0; +unsigned int g_rotationDirectionStatusSet = 0; + +unsigned int g_testCount = 0; +unsigned int g_testNum = 0; + +void User_APTForcePWMAOutputLow(APT_RegStruct *aptx) +{ + /* Enable force output. */ + + + aptx->PG_OUT_FRC.BIT.rg_pga_frc_act = APT_PWM_CONTINUOUS_ACTION_LOW; /* if not invert, set low */ + aptx->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_ENABLE; + /* if PWMA invert */ + return; +} + +void User_APTForcePWMBOutputLow(APT_RegStruct *aptx) +{ + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_act = APT_PWM_CONTINUOUS_ACTION_HIGH; /* if not invert, set low */ + /* Enable force output. */ + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_ENABLE; + return; +} + + +void User_APTPwmARecovery(APT_RegStruct *aptx) +{ + /* Enable force output. */ + aptx->PG_OUT_FRC.BIT.rg_pga_frc_en = BASE_CFG_DISABLE; + return; +} + +void User_APTPwmBRecovery(APT_RegStruct *aptx) +{ + /* Enable force output. */ + aptx->PG_OUT_FRC.BIT.rg_pgb_frc_en = BASE_CFG_DISABLE; + return; +} + +/* 电机启动 */ +void startMotor(void) +{ + HAL_APT_StartModule(RUN_APT0|RUN_APT1); +} + +/* 电机停止 */ +void stopMotor(void) +{ + HAL_APT_StopModule(RUN_APT0|RUN_APT1); +} + +/* 电机正转 */ +void MotorForwardRotation(void) +{ + User_APTPwmARecovery(g_apt0.baseAddress); // 左转,右轮子前进 + User_APTForcePWMBOutputLow(g_apt0.baseAddress); + User_APTForcePWMAOutputLow(g_apt1.baseAddress); // 右转,左轮子前进 + User_APTPwmBRecovery(g_apt1.baseAddress); +} + +/* 电机反转 */ +void MotorReverse(void) +{ + User_APTForcePWMAOutputLow(g_apt0.baseAddress); + User_APTPwmBRecovery(g_apt0.baseAddress); + + User_APTPwmARecovery(g_apt1.baseAddress); + User_APTForcePWMBOutputLow(g_apt1.baseAddress); +} + +/* 电机左转 */ +void MotorLeft(void) +{ + User_APTPwmARecovery(g_apt0.baseAddress); // 左转,右轮子前进 + User_APTForcePWMBOutputLow(g_apt0.baseAddress); + HAL_APT_StopModule(RUN_APT1); +} + +/* 电机右转 */ +void MotorRight(void) +{ + HAL_APT_StopModule(RUN_APT0); + User_APTForcePWMAOutputLow(g_apt1.baseAddress); // 右转,左轮子前进 + User_APTPwmBRecovery(g_apt1.baseAddress); +} + +/* 通过占空比调节电机速度 */ +void MotorSpeedAdjustmentByDuty(unsigned int duty, unsigned int directions) +{ + /* 正转 */ + if (directions == 0) { + HAL_APT_SetPWMDutyByNumber(&g_apt0, duty); + HAL_APT_SetPWMDutyByNumber(&g_apt1, duty); + } else { + /* 反转 */ + HAL_APT_SetPWMDutyByNumber(&g_apt0, (100 - duty)); + HAL_APT_SetPWMDutyByNumber(&g_apt1, (100 - duty)); + } +} + +/* 通过修改频率调节电机速度 */ +void MotorSpeedAdjustmentByFreq(unsigned int freq) +{ + DCL_APT_SetTimeBasePeriod(g_apt0.baseAddress, freq); + DCL_APT_SetTimeBasePeriod(g_apt1.baseAddress, freq); +} + +void initMotor() +{ + MotorSpeedAdjustmentByDuty(g_aptDutyCur, g_rotationDirectionStatus); +} + +void MotorProcess() +{ + + //MotorSpeedAdjustmentByFreq(g_aptFreqCntCur); + // HAL_APT_StartModule(RUN_APT0|RUN_APT1); + + // while (1) { + /* 改变转动方向 */ + g_testCount ++; + + /*if (g_rotationDirectionStatus != g_rotationDirectionStatusSet) { + g_rotationDirectionStatus = g_rotationDirectionStatusSet; + if (g_rotationDirectionStatus == 0) { + MotorForwardRotation(); //电机正转 + } else { + MotorReverse(); //电机反转 + } + } */ + + if (g_testCount > 200) { + if (g_rotationDirectionStatus == 1) + { + MotorForwardRotation(); /* 电机正转 */ + g_rotationDirectionStatus = 0; + } + else + { + MotorReverse(); /* 电机反转 */ + g_rotationDirectionStatus = 1; + } + + DBG_PRINTF("Test Num = %d\r\n",g_testNum++); + g_testCount =0; + } + + + /* 改变速度 */ + if (g_aptDutyCur != g_aptDutySet) { + g_aptDutyCur = g_aptDutySet; + MotorSpeedAdjustmentByDuty(g_aptDutyCur, g_rotationDirectionStatus); + } + + if (g_aptFreqCntCur != g_aptFreqCntSet) { + g_aptFreqCntCur = g_aptFreqCntSet; + MotorSpeedAdjustmentByFreq(g_aptFreqCntCur); + } + // } + +} \ No newline at end of file diff --git a/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/user_motor_control.h b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/user_motor_control.h new file mode 100644 index 0000000000000000000000000000000000000000..df4fffd914a0806803315303815b5e284bed5ff1 --- /dev/null +++ b/hi-sle/EulerCar_Slave_Computer_Hi3061_Source_Code/user/user_motor_control.h @@ -0,0 +1,21 @@ +#ifndef USER_MOTOR_CONTROL_H +#define USER_MOTOR_CONTROL_H + +#include + +void initMotor(void); +void startMotor(void); +void stopMotor(void); +void MotorForwardRotation(void); +void MotorReverse(void); +void MotorSpeedAdjustmentByDuty(unsigned int duty, unsigned int directions); +void MotorSpeedAdjustmentByFreq(unsigned int freq); +void MotorProcess(void); +void MotorRight(void); +void MotorLeft(void); +void User_APTForcePWMAOutputLow(APT_RegStruct *aptx); +void User_APTForcePWMBOutputLow(APT_RegStruct *aptx); +void User_APTPwmARecovery(APT_RegStruct *aptx); +void User_APTPwmBRecovery(APT_RegStruct *aptx); + +#endif \ No newline at end of file diff --git a/hi-sle/JLCPCB_Files/BOM_Board1_EulerCar.xlsx b/hi-sle/JLCPCB_Files/BOM_Board1_EulerCar.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..8ba4be5de55f9b7557787edeaa7f0bf1b1b8b1da Binary files /dev/null and b/hi-sle/JLCPCB_Files/BOM_Board1_EulerCar.xlsx differ diff --git a/hi-sle/JLCPCB_Files/Gerber_eulercar_2024-09-15.zip b/hi-sle/JLCPCB_Files/Gerber_eulercar_2024-09-15.zip new file mode 100644 index 0000000000000000000000000000000000000000..2b36ef2a6f88781d81b9604aed2f1bb1aeed1208 Binary files /dev/null and b/hi-sle/JLCPCB_Files/Gerber_eulercar_2024-09-15.zip differ diff --git a/hi-sle/JLCPCB_Files/pin_func.md b/hi-sle/JLCPCB_Files/pin_func.md new file mode 100644 index 0000000000000000000000000000000000000000..cf8def09afdddcffed2ed4e0f659ade32f37fb99 --- /dev/null +++ b/hi-sle/JLCPCB_Files/pin_func.md @@ -0,0 +1,21 @@ +- 左摇杆 + - X IO9 + - Y IO8 + - Z IO14 +- 右摇杆 + - X IO10 + - Y IO7 + - Z IO6 + +- 左按键 u13 + - IO2 +- 右按键 u14 + - IO4 + +- 左钮子 SW8 + - IO5 +- 右钮子 SW9 + - IO3 + +- 震动马达 + - IO11 diff --git a/hi-sle/README.md b/hi-sle/README.md index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..750993f39b1543cc0e325af04eecfcab40fecc4e 100644 --- a/hi-sle/README.md +++ b/hi-sle/README.md @@ -0,0 +1,484 @@ +# 基于openEuler Embedded的星闪开源应用案例开发 + +本开源项目是一款「基于NearLink_DK_WS63星闪开发板制作的遥控手柄」,无缝互联并操作「集成星闪WS73的智能小车」(小车可兼容Open Euler与Ros2系统) + +> 星光熠熠,科技浪潮涌动!"Euler星闪耀·万物智联" —— 星闪+OpenEuler Embedded,一场关于智能交互的盛宴,让未来触手可及! + + +
+

+ + + + 梅科尔 + + + +

+
+ +

+ + Logo + Logo + + +

「星闪 · 遥控手柄」

+

+ 「星闪:短距新赛道」: 不止于控,更在于“速”  +
+
+ 查看Demo + · + 报告Bug + · + 提出新特性 +

+

+ +--- + +- [基于openEuler Embedded的星闪开源应用案例开发](#基于openeuler-embedded的星闪开源应用案例开发) + - [项目介绍](#项目介绍) + - [目录结构](#目录结构) + - [软件指南](#软件指南) + - [1. 环境搭建](#1-环境搭建) + - [2. 编译烧录](#2-编译烧录) + - [2.1 Ws63主控](#21-ws63主控) + - [2.2 EulerPi](#22-eulerpi) + - [2.3 Hi3061M](#23-hi3061m) + - [ws63代码文件详解](#ws63代码文件详解) + - [EulerCar控制核心代码](#eulercar控制核心代码) + - [硬件指南](#硬件指南) + - [1. 电路设计](#1-电路设计) + - [2. PCBlayout](#2-pcblayout) + - [3. 主体建模](#3-主体建模) + - [4. 物料购买](#4-物料购买) + - [5. 焊接说明](#5-焊接说明) + - [6. 测试说明](#6-测试说明) + - [7. 硬件总装](#7-硬件总装) + - [8. 软硬件调试](#8-软硬件调试) + - [星闪手柄实操展示](#星闪手柄实操展示) + - [作者](#作者) + - [特别鸣谢 「梅科尔工作室」](#特别鸣谢-梅科尔工作室) + + +## 项目介绍 + +这是一个完整的星闪手柄开源项目,包含星闪手柄主控源码、星闪手柄结构设计、 星闪手柄电子硬件设计等多个部分,完成了以下内容: + +- 使用 Autodesk Fusion 360 完成的星闪手柄模型设计 +- 使用 嘉立创EDA完成的星闪手柄PCB设计 +- 基于 Hispark Studio完成润和ws63星闪开发板(主控)嵌入式软件设计 +- 基于 Ubuntu-vm22.04 完成ws73星闪模组代码编译 + +整个星闪手柄从一个ieda到真正实现、从前期部分投入到最后全身心投入经历了约三个月的时间,这个经历也让我更明白技术无止境,只有不停地学习、分享、复盘才能进步更快。所以我更希望把对制作星闪手柄过程中的困难和思考分享给大家。 + + +所以呢,整个开源项目最重要的不是星闪手柄本身(当然落地是非常困难的),而是,这是一套非常详细的开发教程,甚至可以说是手把手产品开发教程。从一个需求开始,到提取重点、外设选型、原理图设计、PCBlayout、代码编写、调试、烧录、结构设计、安装。如果本项目能对正在观看的你引起对星闪的兴趣和帮助,将是对我极大的鼓励和慰藉。 + +### 目录结构 + +如果刚刚开始接触这个项目,那么您可以看看本项目的文件结构,这样您可以更好的理解这个项目。 +``` +hi-sle +├── Autodesk_Fusion_360_Designs/ # Autodesk Fusion 360 模型设计文件夹 +├── Bill_of_Materials/ # 物料清单 +├── JLCPCB_Files/ # 立创PCB文件夹 +│── RemoteController_WS63E_Source_Code/ # NearLink_DK_WS63源代码 +│ ├── /SLE_OSPP_SERVER/ +│ │ ├── inc/ # 头文件 +│ │ └── src/ # 源文件 +├── EulerCar_Host_Computer_EulerPi_Source_Code # 上位机EulerPi源代码文件夹 +├── EulerCar_Slave_Computer_Hi3061_Source_Code # 下位机Hi3061源代码文件夹 +├── Images # 图片文件夹 +└── README.md # 项目说明文件 + +``` + +## 软件指南 + +### 1. 环境搭建 + +工欲善其事,必先利其器。在开始项目之前,我们需要搭建好开发环境。本项目的开发环境主要分为两个部分:**星闪遥控手柄** 开发环境 和 **EulerCar星闪遥控小车** 开发环境。由于官方基本上都有相对应的搭建教程,在本文档中就不再过多赘述。同时当然,如果您在真实开发过程中确实遇到了问题,无论问题简单与否,请大胆询问,摒弃掉学生思维。任何问题也欢迎在issue中提出,或者联系我,我会尽力解答。 + +1. **星闪遥控手柄** + + 星闪遥控手柄的主控是**NearLink_DK_WS63**,海思官方和小熊派团队都提供了开发环境搭建教程。 + - [海思Hispark Gitee组织提供的基于Windows搭建的开发环境教程](https://gitee.com/HiSpark/fbb_ws63/tree/master/tools#windows-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA) + - [小熊派团队提供的基于Window环境下开发环境搭建教程](https://www.bearpi.cn/core_board/bearpi/pico/h3863/software/%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BAwindows_IDE.html) + +2. **EulerCar星闪遥控小车** + + EulerCar是基于 Eulerpi主控板 和 Hi3061M控制板构建,那么我们需要搭建的环境主要分为两个部分:**EulerPi主控板** 开发环境 和 **Hi3061M控制板** 开发环境。 + +3. **EulerCar星闪遥控小车-EulerPi主控板** + + 易百纳官方提供了[海欧派开发及使用一指禅](https://gitee.com/HiEuler/doc/blob/master/EulerPi%20Compile%20using%20One%20Finger%20Zen.md),同时也可观看官方文档提供的[海鸥派Euler Pi 快速体验手册.pdf](https://github.com/Abrillant-Lee/Abrillant-Lee.github.io/blob/main/Summer-OSPP2024/EulerPi_Quick%20_Experience.pdf) 进行快速体验。 + >注意事项: + >1. 固件来源有很多种:官方网盘中给的固件、gitee中下载固件、自己构建的固件,我选择使用wsl构建固件,如果对Linux不熟悉的同学可以直接使用官方提供的VM虚拟机 + >2. PD电源输入端供电不支持电脑USB接口或者5v供电,12v供电最佳。
+ 1. 电脑USB接口的标准电压为5V,标准电流为500mA。
+ 2. 否则网口无法正常工作💢😠
+ >3. 注意烧录固件大小,4G使用4G的固件,8G使用8G的固件 + +4. **EulerCar星闪遥控小车-Hi3061M主控板** + + 官方教程:[eulercar mcu底盘代码和MCU开发IDE、MCU开发板指导手册](https://gitee.com/HiEuler/eulercar_controller) + +### 2. 编译烧录 + +1. 将本项目clone到本地 + + ```bash + git clone https://gitee.com/AbrillantLee/yocto-embedded-tools.git + ``` + +2. 切换到hieuler分支 + + ```bash + git switch hieuler + ``` + +#### 2.1 Ws63主控 + +1. 进入到项目目录下,将`RemoteController_WS63E_Source_Code`目录下`SLE_OSPP_Server`的拷贝到您的hispark studio 开发环境`xxx\src\application\samples\peripheral\`目录下。 + + ```bash + cd hi-sle + cp -r RemoteController_WS63E_Source_Code xxx\src\application\samples\peripheral\ + ``` + +2. 在xxx\src\application\samples\peripheral\CMakeLists.txt文件中新增编译案例(如果不知道在哪个地方加的,可以在“set(SOURCES "${SOURCES}" PARENT_SCOPE)”上面一行添加)。 + + ``` + if(DEFINED CONFIG_SAMPLE_SUPPORT_SLE_OSPP) + add_subdirectory_if_exist(sle_ospp) + endif() + ``` + +3. 在xxx\src\application\samples\peripheral\Kconfig文件中新增编译案例,具体如下图所示(如果不知道在哪个地方加,可以在最后一行添加)。 + + ``` + config SAMPLE_SUPPORT_SLE_OSPP + bool + prompt "使能星闪遥控器" + default n + depends on ENABLE_PERIPHERAL_SAMPLE + help + This option means support SLE_OSPP Sample. + ``` + +4. 选择”**系统配置**“,具体选择路径“Application/Enable the Sample of peripheral”,在弹出框中选择“使能星闪遥控器”,点击Save,关闭弹窗。 + +5. 点击“build”或者“rebuild”编译 + +6. 编译完成之后,在HiSpark Studio工具中点击“工程配置”按钮,选择“程序加载”,传输方式选择“serial”,端口选择“comxxx”,com口在设备管理器中查看。 + +7. 配置完成后,点击工具“程序加载”按钮烧录。 + +8. 出现“Connecting, please reset device...”字样时,复位开发板,等待烧录结束。 + +#### 2.2 EulerPi + +- EulerPi官方Gitee仓库提供教程,可以参考[EulerPi Gitee仓库 教程 ](https://gitee.com/HiEuler/doc/blob/master/Vm-Ubuntu22.04-ROSSDK.md)。 + +- 注意在在`先从gitee网站上,将项目代码下载到到ubuntu环境,普通目录/home/robot下` 这一步时: + +- 将`xxx/eulercar/sle_control/src/bs21_ws73_ros2.c`文件替换为本目录下的`EulerCar_Host_Computer_EulerPi_Source_Code\ws63_ws73_ros2.c`文件 + +#### 2.3 Hi3061M + +- 使用HisparkStudio打开Hi3061M的工程,将User目录下的文件替换为本目录下`EulerCar_Slave_Computer_Hi3061_Source_Code`文件编译烧录即可。 + +- 还有一种最为简单的方式就是将`Hispark`配置中的`Bin`文案金更换为`EulerCar_Slave_Computer_Hi3061_Source_Code/out/target.bin`文件,然后直接烧录即可。 + +

+Logo +

+ +### ws63代码文件详解 + +``` +│ ├── /SLE_OSPP_SERVER/ +│ │ ├── inc/ +│ │ │ │ ├── button.h # 按钮模块的头文件 +│ │ │ │ ├── shake.h # 震动传感器模块的头文件 +│ │ │ │ ├── eulercar_control.h # EulerCar控制模块的头文件 +│ │ │ │ ├── sle_ospp_server.h +│ │ └── src/ +│ │ │ │ ├── button.c # 按钮/扭子开关模块的实现文件 +│ │ │ │ ├── shake.c # 震动传感器模块的实现文件 +│ │ │ │ ├── eulercar_control.c # EulerCar控控制模块的实现文件, +│ │ │ │ ├── sle_ospp_server_adv.c +│ │ │ │ ├── sle_ospp_server.c # SLE OSPP服务器的主实现文件 +│ │ │ ├── CMakeLists.txt # CMake 构建系统的配置文件 +│ │ │ ├── Kconfig # Kconfig 配置文件 + +``` +#### EulerCar控制核心代码 + +``` +// 键盘报告结构体定义 +typedef struct +{ + uint8_t kind; // 键盘报告类型 + uint8_t special_key; // 特殊按键 + uint8_t reserve; // 保留字段 + uint8_t key[6]; // 按键值数组 +} usb_hid_rcu_keyboard_report_t; + +// 向上键报告 +usb_hid_rcu_keyboard_report_t EulerCarUp = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x52, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 释放键报告 +usb_hid_rcu_keyboard_report_t EulerCarRelease = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x0, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 辅助函数:发送键盘报告通知 +void send_keyboard_report(usb_hid_rcu_keyboard_report_t *report) +{ + ssaps_ntf_ind_t param = {0}; // 初始化通知参数结构体 + param.handle = g_property_handle; // 设置通知的句柄 + param.type = 0; // 设置通知类型为0 + param.value = (uint8_t *)report; // 将键盘报告数据转换为 uint8_t 指针 + param.value_len = sizeof(*report); // 设置通知数据的长度 + ssaps_notify_indicate(g_server_id, g_conn_id, ¶m); // 发送通知 +} + +/** + * @brief 控制小车前进 + * + * 该函数通过发送键盘报告通知来控制小车前进。首先发送前进键报告, + * 然后延时一段时间,再发送释放键报告。最后打印一条日志信息并延时一段时间。 + */ +void eulercar_control_forward(void) +{ + send_keyboard_report(&EulerCarUp); // 发送前进键报告 + (void)osal_msleep(PRESS_RELEASE_INTERVAL); // 延时 + send_keyboard_report(&EulerCarRelease); // 发送释放键报告 + Vibration_CarControl(); + PRINT("[SLE Server] 星闪小车前进! \r\n"); + (void)osal_msleep(LONG_PRESS_INTERVAL); // 延时,等待响应 +} + +...... # 向左、右、后代码查看源代码即可,注释非常详细 + +``` + + +## 硬件指南 +硬件主要由底板,PCB主板和亚克力板组成 +

+Logo +

+ +以下是PCB主板主要功能图示 +

+Logo +

+

+Logo +

+ +### 1. 电路设计 + +> 本硬件电路主要分为电源管理电路,震动马达驱动电路和控制模块电路构成 +

+Logo +

+ +1. 电源管理电路以IP5306(产品资料🔗)为核心。IP5306是一款集成升压转换器、锂电池充电管理、电池电量指示的多功能电源管理 SOC,为移动电源提供完整的电源解决方案。 + - 可同步开关充放电,支持4LED电量显示 + - 自动检测充电器插拔,自适应充电电流调节 + - 按键功能: + - 短按(持续时间长于 50ms,但小于 2s)会打开电量显示灯和升压输出。 + - 连续两次短按键( 1s 内),会关闭电量显示和升压输出 +

+Logo +

+

+Logo +

+ +2. 震动马达驱动电路以微型震动马达为核心,在这个电路中,场效应管能够通过控制门极电压来开启或关闭电流,从而控制电机的工作状态。肖特基二极管防止电机在停止时产生的反向电流对电路造成损坏,起到保护作用。 + +

+ Logo +

+ +3. 控制模块电路以WS63E为核心,用于各个引脚与传感器或执行器之间的通信。 + +### 2. PCBlayout + + +以下是PCB设计🔗 +

+ Logo +

+ + +为了方便硬件焊接测试与软件调试,我们将各个摇杆等主要功能按键导出为markdown文件🔗 +以供快速参考 + +### 3. 主体建模 +1. 遥控器底板模型🔗总体按照PCB轮廓构建,使用Autodesk Fusion进行建模。 + - 整体参考游戏手柄与遥控手柄设计 + - 底板前端突起为外置天线座,可以搭载外设SLE天线 + - 预留四个M3空位,用于与PCB和顶板的连接固定 + +

+ Logo + Logo +

+ + +2. 顶层亚克力板轮廓🔗由底板模型轮廓构建,使用Fusion进行导出 + - 顶板设计需要考虑按键与摇杆等传感器加上键帽配件等的总体高度 + - 预留四个M3空位,用于与PCB和顶板的连接固定 + - 六角铜柱需要的最小高度为:PCB插排高度+WS63E最大高度 = 16mm + +

+ Logo +

+ +### 4. 物料购买 + +PDB电子元器件物料可直接由嘉立创EDA导出 +BOM表单🔗,交由专业配件商家购买。 + +除此之外,完成总体装配还需要其他配件或耗材🔗。 + + +1. 摇杆帽:用于摇杆操控(注意底孔是小孔型号哦) +2. 亚克力板:用于遥控器整体面板(dxf亚克力轮廓图🔗) +3. 焊锡膏:用于贴片原件焊料 +4. 704硅橡胶:用于PCB电池盒固定 +5. 18650电池:用于遥控板供电 +6. 六角铜柱:用于整体连接 + + +### 5. 焊接说明 + +1. 准备好PCB、元器件、电烙铁或热风枪、锡膏或锡丝、镊子。 +2. 打开BOM表或EDA,从贴片元器件开始,找到要焊接的元器件型号。 + +

+ Logo +

+ +3. 按照元器件位置进行分区,使用热风枪时对邻近贴片元器件一起焊接。 + +

+ Logo +

+ +4. 每个模块焊接完成后,可以对照PCB工程图,用万用表逐个检查是否存在焊错、短路、虚焊、脱焊等情况。 +5. 按上述的步骤,完成所有元器件的焊接即可。也可使用洗板水确保焊后的美观。 +

+ Logo +

+ +

+ Logo +

+ + +### 6. 测试说明 + +> 焊接完成后,要先目测、用万用表检测下,有没有焊接错的地方。尤其确保没有短路。第一次上电时也要第一时间观察下有没有异常,有异常迅速拔掉电源。 + +可能遇到的问题: +1. IP5306相关问题 + - [x] 1. 输出电压很低,只有2-3V,没有了升压。
+ - 原因 + 是芯片底部GND与PCB之间脱焊所致。 + - 解决方案 + IP5306底部的焊盘为GND,在焊接时建议为底盘加锡进行焊接 + - [x] 2. 开机半分钟自动休眠 + - 原因 + - 是电流过低,可以检查是否有元器件虚焊脱焊现象。当一段时间内芯片负载电流持续小于45mA左右时,芯片会自动进入休眠状态。 但在实际应用中,此芯片个体差异很大,有部分芯片负载电流需要达到70mA以上才不会自动休眠 + - 解决方案 + - 检查元器件是否脱焊、虚焊,重新焊接。 + - [x] 不断关机重启 + - 原因 + - 可能是芯片检测到过流或者短路引起的 + - 可能是散热不足触发过温保护导致的 + - 解决方案 + - 检查是否短路,进行重新焊接; + - 检查是否由过温导致,检查工作温度是否符合要求,增加散热片等散热措施; +

+ Logo +

+ + - [x] 芯片烧毁 + - 原因 + - 电池持续放电或温度过高等原因导致芯片烧毁 + - 解决方案 + - 检查电池质量与焊接质量,进行重新焊接,更换芯片。 +2. 其他问题 + - [x] 传感器失灵 + - 原因 + - 传感器元器件与PCB脱焊或虚焊 + - 解决方案 + - 检查元器件是否脱焊、虚焊,重新焊接。 + +### 7. 硬件总装 +注意三个组件从底部往上装配。 +1. 从底版底部拧入螺丝,在底版上部放入垫片与螺帽。在确保与PCB孔位对齐的情况下固定好底板与螺丝。 +2. 在底板上部侧放入PCB,注意对准螺孔,在上侧放入垫片与六角铜柱拧紧。 +3. 在螺柱顶部放入亚克力板,对齐后加上垫片拧入螺丝 +4. 您的第一个星闪遥控器大功告成 + +

+ Logo +

+ +### 8. 软硬件调试 + +启动遥控器,检查是否有异常现象,如有异常现象,及时断电检查。正常情况下,遥控器应该可以正常工作。 + +同时启动EulerCar小车sle和ros节点即可。 + + +## 星闪手柄实操展示 +> + +手柄操作方法: +1. 左摇杆:控制EulerCar前进、后退、左转、右转 +2. 右摇杆:控制EulerCar夹爪:张开、闭合 +3. 左右扭子开关:切换不同EulerCar小车 +前进 + +左转 + +右转 + +后退 + + Logo + Logo + Logo + Logo + +## 作者 + +Github: [AbrillantLee](https://github.com/Abrillant-Lee) 、[pete](https://github.com/Pete-Young) + +## 特别鸣谢 「梅科尔工作室」 +大一入学时我是一个对计算机一无所知的小白,更别提海思开发;一切的转机发生在加入梅科尔工作室这个大家庭后,受到了李老师和学长们的用心培养。 + +在这里 我怀着崇敬之心真诚地感谢梅科尔工作室! 感谢感谢杨阳学长的信任、感谢杨瑞学弟与我共同奋斗。 + +同时,感谢杨帆工程师、杨红亮导师的耐心指导。 + +工作室也时刻激励着我,做一件事,就得用心做好,无论是学习、项目、还是为人。 diff --git a/hi-sle/RelevantDetails/IP5306_datasheet_v1.01.pdf b/hi-sle/RelevantDetails/IP5306_datasheet_v1.01.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cb968e06b592716a00d1305526b82cad503fef39 Binary files /dev/null and b/hi-sle/RelevantDetails/IP5306_datasheet_v1.01.pdf differ diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/SLE_OSPP_Server.h b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/SLE_OSPP_Server.h new file mode 100644 index 0000000000000000000000000000000000000000..ca56a47cbf15cff2be40f68cb5aff41def12b4ac --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/SLE_OSPP_Server.h @@ -0,0 +1,25 @@ + +/** + * @defgroup + * @ingroup + * @{ + */ +#ifndef SLE_LED_SERVER_H +#define SLE_LED_SERVER_H + +#include "sle_ssap_server.h" +// #include "gpio.h" // GPIO操作相关的头文件 +// #include "pinctrl_porting.h" + +// 这些UUID的值是如何确定的? + +/* Service UUID 服务UUID*/ +#define SLE_UUID_SERVER_SERVICE 0xABCD + +/* Notify Repoert UUID 通知报告UUID*/ +#define SLE_UUID_SERVER_NTF_REPORT 0x1122 + +/* Property UUID 特征信息UUID*/ +#define SLE_UUID_SERVER_PROPERTY 0x3344 + +#endif diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/SLE_OSPP_Server_adv.h b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/SLE_OSPP_Server_adv.h new file mode 100644 index 0000000000000000000000000000000000000000..c0222d3e0a97c60eff32469cd4d06cc17a69ed74 --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/SLE_OSPP_Server_adv.h @@ -0,0 +1,96 @@ +/* +# 版权所有 (C) 2024 HiHope 开源组织。 +# 根据 Apache 许可证 2.0 版(“许可证”)授权; +# 除非遵守许可证,否则您不得使用此文件。 +# 您可以在以下位置获取许可证的副本 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# 除非适用法律要求或书面同意,否则根据许可证分发的软件 +# 以“原样”分发, +# 不附带任何明示或暗示的保证或条件。 +# 请参阅许可证,了解许可证下管理权限和 +# 限制的特定语言。 +*/ + +/** 这个注释是 Doxygen 风格的注释,用于生成文档 + * @defgroup + * @ingroup + * @{ + */ + +#ifndef SLE_LED_SERVER_ADV_H +#define SLE_LED_SERVER_ADV_H + +/** + * @if Eng + * @brief Definitaion of BLE ADV 通用广播结构. + * @else + * @brief SLE 广播普通数据结构。 + * @endif + */ +struct sle_adv_common_value { + uint8_t length; + uint8_t type; + uint8_t value; +}; + +/** + * @if Eng + * @brief Definitaion of BLE ADV Channel mapping. + * @else + * @brief SLE 广播信道映射。 + * @endif + */ +typedef enum { + SLE_ADV_CHANNEL_MAP_77 = 0x01, + SLE_ADV_CHANNEL_MAP_78 = 0x02, + SLE_ADV_CHANNEL_MAP_79 = 0x04, + SLE_ADV_CHANNEL_MAP_DEFAULT = 0x07 +} sle_adv_channel_map; + +/** + * @if Eng + * @brief Definitaion of SLE ADV Data Type. + * @else + * @brief SLE 广播数据类型 + * @endif + */ +typedef enum { + SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL = 0x01, /*!< 发现等级 */ + SLE_ADV_DATA_TYPE_ACCESS_MODE = 0x02, /*!< 接入层能力 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_16BIT_UUID = 0x03, /*!< 标准服务数据信息 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_128BIT_UUID = 0x04, /*!< 自定义服务数据信息 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x05, /*!< 完整标准服务标识列表 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x06, /*!< 完整自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x07, /*!< 部分标准服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x08, /*!< 部分自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_SERVICE_STRUCTURE_HASH_VALUE = 0x09, /*!< 服务结构散列值 */ + SLE_ADV_DATA_TYPE_SHORTENED_LOCAL_NAME = 0x0A, /*!< 设备缩写本地名称 */ + SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME = 0x0B, /*!< 设备完整本地名称 */ + SLE_ADV_DATA_TYPE_TX_POWER_LEVEL = 0x0C, /*!< 广播发送功率 */ + SLE_ADV_DATA_TYPE_SLB_COMMUNICATION_DOMAIN = 0x0D, /*!< SLB通信域域名 */ + SLE_ADV_DATA_TYPE_SLB_MEDIA_ACCESS_LAYER_ID = 0x0E, /*!< SLB媒体接入层标识 */ + SLE_ADV_DATA_TYPE_EXTENDED = 0xFE, /*!< 数据类型扩展 */ + SLE_ADV_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF /*!< 厂商自定义信息 */ +} sle_adv_data_type; + +/** + * @if Eng + * @brief sle adv config and announce. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle广播配置和公开。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +errcode_t example_sle_server_adv_init(void); +#endif \ No newline at end of file diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/button.h b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/button.h new file mode 100644 index 0000000000000000000000000000000000000000..3eb03f8228809aba6c38936da10d9dccd7a87b1b --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/button.h @@ -0,0 +1,19 @@ +#ifndef BUTTON_H +#define BUTTON_H + +#include "pinctrl.h" +#include "hal_gpio.h" +#include "gpio.h" +#include "osal_task.h" + +// 定义按键引脚 +#define LEFT_BUTTON_PIN 2 +#define RIGHT_BUTTON_PIN 4 +#define LEFT_TOGGLE_PIN 5 +#define RIGHT_TOGGLE_PIN 3 + +// 初始化按键 +void Key_Init(void); + + +#endif // KEY_H \ No newline at end of file diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/eulercar_control.h b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/eulercar_control.h new file mode 100644 index 0000000000000000000000000000000000000000..5b645b66af10e874e41d873b346f7d52f79e8df2 --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/eulercar_control.h @@ -0,0 +1,26 @@ +#ifndef EULERCAR_CONTROL_H +#define EULERCAR_CONTROL_H + +#include + +// 宏定义延时参数(毫秒) +#define PRESS_RELEASE_INTERVAL 50 +#define LONG_PRESS_INTERVAL 100 + +// 键盘报告结构体定义 +typedef struct +{ + uint8_t kind; // 键盘报告类型 + uint8_t special_key; // 特殊按键 + uint8_t reserve; // 保留字段 + uint8_t key[6]; // 按键值数组 +} usb_hid_rcu_keyboard_report_t; + +// 函数声明 +void eulercar_control_forward(void); +void eulercar_control_backward(void); +void eulercar_control_left(void); +void eulercar_control_right(void); +void eulercar_control_stop(void); + +#endif // EULERCAR_CONTROL_H \ No newline at end of file diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/shake.h b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/shake.h new file mode 100644 index 0000000000000000000000000000000000000000..2a9379b6bfced0e91686768e68e8327988b035cf --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/inc/shake.h @@ -0,0 +1,70 @@ +#ifndef SHAKE_H +#define SHAKE_H + +#define SHAKE_PIN 11 + +// 震动时长定义(单位:毫秒) +#define VIBRATION_DURATION_POWER_ON 250 // 开发板上电震动时长 +#define VIBRATION_DURATION_CONN_CHANGE 500 // 星闪连接状态改变震动时长 +#define VIBRATION_DURATION_GRIPPER_LIMIT 100 // 夹爪行程极限震动时长 +#define VIBRATION_DURATION_CAR_CONTROL 100 // 控制小车震动时长 + +/** + * @brief 开发板上电震动函数 + * + * 该函数用于在开发板上电时触发震动马达震动。 + */ +void Vibration_PowerOn(void); + +/** + * @brief 星闪连接状态改变震动函数 + * + * 该函数用于在星闪连接状态改变(连接上或断连)时触发震动马达震动。 + */ +void Vibration_ConnChange(void); + +/** + * @brief 夹爪行程极限震动函数 + * + * 该函数用于在夹爪达到行程极限时触发震动马达震动。 + */ +void Vibration_GripperLimit(void); + +/** + * @brief 控制小车震动函数 + * + * 该函数用于在控制小车前进、后退、左转或右转时触发震动马达震动。 + */ +void Vibration_CarControl(void); + +/** + * @brief 震动马达初始化函数 + * + * 该函数用于初始化震动马达的相关硬件和软件资源。 + */ +void Shake_Init(void); + +/** + * @brief 启动震动马达函数 + * + * 该函数用于启动震动马达,使其开始震动。 + */ +void Shake_Start(void); + +/** + * @brief 停止震动马达函数 + * + * 该函数用于停止震动马达,使其停止震动。 + */ +void Shake_Stop(void); + +/** + * @brief 震动马达震动函数 + * + * @param duration 震动时长(单位:毫秒) + * + * 该函数用于使震动马达震动指定时长。 + */ +void Shake_Buzz(unsigned int duration); + +#endif // SHAKE_H \ No newline at end of file diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/log/log b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/log/log new file mode 100644 index 0000000000000000000000000000000000000000..c71b80f23a83cbf807e32a5312c02d1684793713 --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/log/log @@ -0,0 +1,548 @@ +./service.sh +[INFO] [launch]: All log files can be found below /root/.ros/log/2018-03-09-12-45-23-878167-hieulerpi1-2403 +[INFO] [launch]: Default logging verbosity is set to INFO +[INFO] [nearlink_robot_node-1]: process started with pid [2404] +[INFO] [bs21_ws73_ros2-2]: process started with pid [2406] +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.412] [uapi gle_init] +[bs21_ws73_ros2-2] [bts][info] btsrv_task_init btsrv_init: task create success +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.412] ssapc client init +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.412] ssapc register inter cbk +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [uapi gle_enable] +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [gle manger enable]enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle dd init +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle cm init enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [GLE DM][DM init] transmission management module init +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [GLE TM][TM init] transmission management module init +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle ssap init ok +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [GLE SM] start init +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [GLE DM][DM init] security management module init +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hadm init enter. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle factory init enter. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle glp init enter. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [gle manager_enable]enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle read maximum adv data len +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] read access filter list size +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [GLE SM] read support cryptography algorithm +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci struct to stream opcode:0xc06, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] hci command encode send tl paramlen=0x0 opcode:0xc06 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci internal command send core send opcode=0xc06 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci internal command send core send opcode=0x40a +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci internal command send core send opcode=0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci internal command send core send opcode=0x402 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.413] gle hci internal command send core send opcode=0x1c07 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] gle execute command cbk evindex:c06 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] opcode = 0x0c06, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] max_adv_data_len = 0x00fb +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] gle read maximum adv data len +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] gle hci struct to stream opcode:0x40a, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] hci command encode send tl paramlen=0x0 opcode:0x40a +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] [HCI]gle hci internal evt cbk unreg table->id = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] gle hci internal command send core send opcode=0xc07 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.414] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] gle execute command cbk evindex:40a +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] opcode = 0x040a, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] read access filter list size = 16 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] [TIMRE_ADD][STACK_TIMER] TIMER=0xb00011e0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] gle hci struct to stream opcode:0x406, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] hci command encode send tl paramlen=0x0 opcode:0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] [TIMER_DEL][STACK_TIMER] TIMER=0xb00011e0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] gle execute command cbk evindex:406 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] opcode = 0x0406, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] get addr:0xb0:66:**:**:**:00 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001290, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] gle hci struct to stream opcode:0x402, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] hci command encode send tl paramlen=0x0 opcode:0x402 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.415] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle execute command cbk evindex:402 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle hci read buffer size cfm result:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] [gle manger enable]result = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] [GLE DM] event = 0x0 +[bs21_ws73_ros2-2] [ACore] sle enable cbk in, result:0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] dev enable ret:0. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] recover key fail, there is no key +[bs21_ws73_ros2-2] sle enable +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.416] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] sle_set_local_addr 0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] [gle hci read buffer size] result = 0x0, opindex: 0x00000402 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] [gle hci read buffer size] acb data len: 254 num: 5, icb data len: 0 num: 0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001340, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle hci struct to stream opcode:0x1c07, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] hci command encode send tl paramlen=0x0 opcode:0x1c07 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle hci internal command send core send opcode=0x405 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.420] gle hci internal command send core send opcode=0x1001 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.437] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001340 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.437] gle execute command cbk evindex:1c07 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.437] opcode = 0x1c07, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.437] [GLE SM] algo: 0x02 0x02 0x02 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.437] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.437] gle hci struct to stream opcode:0xc07, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.438] hci command encode send tl paramlen=0x0 opcode:0xc07 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.438] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.438] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.438] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.438] gle execute command cbk evindex:c07 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.438] opcode = 0x0c07, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.438] supported_adv_sets_num = 0x8 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001130, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] gle hci struct to stream opcode:0x405, stream_len=0x6 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] hci command encode send tl paramlen=0x6 opcode:0x405 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 + + +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001130 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] gle execute command cbk evindex:405 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] opcode = 0x0405, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.439] gle set public address status success. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] gle hci struct to stream opcode:0x1001, stream_len=0x8 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] hci command encode send tl paramlen=0x8 opcode:0x1001 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] [HCI]gle hci internal evt cbk unreg table->id = 0x405 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.440] gle hci internal command send core send opcode=0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] gle execute command cbk evindex:1001 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] opcode = 0x1001, cmd_result = 0xb +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] [dd]event = 0x8 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] [SLE SCAN CBK] event: 8. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] start device seek. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001290, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] gle hci struct to stream opcode:0x406, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] hci command encode send tl paramlen=0x0 opcode:0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.457] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] [HCI]gle hci internal evt cbk unreg table->id = 0x1400 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] scan_enable = 0x1, filter_duplicates = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] gle hci internal command send core send opcode=0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] gle execute command cbk evindex:406 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] opcode = 0x0406, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] get addr:0xb0:66:**:**:**:00 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001370, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] gle hci struct to stream opcode:0x1002, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] hci command encode send tl paramlen=0x2 opcode:0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.458] [HCI]gle hci internal evt cbk unreg table->id = 0x1400 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001370 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] gle execute command cbk evindex:1002 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] opcode = 0x1002, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] gle dd set scan enable cfm scan enabled +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] [dd]event = 0x9 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] [SLE SCAN CBK] event: 9. +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:45:24.459] [HCI]gle hci internal evt cbk unreg table->id = 0x1002 +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:5 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] op_ev = 0x180B +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] cfm_type = 0x1e +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] [dd]event = 0xb +[bs21_ws73_ros2-2] [adv_report] event_type: 0x03, addr_type: 0x0000, addr: 3c:**:**:**:4e:33 +[bs21_ws73_ros2-2] [adv_report] data length: 6, data: 0x02 0x01 0x01 0x02 0x02 0x00 +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:7 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] stop device seek. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] scan_enable = 0x0, filter_duplicates = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001290, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] gle hci struct to stream opcode:0x1002, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] hci command encode send tl paramlen=0x2 opcode:0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.23] gle hci internal command send core send opcode=0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.37] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.37] gle execute command cbk evindex:1002 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.37] opcode = 0x1002, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle dd set scan enable cfm scan disabled +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] [dd]event = 0xa +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] [SLE SCAN CBK] event: 10. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] [HCI]gle hci internal evt cbk unreg table->id = 0x0 +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:6 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] create conn node, addr 3c:4a:xx:xx:xx:33 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle device link add node->status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle hci struct to stream opcode:0x1401, stream_len=0x1b +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] hci command encode send tl paramlen=0x1b opcode:0x1401 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle hci internal command send core send opcode=0x1401 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1401 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] gle hci ev command status restart ertx opcode=0x1401, timeout:0x2710 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.38] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.39] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=10000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.39] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.39] gle hci ev command status in opcode=0x1401, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] gle access link status report in +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [gle connect cfm] result:0x0 status = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [GLE TM][LCID init] LCID = 0x0000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [GLE SM] init new remote device. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] gle ssap create tl link by addr add dev onaddr:0x3c:**:**:**:4e:33 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [cm]event = 0x0 +[bs21_ws73_ros2-2] [Connected] +[bs21_ws73_ros2-2] addr:3c:**:**:**:4e:33, handle:00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] remote(0x3c:**:**:**:4e:33) conn_id(0) +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] remote(0x3c:**:**:**:4e:33) state(1) +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] gle hci struct to stream opcode:0x1801, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] hci command encode send tl paramlen=0x2 opcode:0x1801 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] gle hci internal command send core send opcode=0x1801 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.84] [GLE SM] pairing start, role: 0x0. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.94] [GLE SM] sm pairing request. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.94] [GLE SM] io_ability: 3, oob_flag 0, psk_flag: 0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] [TIMRE_ADD][STACK_TIMER] TIMER=0xa8000da0, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0134, len: 10.[2018-03-09 12:46:03.95] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1801 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] gle hci ev command status restart ertx opcode=0x1801, timeout:0x2904 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=10500 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] gle hci ev command status in opcode=0x1801, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] gle hci struct to stream opcode:0x1812, stream_len=0xf +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] hci command encode send tl paramlen=0xf opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.95] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0134.[2018-03-09 12:46:03.96] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.96] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.100] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.100] gle read remote features complete. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.100] cfm_type = 0x11 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.100] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.100] gle set data len, lcid: 0x0000, tx octets: 0xfe +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.100] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.100] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.101] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.101] gle hci struct to stream opcode:0x1802, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] hci command encode send tl paramlen=0x2 opcode:0x1802 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] gle hci internal command send core send opcode=0x1802 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] gle hci internal command send core send opcode=0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1802 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] gle hci ev command status restart ertx opcode=0x1802, timeout:0x2904 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.102] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.103] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=10500 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.103] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.103] gle hci struct to stream opcode:0x1804, stream_len=0x4 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.103] hci command encode send tl paramlen=0x4 opcode:0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.103] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.103] gle hci ev command status in opcode=0x1802, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.104] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.104] gle execute command cbk evindex:1804 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.104] [GLE HCI] set data len result = 0x0, opindex: 0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.104] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.104] [HCI]gle hci internal evt cbk unreg table->id = 0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.125] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.125] gle read remote version complete. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.125] cfm_type = 0x12 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.125] [cm]event = 0x7 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.125] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] [GLE SM] data recv, lcid: 0x0000, len: 10, opcode: 0x0135 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] [GLE SM] algorithm negotiate: 2 2 2 0[2018-03-09 12:46:03.138] [GLE SM] sm pairing confirm, authentication method: 1. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] [TIMER_DEL][STACK_TIMER] TIMER=0xa8000da0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] [TIMRE_ADD][STACK_TIMER] TIMER=0xa8000da0, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0136, len: 70.[2018-03-09 12:46:03.138] [GLE SM] event = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] [TIMRE_ADD][STACK_TIMER] TIMER=0xb00011e0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.138] gle hci struct to stream opcode:0x1812, stream_len=0x4b +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.139] hci command encode send tl paramlen=0x4b opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.139] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.139] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.139] [TIMER_DEL][STACK_TIMER] TIMER=0xb00011e0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.139] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.139] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.140] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.140] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.140] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.140] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0136.[2018-03-09 12:46:03.140] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.140] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.163] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.163] [GLE SM] data recv, lcid: 0x0000, len: 64, opcode: 0x0137 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] [GLE SM] data recv, lcid: 0x0000, len: 16, opcode: 0x0138 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] [GLE SM] gle sm authentication procedure in, method: 0x1. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] [TIMER_DEL][STACK_TIMER] TIMER=0xa8000da0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] [TIMRE_ADD][STACK_TIMER] TIMER=0xa8000da0, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0139, len: 16.[2018-03-09 12:46:03.175] [GLE SM] authentication pdu send, opcode 0x0139. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001760, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] gle hci struct to stream opcode:0x1812, stream_len=0x15 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] hci command encode send tl paramlen=0x15 opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.175] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001760 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0139.[2018-03-09 12:46:03.176] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.176] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.225] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.225] [GLE SM] data recv, lcid: 0x0000, len: 16, opcode: 0x013a +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.225] [GLE SM] gle sm authentication procedure in, method: 0x1. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.234] [TIMER_DEL][STACK_TIMER] TIMER=0xa8000da0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] [TIMRE_ADD][STACK_TIMER] TIMER=0xa8000da0, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0141, len: 16.[2018-03-09 12:46:03.235] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001290, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] gle hci struct to stream opcode:0x1812, stream_len=0x15 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] hci command encode send tl paramlen=0x15 opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0141.[2018-03-09 12:46:03.235] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.235] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] [GLE SM] data recv, lcid: 0x0000, len: 16, opcode: 0x0142 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] [GLE SM] gle sm authentication procedure in, method: 0x1. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] [GLE SM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] gle acore config data write:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] gle acore set product type sys_config 0x:0! +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] gle acore save sm key write_index:00! +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] gle acore config data write:2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] [GLE SM] enable encryption +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] [GLE AA] enable encryption, crypt 1, key_deriv 1, integr_chk 0. +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] remote(0x3c:**:**:**:0x4e:0x33) conn_id(0) +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.250] [2018-03-09 12:46:03.250] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] auth status:0, crypto algo:2, key deriv algo:2, integr chk ind:0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.251] [TIMRE_ADD][STACK_TIMER] TIMER=0xa8000fb0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.251] gle hci struct to stream opcode:0x1c03, stream_len=0x15 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.251] hci command encode send tl paramlen=0x15 opcode:0x1c03 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.251] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.251] gle hci internal command send core send opcode=0x1c03 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.252] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1c03 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.252] gle hci ev command status restart ertx opcode=0x1c03, timeout:0x2904 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.252] [TIMER_DEL][STACK_TIMER] TIMER=0xa8000fb0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.252] [TIMRE_ADD][STACK_TIMER] TIMER=0xa8000fb0, TIME=10500 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.252] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.252] gle hci ev command status in opcode=0x1c03, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [TIMER_DEL][STACK_TIMER] TIMER=0xa8000fb0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] op_ev = 0x0011 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] cfm_type = 0x27 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [GLE SM] encrypt change, lcid: 0x0000, status: 0x0, encryption change: 0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [TIMER_DEL][STACK_TIMER] TIMER=0xa8000da0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [GLE SM] timer repeated attempts, job: 1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [GLE SM] event = 0x3 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] conn_id(0) pair result:3 +[bs21_ws73_ros2-2] [ssap client] pair complete conn_id:0, addr:3c:4a:83:2f:4e:33 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [uapi ssapc_exchange_info_req]mtu = 300 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [gle ssapc_exchange_mtu]mtu = 0x12c +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] [ssapc exchange_info_req_handle]mtu = 300, version = 0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] task create tl connection tl->status = 0x2, tl->mask = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] mtu = 300, version = 0x0001 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.312] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.313] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001290, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.325] tl task[1] trans done +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.325] tl trans done trans->op:[0x03] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.325] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.325] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.325] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.325] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] tl task[1] trans done +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] op_code[0x03], control_code[0x03], mtu[300], version[0x0001] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] tl->mtu[300] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] task[1] complete, err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] task[0x01] complete, err_code = 0x00 +[bs21_ws73_ros2-2] ssapc exchange info, conn_id:0, err_code:0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] tl done err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] ssapc handle msg type:7 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] sample ssapc indication cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] ssapc find structure conn_id:0, type:1, start hdl:1, end hdl:ffff +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] ssapc find structure uuid len:0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] addr:3c:**:**:**:4e:33, type = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] ssap discovery service all +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] ssapc discovery services conn_handle = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] task->type = 0x1, task->hdl = 0x1ffff, task->uuid.len = 0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] task create tl connection tl->status = 0x2, tl->mask = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] task_id = 0x82, task_type = 0x1, op_code = 0x04 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] dicovery task send uuid.len = 0, uuid:0x0000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] dicovery task send start_hdl: 0x0001, end_hdl: 0xffff +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] data_len = 6 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.337] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001130, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.362] ssap check type by opcode trans->op:0x05 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.362] tl task[130] trans done +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.362] tl trans done trans->op:[0x05] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001130 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] data_len = 9 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] control_code.fragment:0x03, mode:0x00, task->type:0x01, task_id:0x82, task->uuid.len:0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] curent_idx:0, data_len:7 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] uuid_len: 2, service->uuid.len: 2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] ssapc discovery service event handle +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] con_hdl:[0x00], hdl:[0x01], end_hdl:[0x02], svc->type_indication:[0x02] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] [disc_srv_rsp]start_hdl:[0x01], end_hdl:[0x02] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] uuid:[0x00][0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] discovery service start hdl:1, end hdl:2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] sample ssapc discovery services cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] uuid_len = 2, last_hdl = 0x0002, idx = 7 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] cur_hdl:[0x0001ffff], last_hdl:[0x0002] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] task[130] complete, err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] task[0x82] complete, err_code = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] ssapc handle msg type:0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] sample ssapc discovery service cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] op_code:0x04, type:0x01, uuid.len:0, err_code:0x00 +[bs21_ws73_ros2-2] discovery character cbk complete in +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] [internal_discovery_services] op_code:0x04, type:0x01, uuid.len:0, err_code:0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] ssapc handle msg type:2 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] sample ssapc discovery service cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] [ssap client] ssapc_write_req, conn_id:0 data_len:4 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] ssapc write req conn_id:0, hdl:1, data len:4 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] ssapc write req addr:0x3c:**:**:**:0x4e:0x33 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] handle = 0x01, type = 0x00, len = 4 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] tl done err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] [ssapc write_value_req]data_type = 0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] task create tl connection tl->status = 0x2, tl->mask = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] write_data_len = 4, data_len = 4, mtu = 295 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.363] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001370, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] ssap check type by opcode trans->op:0x0e +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] tl task[8] trans done +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] tl trans done trans->op:[0x0e] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001370 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] [write rsp]hdl[0x0001], data_type[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] ssapc write rsp op_code[0x0e], control_code[0x03], value_len[7] +[bs21_ws73_ros2-2] ssapc write rsp handle:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] task[8] complete, err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] task[0x08] complete, err_code = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] [write_req_complete]err_code:0x00 +[bs21_ws73_ros2-2] [sle write_req_complete_cbk]conn_id:0, err_code:0 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] ssapc handle msg type:5 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] [2018-03-09 12:46:03.387] tl done err_code:[0x00] +[bs21_ws73_ros2-2] sample ssapc write cfm cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] ssapc read req conn_id:0, hdl:1, type:0 + +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] ssapc read req addr:0x3c:**:**:**:0x4e:0x33 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.387] handle = 0x01, type = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.388] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.388] [TIMRE_ADD][STACK_TIMER] TIMER=0xb0001290, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.412] ssap check type by opcode trans->op:0x09 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.412] tl trans done trans->op:[0x09] +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.412] [TIMER_DEL][STACK_TIMER] TIMER=0xb0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.412] op_code[0x09], control_code[0x03], data_len[4] +[bs21_ws73_ros2-2] ssapc read rsp handle:0, data len:4 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.412] ssapc handle msg type:4 +[bs21_ws73_ros2-2] [2018-03-09 12:46:03.412] sample ssapc read cfm cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:46:05.337] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:46:05.337] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:46:05.337] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:07.362] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:46:07.362] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:46:07.362] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:09.350] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:46:09.350] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:46:09.350] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:11.362] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:46:11.362] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:46:11.362] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:13.375] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:46:13.375] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:46:13.375] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:46:15.387] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:46:15.387] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:46:15.387] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] \ No newline at end of file diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/log/log_old b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/log/log_old new file mode 100644 index 0000000000000000000000000000000000000000..ea0f0649dff899505c80e437376f26aa7fd131a5 --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/log/log_old @@ -0,0 +1,549 @@ + ./service.sh +[INFO] [launch]: All log files can be found below /root/.ros/log/2018-03-09-12-40-15-200889-hieulerpi1-2216 +[INFO] [launch]: Default logging verbosity is set to INFO +[INFO] [nearlink_robot_node-1]: process started with pid [2219] +[INFO] [bs21_ws73_ros2-2]: process started with pid [2221] +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.753] [uapi gle_init] +[bs21_ws73_ros2-2] [bts][info] btsrv_task_init btsrv_init: task create success +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] ssapc client init +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] ssapc register inter cbk +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [uapi gle_enable] +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [gle manger enable]enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle dd init +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle cm init enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [GLE DM][DM init] transmission management module init +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [GLE TM][TM init] transmission management module init +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle ssap init ok +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [GLE SM] start init +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [GLE DM][DM init] security management module init +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hadm init enter. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle factory init enter. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle glp init enter. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [gle manager_enable]enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle read maximum adv data len +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] read access filter list size +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [GLE SM] read support cryptography algorithm +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci struct to stream opcode:0xc06, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] hci command encode send tl paramlen=0x0 opcode:0xc06 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci internal command send core send opcode=0xc06 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci internal command send core send opcode=0x40a +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci internal command send core send opcode=0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci internal command send core send opcode=0x402 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.754] gle hci internal command send core send opcode=0x1c07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.755] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.755] gle execute command cbk evindex:c06 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.755] opcode = 0x0c06, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.755] max_adv_data_len = 0x00fb +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.755] gle read maximum adv data len +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.755] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.755] gle hci struct to stream opcode:0x40a, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] hci command encode send tl paramlen=0x0 opcode:0x40a +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] [HCI]gle hci internal evt cbk unreg table->id = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle hci internal command send core send opcode=0xc07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle execute command cbk evindex:40a +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] opcode = 0x040a, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] read access filter list size = 16 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] [TIMRE_ADD][STACK_TIMER] TIMER=0xa00011e0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle hci struct to stream opcode:0x406, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] hci command encode send tl paramlen=0x0 opcode:0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] [TIMER_DEL][STACK_TIMER] TIMER=0xa00011e0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] gle execute command cbk evindex:406 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] opcode = 0x0406, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.756] get addr:0xb0:66:**:**:**:00 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001290, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] gle hci struct to stream opcode:0x402, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] hci command encode send tl paramlen=0x0 opcode:0x402 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] gle execute command cbk evindex:402 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] gle hci read buffer size cfm result:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] [gle hci read buffer size] result = 0x0, opindex: 0x00000402 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] [gle hci read buffer size] acb data len: 254 num: 5, icb data len: 0 num: 0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001340, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] gle hci struct to stream opcode:0x1c07, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] hci command encode send tl paramlen=0x0 opcode:0x1c07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.757] [HCI]gle hci internal evt cbk unreg table->id = 0x18a0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001340 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] gle execute command cbk evindex:1c07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] opcode = 0x1c07, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] [GLE SM] algo: 0x02 0x02 0x02 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001340, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] gle hci struct to stream opcode:0xc07, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] hci command encode send tl paramlen=0x0 opcode:0xc07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.758] [HCI]gle hci internal evt cbk unreg table->id = 0x1c07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.759] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001340 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.759] gle execute command cbk evindex:c07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.759] opcode = 0x0c07, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.759] supported_adv_sets_num = 0x8 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.759] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.759] [HCI]gle hci internal evt cbk unreg table->id = 0xc07 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] [gle manger enable]result = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] [GLE DM] event = 0x0 +[bs21_ws73_ros2-2] [ACore] sle enable cbk in, result:0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] dev enable ret:0. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] recover key fail, there is no key +[bs21_ws73_ros2-2] sle enable +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle acore smp keys memcmp err, data all zero! +[bs21_ws73_ros2-2] sle_set_local_addr 0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle hci struct to stream opcode:0x405, stream_len=0x6 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] hci command encode send tl paramlen=0x6 opcode:0x405 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle hci internal command send core send opcode=0x405 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.763] gle hci internal command send core send opcode=0x1001 + + +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] gle execute command cbk evindex:405 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] opcode = 0x0405, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] gle set public address status success. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] gle hci struct to stream opcode:0x1001, stream_len=0x8 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] hci command encode send tl paramlen=0x8 opcode:0x1001 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] [HCI]gle hci internal evt cbk unreg table->id = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.764] gle hci internal command send core send opcode=0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] gle execute command cbk evindex:1001 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] opcode = 0x1001, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] [dd]event = 0x8 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] [SLE SCAN CBK] event: 8. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] start device seek. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001290, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] gle hci struct to stream opcode:0x406, stream_len=0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] hci command encode send tl paramlen=0x0 opcode:0x406 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] [HCI]gle hci internal evt cbk unreg table->id = 0x1710 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] scan_enable = 0x1, filter_duplicates = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] gle hci internal command send core send opcode=0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001290 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] gle execute command cbk evindex:406 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] opcode = 0x0406, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] get addr:0xb0:66:**:**:**:00 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.765] [TIMRE_ADD][STACK_TIMER] TIMER=0xbf65e9a0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] gle hci struct to stream opcode:0x1002, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] hci command encode send tl paramlen=0x2 opcode:0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] [HCI]gle hci internal evt cbk unreg table->id = 0x1710 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] [TIMER_DEL][STACK_TIMER] TIMER=0xbf65e9a0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] gle execute command cbk evindex:1002 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] opcode = 0x1002, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] gle dd set scan enable cfm scan enabled +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] [dd]event = 0x9 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] [SLE SCAN CBK] event: 9. +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:40:15.766] [HCI]gle hci internal evt cbk unreg table->id = 0x0 +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:5 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.843] op_ev = 0x180B +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.843] cfm_type = 0x1e +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.843] [dd]event = 0xb +[bs21_ws73_ros2-2] [adv_report] event_type: 0x03, addr_type: 0x0000, addr: 3c:**:**:**:4e:33 +[bs21_ws73_ros2-2] [adv_report] data length: 6, data: 0x01 0x02 0x01 0x02 0x02 0x00 +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:7 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.843] stop device seek. +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.844] scan_enable = 0x0, filter_duplicates = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.844] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.844] [TIMRE_ADD][STACK_TIMER] TIMER=0xbf65e9a0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.844] gle hci struct to stream opcode:0x1002, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.844] hci command encode send tl paramlen=0x2 opcode:0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.844] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.844] gle hci internal command send core send opcode=0x1002 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] [TIMER_DEL][STACK_TIMER] TIMER=0xbf65e9a0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle execute command cbk evindex:1002 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] opcode = 0x1002, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle dd set scan enable cfm scan disabled +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] [dd]event = 0xa +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] [SLE SCAN CBK] event: 10. +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] [HCI]gle hci internal evt cbk unreg table->id = 0x0 +[bs21_ws73_ros2-2] [ACore] sle device discovery in, action:6 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] create conn node, addr 3c:4a:xx:xx:xx:33 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle device link add node->status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle hci struct to stream opcode:0x1401, stream_len=0x1b +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] hci command encode send tl paramlen=0x1b opcode:0x1401 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.858] gle hci internal command send core send opcode=0x1401 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.859] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1401 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.859] gle hci ev command status restart ertx opcode=0x1401, timeout:0x2710 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.859] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.859] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=10000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.859] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.859] gle hci ev command status in opcode=0x1401, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] gle access link status report in +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [gle connect cfm] result:0x0 status = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [GLE TM][LCID init] LCID = 0x0000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [GLE SM] init new remote device. +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] gle ssap create tl link by addr add dev onaddr:0x3c:**:**:**:4e:33 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [cm]event = 0x0 +[bs21_ws73_ros2-2] [Connected] +[bs21_ws73_ros2-2] addr:3c:**:**:**:4e:33, handle:00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] remote(0x3c:**:**:**:4e:33) conn_id(0) +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] remote(0x3c:**:**:**:4e:33) state(1) +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] gle hci struct to stream opcode:0x1801, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] hci command encode send tl paramlen=0x2 opcode:0x1801 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] gle hci internal command send core send opcode=0x1801 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.880] [GLE SM] pairing start, role: 0x0. +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.890] [GLE SM] sm pairing request. +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.890] [GLE SM] io_ability: 3, oob_flag 0, psk_flag: 0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] [TIMRE_ADD][STACK_TIMER] TIMER=0x98000da0, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0134, len: 10.[2018-03-09 12:41:40.891] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1801 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] gle hci ev command status restart ertx opcode=0x1801, timeout:0x2904 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=10500 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] gle hci ev command status in opcode=0x1801, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] gle hci struct to stream opcode:0x1812, stream_len=0xf +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] hci command encode send tl paramlen=0xf opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.891] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0134.[2018-03-09 12:41:40.897] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.897] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] gle read remote features complete. +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] cfm_type = 0x11 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] gle set data len, lcid: 0x0000, tx octets: 0xfe +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.912] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] gle hci struct to stream opcode:0x1802, stream_len=0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] hci command encode send tl paramlen=0x2 opcode:0x1802 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] gle hci internal command send core send opcode=0x1802 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] gle hci internal command send core send opcode=0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1802 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.913] gle hci ev command status restart ertx opcode=0x1802, timeout:0x2904 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.914] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.914] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=10500 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.914] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.914] gle hci struct to stream opcode:0x1804, stream_len=0x4 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.914] hci command encode send tl paramlen=0x4 opcode:0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.914] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.914] gle hci ev command status in opcode=0x1802, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.915] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.915] gle execute command cbk evindex:1804 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.915] [GLE HCI] set data len result = 0x0, opindex: 0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.915] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.915] [HCI]gle hci internal evt cbk unreg table->id = 0x1804 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.937] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.937] gle read remote version complete. +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.937] cfm_type = 0x12 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.937] [cm]event = 0x7 +[bs21_ws73_ros2-2] [2018-03-09 12:41:40.937] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] [GLE SM] data recv, lcid: 0x0000, len: 10, opcode: 0x0135 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] [GLE SM] algorithm negotiate: 2 2 2 0[2018-03-09 12:41:41.474] [GLE SM] sm pairing confirm, authentication method: 1. +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] [TIMER_DEL][STACK_TIMER] TIMER=0x98000da0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0136, len: 70.[2018-03-09 12:41:41.474] [GLE SM] event = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001450, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.474] gle hci struct to stream opcode:0x1812, stream_len=0x4b +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] hci command encode send tl paramlen=0x4b opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001450 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0136.[2018-03-09 12:41:41.475] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.475] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.500] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.500] [GLE SM] data recv, lcid: 0x0000, len: 64, opcode: 0x0137 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] [GLE SM] data recv, lcid: 0x0000, len: 16, opcode: 0x0138 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] [GLE SM] gle sm authentication procedure in, method: 0x1. +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0139, len: 16.[2018-03-09 12:41:41.537] [GLE SM] authentication pdu send, opcode 0x0139. +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] [TIMRE_ADD][STACK_TIMER] TIMER=0xbf65e9a0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] gle hci struct to stream opcode:0x1812, stream_len=0x15 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] hci command encode send tl paramlen=0x15 opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.537] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] [TIMER_DEL][STACK_TIMER] TIMER=0xbf65e9a0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0139.[2018-03-09 12:41:41.538] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:41.538] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.624] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.624] [GLE SM] data recv, lcid: 0x0000, len: 16, opcode: 0x013a +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.624] [GLE SM] gle sm authentication procedure in, method: 0x1. +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001790, TIME=30000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] [GLE AA] controller data send, co_hdl: 0x0000, data_index: 0x0141, len: 16.[2018-03-09 12:41:42.634] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] [TIMRE_ADD][STACK_TIMER] TIMER=0xa00011e0, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] gle hci struct to stream opcode:0x1812, stream_len=0x15 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] hci command encode send tl paramlen=0x15 opcode:0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.634] gle hci internal command send core send opcode=0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] [TIMER_DEL][STACK_TIMER] TIMER=0xa00011e0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] gle read remote cs caps status(18) +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] [GLE DM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] [ACore] gle manager general event report opcode[05] +[bs21_ws73_ros2-2] general event report opcode[05] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] gle execute command cbk evindex:1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] opcode = 0x1812, cmd_result = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] gle send controller data cfm, co_handle: 0x0000, data_index: 0x0141.[2018-03-09 12:41:42.635] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.635] [HCI]gle hci internal evt cbk unreg table->id = 0x1812 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle access controller data cbk in +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] [GLE SM] data recv, lcid: 0x0000, len: 16, opcode: 0x0142 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] [GLE SM] gle sm authentication procedure in, method: 0x1. +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] [GLE SM] event = 0x2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle acore config data write:1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle acore set product type sys_config 0x:0! +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle acore save sm key write_index:00! +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle acore config data write:2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] [GLE SM] enable encryption +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] [GLE AA] enable encryption, crypt 1, key_deriv 1, integr_chk 0. +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle execute command send enter +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] [GLE HCI] free hci cbk +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] remote(0x3c:**:**:**:0x4e:0x33) conn_id(0) +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] auth status:0, crypto algo:2, key deriv algo:2, integr chk ind:0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] [TIMRE_ADD][STACK_TIMER] TIMER=0x98000f60, TIME=2000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle hci struct to stream opcode:0x1c03, stream_len=0x15 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] hci command encode send tl paramlen=0x15 opcode:0x1c03 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle hci command check send check and send, cmd_num:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.725] gle hci internal command send core send opcode=0x1c03 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.726] [HCI]gle hci ev command status num_hci_command_packets(0x1) command_opcode:0x1c03 status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.726] gle hci ev command status restart ertx opcode=0x1c03, timeout:0x2904 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.726] [TIMER_DEL][STACK_TIMER] TIMER=0x98000f60 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.726] [TIMRE_ADD][STACK_TIMER] TIMER=0x98000f60, TIME=10500 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.726] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.726] gle hci ev command status in opcode=0x1c03, status:0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [TIMER_DEL][STACK_TIMER] TIMER=0x98000f60 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] op_ev = 0x0011 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] cfm_type = 0x27 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [GLE SM] encrypt change, lcid: 0x0000, status: 0x0, encryption change: 0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001790 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [GLE SM] timer repeated attempts, job: 1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [GLE SM] event = 0x3 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] gle hci command check send check and send, cmd_num:0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] conn_id(0) pair result:3 +[bs21_ws73_ros2-2] [ssap client] pair complete conn_id:0, addr:3c:4a:83:2f:4e:33 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [uapi ssapc_exchange_info_req]mtu = 300 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [gle ssapc_exchange_mtu]mtu = 0x12c +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] [ssapc exchange_info_req_handle]mtu = 300, version = 0x1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] task create tl connection tl->status = 0x2, tl->mask = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] mtu = 300, version = 0x0001 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.799] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.800] [TIMRE_ADD][STACK_TIMER] TIMER=0xa00011e0, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] ssap check type by opcode trans->op:0x03 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] tl task[1] trans done +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] tl trans done trans->op:[0x03] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] [TIMER_DEL][STACK_TIMER] TIMER=0xa00011e0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] op_code[0x03], control_code[0x03], mtu[300], version[0x0001] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] tl->mtu[300] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] task[1] complete, err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] task[0x01] complete, err_code = 0x00 +[bs21_ws73_ros2-2] ssapc exchange info, conn_id:0, err_code:0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] tl done err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] ssapc handle msg type:7 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] sample ssapc indication cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] ssapc find structure conn_id:0, type:1, start hdl:1, end hdl:ffff +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] ssapc find structure uuid len:0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] addr:3c:**:**:**:4e:33, type = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] ssap discovery service all +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] ssapc discovery services conn_handle = 0x0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] task->type = 0x1, task->hdl = 0x1ffff, task->uuid.len = 0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] task create tl connection tl->status = 0x2, tl->mask = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] task_id = 0x82, task_type = 0x1, op_code = 0x04 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] dicovery task send uuid.len = 0, uuid:0x0000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] dicovery task send start_hdl: 0x0001, end_hdl: 0xffff +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] data_len = 6 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.824] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001340, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.849] ssap check type by opcode trans->op:0x05 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.849] tl task[130] trans done +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.849] tl trans done trans->op:[0x05] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001340 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] data_len = 9 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] control_code.fragment:0x03, mode:0x00, task->type:0x01, task_id:0x82, task->uuid.len:0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] curent_idx:0, data_len:7 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] uuid_len: 2, service->uuid.len: 2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] ssapc discovery service event handle +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] con_hdl:[0x00], hdl:[0x01], end_hdl:[0x02], svc->type_indication:[0x02] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] [disc_srv_rsp]start_hdl:[0x01], end_hdl:[0x02] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] uuid:[0x00][0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] discovery service start hdl:1, end hdl:2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] sample ssapc discovery services cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] uuid_len = 2, last_hdl = 0x0002, idx = 7 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] cur_hdl:[0x0001ffff], last_hdl:[0x0002] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] task[130] complete, err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] task[0x82] complete, err_code = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] ssapc handle msg type:0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] sample ssapc discovery service cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] op_code:0x04, type:0x01, uuid.len:0, err_code:0x00 +[bs21_ws73_ros2-2] discovery character cbk complete in +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] [internal_discovery_services] op_code:0x04, type:0x01, uuid.len:0, err_code:0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] tl done err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] ssapc handle msg type:2 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] sample ssapc discovery service cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] [ssap client] ssapc_write_req, conn_id:0 data_len:4 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] ssapc write req conn_id:0, hdl:1, data len:4 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] ssapc write req addr:0x3c:**:**:**:0x4e:0x33 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] handle = 0x01, type = 0x00, len = 4 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] [ssapc write_value_req]data_type = 0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] task create tl connection tl->status = 0x2, tl->mask = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] write_data_len = 4, data_len = 4, mtu = 295 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.850] [TIMRE_ADD][STACK_TIMER] TIMER=0xa0001130, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] ssap check type by opcode trans->op:0x0e +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] tl task[8] trans done +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] tl trans done trans->op:[0x0e] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] [TIMER_DEL][STACK_TIMER] TIMER=0xa0001130 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] [write rsp]hdl[0x0001], data_type[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] ssapc write rsp op_code[0x0e], control_code[0x03], value_len[7] +[bs21_ws73_ros2-2] ssapc write rsp handle:1 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] task[8] complete, err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] task[0x08] complete, err_code = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] [write_req_complete]err_code:0x00 +[bs21_ws73_ros2-2] [sle write_req_complete_cbk]conn_id:0, err_code:0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] tl done err_code:[0x00] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] ssapc handle msg type:5 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] sample ssapc write cfm cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] ssapc read req conn_id:0, hdl:1, type:0 + +[nearlink_robot_node-1] [INFO] [1520599455.450516387] [nearlink_robot]: recv ws73 keycode 0x67 +[nearlink_robot_node-1] [INFO] [1520599469.713003727] [nearlink_robot]: recv ws73 keycode 0x67 +[nearlink_robot_node-1] [INFO] [1520599470.612993769] [nearlink_robot]: recv ws73 keycode 0x67 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] ssapc read req addr:0x3c:**:**:**:0x4e:0x33 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] handle = 0x01, type = 0x00 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.874] need wait for response +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.875] [TIMRE_ADD][STACK_TIMER] TIMER=0xa00011e0, TIME=12000 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.899] ssap check type by opcode trans->op:0x09 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.899] tl trans done trans->op:[0x09] +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.900] [TIMER_DEL][STACK_TIMER] TIMER=0xa00011e0 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.900] op_code[0x09], control_code[0x03], data_len[4] +[bs21_ws73_ros2-2] ssapc read rsp handle:0, data len:4 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.900] ssapc handle msg type:4 +[bs21_ws73_ros2-2] [2018-03-09 12:41:42.900] sample ssapc read cfm cbk success +[bs21_ws73_ros2-2] [2018-03-09 12:44:15.275] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:44:15.275] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:44:15.275] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:44:15.450] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:44:15.450] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:44:15.450] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x00 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:0 +[bs21_ws73_ros2-2] [sle ws73] nearlink_mq attr mq_curmsgs 0 mq_maxmsg 10 +[bs21_ws73_ros2-2] [2018-03-09 12:44:29.512] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:44:29.512] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:44:29.512] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:44:29.712] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:44:29.712] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:44:29.712] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x00 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:0 +[bs21_ws73_ros2-2] [sle ws73] nearlink_mq attr mq_curmsgs 0 mq_maxmsg 10 +[bs21_ws73_ros2-2] [2018-03-09 12:44:30.400] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:44:30.400] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:44:30.400] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x52 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:1 +[bs21_ws73_ros2-2] [2018-03-09 12:44:30.612] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:44:30.612] ssapc handle msg type:8 +[bs21_ws73_ros2-2] [2018-03-09 12:44:30.612] sample ssapc notification cbk success +[bs21_ws73_ros2-2] [sle ws73] sle_rcu_notification_cb ok +[bs21_ws73_ros2-2] [sle ws73] sle rcu recive notification +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.kind = [1] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.special_key = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.reversed = [0] +[bs21_ws73_ros2-2] [sle ws73] recv_usb_hid_rcu_keyboard.key = 0x00 0x00 0x00 0x00 0x00 0x00 +[bs21_ws73_ros2-2] code:0x67,value:0 +[bs21_ws73_ros2-2] [sle ws73] nearlink_mq attr mq_curmsgs 0 mq_maxmsg 10 +[bs21_ws73_ros2-2] [2018-03-09 12:44:31.775] op_code[0x0f], control_code[0x03], data_len[13] +[bs21_ws73_ros2-2] [2018-03-09 12:44:31.775] ssapc handle msg type:8 +[nearlink_robot_node-1] [INFO] [1520599471.938074520] [nearlink_robot]: recv ws73 keycode 0x67 \ No newline at end of file diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server.c b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server.c new file mode 100644 index 0000000000000000000000000000000000000000..c81bf10fb4727d1bbab3d50670c282f8d8ba9c0a --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server.c @@ -0,0 +1,783 @@ +#include "securec.h" // 安全C库,提供安全的字符串和内存操作函数 +#include "errcode.h" // 错误码定义,提供错误码的定义和处理函数 +#include "osal_addr.h" // OS抽象层地址管理,提供地址相关的操作函数 +#include "sle_common.h" // SLE通用定义,包含SLE协议的通用数据结构和宏定义 +#include "sle_errcode.h" // SLE错误码定义,提供SLE协议的错误码定义和处理函数 +#include "sle_ssap_server.h" // SLE SSAP服务端,提供SSAP服务端的实现和接口 +#include "sle_connection_manager.h" // SLE连接管理,提供连接管理的实现和接口 +#include "sle_device_discovery.h" // SLE设备发现,提供设备发现的实现和接口 +#include "../inc/SLE_OSPP_Server_adv.h" // SLE LED Server 广播,提供LED Server的广播相关函数 +#include "../inc/SLE_OSPP_Server.h" // SLE LED Server,提供LED Server的主要功能实现 + +#include "cmsis_os2.h" // CMSIS-RTOS v2 API,提供RTOS的API接口 +#include "debug_print.h" // 调试打印,提供调试信息的打印函数 +#include "soc_osal.h" // SOC OS抽象层,提供SOC相关的操作函数 +#include "app_init.h" // 应用初始化,提供应用初始化相关的函数 +#include "common_def.h" // 通用定义,包含通用的数据结构和宏定义 +#include "i2c.h" // I2C接口,提供I2C通信的实现和接口 +#include "osal_debug.h" // OS抽象层调试,提供调试相关的操作函数 +#include "cmsis_os2.h" // CMSIS-RTOS v2 API,提供RTOS的API接口(重复包含) + +#include "adc.h" +#include "adc_porting.h" + +// 这两个头文件顺序不能更改 +#include "pinctrl.h" // 引脚控制相关的头文件 +#include "gpio.h" // GPIO操作相关的头文件 + +// chuan'gan +#include "../inc/eulercar_control.h" // 小车控制,提供小车控制相关的函数 +#include "../inc/shake.h" +#include "../inc/button.h" + +#define OCTET_BIT_LEN 8 // 八位字节长度 +#define UUID_LEN_2 2 // UUID 长度为 2 字节 +// 定义左摇杆引脚 +#define LEFT_JOYSTICK_X_PIN 9 +#define LEFT_JOYSTICK_Y_PIN 8 +#define LEFT_JOYSTICK_Z_PIN 14 +// 定义右摇杆引脚 +#define RIGHT_JOYSTICK_X_PIN 10 +#define RIGHT_JOYSTICK_Y_PIN 7 +#define RIGHT_JOYSTICK_Z_PIN 6 +// 定义ADC通道 +#define LEFT_JOYSTICK_X_Channel 1 +#define LEFT_JOYSTICK_Y_Channel 3 //2 +#define RIGHT_JOYSTICK_X_Channel 0 +#define RIGHT_JOYSTICK_Y_Channel 3 + +#define ADC_AUTO_SAMPLE_TEST_TIMES 500 +#define FILTER_WINDOW_SIZE 10 // 定义滤波窗口大小 + +#define ADC_TASK_STACK_SIZE 0x1000 +#define ADC_TASK_PRIO (osPriority_t)(15) +/** + * @brief 将数据编码为小端格式的 2 字节 + * @param _ptr 指向目标存储位置的指针 + * @param data 要编码的数据 + */ +#define encode2byte_little(_ptr, data) \ + do \ + { \ + *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ + *(uint8_t *)(_ptr) = (uint8_t)(data); \ + } while (0) + +/* SLE 服务应用 UUID 示例 */ +static char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; +/* 服务属性值示例 */ +static char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +/* SLE 连接 ID */ +uint16_t g_conn_id = 0; +/* SLE 服务 ID */ +uint8_t g_server_id = 0; +/* SLE 服务句柄 */ +uint16_t g_service_handle = 0; +/* SLE 通知属性句柄 */ +uint16_t g_property_handle = 0; + +// 初始化摇杆引脚 +void Joystick_Init(void) +{ + // 配置左摇杆Z轴引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(LEFT_JOYSTICK_Z_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(LEFT_JOYSTICK_Z_PIN, GPIO_DIRECTION_INPUT); + uapi_pin_set_pull(LEFT_JOYSTICK_Z_PIN, PIN_PULL_TYPE_DOWN); + + // 配置右摇杆Z轴引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(RIGHT_JOYSTICK_Z_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(RIGHT_JOYSTICK_Z_PIN, GPIO_DIRECTION_INPUT); + uapi_pin_set_pull(RIGHT_JOYSTICK_Z_PIN, PIN_PULL_TYPE_DOWN); +} + +gpio_level_t Left_Joystick_Read_Z(void) +{ + return uapi_gpio_get_val(LEFT_JOYSTICK_Z_PIN); +} + +// typedef struct +// { +// int xStatus; // 0: 暂停, 1: 左转, 2: 右转 +// int yStatus; // 0: 暂停, 1: 前进, 2: 后退 +// int lastXStatus; // 上次的X轴状态 +// int lastYStatus; // 上次的Y轴状态 +// } JoystickStatus; + +// void updateJoystickStatus(JoystickStatus *joystick, uint16_t xValue, uint16_t yValue) +// { +// // 更新X轴状态 +// if (xValue < 1000) +// { +// joystick->xStatus = 1; // 左转 +// printf("X轴左推\n"); +// } +// else if (xValue > 2000) +// { +// joystick->xStatus = 2; // 右转 +// printf("X轴右推\n"); +// } +// else +// { +// joystick->xStatus = 0; // 暂停 +// } + +// // 更新Y轴状态 +// if (yValue < 1000) +// { +// joystick->yStatus = 1; // 前进 +// printf("Y轴上推\n"); +// } +// else if (yValue > 2000) +// { +// joystick->yStatus = 2; // 后退 +// printf("Y轴下推\n"); +// } +// else +// { +// joystick->yStatus = 0; // 暂停 +// } + +// // 处理X轴状态变化 +// if (joystick->xStatus != joystick->lastXStatus) +// { +// if (joystick->xStatus == 1) +// { +// eulercar_control_left(); +// } +// else if (joystick->xStatus == 2) +// { +// eulercar_control_right(); +// } +// joystick->lastXStatus = joystick->xStatus; +// } + +// // 处理Y轴状态变化 +// if (joystick->yStatus != joystick->lastYStatus) +// { +// if (joystick->yStatus == 1) +// { +// eulercar_control_forward(); +// } +// else if (joystick->yStatus == 2) +// { +// eulercar_control_backward(); +// } +// joystick->lastYStatus = joystick->yStatus; +// } + +// // 检查是否需要暂停 +// if (joystick->xStatus == 0 && joystick->yStatus == 0 && +// (joystick->lastXStatus != 0 || joystick->lastYStatus != 0)) +// { +// eulercar_control_stop(); +// joystick->lastXStatus = 0; +// joystick->lastYStatus = 0; +// } +// } +// void test_adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next) +// { +// UNUSED(next); // 未使用的参数 + +// static JoystickStatus leftJoystick = {0, 0, -1, -1}; +// static JoystickStatus rightJoystick = {0, 0, -1, -1}; + +// uint16_t value = buffer[length - 1]; +// printf("channel: %d, Filtered voltage: %dmv\n", ch, value); + +// if (ch == LEFT_JOYSTICK_X_Channel) +// { +// updateJoystickStatus(&leftJoystick, value, leftJoystick.yStatus); +// } +// else if (ch == LEFT_JOYSTICK_Y_Channel) +// { +// updateJoystickStatus(&leftJoystick, leftJoystick.xStatus, value); +// } +// else if (ch == RIGHT_JOYSTICK_X_Channel) +// { +// updateJoystickStatus(&rightJoystick, value, rightJoystick.yStatus); +// } +// else if (ch == RIGHT_JOYSTICK_Y_Channel) +// { +// updateJoystickStatus(&rightJoystick, rightJoystick.xStatus, value); +// } +// } +// typedef struct +// { +// int xStatus; // 0: 暂停, 1: 左转, 2: 右转 +// int lastXStatus; // 上次的X轴状态 +// } JoystickStatus; + +// void updateJoystickStatus(JoystickStatus *joystick, uint16_t xValue, int joystickType) +// { +// // 更新X轴状态 +// if (xValue < 1000) +// { +// joystick->xStatus = 1; // 左转 +// printf("X轴左推\n"); +// } +// else if (xValue > 2000) +// { +// joystick->xStatus = 2; // 右转 +// printf("X轴右推\n"); +// } +// else +// { +// joystick->xStatus = 0; // 暂停 +// } + +// // 处理X轴状态变化 +// if (joystick->xStatus != joystick->lastXStatus) +// { +// if (joystickType == 0) // 左摇杆 +// { +// if (joystick->xStatus == 1) +// { +// eulercar_control_left(); +// } +// else if (joystick->xStatus == 2) +// { +// eulercar_control_right(); +// } +// } +// else if (joystickType == 1) // 右摇杆 +// { +// if (joystick->xStatus == 1) +// { +// eulercar_control_forward(); +// } +// else if (joystick->xStatus == 2) +// { +// eulercar_control_backward(); +// } +// } +// joystick->lastXStatus = joystick->xStatus; +// } + +// // 检查是否需要暂停 +// if (joystick->xStatus == 0 && joystick->lastXStatus != 0) +// { +// eulercar_control_stop(); +// joystick->lastXStatus = 0; +// } +// } + +// void test_adc_callback_X(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next) +// { +// UNUSED(next); // 未使用的参数 + +// // static JoystickStatus leftJoystick = {0, -1}; + +// uint16_t value = buffer[length - 1]; +// printf("channel: %d, Filtered voltage: %dmv\n", ch, value); + +// if (ch == LEFT_JOYSTICK_X_Channel) +// { +// // updateJoystickStatus(&leftJoystick, value, 0); // 左摇杆 +// // // 更新X轴状态 +// if (value < 1000) +// { +// printf("X轴左推\n"); +// eulercar_control_left(); +// } +// else if (value > 2000) +// { +// printf("X轴右推\n"); +// eulercar_control_right(); +// } +// else +// { +// eulercar_control_stop(); +// } +// } +// // else if (ch == RIGHT_JOYSTICK_X_Channel) +// // { +// // updateJoystickStatus(&rightJoystick, value, 1); // 右摇杆 +// // } +// } + +#define ACTION 1 +#define NONE 0 + +int sum; +int num; +int fil_buffer = 0; + +int j = 1; +int *num_buff; + +int stop_x =0; +int stop_y = 0; +int stop = 1; + +void test_adc_callback_X(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next) +{ + UNUSED(next); // 未使用的参数 + // static JoystickStatus rightJoystick = {0, -1}; + sum = 0; + num = 0; + if (ch == LEFT_JOYSTICK_X_Channel) + { + for (uint32_t i = 0; i < length; i++) + { + + // 打印ADC通道和电压值 + if(length > 2) + { + if((buffer[i] < 1500 || buffer[i] > 1900) && buffer[i] != 0) + { + sum += buffer[i]; + num +=1; + // osal_printk("[IRQ]channel: %d, voltage: %dmv\r\n", ch, buffer[i]); + } + } + } + if(num >= (signed int)length / 2) + { + fil_buffer = sum / num; + if(fil_buffer < 1) + { + fil_buffer = 0; + } + } + else + { + printf(" -number- \n"); + fil_buffer = 0; + } + printf("channel: %d, ---XXX-Filtered voltage: %dmv\n", ch, fil_buffer); + printf("length = %d\n",length); + + if (fil_buffer < 1000 && fil_buffer !=0 ) + { + printf("X轴左推\n"); + eulercar_control_left(); + stop = 0; + } + else if (fil_buffer > 2000 && fil_buffer !=0) + { + printf("X轴右推\n"); + eulercar_control_right(); + stop = 0; + } + else + { + // eulercar_control_stop(); + stop_x =1; + } + + } +} + + +void test_adc_callback_Y(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next) +{ + UNUSED(next); // 未使用的参数 + // static JoystickStatus rightJoystick = {0, -1}; + sum = 0; + num = 0; + if (ch == LEFT_JOYSTICK_Y_Channel) + { + for (uint32_t i = 0; i < length; i++) + { + + // 打印ADC通道和电压值 + // osal_printk("[IRQ]channel: %d, voltage: %dmv\r\n", ch, buffer[i]); + if(length > 2) + { + if((buffer[i] < 1000 || buffer[i] > 2000) && buffer[i] != 0) + { + sum += buffer[i]; + num +=1; + osal_printk("[IRQ]channel: %d, voltage: %dmv\r\n", ch, buffer[i]); + } + } + } + if(num >= (signed int)length / 2) + { + fil_buffer = sum / num; + if(fil_buffer < 1) + { + fil_buffer = 0; + } + } + else + { + printf(" -number- \n"); + fil_buffer = 0; + } + printf("channel: %d, ---YYY--Filtered voltage: %dmv\n", ch, fil_buffer); + printf("length = %d\n",length); + + + + if (fil_buffer < 1000 && fil_buffer !=0 ) + { + printf("Y轴上推\n"); + eulercar_control_forward(); + stop = 0; + } + else if (fil_buffer > 2000 && fil_buffer !=0) + { + printf("Y轴下推\n"); + eulercar_control_backward(); + stop = 0; + } + else + { + // eulercar_control_stop(); + stop_y =1; + } + } + + + +} + + +void joystick_task(const char *arg) +{ + UNUSED(arg); + osal_printk("start adc sample test"); + uapi_adc_init(ADC_CLOCK_500KHZ); + uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true); + adc_scan_config_t config = { + .type = 0, + .freq = 1, + }; + + while (1) + { + uapi_adc_auto_scan_ch_enable(LEFT_JOYSTICK_Y_Channel, config, test_adc_callback_Y); + uapi_adc_auto_scan_ch_disable(LEFT_JOYSTICK_Y_Channel); + + uapi_adc_auto_scan_ch_enable(LEFT_JOYSTICK_X_Channel, config, test_adc_callback_X); + uapi_adc_auto_scan_ch_disable(LEFT_JOYSTICK_X_Channel); + + if(stop == 0) + { + if(stop_x == 1 && stop_y == 1) + { + + eulercar_control_stop(); + printf("星闪小车停止!"); + stop_x = 0; + stop_y = 0; + stop = 1; + } + } + + + // if (Left_Joystick_Read_Z() == 1) + // { + // eulercar_control_stop(); + // osal_mdelay(10); + // } + + osal_msleep(ADC_AUTO_SAMPLE_TEST_TIMES); + } +} + +static void joystick_entry(void) +{ + osal_task *task_handle = NULL; // 任务句柄初始化为NULL + osal_kthread_lock(); // 锁定内核线程,防止任务创建过程中被打断 + task_handle = osal_kthread_create((osal_kthread_handler)joystick_task, 0, "LedControlTask", + ADC_TASK_STACK_SIZE); + if (task_handle != NULL) // 如果任务创建成功 + { + osal_kthread_set_priority(task_handle, ADC_TASK_PRIO); // 设置任务优先级 + osal_kfree(task_handle); // 释放任务句柄内存 + } + osal_kthread_unlock(); // 解锁内核线程 +} + +// 系统初始化函数,汇总所有初始化操作 +void Controller_System_Init(void) +{ + Shake_Init(); // 初始化摇动传感器 + Joystick_Init(); // 初始化摇杆 + Key_Init(); // 初始化按键 +} +// SLE UUID基准数组 +static uint8_t sle_uuid_base[] = {0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, + 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // UUID基准值,用于标识SLE服务 + +/* 设置 UUID 基础部分的函数 */ +static void example_sle_uuid_set_base(sle_uuid_t *out) +{ + // 使用安全的 memcpy 函数将 sle_uuid_base 的内容复制到 out->uuid 中 + // (void) 用于显式忽略 memcpy_s 的返回值 + (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); + + // 设置 UUID 的长度为 2 字节 + out->len = UUID_LEN_2; +} + +/* 设置 UUID 的函数 */ +static void example_sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) +{ + // 调用函数设置 UUID 基础部分 + example_sle_uuid_set_base(out); + + // 设置 UUID 长度为 2 字节 + out->len = UUID_LEN_2; + + // 将 2 字节的 u2 编码为小端格式,并存储在 UUID 的第 14 和 15 字节位置 + encode2byte_little(&out->uuid[14], u2); +} + +// 读取请求的回调函数 +static void +example_ssaps_read_request_cbk(uint8_t server_id, + uint16_t conn_id, + ssaps_req_read_cb_t *read_cb_para, + errcode_t status) +{ + // 打印读取请求的详细信息,包括服务器ID、连接ID、句柄、类型和状态 + PRINT("[SLE Server] ssaps read request cbk server_id:0x%x, conn_id:0x%x, handle:0x%x, type:0x%x, status:0x%x\r\n", + server_id, conn_id, read_cb_para->handle, read_cb_para->type, status); +} + +// 写入请求的回调函数 +static void example_ssaps_write_request_cbk(uint8_t server_id, + uint16_t conn_id, + ssaps_req_write_cb_t *write_cb_para, + errcode_t status) +{ + // 打印写入请求的详细信息,包括服务器ID、连接ID、句柄和状态 + PRINT("[SLE Server] ssaps write request cbk server_id:0x%x, conn_id:0x%x, handle:0x%x, status:0x%x\r\n", server_id, + conn_id, write_cb_para->handle, status); + + // 打印写入请求的数据,每个字节的索引和值 + for (uint16_t idx = 0; idx < write_cb_para->length; idx++) + { + PRINT("[SLE Server] write request cbk[0x%x] 0x%02x\r\n", idx, write_cb_para->value[idx]); + } +} + +/* +MTU(Maximum Transmission Unit,最大传输单元)是指在网络通信中,单个数据包或帧的最大字节数。 +MTU的大小决定了一个数据包在网络上传输时的最大尺寸 +*/ +// MTU(最大传输单元)改变的回调函数 +static void example_ssaps_mtu_changed_cbk(uint8_t server_id, + uint16_t conn_id, + ssap_exchange_info_t *mtu_size, + errcode_t status) +{ + // 打印MTU改变的详细信息,包括服务器ID、连接ID、MTU大小和状态 + PRINT("[SLE Server] ssaps mtu changed cbk server_id:0x%x, conn_id:0x%x, mtu_size:0x%x, status:0x%x\r\n", server_id, + conn_id, mtu_size->mtu_size, status); +} + +// 服务启动的回调函数 +static void example_ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + // 打印服务启动的详细信息,包括服务器ID、句柄和状态 + PRINT("[SLE Server] start service cbk server_id:0x%x, handle:0x%x, status:0x%x\r\n", server_id, handle, status); +} + +// 注册所有的SSAPS回调函数 +static errcode_t example_sle_ssaps_register_cbks(void) +{ + ssaps_callbacks_t ssaps_cbk = {0}; // 初始化回调函数结构体 + ssaps_cbk.start_service_cb = example_ssaps_start_service_cbk; // 注册服务启动回调函数 + ssaps_cbk.mtu_changed_cb = example_ssaps_mtu_changed_cbk; // 注册MTU改变回调函数 + ssaps_cbk.read_request_cb = example_ssaps_read_request_cbk; // 注册读取请求回调函数 + ssaps_cbk.write_request_cb = example_ssaps_write_request_cbk; // 注册写入请求回调函数 + return ssaps_register_callbacks(&ssaps_cbk); // 注册所有回调函数并返回状态 +} + +/* 添加 SLE 服务 */ +static errcode_t example_sle_server_service_add(void) +{ + sle_uuid_t service_uuid = {0}; // 初始化服务 UUID + + // 设置服务 UUID + example_sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); + + // 同步添加服务 + ssaps_add_service_sync(g_server_id, &service_uuid, true, &g_service_handle); + + // 打印调试信息,表示服务添加成功 + PRINT("[SLE Server] sle uuid add service service_handle: %u\r\n", g_service_handle); + + return ERRCODE_SUCC; // 返回成功错误码 +} + +static errcode_t example_sle_server_property_add(void) +{ + ssaps_property_info_t property = {0}; // 初始化属性信息结构体 + ssaps_desc_info_t descriptor = {0}; // 初始化描述符信息结构体 + uint8_t ntf_value[] = {0x01, 0x0}; // 通知值 + + // 设置属性的权限为可读和可写 + property.permissions = SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE; + // 设置属性的 UUID + example_sle_uuid_setu2(SLE_UUID_SERVER_PROPERTY, &property.uuid); + // 为属性值分配内存 + osal_vmalloc(sizeof(g_sle_property_value)); + + // 将全局属性值复制到属性的值中 + memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, sizeof(g_sle_property_value)); + + // 同步添加属性 + ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); + // 打印调试信息,表示属性添加成功 + PRINT("[SLE Server] sle uuid add property property_handle: %u\r\n", g_property_handle); + + // 设置描述符的权限为可读和可写 + descriptor.permissions = SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE; + // 为描述符值分配内存 + osal_vmalloc(sizeof(ntf_value)); + + // 将通知值复制到描述符的值中 + memcpy_s(descriptor.value, sizeof(ntf_value), ntf_value, sizeof(ntf_value)); + + // 同步添加描述符 + ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); + + // 释放已分配的属性和描述符内存 + osal_vfree(property.value); + osal_vfree(descriptor.value); + + return ERRCODE_SUCC; // 返回成功错误码 +} + +/* 添加 SLE 服务器 */ +static errcode_t example_sle_server_add(void) +{ + /* + UUID(Universally Unique Identifier,通用唯一标识符)是一种用于标识信息的标准。UUID 的目的是在分布式系统中使得所有元素都能有一个唯一的标识符,而不需要中央协调。 + 0.app uuid + 1.服务(Service)uuid + 2.特性(Characteristic)uuid + 3.属性(Property)uuid + */ + + sle_uuid_t app_uuid = {0}; // 初始化应用 UUID + + PRINT("[SLE Server] sle uuid add service in\r\n"); // 打印调试信息,表示开始添加服务 + app_uuid.len = sizeof(g_sle_uuid_app_uuid); // 设置 UUID 长度 + memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)); + + // 注册服务器 + ssaps_register_server(&app_uuid, &g_server_id); + // 添加服务 + example_sle_server_service_add(); + // 添加属性 + example_sle_server_property_add(); + // 启动服务 + ssaps_start_service(g_server_id, g_service_handle); + // 打印调试信息,表示服务添加完成 + PRINT("[SLE Server] sle uuid add service out\r\n"); + return ERRCODE_SUCC; // 返回成功错误码 +} + +typedef void (*sle_connect_state_changed_callback)(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason); + +// 连接状态改变的回调函数 +static void example_sle_connect_state_changed_cbk(uint16_t conn_id, + const sle_addr_t *addr, + sle_acb_state_t conn_state, + sle_pair_state_t pair_state, + sle_disc_reason_t disc_reason) +{ + // 打印连接状态改变的详细信息,包括连接ID、连接状态、配对状态和断开原因 + PRINT( + "[SLE Server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ + disc_reason:0x%x\r\n", + conn_id, conn_state, pair_state, disc_reason); + // 打印连接设备的地址 + PRINT("[SLE Server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", addr->addr[0], addr->addr[4], + addr->addr[5]); + g_conn_id = conn_id; // 更新全局连接ID + Vibration_ConnChange(); +} + +// 配对完成的回调函数 +static void example_sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + // 打印配对完成的详细信息,包括连接ID和状态 + PRINT("[SLE Server] pair complete conn_id:0x%02x, status:0x%x\r\n", conn_id, status); + // 打印配对设备的地址 + PRINT("[SLE Server] pair complete addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n", addr->addr[0], addr->addr[4], addr->addr[5]); + + if (status == ERRCODE_SUCC) // 如果配对成功 + { + joystick_entry(); + } +} + +// 注册连接相关的回调函数/ +static errcode_t example_sle_conn_register_cbks(void) +{ + // 初始化连接回调函数结构体 + sle_connection_callbacks_t conn_cbks = {0}; + // 注册连接状态改变回调函数 + conn_cbks.connect_state_changed_cb = example_sle_connect_state_changed_cbk; + // 注册配对完成回调函数 + conn_cbks.pair_complete_cb = example_sle_pair_complete_cbk; + // 注册所有连接回调函数并返回状态 + + return sle_connection_register_callbacks(&conn_cbks); +} + +static int example_sle_ospp_server_task(const char *arg) +{ + unused(arg); + Controller_System_Init(); // 摇杆系统初始化(摇杆、震动马达、按键) + Vibration_PowerOn(); // 上电震动 + (void)osal_msleep(4999); // 延时5s,等待SLE初始化完毕 + PRINT("[SLE Server] try enable.\r\n"); + + /* 使能SLE */ + enable_sle(); + /*注册连接管理回调函数 */ + example_sle_conn_register_cbks(); + /* 注册 SSAP server 回调函数 */ + example_sle_ssaps_register_cbks(); + /* 注册Server, 添加Service和property, 启动Service */ + example_sle_server_add(); + /* 设置设备公开,并公开设备 */ + example_sle_server_adv_init(); + + PRINT("[SLE Server] init ok\r\n"); + + return 0; +} + +// 定义任务优先级 +#define SLE_OSPP_SER_TASK_PRIO 24 +// 定义任务堆栈大小 +#define SLE_OSPP_SER_STACK_SIZE 0x2000 + +// 静态函数,创建并配置一个内核线程 +static void example_sle_ospp_server_entry(void) +{ + osal_task *task_handle = NULL; // 定义一个指向 osal_task 类型的指针,并初始化为 NULL + osal_kthread_lock(); // 锁定内核线程,防止在创建任务期间发生竞态条件 + + // 创建一个新的内核线程 + // 参数包括: + // - 任务处理函数,类型转换为 osal_kthread_handler + // - 传递给任务处理函数的数据,这里传递的是 0 + // - 任务名称 + // - 任务堆栈大小 + task_handle = osal_kthread_create((osal_kthread_handler)example_sle_ospp_server_task, 0, "SLEOSPPServerTask", + SLE_OSPP_SER_STACK_SIZE); + + // 检查任务是否成功创建(task_handle 不为 NULL) + if (task_handle != NULL) + { + // LiteOS中,任务优先级的范围通常是从0到31(或0到30),其中0表示最高优先级,31(或30)表示最低优先级。优先级数值越小,任务的优先级越高,调度器会优先执行优先级较高的任务。 + // 设置任务的优先级为 SLE_LED_SER_TASK_PRIO + osal_kthread_set_priority(task_handle, SLE_OSPP_SER_TASK_PRIO); + osal_kfree(task_handle); // 释放任务句柄 + } + osal_kthread_unlock(); // 解锁内核线程,允许其他线程继续执行 +} + +/* Run the example_sle_led_server_entry. */ +app_run(example_sle_ospp_server_entry); diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server.c.bak2 b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server.c.bak2 new file mode 100644 index 0000000000000000000000000000000000000000..53c45f9036eeb5e5bf7f31249c824ebd270710e3 --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server.c.bak2 @@ -0,0 +1,521 @@ +#include "securec.h" // 安全C库,提供安全的字符串和内存操作函数 +#include "errcode.h" // 错误码定义,提供错误码的定义和处理函数 +#include "osal_addr.h" // OS抽象层地址管理,提供地址相关的操作函数 +#include "sle_common.h" // SLE通用定义,包含SLE协议的通用数据结构和宏定义 +#include "sle_errcode.h" // SLE错误码定义,提供SLE协议的错误码定义和处理函数 +#include "sle_ssap_server.h" // SLE SSAP服务端,提供SSAP服务端的实现和接口 +#include "sle_connection_manager.h" // SLE连接管理,提供连接管理的实现和接口 +#include "sle_device_discovery.h" // SLE设备发现,提供设备发现的实现和接口 +#include "../inc/SLE_OSPP_Server_adv.h" // SLE LED Server 广播,提供LED Server的广播相关函数 +#include "../inc/SLE_OSPP_Server.h" // SLE LED Server,提供LED Server的主要功能实现 + +#include "cmsis_os2.h" // CMSIS-RTOS v2 API,提供RTOS的API接口 +#include "debug_print.h" // 调试打印,提供调试信息的打印函数 +#include "soc_osal.h" // SOC OS抽象层,提供SOC相关的操作函数 +#include "app_init.h" // 应用初始化,提供应用初始化相关的函数 +#include "common_def.h" // 通用定义,包含通用的数据结构和宏定义 +#include "i2c.h" // I2C接口,提供I2C通信的实现和接口 +#include "osal_debug.h" // OS抽象层调试,提供调试相关的操作函数 +#include "cmsis_os2.h" // CMSIS-RTOS v2 API,提供RTOS的API接口(重复包含) +#include "watchdog.h" +#include "adc.h" +#include "adc_porting.h" + +// 这两个头文件顺序不能更改 +#include "pinctrl.h" // 引脚控制相关的头文件 +#include "gpio.h" // GPIO操作相关的头文件 + +// chuan'gan +#include "../inc/eulercar_control.h" // 小车控制,提供小车控制相关的函数 +#include "../inc/shake.h" +#include "../inc/button.h" + +#define OCTET_BIT_LEN 8 // 八位字节长度 +#define UUID_LEN_2 2 // UUID 长度为 2 字节 + +#define LEFT_JOYSTICK_X_PIN 9 +#define LEFT_JOYSTICK_Y_PIN 8 +#define LEFT_JOYSTICK_Z_PIN 14 +// 定义右摇杆引脚 +#define RIGHT_JOYSTICK_X_PIN 10 +#define RIGHT_JOYSTICK_Y_PIN 7 +#define RIGHT_JOYSTICK_Z_PIN 6 +// 定义ADC通道 +#define LEFT_JOYSTICK_X_Channel 1 +#define LEFT_JOYSTICK_Y_Channel 2 +#define RIGHT_JOYSTICK_X_Channel 3 +#define RIGHT_JOYSTICK_Y_Channel 0 + +#define ADC_AUTO_SAMPLE_TEST_TIMES 100 +#define FILTER_WINDOW_SIZE 10 // 定义滤波窗口大小 + +#define ADC_TASK_STACK_SIZE 0x1000 +#define ADC_TASK_PRIO (osPriority_t)(15) +/** + * @brief 将数据编码为小端格式的 2 字节 + * @param _ptr 指向目标存储位置的指针 + * @param data 要编码的数据 + */ +#define encode2byte_little(_ptr, data) \ + do \ + { \ + *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ + *(uint8_t *)(_ptr) = (uint8_t)(data); \ + } while (0) + +/* SLE 服务应用 UUID 示例 */ +static char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; +/* 服务属性值示例 */ +static char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; +/* SLE 连接 ID */ +uint16_t g_conn_id = 0; +/* SLE 服务 ID */ +uint8_t g_server_id = 0; +/* SLE 服务句柄 */ +uint16_t g_service_handle = 0; +/* SLE 通知属性句柄 */ +uint16_t g_property_handle = 0; + +// 初始化摇杆引脚 +void Joystick_Init(void) +{ + // 配置左摇杆Z轴引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(LEFT_JOYSTICK_Z_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(LEFT_JOYSTICK_Z_PIN, GPIO_DIRECTION_INPUT); + uapi_pin_set_pull(LEFT_JOYSTICK_Z_PIN, PIN_PULL_TYPE_DOWN); + + // 配置右摇杆Z轴引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(RIGHT_JOYSTICK_Z_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(RIGHT_JOYSTICK_Z_PIN, GPIO_DIRECTION_INPUT); + uapi_pin_set_pull(RIGHT_JOYSTICK_Z_PIN, PIN_PULL_TYPE_DOWN); +} + +// 全局变量,用于存储LED的状态 +static int g_ledState = 0; + +// GPIO中断回调函数,当按钮被按下时调用 +static void gpio_callback_func(pin_t pin, uintptr_t param) +{ + UNUSED(param); // 未使用的参数 + if (pin == LEFT_JOYSTICK_Z_PIN) + { + g_ledState = 1; + eulercar_control_stop(); + printf("中断信号:%d\n", g_ledState); + } + else if (pin == LEFT_BUTTON_PIN) + { + g_ledState = 2; + eulercar_control_forward(); + printf("中断信号:%d\n", g_ledState); + } + else if (pin == RIGHT_BUTTON_PIN) + { + g_ledState = 3; + eulercar_control_backward(); + printf("中断信号:%d\n", g_ledState); + } + else if (pin == LEFT_TOGGLE_PIN) + { + g_ledState = 4; + eulercar_control_left(); + printf("中断信号:%d\n", g_ledState); + } + else if (pin == RIGHT_TOGGLE_PIN) + { + g_ledState = 5; + eulercar_control_right(); + printf("中断信号:%d\n", g_ledState); + } + printf("Button pressed.\r\n"); // 打印按钮按下的信息 +} + +// 按钮任务函数 +static void *button_task(const char *arg) +{ + unused(arg); // 未使用的参数 + + // 注册GPIO中断回调函数,当按钮引脚检测到下降沿时触发中断 + // 注册GPIO中断服务函数 + errcode_t ret0 = uapi_gpio_register_isr_func(14, GPIO_INTERRUPT_RISING_EDGE, gpio_callback_func); + if (ret0 != 0) + { + printf("Failed to register ISR for 14\n"); + } + errcode_t ret1 = uapi_gpio_register_isr_func(LEFT_BUTTON_PIN, GPIO_INTERRUPT_RISING_EDGE, gpio_callback_func); + if (ret1 != 0) + { + printf("Failed to register ISR for LEFT_BUTTON_PIN\n"); + } + + errcode_t ret2 = uapi_gpio_register_isr_func(RIGHT_BUTTON_PIN, GPIO_INTERRUPT_RISING_EDGE, gpio_callback_func); + if (ret2 != 0) + { + printf("Failed to register ISR for RIGHT_BUTTON_PIN\n"); + } + + errcode_t ret3 = uapi_gpio_register_isr_func(LEFT_TOGGLE_PIN, GPIO_INTERRUPT_FALLING_EDGE, gpio_callback_func); + if (ret3 != 0) + { + printf("Failed to register ISR for LEFT_TOGGLE_PIN\n"); + } + + errcode_t ret4 = uapi_gpio_register_isr_func(RIGHT_TOGGLE_PIN, GPIO_INTERRUPT_RISING_EDGE, gpio_callback_func); + if (ret4 != 0) + { + printf("Failed to register ISR for RIGHT_TOGGLE_PIN\n"); + } + + // 无限循环,持续执行任务 + while (1) + { + uapi_watchdog_kick(); // 喂狗,防止程序出现异常系统挂死 + } + return NULL; // 返回NULL表示任务结束 +} +// void joystick_task(const char *arg) +// { +// UNUSED(arg); + +// while (1) +// { + +// gpio_level_t z_button_state = uapi_gpio_get_val(LEFT_JOYSTICK_Z_PIN); +// gpio_level_t left_button_state = uapi_gpio_get_val(LEFT_BUTTON_PIN); +// gpio_level_t right_button_state = uapi_gpio_get_val(RIGHT_BUTTON_PIN); +// gpio_level_t left_toggle_state = uapi_gpio_get_val(LEFT_TOGGLE_PIN); +// gpio_level_t right_toggle_state = uapi_gpio_get_val(LEFT_TOGGLE_PIN); + +// printf("z Button State: %d\n", z_button_state); +// printf("Left Button State: %d\n", left_button_state); +// printf("Right Button State: %d\n", right_button_state); +// printf("Left Toggle State: %d\n", left_toggle_state); +// printf("Right Toggle State: %d\n", right_toggle_state); +// osal_mdelay(1000); +// // if (uapi_gpio_get_val(LEFT_JOYSTICK_Z_PIN) == 1) +// // { +// // eulercar_control_stop(); +// // } +// // else if (uapi_gpio_get_val(LEFT_BUTTON_PIN) == 1) +// // { +// // eulercar_control_forward(); +// // } +// // else if (uapi_gpio_get_val(RIGHT_BUTTON_PIN) == 1) +// // { +// // eulercar_control_backward(); +// // } +// // else if (uapi_gpio_get_val(LEFT_TOGGLE_PIN) == 1) +// // { +// // eulercar_control_left(); +// // } +// // else if (uapi_gpio_get_val(RIGHT_TOGGLE_PIN) == 1) +// // { +// // eulercar_control_right(); +// // } +// } +// } + +static void joystick_entry(void) +{ + osal_task *task_handle = NULL; // 任务句柄初始化为NULL + osal_kthread_lock(); // 锁定内核线程,防止任务创建过程中被打断 + task_handle = osal_kthread_create((osal_kthread_handler)button_task, 0, "LedControlTask", + ADC_TASK_STACK_SIZE); + if (task_handle != NULL) // 如果任务创建成功 + { + osal_kthread_set_priority(task_handle, ADC_TASK_PRIO); // 设置任务优先级 + osal_kfree(task_handle); // 释放任务句柄内存 + } + osal_kthread_unlock(); // 解锁内核线程 +} + +// 系统初始化函数,汇总所有初始化操作 +void Controller_System_Init(void) +{ + Shake_Init(); // 初始化摇动传感器 + Joystick_Init(); // 初始化摇杆 + Key_Init(); // 初始化按键 +} +// SLE UUID基准数组 +static uint8_t sle_uuid_base[] = {0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, + 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // UUID基准值,用于标识SLE服务 + +/* 设置 UUID 基础部分的函数 */ +static void example_sle_uuid_set_base(sle_uuid_t *out) +{ + // 使用安全的 memcpy 函数将 sle_uuid_base 的内容复制到 out->uuid 中 + // (void) 用于显式忽略 memcpy_s 的返回值 + (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); + + // 设置 UUID 的长度为 2 字节 + out->len = UUID_LEN_2; +} + +/* 设置 UUID 的函数 */ +static void example_sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) +{ + // 调用函数设置 UUID 基础部分 + example_sle_uuid_set_base(out); + + // 设置 UUID 长度为 2 字节 + out->len = UUID_LEN_2; + + // 将 2 字节的 u2 编码为小端格式,并存储在 UUID 的第 14 和 15 字节位置 + encode2byte_little(&out->uuid[14], u2); +} + +// 读取请求的回调函数 +static void +example_ssaps_read_request_cbk(uint8_t server_id, + uint16_t conn_id, + ssaps_req_read_cb_t *read_cb_para, + errcode_t status) +{ + // 打印读取请求的详细信息,包括服务器ID、连接ID、句柄、类型和状态 + PRINT("[SLE Server] ssaps read request cbk server_id:0x%x, conn_id:0x%x, handle:0x%x, type:0x%x, status:0x%x\r\n", + server_id, conn_id, read_cb_para->handle, read_cb_para->type, status); +} + +// 写入请求的回调函数 +static void example_ssaps_write_request_cbk(uint8_t server_id, + uint16_t conn_id, + ssaps_req_write_cb_t *write_cb_para, + errcode_t status) +{ + // 打印写入请求的详细信息,包括服务器ID、连接ID、句柄和状态 + PRINT("[SLE Server] ssaps write request cbk server_id:0x%x, conn_id:0x%x, handle:0x%x, status:0x%x\r\n", server_id, + conn_id, write_cb_para->handle, status); + + // 打印写入请求的数据,每个字节的索引和值 + for (uint16_t idx = 0; idx < write_cb_para->length; idx++) + { + PRINT("[SLE Server] write request cbk[0x%x] 0x%02x\r\n", idx, write_cb_para->value[idx]); + } +} + +/* +MTU(Maximum Transmission Unit,最大传输单元)是指在网络通信中,单个数据包或帧的最大字节数。 +MTU的大小决定了一个数据包在网络上传输时的最大尺寸 +*/ +// MTU(最大传输单元)改变的回调函数 +static void example_ssaps_mtu_changed_cbk(uint8_t server_id, + uint16_t conn_id, + ssap_exchange_info_t *mtu_size, + errcode_t status) +{ + // 打印MTU改变的详细信息,包括服务器ID、连接ID、MTU大小和状态 + PRINT("[SLE Server] ssaps mtu changed cbk server_id:0x%x, conn_id:0x%x, mtu_size:0x%x, status:0x%x\r\n", server_id, + conn_id, mtu_size->mtu_size, status); +} + +// 服务启动的回调函数 +static void example_ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + // 打印服务启动的详细信息,包括服务器ID、句柄和状态 + PRINT("[SLE Server] start service cbk server_id:0x%x, handle:0x%x, status:0x%x\r\n", server_id, handle, status); +} + +// 注册所有的SSAPS回调函数 +static errcode_t example_sle_ssaps_register_cbks(void) +{ + ssaps_callbacks_t ssaps_cbk = {0}; // 初始化回调函数结构体 + ssaps_cbk.start_service_cb = example_ssaps_start_service_cbk; // 注册服务启动回调函数 + ssaps_cbk.mtu_changed_cb = example_ssaps_mtu_changed_cbk; // 注册MTU改变回调函数 + ssaps_cbk.read_request_cb = example_ssaps_read_request_cbk; // 注册读取请求回调函数 + ssaps_cbk.write_request_cb = example_ssaps_write_request_cbk; // 注册写入请求回调函数 + return ssaps_register_callbacks(&ssaps_cbk); // 注册所有回调函数并返回状态 +} + +/* 添加 SLE 服务 */ +static errcode_t example_sle_server_service_add(void) +{ + sle_uuid_t service_uuid = {0}; // 初始化服务 UUID + + // 设置服务 UUID + example_sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); + + // 同步添加服务 + ssaps_add_service_sync(g_server_id, &service_uuid, true, &g_service_handle); + + // 打印调试信息,表示服务添加成功 + PRINT("[SLE Server] sle uuid add service service_handle: %u\r\n", g_service_handle); + + return ERRCODE_SUCC; // 返回成功错误码 +} + +static errcode_t example_sle_server_property_add(void) +{ + ssaps_property_info_t property = {0}; // 初始化属性信息结构体 + ssaps_desc_info_t descriptor = {0}; // 初始化描述符信息结构体 + uint8_t ntf_value[] = {0x01, 0x0}; // 通知值 + + // 设置属性的权限为可读和可写 + property.permissions = SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE; + // 设置属性的 UUID + example_sle_uuid_setu2(SLE_UUID_SERVER_PROPERTY, &property.uuid); + // 为属性值分配内存 + osal_vmalloc(sizeof(g_sle_property_value)); + + // 将全局属性值复制到属性的值中 + memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, sizeof(g_sle_property_value)); + + // 同步添加属性 + ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); + // 打印调试信息,表示属性添加成功 + PRINT("[SLE Server] sle uuid add property property_handle: %u\r\n", g_property_handle); + + // 设置描述符的权限为可读和可写 + descriptor.permissions = SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE; + // 为描述符值分配内存 + osal_vmalloc(sizeof(ntf_value)); + + // 将通知值复制到描述符的值中 + memcpy_s(descriptor.value, sizeof(ntf_value), ntf_value, sizeof(ntf_value)); + + // 同步添加描述符 + ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); + + // 释放已分配的属性和描述符内存 + osal_vfree(property.value); + osal_vfree(descriptor.value); + + return ERRCODE_SUCC; // 返回成功错误码 +} + +/* 添加 SLE 服务器 */ +static errcode_t example_sle_server_add(void) +{ + /* + UUID(Universally Unique Identifier,通用唯一标识符)是一种用于标识信息的标准。UUID 的目的是在分布式系统中使得所有元素都能有一个唯一的标识符,而不需要中央协调。 + 0.app uuid + 1.服务(Service)uuid + 2.特性(Characteristic)uuid + 3.属性(Property)uuid + */ + + sle_uuid_t app_uuid = {0}; // 初始化应用 UUID + + PRINT("[SLE Server] sle uuid add service in\r\n"); // 打印调试信息,表示开始添加服务 + app_uuid.len = sizeof(g_sle_uuid_app_uuid); // 设置 UUID 长度 + memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)); + + // 注册服务器 + ssaps_register_server(&app_uuid, &g_server_id); + // 添加服务 + example_sle_server_service_add(); + // 添加属性 + example_sle_server_property_add(); + // 启动服务 + ssaps_start_service(g_server_id, g_service_handle); + // 打印调试信息,表示服务添加完成 + PRINT("[SLE Server] sle uuid add service out\r\n"); + return ERRCODE_SUCC; // 返回成功错误码 +} + +typedef void (*sle_connect_state_changed_callback)(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason); + +// 连接状态改变的回调函数 +static void example_sle_connect_state_changed_cbk(uint16_t conn_id, + const sle_addr_t *addr, + sle_acb_state_t conn_state, + sle_pair_state_t pair_state, + sle_disc_reason_t disc_reason) +{ + // 打印连接状态改变的详细信息,包括连接ID、连接状态、配对状态和断开原因 + PRINT( + "[SLE Server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ + disc_reason:0x%x\r\n", + conn_id, conn_state, pair_state, disc_reason); + // 打印连接设备的地址 + PRINT("[SLE Server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", addr->addr[0], addr->addr[4], + addr->addr[5]); + g_conn_id = conn_id; // 更新全局连接ID + Vibration_ConnChange(); +} + +// 配对完成的回调函数 +static void example_sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + // 打印配对完成的详细信息,包括连接ID和状态 + PRINT("[SLE Server] pair complete conn_id:0x%02x, status:0x%x\r\n", conn_id, status); + // 打印配对设备的地址 + PRINT("[SLE Server] pair complete addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n", addr->addr[0], addr->addr[4], addr->addr[5]); + + if (status == ERRCODE_SUCC) // 如果配对成功 + { + joystick_entry(); + } +} + +// 注册连接相关的回调函数/ +static errcode_t example_sle_conn_register_cbks(void) +{ + // 初始化连接回调函数结构体 + sle_connection_callbacks_t conn_cbks = {0}; + // 注册连接状态改变回调函数 + conn_cbks.connect_state_changed_cb = example_sle_connect_state_changed_cbk; + // 注册配对完成回调函数 + conn_cbks.pair_complete_cb = example_sle_pair_complete_cbk; + // 注册所有连接回调函数并返回状态 + + return sle_connection_register_callbacks(&conn_cbks); +} + +static int example_sle_ospp_server_task(const char *arg) +{ + unused(arg); + Controller_System_Init(); // 摇杆系统初始化(摇杆、震动马达、按键) + Vibration_PowerOn(); // 上电震动 + (void)osal_msleep(4999); // 延时5s,等待SLE初始化完毕 + PRINT("[SLE Server] try enable.\r\n"); + + /* 使能SLE */ + enable_sle(); + /*注册连接管理回调函数 */ + example_sle_conn_register_cbks(); + /* 注册 SSAP server 回调函数 */ + example_sle_ssaps_register_cbks(); + /* 注册Server, 添加Service和property, 启动Service */ + example_sle_server_add(); + /* 设置设备公开,并公开设备 */ + example_sle_server_adv_init(); + + PRINT("[SLE Server] init ok\r\n"); + + return 0; +} + +// 定义任务优先级 +#define SLE_OSPP_SER_TASK_PRIO 24 +// 定义任务堆栈大小 +#define SLE_OSPP_SER_STACK_SIZE 0x2000 + +// 静态函数,创建并配置一个内核线程 +static void example_sle_ospp_server_entry(void) +{ + osal_task *task_handle = NULL; // 定义一个指向 osal_task 类型的指针,并初始化为 NULL + osal_kthread_lock(); // 锁定内核线程,防止在创建任务期间发生竞态条件 + + // 创建一个新的内核线程 + // 参数包括: + // - 任务处理函数,类型转换为 osal_kthread_handler + // - 传递给任务处理函数的数据,这里传递的是 0 + // - 任务名称 + // - 任务堆栈大小 + task_handle = osal_kthread_create((osal_kthread_handler)example_sle_ospp_server_task, 0, "SLEOSPPServerTask", + SLE_OSPP_SER_STACK_SIZE); + + // 检查任务是否成功创建(task_handle 不为 NULL) + if (task_handle != NULL) + { + // LiteOS中,任务优先级的范围通常是从0到31(或0到30),其中0表示最高优先级,31(或30)表示最低优先级。优先级数值越小,任务的优先级越高,调度器会优先执行优先级较高的任务。 + // 设置任务的优先级为 SLE_LED_SER_TASK_PRIO + osal_kthread_set_priority(task_handle, SLE_OSPP_SER_TASK_PRIO); + osal_kfree(task_handle); // 释放任务句柄 + } + osal_kthread_unlock(); // 解锁内核线程,允许其他线程继续执行 +} + +/* Run the example_sle_led_server_entry. */ +app_run(example_sle_ospp_server_entry); diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server_adv.c b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server_adv.c new file mode 100644 index 0000000000000000000000000000000000000000..4246e1c6b214aa6f9a3615e6b2ee81de55bbfb09 --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/SLE_OSPP_Server_adv.c @@ -0,0 +1,292 @@ +/* +# Copyright (C) 2024 HiHope Open Source Organization . +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + */ +#include "securec.h" // 安全C库,用于安全的内存操作 +#include "errcode.h" // 错误码定义 +#include "osal_addr.h" // OS抽象层地址操作 +#include "sle_common.h" // SLE通用定义 +#include "sle_device_discovery.h" // SLE设备发现功能 +#include "sle_errcode.h" // SLE错误码定义 +#include "../inc/SLE_OSPP_Server_adv.h" // SLE LED服务器广播头文件 + +#include "cmsis_os2.h" // CMSIS-RTOS API +#include "debug_print.h" // 调试打印功能 + +/* sle device name */ +#define NAME_MAX_LENGTH 16 // 设备名称的最大长度 +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MIN_DEFAULT 0x64 // 最小连接间隔默认值 +/* 连接调度间隔12.5ms,单位125us */ +#define SLE_CONN_INTV_MAX_DEFAULT 0x64 // 最大连接间隔默认值 +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MIN_DEFAULT 0xC8 // 最小广播间隔默认值 +/* 连接调度间隔25ms,单位125us */ +#define SLE_ADV_INTERVAL_MAX_DEFAULT 0xC8 // 最大广播间隔默认值 +/* 超时时间5000ms,单位10ms */ +#define SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT 0x1F4 // 连接监督超时默认值 +/* 超时时间4990ms,单位10ms */ +#define SLE_CONN_MAX_LATENCY 0x1F3 // 最大连接延迟默认值 +/* 广播发送功率 */ +#define SLE_ADV_TX_POWER 10 // 广播发送功率 +/* 广播ID */ +#define SLE_ADV_HANDLE_DEFAULT 1 // 广播句柄默认值 +/* 最大广播数据长度 */ +#define SLE_ADV_DATA_LEN_MAX 251 // 最大广播数据长度 +/* 广播名称 */ +static uint8_t sle_local_name[NAME_MAX_LENGTH] = {'S', 'L', 'E', '_', 'O', 'S', 'P', 'P', '_', + 'S', 'E', 'R', 'V', 'E', 'R', '\0'}; // 本地设备名称 + +// 设置广播本地名称 +static uint16_t example_sle_set_adv_local_name(uint8_t *adv_data, uint16_t max_len) +{ + errno_t ret = -1; // 错误码初始化为-1 + uint8_t index = 0; // 广播数据索引初始化为0 + + uint8_t *local_name = sle_local_name; // 获取本地设备名称 + uint8_t local_name_len = (uint8_t)strlen((char *)local_name); // 获取本地设备名称长度 + for (uint8_t i = 0; i < local_name_len; i++) + { + PRINT("[SLE Adv] local_name[%d] = 0x%02x\r\n", i, local_name[i]); // 打印本地设备名称的每个字符 + } + + adv_data[index++] = local_name_len + 1; // 设置广播数据长度 + adv_data[index++] = SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME; // 设置广播数据类型为完整本地名称 + ret = memcpy_s(&adv_data[index], max_len - index, local_name, local_name_len); // 复制本地名称到广播数据中 + if (ret != EOK) + { // 检查复制是否成功 + PRINT("[SLE Adv] memcpy fail\r\n"); // 打印复制失败信息 + return 0; // 返回0表示失败 + } + return (uint16_t)index + local_name_len; // 返回广播数据的总长度 +} + +// 设置广播数据 +static uint16_t example_sle_set_adv_data(uint8_t *adv_data) +{ + size_t len = 0; // 数据长度初始化为0 + uint16_t idx = 0; // 广播数据索引初始化为0 + errno_t ret = 0; // 错误码初始化为0 + + len = sizeof(struct sle_adv_common_value); // 获取通用广播数据结构体的长度 + struct sle_adv_common_value adv_disc_level = { + .length = len - 1, // 设置数据长度 + .type = SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL, // 设置数据类型为发现级别 + .value = SLE_ANNOUNCE_LEVEL_NORMAL, // 设置数据值为正常级别 + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_disc_level, len); // 复制发现级别数据到广播数据中 + if (ret != EOK) + { // 检查复制是否成功 + PRINT("[SLE Adv] adv_disc_level memcpy fail\r\n"); // 打印复制失败信息 + return 0; // 返回0表示失败 + } + idx += len; // 更新广播数据索引 + + len = sizeof(struct sle_adv_common_value); // 获取通用广播数据结构体的长度 + struct sle_adv_common_value adv_access_mode = { + .length = len - 1, // 设置数据长度 + .type = SLE_ADV_DATA_TYPE_ACCESS_MODE, // 设置数据类型为访问模式 + .value = 0, // 设置数据值为0 + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_access_mode, len); // 复制访问模式数据到广播数据中 + if (ret != EOK) + { // 检查复制是否成功 + PRINT("[SLE Adv] memcpy fail\r\n"); // 打印复制失败信息 + return 0; // 返回0表示失败 + } + idx += len; // 更新广播数据索引 + return idx; // 返回广播数据的总长度 +} + +// 设置扫描响应数据 +static uint16_t example_sle_set_scan_response_data(uint8_t *scan_rsp_data) +{ + uint16_t idx = 0; // 扫描响应数据索引初始化为0 + errno_t ret = -1; // 错误码初始化为-1 + size_t scan_rsp_data_len = sizeof(struct sle_adv_common_value); // 获取通用广播数据结构体的长度 + + struct sle_adv_common_value tx_power_level = { + .length = scan_rsp_data_len - 1, // 设置数据长度 + .type = SLE_ADV_DATA_TYPE_TX_POWER_LEVEL, // 设置数据类型为发送功率级别 + .value = SLE_ADV_TX_POWER, // 设置数据值为广播发送功率 + }; + ret = memcpy_s(scan_rsp_data, SLE_ADV_DATA_LEN_MAX, &tx_power_level, scan_rsp_data_len); // 复制发送功率级别数据到扫描响应数据中 + if (ret != EOK) + { // 检查复制是否成功 + PRINT("[SLE Adv] sle scan response data memcpy fail\r\n"); // 打印复制失败信息 + return 0; // 返回0表示失败 + } + idx += scan_rsp_data_len; // 更新扫描响应数据索引 + + /* set local name */ + idx += example_sle_set_adv_local_name(&scan_rsp_data[idx], SLE_ADV_DATA_LEN_MAX - idx); // 设置本地名称到扫描响应数据中 + return idx; // 返回扫描响应数据的总长度 +} + +static uint8_t g_sle_local_addr[SLE_ADDR_LEN] = {0x3c, 0x4a, 0x83, 0x2f, 0x4e, 0x33}; // 要遥控器设备地址 + +// 设置本地设备地址 +static void example_sle_set_addr(void) +{ + uint8_t *addr = g_sle_local_addr; // 获取本地设备地址 + + sle_addr_t sle_addr = {0}; // 初始化SLE地址结构体 + sle_addr.type = 0; // 设置地址类型为0 + if (memcpy_s(sle_addr.addr, SLE_ADDR_LEN, addr, SLE_ADDR_LEN) != EOK) + { // 复制本地设备地址到SLE地址结构体中 + PRINT("[SLE Adv] addr memcpy fail \r\n"); // 打印复制失败信息 + } + + if (sle_set_local_addr(&sle_addr) == ERRCODE_SUCC) + { // 设置本地设备地址并检查是否成功 + PRINT("[SLE Adv] set sle addr SUCC \r\n"); // 打印设置成功信息 + } +} + +static uint8_t g_local_device_name[] = {'s', 'l', 'e', '_', 'l', 'e', 'd', '_', 's', 'e', 'r', 'v', 'e', 'r'}; // 本地设备名称 + +// 设置本地设备名称 +static void example_sle_set_name(void) +{ + errcode_t ret = ERRCODE_SUCC; // 错误码初始化为成功 + ret = sle_set_local_name(g_local_device_name, sizeof(g_local_device_name)); // 设置本地设备名称并获取返回码 + if (ret != ERRCODE_SUCC) + { // 检查设置是否成功 + PRINT("[SLE Adv] set local name fail, ret:%x\r\n", ret); // 打印设置失败信息 + } +} + +// 设置默认的广播参数 +static errcode_t example_sle_set_default_announce_param(void) +{ + sle_announce_param_t param = {0}; // 初始化广播参数结构体 + param.announce_mode = SLE_ANNOUNCE_MODE_CONNECTABLE_SCANABLE; // 设置广播模式为可连接可扫描 + param.announce_handle = SLE_ADV_HANDLE_DEFAULT; // 设置广播句柄为默认值 + param.announce_gt_role = SLE_ANNOUNCE_ROLE_T_CAN_NEGO; // 设置广播角色为可协商 + param.announce_level = SLE_ANNOUNCE_LEVEL_NORMAL; // 设置广播级别为正常 + param.announce_channel_map = SLE_ADV_CHANNEL_MAP_DEFAULT; // 设置广播信道映射为默认值 + param.announce_interval_min = SLE_ADV_INTERVAL_MIN_DEFAULT; // 设置最小广播间隔为默认值 + param.announce_interval_max = SLE_ADV_INTERVAL_MAX_DEFAULT; // 设置最大广播间隔为默认值 + param.conn_interval_min = SLE_CONN_INTV_MIN_DEFAULT; // 设置最小连接间隔为默认值 + param.conn_interval_max = SLE_CONN_INTV_MAX_DEFAULT; // 设置最大连接间隔为默认值 + param.conn_max_latency = SLE_CONN_MAX_LATENCY; // 设置最大连接延迟为默认值 + param.conn_supervision_timeout = SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT; // 设置连接监督超时为默认值 + + if (memcpy_s(param.own_addr.addr, SLE_ADDR_LEN, g_sle_local_addr, SLE_ADDR_LEN) != EOK) + { // 复制本地设备地址到广播参数中 + PRINT("[SLE Adv] set sle adv param addr memcpy fail\r\n"); // 打印复制失败信息 + return ERRCODE_MEMCPY; // 返回内存复制错误码 + } + + return sle_set_announce_param(param.announce_handle, ¶m); // 设置广播参数并返回状态码 +} + +// 设置默认的广播数据 +static errcode_t example_sle_set_default_announce_data(void) +{ + errcode_t ret = ERRCODE_FAIL; // 错误码初始化为失败 + uint8_t announce_data_len = 0; // 广播数据长度初始化为0 + uint8_t seek_data_len = 0; // 扫描响应数据长度初始化为0 + sle_announce_data_t data = {0}; // 初始化广播数据结构体 + uint8_t adv_handle = SLE_ADV_HANDLE_DEFAULT; // 广播句柄初始化为默认值 + uint8_t announce_data[SLE_ADV_DATA_LEN_MAX] = {0}; // 初始化广播数据数组 + uint8_t seek_rsp_data[SLE_ADV_DATA_LEN_MAX] = {0}; // 初始化扫描响应数据数组 + + PRINT("[SLE Adv] set adv data default\r\n"); // 打印设置默认广播数据信息 + announce_data_len = example_sle_set_adv_data(announce_data); // 设置广播数据并获取长度 + data.announce_data = announce_data; // 设置广播数据 + data.announce_data_len = announce_data_len; // 设置广播数据长度 + + seek_data_len = example_sle_set_scan_response_data(seek_rsp_data); // 设置扫描响应数据并获取长度 + data.seek_rsp_data = seek_rsp_data; // 设置扫描响应数据 + data.seek_rsp_data_len = seek_data_len; // 设置扫描响应数据长度 + + ret = sle_set_announce_data(adv_handle, &data); // 设置广播数据并获取返回码 + if (ret == ERRCODE_SUCC) + { // 检查设置是否成功 + PRINT("[SLE Adv] set announce data success."); // 打印设置成功信息 + } + else + { + PRINT("[SLE Adv] set adv param fail."); // 打印设置失败信息 + } + return ERRCODE_SUCC; // 返回成功码 +} + +// 广播启用回调函数 +void example_sle_announce_enable_cbk(uint32_t announce_id, errcode_t status) +{ + PRINT("[SLE Adv] sle announce enable id:%02x, state:%02x\r\n", announce_id, status); // 打印广播启用信息 +} + +// 广播禁用回调函数 +void example_sle_announce_disable_cbk(uint32_t announce_id, errcode_t status) +{ + PRINT("[SLE Adv] sle announce disable id:%02x, state:%02x\r\n", announce_id, status); // 打印广播禁用信息 +} + +// 广播终止回调函数 +void example_sle_announce_terminal_cbk(uint32_t announce_id) +{ + PRINT("[SLE Adv] sle announce terminal id:%02x\r\n", announce_id); // 打印广播终止信息 +} + +// SLE启用回调函数 +void example_sle_enable_cbk(errcode_t status) +{ + PRINT("[SLE Adv] sle enable status:%02x\r\n", status); // 打印SLE启用状态信息 +} + +// 注册广播相关的回调函数 +// 注册SLE广播相关的回调函数 +void example_sle_announce_register_cbks(void) +{ + sle_announce_seek_callbacks_t seek_cbks = {0}; // 初始化广播回调函数结构体 + + // 注册广播启用回调函数 + seek_cbks.announce_enable_cb = example_sle_announce_enable_cbk; + + // 注册广播禁用回调函数 + seek_cbks.announce_disable_cb = example_sle_announce_disable_cbk; + + // 注册广播终止回调函数 + seek_cbks.announce_terminal_cb = example_sle_announce_terminal_cbk; + + // 注册SLE启用回调函数 + seek_cbks.sle_enable_cb = example_sle_enable_cbk; + + // 注册所有广播回调函数 + sle_announce_seek_register_callbacks(&seek_cbks); +} + +// 初始化SLE服务器广播的函数 +errcode_t example_sle_server_adv_init(void) +{ + PRINT("[SLE Adv] example_sle_server_adv_init in\r\n"); // 打印初始化开始信息 + + example_sle_announce_register_cbks(); // 注册广播相关的回调函数 + + example_sle_set_default_announce_param(); // 设置默认的广播参数 + + example_sle_set_default_announce_data(); // 设置默认的广播数据 + + example_sle_set_addr(); // 设置设备地址 + + example_sle_set_name(); // 设置设备名称 + + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); // 启动广播 + + PRINT("[SLE Adv] example_sle_server_adv_init out\r\n"); // 打印初始化结束信息 + + return ERRCODE_SUCC; // 返回成功码 +} \ No newline at end of file diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/button.c b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/button.c new file mode 100644 index 0000000000000000000000000000000000000000..d07ee44ca507563ca1bfc772e7ede7a01534ca2f --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/button.c @@ -0,0 +1,31 @@ +#include "../inc/button.h" + +// 定义按键引脚 +#define LEFT_BUTTON_PIN 2 +#define RIGHT_BUTTON_PIN 4 +#define LEFT_TOGGLE_PIN 5 +#define RIGHT_TOGGLE_PIN 3 + +#define DEBOUNCE_DELAY 5 // 消抖延时,单位为毫秒 +#define DEBOUNCE_READS 5 // 消抖读取次数 + +// 初始化按键引脚 +void Key_Init(void) +{ + // 配置左按钮引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(LEFT_BUTTON_PIN, HAL_PIO_FUNC_GPIO); + gpio_select_core(LEFT_BUTTON_PIN, CORES_APPS_CORE); + uapi_gpio_set_dir(LEFT_BUTTON_PIN, GPIO_DIRECTION_INPUT); + + // 配置右按钮引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(RIGHT_BUTTON_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(RIGHT_BUTTON_PIN, GPIO_DIRECTION_INPUT); + + // 配置左切换开关引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(LEFT_TOGGLE_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(LEFT_TOGGLE_PIN, GPIO_DIRECTION_INPUT); + + // 配置右切换开关引脚为GPIO模式并设置为输入 + uapi_pin_set_mode(RIGHT_TOGGLE_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(RIGHT_TOGGLE_PIN, GPIO_DIRECTION_INPUT); +} diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/eulercar_control.c b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/eulercar_control.c new file mode 100644 index 0000000000000000000000000000000000000000..f3f3115551a43696d0cbf03cb16774ad0478eb46 --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/eulercar_control.c @@ -0,0 +1,148 @@ +#include "../inc/eulercar_control.h" +#include "debug_print.h" +#include "sle_ssap_server.h" // SLE SSAP服务端,提供SSAP服务端的实现和接口 +#include "osal_task.h" +#include "../inc/shake.h" + +extern uint16_t g_property_handle; +extern uint16_t g_server_id; +extern uint16_t g_conn_id; + +// 向上键报告 +usb_hid_rcu_keyboard_report_t EulerCarUp = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x52, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 向下键报告 +usb_hid_rcu_keyboard_report_t EulerCarDown = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x51, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 向左键报告 +usb_hid_rcu_keyboard_report_t EulerCarLeft = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x50, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 向右键报告 +usb_hid_rcu_keyboard_report_t EulerCarRight = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x4f, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 释放键报告 +usb_hid_rcu_keyboard_report_t EulerCarStop = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x28, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 释放键报告 +usb_hid_rcu_keyboard_report_t EulerCarRelease = { + .kind = 1, // 键盘报告类型 + .special_key = 0, // 特殊按键 + .reserve = 0, // 保留字段 + .key = {0x0, 0x00, 0x00, 0x00, 0x00, 0x00} // 按键值数组 +}; + +// 辅助函数:发送键盘报告通知 +void send_keyboard_report(usb_hid_rcu_keyboard_report_t *report) +{ + ssaps_ntf_ind_t param = {0}; // 初始化通知参数结构体 + param.handle = g_property_handle; // 设置通知的句柄 + param.type = 0; // 设置通知类型为0 + param.value = (uint8_t *)report; // 将键盘报告数据转换为 uint8_t 指针 + param.value_len = sizeof(*report); // 设置通知数据的长度 + ssaps_notify_indicate(g_server_id, g_conn_id, ¶m); // 发送通知 +} + +/** + * @brief 控制小车前进 + * + * 该函数通过发送键盘报告通知来控制小车前进。首先发送前进键报告, + * 然后延时一段时间,再发送释放键报告。最后打印一条日志信息并延时一段时间。 + */ +void eulercar_control_forward(void) +{ + send_keyboard_report(&EulerCarUp); // 发送前进键报告 + (void)osal_msleep(PRESS_RELEASE_INTERVAL); // 延时 + send_keyboard_report(&EulerCarRelease); // 发送释放键报告 + Vibration_CarControl(); + PRINT("[SLE Server] 星闪小车前进! \r\n"); + (void)osal_msleep(LONG_PRESS_INTERVAL); // 延时,等待响应 +} + +/** + * @brief 控制小车后退 + * + * 该函数通过发送键盘报告通知来控制小车后退。首先发送后退键报告, + * 然后延时一段时间,再发送释放键报告。最后打印一条日志信息并延时一段时间。 + */ +void eulercar_control_backward(void) +{ + send_keyboard_report(&EulerCarDown); // 发送后退键报告 + (void)osal_msleep(PRESS_RELEASE_INTERVAL); // 延时 + send_keyboard_report(&EulerCarRelease); // 发送释放键报告 + Vibration_CarControl(); + PRINT("[SLE Server] 星闪小车后退! \r\n"); + (void)osal_msleep(LONG_PRESS_INTERVAL); // 延时,等待响应 +} + +/** + * @brief 控制小车左转 + * + * 该函数通过发送键盘报告通知来控制小车左转。首先发送左转键报告, + * 然后延时一段时间,再发送释放键报告。最后打印一条日志信息并延时一段时间。 + */ +void eulercar_control_left(void) +{ + send_keyboard_report(&EulerCarLeft); // 发送左转键报告 + (void)osal_msleep(PRESS_RELEASE_INTERVAL); // 延时 + send_keyboard_report(&EulerCarRelease); // 发送释放键报告 + Vibration_CarControl(); + PRINT("[SLE Server] 星闪小车左转! \r\n"); + (void)osal_msleep(LONG_PRESS_INTERVAL); // 延时,等待响应 +} + +/** + * @brief 控制小车右转 + * + * 该函数通过发送键盘报告通知来控制小车右转。首先发送右转键报告, + * 然后延时一段时间,再发送释放键报告。最后打印一条日志信息并延时一段时间。 + */ +void eulercar_control_right(void) +{ + send_keyboard_report(&EulerCarRight); // 发送右转键报告 + (void)osal_msleep(PRESS_RELEASE_INTERVAL); // 延时 + send_keyboard_report(&EulerCarRelease); // 发送释放键报告 + Vibration_CarControl(); + PRINT("[SLE Server] 星闪小车右转! \r\n"); + (void)osal_msleep(LONG_PRESS_INTERVAL); // 延时,等待响应 +} + +/** + * @brief 控制小车暂停 + * + * 该函数通过发送键盘报告通知来控制小车暂停。发送释放键报告, + * 然后打印一条日志信息并延时一段时间。 + */ +void eulercar_control_stop(void) +{ + send_keyboard_report(&EulerCarStop); // 发送停止键报告 + (void)osal_msleep(PRESS_RELEASE_INTERVAL); // 延时 + send_keyboard_report(&EulerCarRelease); // 发送释放键报告 + Vibration_CarControl(); + PRINT("[SLE Server] 星闪小车暂停! \r\n"); + (void)osal_msleep(LONG_PRESS_INTERVAL); // 延时,等待响应 +} diff --git a/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/shake.c b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/shake.c new file mode 100644 index 0000000000000000000000000000000000000000..7f25251c029d7dfa850f8ef94a5ca1f5960742fc --- /dev/null +++ b/hi-sle/RemoteController_WS63E_Source_Code/SLE_OSPP_Server/src/shake.c @@ -0,0 +1,57 @@ +#include "../inc/shake.h" +#include "pinctrl.h" +#include "hal_gpio.h" +#include "gpio.h" +#include "tcxo.h" + + +void Shake_Init(void) +{ + // 配置SHAKE_PIN为输出,默认不震动 + uapi_pin_set_mode(SHAKE_PIN, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(SHAKE_PIN, GPIO_DIRECTION_OUTPUT); + uapi_gpio_set_val(SHAKE_PIN, GPIO_LEVEL_LOW); +} + +void Shake_Start(void) +{ + // 设置SHAKE_PIN为高电平,启动震动马达 + uapi_gpio_set_val(SHAKE_PIN, GPIO_LEVEL_HIGH); +} + +void Shake_Stop(void) +{ + // 设置SHAKE_PIN为低电平,停止震动马达 + uapi_gpio_set_val(SHAKE_PIN, GPIO_LEVEL_LOW); +} + +void Shake_Buzz(unsigned int duration) +{ + Shake_Start(); + uapi_tcxo_delay_ms((uint32_t)duration);// 延时指定的毫秒数 + Shake_Stop(); +} + +// 开发板上电震动函数 +void Vibration_PowerOn(void) +{ + Shake_Buzz(VIBRATION_DURATION_POWER_ON); +} + +// 星闪连接状态改变震动函数 +void Vibration_ConnChange(void) +{ + Shake_Buzz(VIBRATION_DURATION_CONN_CHANGE); +} + +// 夹爪行程极限震动函数 +void Vibration_GripperLimit(void) +{ + Shake_Buzz(VIBRATION_DURATION_GRIPPER_LIMIT); +} + +// 控制小车震动函数 +void Vibration_CarControl(void) +{ + Shake_Buzz(VIBRATION_DURATION_CAR_CONTROL); +} \ No newline at end of file diff --git a/hi-sle/images/EDA1.png b/hi-sle/images/EDA1.png new file mode 100644 index 0000000000000000000000000000000000000000..ef9a5b71df7c79513fb2e38663dee4743c48c831 Binary files /dev/null and b/hi-sle/images/EDA1.png differ diff --git a/hi-sle/images/EDA2.png b/hi-sle/images/EDA2.png new file mode 100644 index 0000000000000000000000000000000000000000..531b260c622499be6f0876bac9321c5688c201ac Binary files /dev/null and b/hi-sle/images/EDA2.png differ diff --git a/hi-sle/images/EDA3.png b/hi-sle/images/EDA3.png new file mode 100644 index 0000000000000000000000000000000000000000..cc7d397140c89b92771edbcf94693841188438da Binary files /dev/null and b/hi-sle/images/EDA3.png differ diff --git a/hi-sle/images/IP5306_design.png b/hi-sle/images/IP5306_design.png new file mode 100644 index 0000000000000000000000000000000000000000..0e46ed59dd46561aa93cacf1391068d3bf30ebfd Binary files /dev/null and b/hi-sle/images/IP5306_design.png differ diff --git a/hi-sle/images/IP5306_pin.png b/hi-sle/images/IP5306_pin.png new file mode 100644 index 0000000000000000000000000000000000000000..65f3c130eb0f53fccbe61044285bcf5253347209 Binary files /dev/null and b/hi-sle/images/IP5306_pin.png differ diff --git a/hi-sle/images/Intro1.jpg b/hi-sle/images/Intro1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4c94d6a714bba60ccfc24b29244bd9bd6acdf8c3 Binary files /dev/null and b/hi-sle/images/Intro1.jpg differ diff --git a/hi-sle/images/Intro2.jpg b/hi-sle/images/Intro2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9a644f30c70bfaa9256bf819d4a481351b04a6e9 Binary files /dev/null and b/hi-sle/images/Intro2.jpg differ diff --git a/hi-sle/images/board.png b/hi-sle/images/board.png new file mode 100644 index 0000000000000000000000000000000000000000..e88aa9b19818fed24fad360d765ac342d345a5c6 Binary files /dev/null and b/hi-sle/images/board.png differ diff --git a/hi-sle/images/checkout1.jpg b/hi-sle/images/checkout1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aacc895deb8ab9566d79c9e1c6b54ec776f9fa86 Binary files /dev/null and b/hi-sle/images/checkout1.jpg differ diff --git a/hi-sle/images/checkout2.jpg b/hi-sle/images/checkout2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..499a7bece0772ec4de55f1b2052e6d751f40983a Binary files /dev/null and b/hi-sle/images/checkout2.jpg differ diff --git a/hi-sle/images/checkout3.jpg b/hi-sle/images/checkout3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce9199ab2f57cb8ee4f7a304ff5bb6e5538809b7 Binary files /dev/null and b/hi-sle/images/checkout3.jpg differ diff --git a/hi-sle/images/fusion1.png b/hi-sle/images/fusion1.png new file mode 100644 index 0000000000000000000000000000000000000000..fa15be8c70d62e93d634a8db7292a591810f1746 Binary files /dev/null and b/hi-sle/images/fusion1.png differ diff --git a/hi-sle/images/fusion2.png b/hi-sle/images/fusion2.png new file mode 100644 index 0000000000000000000000000000000000000000..11af04f14c0d1b482fa52c4435c73b0f562542eb Binary files /dev/null and b/hi-sle/images/fusion2.png differ diff --git a/hi-sle/images/fusion3.png b/hi-sle/images/fusion3.png new file mode 100644 index 0000000000000000000000000000000000000000..f4a336b14c5eb306338c89318ba1af47ec54d1da Binary files /dev/null and b/hi-sle/images/fusion3.png differ diff --git a/hi-sle/images/fusion4.png b/hi-sle/images/fusion4.png new file mode 100644 index 0000000000000000000000000000000000000000..02b6678006bc4522feeefa66143060e39ad20894 Binary files /dev/null and b/hi-sle/images/fusion4.png differ diff --git a/hi-sle/images/hi3061_upload.png b/hi-sle/images/hi3061_upload.png new file mode 100644 index 0000000000000000000000000000000000000000..68fdb20364d7029df013f7db82a8481178188d0e Binary files /dev/null and b/hi-sle/images/hi3061_upload.png differ diff --git a/hi-sle/images/i.png b/hi-sle/images/i.png new file mode 100644 index 0000000000000000000000000000000000000000..d9bdf30e8cc2772aece68898363e38128324f00c Binary files /dev/null and b/hi-sle/images/i.png differ diff --git a/hi-sle/images/logo.png b/hi-sle/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d9bdf30e8cc2772aece68898363e38128324f00c Binary files /dev/null and b/hi-sle/images/logo.png differ diff --git a/hi-sle/images/logo2.png b/hi-sle/images/logo2.png new file mode 100644 index 0000000000000000000000000000000000000000..c5dd5917cb5211f4239e1fcd655785367d6c7104 Binary files /dev/null and b/hi-sle/images/logo2.png differ diff --git a/hi-sle/images/logo3.jpg b/hi-sle/images/logo3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..329a129c9f3b487a86008a64aa05c66ed565c7ca Binary files /dev/null and b/hi-sle/images/logo3.jpg differ diff --git a/hi-sle/images/logo4.jpg b/hi-sle/images/logo4.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a7a93fb8f86bc8e151cccd9e56ae50e22666246b Binary files /dev/null and b/hi-sle/images/logo4.jpg differ diff --git a/hi-sle/images/solder.gif b/hi-sle/images/solder.gif new file mode 100644 index 0000000000000000000000000000000000000000..04996aacc20f9f4ec19ef0632f8926a24c378101 Binary files /dev/null and b/hi-sle/images/solder.gif differ diff --git a/hi-sle/images/stuff.gif b/hi-sle/images/stuff.gif new file mode 100644 index 0000000000000000000000000000000000000000..738ed22fffcadd9ba7f82c96eb9cb0ab2444264f Binary files /dev/null and b/hi-sle/images/stuff.gif differ