移植GS21 sdk源码U8 上gnss可以工作 1527/1 1527/head sdk615
authorSnickerSun <snickersun@163.com>
Tue, 17 Dec 2024 09:40:55 +0000 (17:40 +0800)
committerSnickerSun <snickersun@163.com>
Tue, 17 Dec 2024 09:40:55 +0000 (17:40 +0800)
103 files changed:
code/sdk/build/config/target_config/brandy/config.py
code/sdk/drivers/boards/brandy_evb/board_config/board_u8.h
code/sdk/drivers/chips/brandy/porting/uart/uart_porting.c
code/sdk/zhihui/gnss/CMakeLists.txt
code/sdk/zhihui/gnss/driver/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/controller/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/controller/tiot_controller.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/controller/tiot_controller.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/controller/tiot_controller_helper.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/controller/tiot_device_info.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/fw_load/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/fw_load/cfg_handle_priv/tiot_cfg_handle_priv.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/fw_load/cfg_handle_priv/tiot_cfg_handle_priv.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware_utils.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_log.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit_ops.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit_ops.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/gnss_board_port.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_misc_port.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_pin_port.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_uart_port.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/board_interface/osal_porting/tiot_osal.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface_ext.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/pm_default/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/pm_default/tiot_pm_default.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/pm_default/tiot_pm_default.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/pm_slave/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/pm_slave/tiot_pm_slave.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/pm_slave/tiot_pm_slave.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/tiot_pm.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/tiot_pm.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/tiot_pm_wakelock.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/pm/tiot_pm_wakelock.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/sys_msg_handler/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_handle.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_handle.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_slave_handle.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_types.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet_manager.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet_manager.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer_utils.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer_utils.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/circ_buf/tiot_circ_buf.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/circ_queue/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/circ_queue/tiot_circ_queue.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/circ_queue/tiot_circ_queue.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/fileops/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/fileops/tiot_fileops.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/fileops/tiot_fileops.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/list/tiot_list.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/misc/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/misc/tiot_misc.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/misc/tiot_misc.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/common/utils/tiot_types.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/Makefile [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_cfg.bin [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_fw_file_array.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_fw_file_array.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/gnss_device_info.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/gnss_device_info.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/gnss_service.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/device/gnss/gnss_service.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/porting/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/porting/gnss_board_port.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_log_port.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_misc_port.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_pin_port.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_uart_port.c [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/readme.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/tiot_autoconfig.h [new file with mode: 0644]
code/sdk/zhihui/gnss/driver/product_porting/tiot_defconfig [new file with mode: 0644]
code/sdk/zhihui/gnss/inc/gnss_ctl.h [moved from code/sdk/zhihui/gnss/gnss_ctl.h with 100% similarity]
code/sdk/zhihui/gnss/inc/uart_gnss.h [moved from code/sdk/zhihui/gnss/uart_gnss.h with 100% similarity]
code/sdk/zhihui/gnss/sample/agnss_sample/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/agnss_sample/agnss_encode.c [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/agnss_sample/agnss_encode.h [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/agnss_sample/agnss_sample.c [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/agnss_sample/agnss_sample.h [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/agnss_sample/gnss_datatypes.h [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/gnss_sample/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/gnss_sample/gnss_sample.c [new file with mode: 0644]
code/sdk/zhihui/gnss/sample/gnss_sample/gnss_sample.h [new file with mode: 0644]
code/sdk/zhihui/gnss/src/gnss_config_array.c [moved from code/sdk/zhihui/gnss/gnss_config_array.c with 100% similarity]
code/sdk/zhihui/gnss/src/gnss_ctl.c [moved from code/sdk/zhihui/gnss/gnss_ctl.c with 100% similarity]
code/sdk/zhihui/gnss/src/uart_gnss.c [moved from code/sdk/zhihui/gnss/uart_gnss.c with 91% similarity]

index 151b626..d63fbb3 100644 (file)
@@ -373,7 +373,7 @@ target = {
             'NANDFLASH_DS35X'
         ],
         #添加自定义应用
-        'ram_component': ['custom_cmd_service','gnss','custom_utils']
+        'ram_component': ['custom_cmd_service','gnss','gnss_sample','custom_utils']
     },
     'brandy-native-js-u8-r': {
         'base_target_name': 'brandy-native-js-r',
index e7dbd2e..19195ce 100644 (file)
@@ -266,7 +266,7 @@ const hal_gpio_config_t g_gpio_function_config[PIN_MAX_NUMBER] = {
 /***GPS Power*/
     {   S_AGPIO_L23, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL }, //GPS_BAT_ON
     {   S_AGPIO_L28, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL }, //GPS_1V8
-    {   S_AGPIO_L30, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_HIGH, 0, NULL }, //S_AGPIO_L30
+    {   S_AGPIO_L30, HAL_GPIO_DIRECTION_OUTPUT, HAL_GPIO_LEVEL_LOW, 0, NULL }, //S_AGPIO_L30
     
     // S_AGPIO_L17   HX3507_INT 
     // {   S_AGPIO_L17, HAL_GPIO_DIRECTION_INPUT, HAL_GPIO_LEVEL_LOW, 0, NULL },
index 543209b..62d5370 100644 (file)
@@ -265,7 +265,7 @@ void log_factory_at_callback(const void *buffer, uint16_t length, bool remaining
  #if defined(GNSS_UART1) && defined(SUPPORT_GNSS_SERVER)
     if (is_gnss_on())
     {
-        gnss_receive_handler((uint8_t *)buffer,length);
+        // gnss_receive_handler((uint8_t *)buffer,length);
         hal_uart_clear_pending(UART_BUS_1);
     }else{
 #endif
@@ -341,7 +341,7 @@ static void at_cmd_uart_rx_callback(const void *buf, uint16_t buf_len, bool rema
     at_cmd_msg_receive_handler((uint8_t *)buf, buf_len);
     #endif
     #if defined(GNSS_UART0) && defined(SUPPORT_GNSS_SERVER)
-    gnss_receive_handler((uint8_t *)buf,buf_len);
+    // gnss_receive_handler((uint8_t *)buf,buf_len);
     #endif
     hal_uart_clear_pending(SW_DEBUG_UART_BUS);
 }
index 679cc2b..9ae3144 100644 (file)
@@ -2,20 +2,45 @@
 # @brief    cmake file
 # Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved.
 #===============================================================================
+
+add_subdirectory(driver)
+
 set(COMPONENT_NAME "gnss")
-set(SOURCES ${SOURCES}
-    ${CMAKE_CURRENT_SOURCE_DIR}/gnss_config_array.c
-    ${CMAKE_CURRENT_SOURCE_DIR}/uart_gnss.c
-    ${CMAKE_CURRENT_SOURCE_DIR}/gnss_ctl.c
+# include(${CMAKE_CURRENT_SOURCE_DIR}/driver/CMakeLists.txt)
+set(SOURCES
+    # ${CMAKE_CURRENT_SOURCE_DIR}/gnss_config_array.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/uart_gnss.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/gnss_ctl.c
+    ${TIOT_SRC_LIST}
 )
 set(PUBLIC_HEADER
-${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/inc
 )
 set(PUBLIC_DEFINES
-SUPPORT_GNSS_SERVER
+    SUPPORT_GNSS_SERVER
+    CONFIG_DEV_GNSS=1
+    CONFIG_GNSS_DEV_NUM=1
+    CONFIG_GNSS_WAKEUP_TYPE_UART=1
+    CONFIG_GNSS_TCXO_FREQ_26M=1
+    CONFIG_GNSS_UART_BAUDRATE=115200
+    CONFIG_FILE_BY_ARRAY=1
+    CONFIG_FIRMWARE_CFG_HANDLE_PRIV=1
+    CONFIG_FIRMWARE_FILE_READ_BUF_LEN=1029
+    CONFIG_PM_WAKEUP_BY_UART=1
+    CONFIG_PM_MANAGE_LOWPOWER=1
+    CONFIG_XMIT_WITH_UART=1
+    CONFIG_UART_RX_MODE_BUFFED=1
+    CONFIG_XFER_PACKET_TIOT=1
+    CONFIG_XFER_DEFAULT_RX_BUFF=1
+    CONFIG_XFER_RX_BUFF_SIZE=512
+    CONFIG_OSAL_DEFINED=1
+    CONFIG_LIBBOUNDSCHECK_IMPLEMENTED=1
+    CONFIG_BOARD_DYNAMIC_ALLOC=1
+    CONFIG_GNSS_PACKET_BUFF_MAX=10000
 )
-set(PRIVATE_HEADER
 
+set(PRIVATE_HEADER
+    ${TIOT_HEADER_LIST}
 )
 
 set(PRIVATE_DEFINES
@@ -28,6 +53,7 @@ set(COMPONENT_PUBLIC_CCFLAGS
 set(COMPONENT_CCFLAGS
     -Wno-incompatible-function-pointer-types
     -Wno-unused-function
+    # ${TIOT_CFLAGS}
 )
 
 set(WHOLE_LINK
@@ -38,5 +64,11 @@ set(MAIN_COMPONENT
     false
 )
 
+message("TIOT_HEADER_LIST" ${TIOT_HEADER_LIST})
+message("TIOT_SRC_LIST" ${TIOT_SRC_LIST})
+
 build_component()
 
+
+
+add_subdirectory(sample/gnss_sample)
diff --git a/code/sdk/zhihui/gnss/driver/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/CMakeLists.txt
new file mode 100644 (file)
index 0000000..2db3bc6
--- /dev/null
@@ -0,0 +1,73 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+# 此处为TIoT驱动顶层CMake
+
+# CMake读取Kconfig配置
+# function(KCONFIG_GET_PARAMS KCONFIG_PATH)
+#     file(STRINGS ${KCONFIG_PATH} TIOT_CONFIG_LIST ENCODING "UTF-8")
+
+#     foreach (CONFIG ${TIOT_CONFIG_LIST})
+#         # CONFIG maybe: CONFIG_CC_STACKPROTECTOR_STRONG=y
+
+#         # The first: variable name
+#         string(REGEX MATCH "[^=]+" CONFIG_VAR_NAME ${CONFIG})
+
+#         # The second: variable value
+#         string(REGEX MATCH "=(.+$)" CONFIG_VAR_VAL ${CONFIG})
+#         set(CONFIG_VAR_VAL ${CMAKE_MATCH_1})
+#         if(CONFIG_VAR_VAL MATCHES "^y$")
+#             set(${CONFIG_VAR_NAME} ${CONFIG_VAR_VAL} PARENT_SCOPE)
+#         endif()
+#     endforeach()
+# endfunction()
+
+# macro(add_subdirectory_if_exist _path)
+#     if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${_path}/CMakeLists.txt)
+#         add_subdirectory(${_path})
+#     endif()
+# endmacro()
+
+# macro(list_sub_dirs result curdir)
+#   file(GLOB children RELATIVE ${curdir} ${curdir}/*)
+#   set(dirlist "")
+#   foreach(child ${children})
+#     if(IS_DIRECTORY ${curdir}/${child})
+#       list(APPEND dirlist ${child})
+#     endif()
+#   endforeach()
+#   set(${result} ${dirlist})
+# endmacro()
+
+if(NOT DEFINED TIOT_COMMON_DIR)
+    set(TIOT_COMMON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/common")
+endif()
+
+if(NOT DEFINED TIOT_PORTING_DIR)
+    set(TIOT_PORTING_DIR "${CMAKE_CURRENT_SOURCE_DIR}/product_porting")
+endif()
+
+if(NOT DEFINED TIOT_PORTING_CONFIG_DIR)
+    set(TIOT_PORTING_CONFIG_DIR "${CMAKE_CURRENT_SOURCE_DIR}/product_porting")
+endif()
+
+# if(NOT DEFINED TIOT_DEVICE_LIST)
+#     list_sub_dirs(TIOT_DEVICE_LIST ${CMAKE_CURRENT_SOURCE_DIR}/device)
+# endif()
+
+# 初始化CMake全局变量
+# set(TIOT_CFLAGS " -i ${TIOT_PORTING_CONFIG_DIR}/tiot_autoconfig.h" CACHE INTERNAL "tiot c flags" FORCE)
+# all header and files listed here
+set(TIOT_HEADER_LIST "${TIOT_PORTING_CONFIG_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "" CACHE INTERNAL "tiot src list" FORCE)
+
+# 获取Kconfig配置
+KCONFIG_GET_PARAMS(${TIOT_PORTING_CONFIG_DIR}/tiot_defconfig)
+
+add_subdirectory(device/gnss)
+
+# common
+add_subdirectory("${TIOT_COMMON_DIR}" common.out)
+# porting
+add_subdirectory("${TIOT_PORTING_DIR}" porting.out)
diff --git a/code/sdk/zhihui/gnss/driver/common/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a9f7cd3
--- /dev/null
@@ -0,0 +1,20 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+add_subdirectory(controller)
+add_subdirectory(fw_load)
+add_subdirectory(interface)
+add_subdirectory_if_exist(libboundscheck)
+add_subdirectory(pm)
+add_subdirectory(transfer)
+add_subdirectory(sys_msg_handler)
+add_subdirectory(utils)
+
+if(DEFINED CONFIG_COMMON_SUPPORT_DEBUG)
+add_subdirectory_if_exist(debug)
+endif()
+
+if(DEFINED CONFIG_COMMON_SUPPORT_DFR)
+add_subdirectory_if_exist(dfr)
+endif()
diff --git a/code/sdk/zhihui/gnss/driver/common/controller/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/controller/CMakeLists.txt
new file mode 100644 (file)
index 0000000..89ea3c5
--- /dev/null
@@ -0,0 +1,11 @@
+#===============================================================================\r
+# @brief    cmake make file\r
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+#===============================================================================\r
+set(\r
+    tiot_controller_src_list\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_controller.c\r
+)\r
+\r
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)\r
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_controller_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/controller/tiot_controller.c b/code/sdk/zhihui/gnss/driver/common/controller/tiot_controller.c
new file mode 100644 (file)
index 0000000..3fe85a0
--- /dev/null
@@ -0,0 +1,157 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: TIoT device controller. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-17, Create file. \n\r
+ */\r
+\r
+#include <stddef.h>\r
+#include "tiot_device_info.h"\r
+#include "tiot_controller.h"\r
+#include "tiot_board_log.h"\r
+\r
+#define CTRL_OPEN_COUNT_MAX  0xFFFFFFFFU\r
+\r
+int32_t tiot_controller_init(tiot_controller *ctrl, tiot_controller_info *info)\r
+{\r
+    int32_t ret;\r
+    tiot_board_info *board_info = info->board_info;\r
+    const tiot_device_info *device_info = info->dev_info;\r
+\r
+    if ((ctrl == NULL) || (ctrl->state == TIOT_CONTROLLER_INIT)) {\r
+        return -1;\r
+    }\r
+\r
+    /***** 软件初始化 *****/\r
+    /* 初始化open状态互斥锁. */\r
+    ret = osal_mutex_init(&ctrl->open_mutex);\r
+    if (ret != 0) {\r
+        goto mutex_init_fail;\r
+    }\r
+\r
+    /* 注册:1) PM状态机,如为NULL则使用默认状态机.\r
+             2)板级PM管脚信息,依据产品不同而不同. */\r
+    ret = tiot_pm_init(&ctrl->pm, board_info->hw_info.pm_info,\r
+                       device_info->pm_event_map, device_info->pm_event_map_size);\r
+    if (ret != 0) {\r
+        goto pm_init_fail;\r
+    }\r
+\r
+    /* 注册:1)固件加载回调,加载前 + 加载后,用于注册不同加载协议或设置波特率等,依据芯片不同而不同. */\r
+    ret = tiot_firmware_init(&ctrl->firmware, &device_info->exec_cbs);\r
+    if (ret != 0) {\r
+        goto fw_init_fail;\r
+    }\r
+\r
+    /* 注册:1) 接收回调 */\r
+    ret = tiot_xfer_init(&ctrl->transfer, board_info->hw_info.xmit_id, &device_info->xfer_info);\r
+    if (ret != 0) {\r
+        goto xfer_init_fail;\r
+    }\r
+\r
+    /* device info必须为静态分配变量. */\r
+    ctrl->dev_info = device_info;\r
+    ctrl->state = TIOT_CONTROLLER_INIT;\r
+    ctrl->dev_cus = (uintptr_t)info->dev_cus;\r
+\r
+    return 0;\r
+\r
+xfer_init_fail:\r
+    tiot_xfer_deinit(&ctrl->transfer);\r
+    memset_s((void *)&ctrl->transfer, sizeof(tiot_xfer_manager), 0, sizeof(tiot_xfer_manager));\r
+fw_init_fail:\r
+    memset_s((void *)&ctrl->firmware, sizeof(tiot_fw), 0, sizeof(tiot_fw));\r
+pm_init_fail:\r
+    memset_s((void *)&ctrl->pm, sizeof(tiot_pm), 0, sizeof(tiot_pm));\r
+    osal_mutex_destroy(&ctrl->open_mutex);\r
+mutex_init_fail:\r
+    return ret;\r
+}\r
+\r
+int32_t tiot_controller_open(tiot_controller *ctrl, void *param)\r
+{\r
+    int32_t ret = 0;\r
+    if (ctrl == NULL) {\r
+        tiot_print_dbg("[TIoT]device is null.\n");\r
+        return -1;\r
+    }\r
+    osal_mutex_lock(&ctrl->open_mutex);\r
+    if (ctrl->state == TIOT_CONTROLLER_UNINIT) {\r
+        tiot_print_err("[TIoT]dev state wrong %d.\r\n", ctrl->state);\r
+        ret = -1;\r
+        goto out;\r
+    }\r
+    if (ctrl->open_count == CTRL_OPEN_COUNT_MAX) {\r
+        tiot_print_err("[TIoT]reach max open count.\r\n");\r
+        ret = -1;\r
+        goto out;\r
+    }\r
+    ctrl->open_count++;\r
+    if (ctrl->state == TIOT_CONTROLLER_OPEN) {\r
+        /* 重复调用open仅添加计数. */\r
+        goto out;\r
+    }\r
+    ctrl->state = TIOT_CONTROLLER_OPENING; /* 中间状态,受mutex锁保护,不需要在open内判断. */\r
+    if (ctrl->ops.open(ctrl, param) != 0) {\r
+        ctrl->open_count--;\r
+        ctrl->state = TIOT_CONTROLLER_INIT;\r
+        ret = -1;\r
+        goto out;\r
+    }\r
+    ctrl->state = TIOT_CONTROLLER_OPEN;\r
+out:\r
+    osal_mutex_unlock(&ctrl->open_mutex);\r
+    return ret;\r
+}\r
+\r
+bool tiot_controller_check_opened(tiot_controller *ctrl)\r
+{\r
+    bool ret = true;\r
+    if (ctrl == NULL) {\r
+        tiot_print_dbg("[TIoT]device is null.\n");\r
+        return false;\r
+    }\r
+    osal_mutex_lock(&ctrl->open_mutex);\r
+    if (ctrl->state != TIOT_CONTROLLER_OPEN) {\r
+        tiot_print_dbg("[TIoT]device not opened.\n");\r
+        ret = false;\r
+    }\r
+    osal_mutex_unlock(&ctrl->open_mutex);\r
+    return ret;\r
+}\r
+\r
+void tiot_controller_close(tiot_controller *ctrl)\r
+{\r
+    if (ctrl == NULL) {\r
+        tiot_print_dbg("[TIoT]device is null.\n");\r
+        return;\r
+    }\r
+    osal_mutex_lock(&ctrl->open_mutex);\r
+    if ((ctrl->state != TIOT_CONTROLLER_OPEN) && (ctrl->state != TIOT_CONTROLLER_OPENING)) {\r
+        tiot_print_dbg("[TIoT]device is not opening or not opened.\n");\r
+        osal_mutex_unlock(&ctrl->open_mutex);\r
+        return;\r
+    }\r
+    /* 打开状态且open_count >=1时,减少open_count计数; 当open_count减少后变为0时,实际调用close操作. */\r
+    ctrl->open_count--;\r
+    if (ctrl->open_count == 0) {\r
+        ctrl->ops.close(ctrl);\r
+        ctrl->state = TIOT_CONTROLLER_INIT;\r
+    }\r
+    osal_mutex_unlock(&ctrl->open_mutex);\r
+}\r
+\r
+void tiot_controller_deinit(tiot_controller *ctrl)\r
+{\r
+    if ((ctrl == NULL) || (ctrl->state == TIOT_CONTROLLER_UNINIT)) {\r
+        return;\r
+    }\r
+\r
+    tiot_xfer_deinit(&ctrl->transfer);\r
+    tiot_pm_deinit(&ctrl->pm);\r
+    osal_mutex_destroy(&ctrl->open_mutex);\r
+    (void)memset_s((void *)ctrl, sizeof(tiot_controller), 0, sizeof(tiot_controller));\r
+    ctrl->state = TIOT_CONTROLLER_UNINIT;\r
+}\r
diff --git a/code/sdk/zhihui/gnss/driver/common/controller/tiot_controller.h b/code/sdk/zhihui/gnss/driver/common/controller/tiot_controller.h
new file mode 100644 (file)
index 0000000..64a0dd3
--- /dev/null
@@ -0,0 +1,152 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: TIoT device controller header. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-17, Create file. \n\r
+ */\r
+\r
+#ifndef TIOT_CONTROLLER_H\r
+#define TIOT_CONTROLLER_H\r
+\r
+#ifndef __KERNEL__\r
+#include <stdbool.h>\r
+#endif\r
+#include "tiot_board.h"\r
+#include "tiot_pm.h"\r
+#include "tiot_firmware.h"\r
+#include "tiot_xfer.h"\r
+#include "tiot_device_info.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_controller Controller\r
+ * @ingroup  tiot_common\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief TIoT controller state.\r
+ */\r
+typedef enum {\r
+    TIOT_CONTROLLER_UNINIT,\r
+    TIOT_CONTROLLER_INIT,\r
+    TIOT_CONTROLLER_OPENING,\r
+    TIOT_CONTROLLER_OPEN,\r
+} tiot_controller_state;\r
+\r
+/**\r
+ * @brief TIoT controller info provided outside.\r
+ */\r
+typedef struct {\r
+    tiot_board_info *board_info;       /*!< Board infomations. */\r
+    const tiot_device_info *dev_info;  /*!< Reserved device info, must be allocated staticly. */\r
+    const tiot_dev_customize *dev_cus; /*!< Reserved device customize. */\r
+} tiot_controller_info;\r
+\r
+struct _tiot_controller;\r
+\r
+/**\r
+ * @brief  TIoT controller ops.\r
+ */\r
+typedef struct {\r
+    int32_t (* open)(struct _tiot_controller *ctrl, void *param);\r
+    void (* close)(struct _tiot_controller *ctrl);\r
+    int32_t (* write)(struct _tiot_controller *ctrl, const uint8_t *data,\r
+                      uint32_t len, const tiot_xfer_tx_param *param);\r
+    int32_t (* read)(struct _tiot_controller *ctrl, uint8_t *buff, uint32_t buff_len, const tiot_xfer_rx_param *param);\r
+    int32_t (* pm_ctrl)(struct _tiot_controller *ctrl, uint8_t cmd);\r
+} tiot_controller_ops;\r
+\r
+/**\r
+ * @brief TIoT device controller.\r
+ */\r
+typedef struct _tiot_controller {\r
+    uint32_t state;                    /*!< Current state. */\r
+    tiot_pm pm;                        /*!< Power Manangement module. */\r
+    tiot_fw firmware;                  /*!< Firmware module. */\r
+    tiot_xfer_manager transfer;        /*!< Transfer manager modele. */\r
+    const tiot_device_info *dev_info;  /*!< Reserved device info, must be allocated staticly. */\r
+    tiot_controller_ops ops;           /*!< Controller ops, open, close, write, read. */\r
+    volatile uint32_t open_count;      /*!< open count. */\r
+    osal_mutex open_mutex;             /*!< open state mutex. */\r
+    uintptr_t dev_cus;                  /*!< device customize. */\r
+} tiot_controller;\r
+\r
+/**\r
+ * @brief  TIoT find controller by pin from controllers.\r
+ * @param  [in]  ctrls TIoT controller instances array.\r
+ * @param  [in]  ctrl_num TIoT controller instances num.\r
+ * @param  [in]  pin Pin number.\r
+ * @param  [in]  pin_type Pin type.\r
+ * @return if found controller, return controller pointer, else return NULL.\r
+ */\r
+static inline tiot_controller *tiot_find_controller_by_pin(tiot_controller *ctrls, uint8_t ctrl_num,\r
+                                                           uint32_t pin, uint32_t pin_type)\r
+{\r
+    const uint32_t *pm_info;\r
+    uint8_t i;\r
+    for (i = 0; i < ctrl_num; i++) {\r
+        pm_info = ctrls[i].pm.pm_info;\r
+        if (pm_info[pin_type] == pin) {\r
+            return &ctrls[i];\r
+        }\r
+    }\r
+    return NULL;\r
+}\r
+\r
+/**\r
+ * @brief  TIoT controller init.\r
+ * @param  [in]  ctrl TIoT controller instance.\r
+ * @param  [in]  info TIoT controller information.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_controller_init(tiot_controller *ctrl, tiot_controller_info *info);\r
+\r
+/**\r
+ * @brief  TIoT controller open, if already opened, add open count only.\r
+ * @param  [in]  ctrl TIoT controller instance.\r
+ * @param  [in]  param TIoT controller open param.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_controller_open(tiot_controller *ctrl, void *param);\r
+\r
+/**\r
+ * @brief  TIoT controller check opened or not, must be used after init.\r
+ * @param  [in]  ctrl TIoT controller instance.\r
+ * @return true if Opened;\r
+ *         false if not opened.\r
+ */\r
+bool tiot_controller_check_opened(tiot_controller *ctrl);\r
+\r
+/**\r
+ * @brief  TIoT controller close, if opened multiple times, only remove open count.\r
+ * @param  [in]  ctrl TIoT controller instance.\r
+ */\r
+void tiot_controller_close(tiot_controller *ctrl);\r
+\r
+/**\r
+ * @brief  TIoT controller deinit.\r
+ * @param  [in]  ctrl TIoT controller instance.\r
+ */\r
+void tiot_controller_deinit(tiot_controller *ctrl);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/gnss/driver/common/controller/tiot_controller_helper.h b/code/sdk/zhihui/gnss/driver/common/controller/tiot_controller_helper.h
new file mode 100644 (file)
index 0000000..e0e02e1
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description: TIoT Controllrt helper. \n
+ *
+ * History: \n
+ * 2024-03-05, Create file. \n
+ */
+#ifndef TIOT_CONTROLLER_HELPER_H
+#define TIOT_CONTROLLER_HELPER_H
+
+#include "tiot_board_pin_port.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_controller_helper Controller Helper
+ * @ingroup  tiot_common_controllrt
+ * @{
+ */
+
+static inline void tiot_pin_int_request(uint32_t pin, tiot_pin_int_callback cb)
+{
+    if (pin != TIOT_PIN_NONE) {
+        (void)tiot_board_pin_register_int_callback(pin, cb);
+        (void)tiot_board_pin_enable_int(pin, TIOT_PIN_INT_ENABLE);
+    }
+}
+
+static inline void tiot_pin_int_release(uint32_t pin)
+{
+    if (pin != TIOT_PIN_NONE) {
+        (void)tiot_board_pin_enable_int(pin, TIOT_PIN_INT_DISABLE);
+        (void)tiot_board_pin_register_int_callback(pin, NULL);
+    }
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/controller/tiot_device_info.h b/code/sdk/zhihui/gnss/driver/common/controller/tiot_device_info.h
new file mode 100644 (file)
index 0000000..cd4f54f
--- /dev/null
@@ -0,0 +1,78 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Device info header. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-25, Create file. \n\r
+ */\r
+#ifndef TIOT_DEVICE_INFO_H\r
+#define TIOT_DEVICE_INFO_H\r
+\r
+#include "tiot_pm.h"\r
+#include "tiot_firmware.h"\r
+#include "tiot_xfer.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_interface_device Device Interface\r
+ * @ingroup  tiot_common_interface\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief  Device common timing specs.\r
+ */\r
+typedef struct {\r
+    const uint32_t power_on_wait_ms;       /*!< Before power on wait time. */\r
+    const uint32_t boot_time_ms;           /*!< Boot wait time. */\r
+    const uint32_t init_time_ms;           /*!< Init time wait time. */\r
+    const uint32_t wakeup_pulse_ms;        /*!< Wakeup pin pulse time. */\r
+    const uint32_t wakeup_wait_ms;         /*!< Wakeup wait time. */\r
+    const uint32_t baud_change_wait_us;    /*!< Baudrate change wait time. */\r
+} tiot_device_timings;\r
+\r
+struct _tiot_controller;\r
+\r
+/**\r
+ * @brief  Device infomations to be registed in driver.\r
+ */\r
+typedef struct {\r
+    /*!< Power management event map, set NULL if use default event map. */\r
+    tiot_pm_event_entry *pm_event_map;\r
+    uint8_t pm_event_map_size;\r
+    /*!< Firmware callback called before and after commands execute. */\r
+    const tiot_fw_ops exec_cbs;\r
+\r
+    /*!< Transfer */\r
+    tiot_xfer_device_info xfer_info;\r
+\r
+    /*!< Tiot packet sys msg handle. */\r
+    void (*pkt_sys_msg_handle)(struct _tiot_controller *ctrl, uint8_t code);\r
+\r
+    tiot_device_timings timings;\r
+} tiot_device_info;\r
+\r
+typedef struct {\r
+    uintptr_t start_data;\r
+    uintptr_t curr_data;\r
+    uintptr_t end_data;\r
+    uint32_t unit_data_len;\r
+} tiot_dev_customize;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/fw_load/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/fw_load/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4f6793e
--- /dev/null
@@ -0,0 +1,46 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+set(
+    tiot_firmware_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_firmware.c
+)
+
+set(
+    tiot_firmware_header_list
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+if(CONFIG_FIRMWARE_CFG_HANDLE_PRIV)
+list(APPEND
+     tiot_firmware_src_list
+     ${CMAKE_CURRENT_SOURCE_DIR}/cfg_handle_priv/tiot_cfg_handle_priv.c)
+
+list(APPEND
+     tiot_firmware_header_list
+     ${CMAKE_CURRENT_SOURCE_DIR}/cfg_handle_priv)
+endif()
+
+if(CONFIG_FIRMWARE_CFG_HANDLE_XCI)
+list(APPEND
+     tiot_firmware_src_list
+     ${CMAKE_CURRENT_SOURCE_DIR}/cfg_handle_xci/tiot_cfg_handle_xci.c)
+
+list(APPEND
+     tiot_firmware_header_list
+     ${CMAKE_CURRENT_SOURCE_DIR}/cfg_handle_xci)
+endif()
+
+if(CONFIG_FIRMWARE_CFG_HANDLE_HIBURN)
+list(APPEND
+     tiot_firmware_src_list
+     ${CMAKE_CURRENT_SOURCE_DIR}/cfg_handle_hiburn/tiot_cfg_handle_hiburn.c)
+
+list(APPEND
+     tiot_firmware_header_list
+     ${CMAKE_CURRENT_SOURCE_DIR}/cfg_handle_hiburn)
+endif()
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${tiot_firmware_header_list}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_firmware_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/fw_load/cfg_handle_priv/tiot_cfg_handle_priv.c b/code/sdk/zhihui/gnss/driver/common/fw_load/cfg_handle_priv/tiot_cfg_handle_priv.c
new file mode 100644 (file)
index 0000000..b69bf1d
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-12-05, Create file. \n
+ */
+
+#include "tiot_misc.h"
+#include "tiot_firmware.h"
+#include "tiot_firmware_utils.h"
+#include "tiot_board_log.h"
+#include "tiot_cfg_handle_priv.h"
+
+#define TIOT_FW_FILE_STA        0x43
+#define TIOT_FW_FILE_ACK        0x06
+#define TIOT_FW_FILE_NAK        0x15
+#define TIOT_FW_PRIV_CMD_OK     'G'
+
+#define TIOT_FW_PRIV_ACK_MAX    128
+#define TIOT_FW_CUS_STR_LEN     12
+
+typedef enum {
+    TIOT_FW_EXTCMD_ACK = 0x0,
+    TIOT_FW_EXTCMD_ACK_EXT = 0x1,
+    TIOT_FW_EXTCMD_CUSTOMIZE = 0x2,
+    TIOT_FW_EXTCMD_NUM
+} tiot_fw_ext_cmd_priv;
+
+typedef int32_t (*priv_ext_cmd_handle_func)(tiot_fw *fw, const uint8_t *cmd, uint16_t len);
+typedef int32_t (*pre_priv_ext_cmd_handle_func)(tiot_fw *fw, uint8_t *cmd, uint16_t *len);
+
+static int32_t tiot_fw_ack_handle_priv(tiot_fw *fw, const uint8_t *cmd, uint16_t len);
+static int32_t tiot_fw_ack_ext_handle_priv(tiot_fw *fw, const uint8_t *cmd, uint16_t len);
+static int32_t tiot_fw_customize_ext_cmd_handle_priv(tiot_fw *fw, uint8_t *cmd, uint16_t *len);
+
+static const priv_ext_cmd_handle_func tiot_fw_priv_ext_cmd_table[TIOT_FW_EXTCMD_NUM] = {
+    tiot_fw_ack_handle_priv,
+    tiot_fw_ack_ext_handle_priv,
+    tiot_fw_ack_handle_priv,
+};
+
+static const pre_priv_ext_cmd_handle_func tiot_fw_pre_priv_ext_cmd_table[TIOT_FW_EXTCMD_NUM] = {
+    NULL,
+    NULL,
+    tiot_fw_customize_ext_cmd_handle_priv,
+};
+
+static int32_t tiot_fw_customize_para_replace(uint8_t *cmd, uint16_t *len, uint32_t cus_data)
+{
+    char *tmp = NULL;
+    size_t str_len;
+    char cus_data_str[TIOT_FW_CUS_STR_LEN] = { 0 };
+
+    if (*len == 0 || (cmd[*len - 1] != ' ')) {
+        tiot_print_err("[TIoT:priv] customize cmd not space-terminated.\r\n");
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+
+    if (tiot_num_to_hex(cus_data, cus_data_str, TIOT_FW_CUS_STR_LEN) != TIOT_FW_LOAD_RET_OK) {
+        tiot_print_err("[TIoT:priv] tiot_num_to_hex failed.\r\n");
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+
+    // cmd如下格式"WRITEM 4 0x3ff08 0x1e8480 "; tmp指向子串"0x1e8480"的起始地址.
+    cmd[*len - 1] = '\0';
+    tmp = strrchr((const char *)cmd, ' ');
+    if (tmp == NULL) {
+        tiot_print_err("[TIoT:priv] customize cmd string does not have space.\r\n");
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+    tmp++;
+
+    // 把tmp指向的字符串替换为tiot驱动配置的参数
+    int ret = strcpy_s((char *)tmp, strlen(tmp) + 1, cus_data_str);
+    if (ret != 0) {
+        tiot_print_err("[TIoT:priv] customize para replace failed. \r\n");
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+
+    // cmd最后的'\0'替换为空格
+    str_len = strlen((const char *)cmd);
+    cmd[str_len] = ' ';
+
+    // 更新cmd的长度
+    *len = str_len + 1;
+    return TIOT_FW_LOAD_RET_OK;
+}
+
+static int32_t tiot_fw_ack_handle_priv(tiot_fw *fw, const uint8_t *cmd, uint16_t len)
+{
+    int32_t ret = 0;
+    uint8_t ack = 0;
+    const uint8_t quit_cmd[] = "QUIT ";
+    // QUIT命令特殊处理
+    if ((len == (sizeof(quit_cmd) - 1)) && (memcmp(quit_cmd, cmd, len) == 0)) {
+        return 0;
+    }
+    ret = tiot_firmware_read(fw, &ack, sizeof(uint8_t));
+    if (ret != sizeof(uint8_t)) {
+        return -1;
+    }
+
+    tiot_print_dbg("[TIoT:priv]ack 0x%x\r\n", ack);
+    if ((ack == TIOT_FW_PRIV_CMD_OK) || (ack == TIOT_FW_FILE_STA) || (ack == TIOT_FW_FILE_ACK)) {
+        return TIOT_FW_LOAD_RET_OK;
+    } else if (ack == TIOT_FW_FILE_NAK) {
+        return TIOT_FW_LOAD_RET_RETRY;
+    }
+    return TIOT_FW_LOAD_RET_ERR;
+}
+
+static int32_t tiot_fw_ack_ext_handle_priv(tiot_fw *fw, const uint8_t *cmd, uint16_t len)
+{
+    tiot_unused(cmd);
+    tiot_unused(len);
+    int32_t ret = 0;
+    uint8_t ack_buff[TIOT_FW_PRIV_ACK_MAX] = { 0 };
+    ret = tiot_firmware_read(fw, ack_buff, sizeof(ack_buff));
+    if ((ret <= 0) || ((uint32_t)ret > sizeof(ack_buff))) {
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+    tiot_print_info("[TIoT:fw]ack ext: ");
+    for (uint32_t i = 0; i < (uint32_t)ret; i++) {
+        tiot_print_info("0x%x ", ack_buff[i]);
+    }
+    tiot_print_info("\r\n");
+    return TIOT_FW_LOAD_RET_OK;
+}
+
+static int32_t tiot_fw_customize_ext_cmd_handle_priv(tiot_fw *fw, uint8_t *cmd, uint16_t *len)
+{
+    uint32_t cus_data;
+
+    tiot_controller *ctrl = tiot_container_of(fw, tiot_controller, firmware);
+    if (ctrl->dev_cus == 0) {
+        tiot_print_info("[TIoT:priv] customize is NULL.\r\n");
+        return TIOT_FW_LOAD_RET_OK;
+    }
+
+    if (tiot_firmware_customize_value_get(fw, &cus_data) != TIOT_FW_LOAD_RET_OK) {
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+
+    return tiot_fw_customize_para_replace(cmd, len, cus_data);
+}
+
+int32_t tiot_fw_ext_cmd_handle_priv(tiot_fw *fw, uint16_t ext_cmd, const uint8_t *cmd, uint16_t len)
+{
+    if (ext_cmd >= TIOT_FW_EXTCMD_NUM) {
+        tiot_print_err("[TIoT:fw]priv ext cmd exceed max!\r\n");
+        return -1;
+    }
+    return tiot_fw_priv_ext_cmd_table[ext_cmd](fw, cmd, len);
+}
+
+int32_t tiot_fw_pre_ext_cmd_handle_priv(tiot_fw *fw, uint16_t ext_cmd, uint8_t *cmd, uint16_t *len)
+{
+    if (ext_cmd >= TIOT_FW_EXTCMD_NUM) {
+        tiot_print_err("[TIoT:fw]pre priv ext cmd exceed max!\r\n");
+        return -1;
+    }
+
+    if (tiot_fw_pre_priv_ext_cmd_table[ext_cmd] == NULL) {
+        return TIOT_FW_LOAD_RET_OK;
+    }
+
+    return tiot_fw_pre_priv_ext_cmd_table[ext_cmd](fw, cmd, len);
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/fw_load/cfg_handle_priv/tiot_cfg_handle_priv.h b/code/sdk/zhihui/gnss/driver/common/fw_load/cfg_handle_priv/tiot_cfg_handle_priv.h
new file mode 100644 (file)
index 0000000..23a4069
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT firmware load module private cfg handle. \n
+ *
+ * History: \n
+ * 2023-12-05, Create file. \n
+ */
+#ifndef TIOT_CFG_HANDLE_PRIV_H
+#define TIOT_CFG_HANDLE_PRIV_H
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_firmware_cfg_handle_priv CFG HANDLE PRIVATE
+ * @ingroup  tiot_common_firmware
+ * @{
+ */
+
+/**
+ * @brief  TIoT firmware private extend command handle.
+ * @param  [in]  fw TIoT firmware object.
+ * @param  [in]  ext_cmd Extend command.
+ * @param  [in]  cmd Firmware Command.
+ * @param  [in]  len Firmware Command length.
+ * @return if OK, return 0, if need retry ,return 1, else return -1.
+ */
+int32_t tiot_fw_ext_cmd_handle_priv(tiot_fw *fw, uint16_t ext_cmd, const uint8_t *cmd, uint16_t len);
+
+/**
+ * @brief  TIoT firmware before private extend command handle.
+ * @param  [in]  fw TIoT firmware object.
+ * @param  [in]  ext_cmd Extend command.
+ * @param  [in]  cmd Firmware Command.
+ * @param  [in]  len Firmware Command length.
+ * @return if OK, return 0, if need retry ,return 1, else return -1.
+ */
+int32_t tiot_fw_pre_ext_cmd_handle_priv(tiot_fw *fw, uint16_t ext_cmd, uint8_t *cmd, uint16_t *len);
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware.c b/code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware.c
new file mode 100644 (file)
index 0000000..0219376
--- /dev/null
@@ -0,0 +1,277 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT firmware load module. \n
+ *
+ * History: \n
+ * 2023-03-30, Create file. \n
+ */
+#include "tiot_firmware.h"
+#include <stdbool.h>
+#include "tiot_firmware_utils.h"
+#include "securec.h"
+#include "tiot_board_log.h"
+
+#define FW_LEN_PER_SEND   64
+
+#define TIOT_FW_LOAD_FINISH    0
+#define TIOT_FW_LOAD_NEXT      1
+
+#define TIOT_FW_LOAD_RETRY_CNT 3
+
+#define TIOT_FW_EXT_VERSION1 0x1
+
+static inline uint32_t little_endian_to_u32(const uint8_t *data)
+{
+    uint32_t val;
+    val = data[0x3];
+    val <<= 0x8;
+    val |= data[0x2];
+    val <<= 0x8;
+    val |= data[0x1];
+    val <<= 0x8;
+    val |= data[0x0];
+    return val;
+}
+
+int32_t tiot_firmware_init(tiot_fw *fw, const tiot_fw_ops *ops)
+{
+    if ((fw == NULL) || (ops == NULL) || (ops->ext_cmd_handle == NULL)) {
+        tiot_print_dbg("[TIoT][fw]param invalid!\n");
+        return -1;
+    }
+    fw->ops = ops;
+    fw->fw_file = NULL;
+    return 0;
+}
+
+static int32_t tiot_firmware_pre_ext_cmd_write(tiot_fw *fw, uint16_t ext_cmd, uint8_t *cmd, uint16_t *cmd_len)
+{
+    int32_t ret = 0;
+
+    if (fw->ops->pre_ext_cmd_handle != NULL) {
+        ret = fw->ops->pre_ext_cmd_handle(fw, ext_cmd, cmd, cmd_len);
+    }
+    return ret;
+}
+
+static int32_t firmware_send_cmd(tiot_fw *fw, uint16_t ext_cmd, uint16_t cmd_len)
+{
+    uint16_t send_len;
+    uint16_t tmp_len;
+    // 加载时uart等接口每次最多发送64字节数据, 避免资源受限的场景申请大块内存
+    uint8_t cmd[FW_LEN_PER_SEND] = { 0 };
+    int32_t ret = 0;
+    uint16_t remain_len = cmd_len;
+
+    // 一个完整的命令分多次发送,每次发送FW_LEN_PER_SEND字节
+    do {
+        // 1, Get cmd data from file, maximum of 64 bytes each time.
+        send_len = (remain_len > FW_LEN_PER_SEND) ? FW_LEN_PER_SEND : remain_len;
+        ret = tiot_file_read(fw->fw_file, (char *)cmd, send_len, fw->cur_offset);
+        if (ret != send_len) {
+            tiot_print_err("[TIoT:fw]cmd content read fail\r\n");
+            return TIOT_FW_LOAD_RET_ERR;
+        }
+        fw->cur_offset += send_len;
+
+        // 2, Callback function before sending data.
+        tmp_len = send_len;
+        // 要确保需要处理的扩展命令长度都小于FW_LEN_PER_SEND字节(customize当前已保证),否则需要调整当前的分包发送逻辑
+        if (tiot_firmware_pre_ext_cmd_write(fw, ext_cmd, cmd, &tmp_len) != TIOT_FW_LOAD_RET_OK) {
+            tiot_print_err("[TIoT:fw]pre ext cmd handle failed.\r\n");
+            return TIOT_FW_LOAD_RET_ERR;
+        }
+
+        // 3, send data
+        ret = tiot_firmware_write(fw, cmd, tmp_len);
+        if (ret != tmp_len) {
+            tiot_print_err("[TIoT:fw]cmd content send fail\r\n");
+            return TIOT_FW_LOAD_RET_ERR;
+        }
+
+        remain_len -= send_len;
+    } while (remain_len > 0);
+
+    // 4, after the whole cmd data send, handle the cmd ack (注意: ext_cmd_handle只能使用最后一包cmd)
+    ret = fw->ops->ext_cmd_handle(fw, ext_cmd, cmd, tmp_len);
+    if (ret == TIOT_FW_LOAD_RET_RETRY) {
+        // 如果命令要重试,需复位文件指针, 以及customize数据指针(当前不实现,customize对应的命令不会返回RETRY)
+        fw->cur_offset -= cmd_len;
+    }
+
+    return ret;
+}
+
+static int32_t tiot_firmware_send_cmd_retry(tiot_fw *fw, uint16_t ext_cmd, uint16_t cmd_len)
+{
+    uint8_t retry_cnt;
+    int32_t ret = -1;
+
+    for (retry_cnt = 0; retry_cnt < TIOT_FW_LOAD_RETRY_CNT; retry_cnt++) {
+        ret = firmware_send_cmd(fw, ext_cmd, cmd_len);
+        if (ret != TIOT_FW_LOAD_RET_RETRY) {
+            break;
+        }
+        tiot_print_warning("[TIoT:fw]single cmd retry %d\r\n", retry_cnt);
+    }
+
+    if (ret == TIOT_FW_LOAD_RET_QUIT) {
+        tiot_print_info("[TIoT:fw]version matches, no need to upgrade firmware.\r\n");
+    } else if ((ret != TIOT_FW_LOAD_RET_OK) || (retry_cnt == TIOT_FW_LOAD_RETRY_CNT)) {
+        tiot_print_err("[TIoT:fw]cmd handle retry fail.\r\n");
+        ret = -1;
+    }
+
+    return ret;
+}
+
+static int32_t tiot_firmware_customize_index_init(tiot_fw *fw)
+{
+    tiot_controller *ctrl = tiot_container_of(fw, tiot_controller, firmware);
+    if (ctrl->dev_cus == 0) {
+        tiot_print_info("[TIoT:fw]tiot firmware no customize. \r\n");
+        return TIOT_FW_LOAD_RET_OK;
+    }
+
+    tiot_dev_customize *cus_ptr = (tiot_dev_customize *)ctrl->dev_cus;
+    cus_ptr->curr_data = cus_ptr->start_data;
+
+    return TIOT_FW_LOAD_RET_OK;
+}
+
+static int32_t tiot_firmware_load_cmds(tiot_fw *fw)
+{
+    int32_t ret;
+    uint16_t cmd_len, ext_cmd;
+
+    if (tiot_firmware_customize_index_init(fw) != TIOT_FW_LOAD_RET_OK) {
+        return -1;
+    }
+
+    do {
+        ret = tiot_file_read(fw->fw_file, (char *)&cmd_len, sizeof(uint16_t), fw->cur_offset);
+        // 处于文件末尾,读文件结束
+        if (ret == 0) {
+            break;
+        }
+        if (ret != sizeof(uint16_t)) {
+            tiot_print_err("[TIoT:fw]cmd len read fail\r\n");
+            ret = -1;
+            break;
+        }
+        ext_cmd = cmd_len >> 12;   // 拓展命令高4位, 右移12位
+        cmd_len = cmd_len & 0xFFF; // 长度为低12位
+
+        // 更新offset
+        fw->cur_offset += sizeof(uint16_t);
+
+        ret = tiot_firmware_send_cmd_retry(fw, ext_cmd, cmd_len);
+        if (ret != 0) {
+            break;
+        }
+    } while (true);
+
+    return ret == TIOT_FW_LOAD_RET_QUIT ? 0 : ret;
+}
+
+static inline int32_t firmware_read_u32(tiot_fw *fw, uint32_t *val)
+{
+    uint8_t data[4];
+    int32_t ret = tiot_file_read(fw->fw_file, (char *)data, sizeof(uint32_t), fw->cur_offset);
+    if (ret != sizeof(uint32_t)) {
+        return -1;
+    }
+    fw->cur_offset += sizeof(uint32_t);
+    *val = little_endian_to_u32(data);
+    return 0;
+}
+
+static int32_t firmware_load_ext_version1(tiot_fw *fw, tiot_fw_ext_version1 *ext)
+{
+    if (firmware_read_u32(fw, &ext->file_len) != 0) {
+        tiot_print_err("[TIoT:fw]read img file size fail.\n");
+        return -1;
+    }
+    tiot_print_info("[TIoT:fw]img file size = %d\n", ext->file_len);
+    return 0;
+}
+
+static int32_t tiot_firmware_load_file(tiot_fw *fw, const tiot_file_path *file_path, const char *file_name)
+{
+    uint32_t version;
+    int32_t ret = -1;
+    tiot_fw_ext_version1 ext = { 0 };
+
+    /* 初始化时保证cfg_path不为null */
+    fw->fw_file = tiot_file_open(file_path, file_name, OSAL_O_RDONLY, 0);
+    if (fw->fw_file == NULL) {
+        tiot_print_err("open file %s fail\n", file_name);
+        return ret;
+    }
+    /* 读取镜像格式版本号 */
+    fw->cur_offset = 0;  /* 从偏移量为0开始读取镜像格式版本号 */
+    if (firmware_read_u32(fw, &version) != 0) {
+        goto file_close;
+    }
+    tiot_print_info("[TIoT:fw]cfg img version: 0x%x\n", version);
+    if (version == TIOT_FW_EXT_VERSION1) { /* 存在拓展区 */
+        if (firmware_load_ext_version1(fw, &ext) != 0) {
+            goto file_close;
+        }
+#ifdef CONFIG_FILE_BY_ARRAY
+        fw->fw_file->len = ext.file_len;
+#else
+        tiot_print_warning("[TIoT:fw]non file-array should not use ext version1.\n");
+#endif
+    }
+    // 读取发送命令
+    ret = tiot_firmware_load_cmds(fw);
+file_close:
+    tiot_file_close(fw->fw_file);
+    fw->fw_file = NULL;
+    return ret;
+}
+
+int32_t tiot_firmware_load(tiot_fw *fw, const tiot_file_path *file_path, const char *file_name)
+{
+    if (fw == NULL || file_name == NULL) {
+        tiot_print_dbg("[TIoT][fw]fw object or file_name is NULL.\n");
+        return -1;
+    }
+    if (fw->ops->pre_cmd_execute != NULL) {
+        tiot_print_info("[TIoT][fw]Pre command execute\n");
+        fw->ops->pre_cmd_execute(fw);
+    }
+    /* 执行cfg镜像内命令 */
+    if (tiot_firmware_load_file(fw, file_path, file_name) != 0) {
+        tiot_print_err("[TIoT][fw]command execute err!\n");
+        return -1;
+    }
+    if (fw->ops->after_cmd_execute != NULL) {
+        tiot_print_info("[TIoT][fw]After command execute\n");
+        fw->ops->after_cmd_execute(fw);
+    }
+    return 0;
+}
+
+int32_t tiot_firmware_customize_value_get(tiot_fw *fw, uint32_t *cus_data)
+{
+    tiot_dev_customize *cus_ptr;
+
+    tiot_controller *ctrl = tiot_container_of(fw, tiot_controller, firmware);
+    if (ctrl->dev_cus == 0) {
+        tiot_print_err("[TIoT:fw]customize dev_cus is NULL.\r\n");
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+
+    cus_ptr = (tiot_dev_customize *)ctrl->dev_cus;
+    if (cus_ptr->curr_data > cus_ptr->end_data) {
+        tiot_print_err("[TIoT:fw] firmware customize get overflow.\r\n");
+        return TIOT_FW_LOAD_RET_ERR;
+    }
+
+    *cus_data = *(uint32_t *)(cus_ptr->curr_data);
+    cus_ptr->curr_data += cus_ptr->unit_data_len;
+    return TIOT_FW_LOAD_RET_OK;
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware.h b/code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware.h
new file mode 100644 (file)
index 0000000..37d184d
--- /dev/null
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT firmware load module. \n
+ *
+ * History: \n
+ * 2023-12-05, Create file. \n
+ */
+#ifndef TIOT_FIRMWARE_H
+#define TIOT_FIRMWARE_H
+
+#include "tiot_types.h"
+#include "tiot_board.h"
+#include "tiot_fileops.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_firmware_load Firmware Load
+ * @ingroup  tiot_common
+ * @{
+ */
+
+#ifdef CONFIG_FILE_BY_ARRAY
+#define TIOT_FW_FILE_ARRAY_CFG_NAME   "cfg"
+#endif
+
+typedef enum {
+    TIOT_FW_LOAD_RET_ERR = -1,
+    TIOT_FW_LOAD_RET_OK = 0,
+    TIOT_FW_LOAD_RET_RETRY = 1,
+    TIOT_FW_LOAD_RET_QUIT = 2,
+} tiot_fw_ret;
+
+/*
+    固件文件格式:
+        | Version | Extended Info | Command1 | Command2 | ... | CommandN |
+        |---------|---------------|----------|----------|-----|----------|
+        | 4bytes  |      --       |     -    |     -    |     |     -    |
+    单条命令格式:
+        | ext_cmd | cmd_len |  cmd   |
+        |---------|---------|--------|
+        |       2bytes      | Nbytes |
+        | [12:15] | [0:11]  |        |
+*/
+
+/**
+ * @brief  TIoT firmware extended infos.
+ */
+typedef struct {
+    uint32_t file_len; /*!< img file size */
+} tiot_fw_ext_version1;
+
+struct _tiot_fw;
+
+/**
+ * @brief  TIoT firmware command execute callbacks.
+ */
+typedef struct {
+    void (* pre_cmd_execute)(struct _tiot_fw *fw);   /*!< Before command execute. */
+    void (* after_cmd_execute)(struct _tiot_fw *fw); /*!< After command execute. */
+     /*!< After single command execute. */
+    int32_t (* ext_cmd_handle)(struct _tiot_fw *fw, uint16_t ext_cmd, const uint8_t *cmd, uint16_t cmd_len);
+    /*!< Before single command execute. */
+    int32_t (* pre_ext_cmd_handle)(struct _tiot_fw *fw, uint16_t ext_cmd, uint8_t *cmd, uint16_t *cmd_len);
+} tiot_fw_ops;
+
+/**
+ * @brief  TIoT firmware object.
+ */
+typedef struct _tiot_fw {
+    const tiot_fw_ops *ops;        /*!< Firmware ops. */
+    tiot_file *fw_file;            /*!< Firmware file pointer. */
+    uint32_t cur_offset;           /*!< Firmware file offset. */
+} tiot_fw;
+
+/**
+ * @brief  TIoT firmware object init.
+ * @param  [in]  fw           TIoT firmware object.
+ * @param  [in]  ops     Firmware command execute callbacks.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_firmware_init(tiot_fw *fw, const tiot_fw_ops *ops);
+
+/**
+ * @brief  TIoT firmware start load process.
+ * @param  [in]  fw TIoT firmware object.
+ * @param  [in]  file_path TIoT firmware load file path.
+ * @param  [in]  file_name TIoT firmware load file name.
+ * @param  [in/out] fw_cmd_info TIoT firmware load command info.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_firmware_load(tiot_fw *fw, const tiot_file_path *file_path, const char *file_name);
+
+
+/**
+ * @brief  TIoT firmware obtaining customized parameters.
+ * @param  [in]  fw TIoT firmware object.
+ * @param  [out] cus_data customized parameter.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_firmware_customize_value_get(tiot_fw *fw, uint32_t *cus_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware_utils.h b/code/sdk/zhihui/gnss/driver/common/fw_load/tiot_firmware_utils.h
new file mode 100644 (file)
index 0000000..a4b7e0f
--- /dev/null
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT firmware load module utils. \n
+ *
+ * History: \n
+ * 2023-12-05, Create file. \n
+ */
+#ifndef TIOT_FIRMWARE_UTILS_H
+#define TIOT_FIRMWARE_UTILS_H
+
+#include "tiot_firmware.h"
+#include "tiot_controller.h"
+#include "tiot_xfer.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_firmware_utils Firmware Utils
+ * @ingroup  tiot_common_firmware
+ * @{
+ */
+
+static inline int32_t tiot_firmware_write(tiot_fw *fw, const uint8_t *data, uint32_t len)
+{
+    tiot_controller *controller = tiot_container_of(fw, tiot_controller, firmware);
+    return tiot_xfer_send(&controller->transfer, data, len, NULL);
+}
+
+static inline int32_t tiot_firmware_read_timeout(tiot_fw *fw, uint8_t *data, uint32_t len, uint32_t timeout_ms)
+{
+    tiot_xfer_rx_param rx_param = { 0 };
+    tiot_controller *controller = tiot_container_of(fw, tiot_controller, firmware);
+    rx_param.timeout = timeout_ms;
+    rx_param.subsys  = 0;
+    return tiot_xfer_recv(&controller->transfer, data, len, &rx_param);
+}
+
+static inline int32_t tiot_firmware_read(tiot_fw *fw, uint8_t *data, uint32_t len)
+{
+    return tiot_firmware_read_timeout(fw, data, len, TIOT_XFER_RECV_WAIT_FOREVER);
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/interface/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fc47d89
--- /dev/null
@@ -0,0 +1,20 @@
+#===============================================================================\r
+# @brief    cmake make file\r
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+#===============================================================================\r
+set(\r
+    tiot_interface_src_list\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/board_interface/board_internal/tiot_board_xmit_ops.c\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/device_interface/tiot_service_interface.c\r
+)\r
+\r
+set(\r
+    interface_header_lists\r
+    "${CMAKE_CURRENT_SOURCE_DIR}/board_interface/board_internal"\r
+    "${CMAKE_CURRENT_SOURCE_DIR}/board_interface/board_porting"\r
+    "${CMAKE_CURRENT_SOURCE_DIR}/board_interface/osal_porting"\r
+    "${CMAKE_CURRENT_SOURCE_DIR}/device_interface"\r
+)\r
+\r
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${interface_header_lists}" CACHE INTERNAL "tiot header list" FORCE)\r
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_interface_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board.h
new file mode 100644 (file)
index 0000000..cae119b
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-07-04, Create file. \n
+ */
+#ifndef TIOT_BOARD_H
+#define TIOT_BOARD_H
+
+#include "tiot_types.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_interface_board_internal_base Board
+ * @ingroup  tiot_common_interface_board_internal
+ * @{
+ */
+
+/**
+ * @brief  TIoT common board pins.
+ */
+typedef enum {
+    TIOT_PIN_POWER_CTRL,
+    TIOT_PIN_HOST_WAKEUP_DEVICE,
+    TIOT_PIN_DEVICE_WAKEUP_HOST,
+    TIOT_PIN_MAX
+} tiot_board_pin;
+
+/**
+ * @brief  Board hardware infomations.
+ */
+typedef struct {
+    uintptr_t xmit_id;         /*!< Transmit(UART/I2C/SPI/...) port index. */
+    const uint32_t *pm_info;   /*!< Power manager related infomations. */
+} tiot_board_hw_info;
+
+/**
+ * @brief  Board infomations, includes hardware infos and firmware info.
+ */
+typedef struct {
+    tiot_board_hw_info hw_info;       /*!< Power manager related infomations. */
+} tiot_board_info;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_log.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_log.h
new file mode 100644 (file)
index 0000000..9de1f1f
--- /dev/null
@@ -0,0 +1,81 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board log header. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-24, Create file. \n\r
+ */\r
+#ifndef TIOT_BOARD_LOG_H\r
+#define TIOT_BOARD_LOG_H\r
+\r
+#include "tiot_board_log_port.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_interface_board_internal_log Board Log\r
+ * @ingroup  tiot_common_interface_board_internal\r
+ * @{\r
+ */\r
+\r
+#define TIOT_LOG_ALERT    0   /*!< Log level alert. */\r
+#define TIOT_LOG_ERR      1   /*!< Log level error. */\r
+#define TIOT_LOG_WARNING  2   /*!< Log level warning. */\r
+#define TIOT_LOG_INFO     3   /*!< Log level info. */\r
+#define TIOT_LOG_DEBUG    4   /*!< Log level debug. */\r
+\r
+#ifndef TIOT_BOARD_LOG_LEVEL\r
+#define TIOT_BOARD_LOG_LEVEL  TIOT_LOG_INFO\r
+#endif\r
+\r
+/* 宏定义 */\r
+#if TIOT_BOARD_LOG_LEVEL >= TIOT_LOG_DEBUG\r
+#define TIOT_PRINT_FUNCTION_NAME    BOARD_PRINT_FUNCTION_NAME\r
+#define tiot_print_dbg(s, ...)  board_print_dbg(s, ##__VA_ARGS__)\r
+#else\r
+#define TIOT_PRINT_FUNCTION_NAME\r
+#define tiot_print_dbg(s, ...)\r
+#endif\r
+\r
+#if TIOT_BOARD_LOG_LEVEL >= TIOT_LOG_INFO\r
+#define tiot_print_info(s, ...)  board_print_info(s, ##__VA_ARGS__)\r
+#define tiot_print_suc(s, ...)   board_print_suc(s, ##__VA_ARGS__)\r
+#else\r
+#define tiot_print_info(s, ...)\r
+#define tiot_print_suc(s, ...)\r
+#endif\r
+\r
+#if TIOT_BOARD_LOG_LEVEL >= TIOT_LOG_WARNING\r
+#define tiot_print_warning(s, ...)  board_print_warning(s, ##__VA_ARGS__)\r
+#else\r
+#define tiot_print_warning(s, ...)\r
+#endif\r
+\r
+#if TIOT_BOARD_LOG_LEVEL >= TIOT_LOG_ERR\r
+#define tiot_print_err(s, ...)      board_print_err(s, ##__VA_ARGS__)\r
+#else\r
+#define tiot_print_err(s, ...)\r
+#endif\r
+\r
+#if TIOT_BOARD_LOG_LEVEL >= TIOT_LOG_ALERT\r
+#define tiot_print_alert(s, ...)      board_print_alter(s, ##__VA_ARGS__)\r
+#else\r
+#define tiot_print_alert(s, ...)\r
+#endif\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit.h
new file mode 100644 (file)
index 0000000..6a23acb
--- /dev/null
@@ -0,0 +1,64 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board transmit io common header. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-25, Create file. \n\r
+ */\r
+#ifndef TIOT_BOARD_XMIT_H\r
+#define TIOT_BOARD_XMIT_H\r
+\r
+#include "tiot_types.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_interface_board_internal_xmit Board Transmit\r
+ * @ingroup  tiot_common_interface_board_internal\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief  Transmit handle, compatible for board transmit handle.\r
+ */\r
+typedef void *tiot_xmit_handle;\r
+\r
+/**\r
+ * @brief  Universal transmit config, compatible for all types of transmit io.\r
+ */\r
+struct tiot_xmit_config;\r
+\r
+/**\r
+ * @brief  Transmit object.\r
+ */\r
+typedef struct {\r
+    uintptr_t id;               /*!< Transmit io id.\r
+                                     If board io operations use index, set this id in port open interface. */\r
+    tiot_xmit_handle handle;    /*!< Transmit handle compatible for board io handle.\r
+                                     If board io operations use handle, set this handle in port open interface. */\r
+} tiot_xmit;\r
+\r
+/**\r
+ * @brief  Transmit callbacks, registed in port open interface.\r
+ */\r
+typedef struct {\r
+    /*!< Rx data receive notify callback when use asynchronous board interface to read data. */\r
+    void (*rx_notify)(tiot_xmit *xmit, uint8_t *data, uint32_t len);\r
+} tiot_xmit_callbacks;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit_ops.c b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit_ops.c
new file mode 100644 (file)
index 0000000..32741b1
--- /dev/null
@@ -0,0 +1,62 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board Transmit select. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-27, Create file. \n\r
+ */\r
+#include "tiot_board_xmit_ops.h"\r
+\r
+const tiot_xmit_ops g_tiot_xmit_ops_map[TIOT_XMIT_TYPE_BUTT] = {\r
+#ifdef CONFIG_XMIT_WITH_UART\r
+    {\r
+        .open = tiot_board_uart_open,\r
+        .close = tiot_board_uart_close,\r
+        .write = tiot_board_uart_write,\r
+        .read = tiot_board_uart_read,\r
+        .set_config = tiot_board_uart_set_config,\r
+#ifdef CONFIG_UART_RX_MODE_BUFFED\r
+        .rx_mode = TIOT_XMIT_RX_MODE_BUFFED,\r
+#else\r
+        .rx_mode = TIOT_XMIT_RX_MODE_POLL,\r
+#endif\r
+    },\r
+#endif\r
+#ifdef CONFIG_XMIT_WITH_SPI\r
+    {\r
+        .open = tiot_board_spi_open,\r
+        .close = tiot_board_spi_close,\r
+        .write = tiot_board_spi_write,\r
+        .read = tiot_board_spi_read,\r
+        .set_config = tiot_board_spi_set_config,\r
+#ifdef CONFIG_SPI_RX_MODE_BUFFED\r
+        .rx_mode = TIOT_XMIT_RX_MODE_BUFFED,\r
+#else\r
+        .rx_mode = TIOT_XMIT_RX_MODE_POLL,\r
+#endif\r
+    },\r
+#endif\r
+#ifdef CONFIG_XMIT_WITH_I2C\r
+    {\r
+        .open = tiot_board_i2c_open,\r
+        .close = tiot_board_i2c_close,\r
+        .write = tiot_board_i2c_write,\r
+        .read = tiot_board_i2c_read,\r
+        .set_config = tiot_board_i2c_set_config,\r
+#ifdef CONFIG_I2C_RX_MODE_BUFFED\r
+        .rx_mode = TIOT_XMIT_RX_MODE_BUFFED,\r
+#else\r
+        .rx_mode = TIOT_XMIT_RX_MODE_POLL,\r
+#endif\r
+    },\r
+#endif\r
+};\r
+\r
+const tiot_xmit_ops *tiot_xmit_get_ops(tiot_xmit_type type)\r
+{\r
+    if (type >= TIOT_XMIT_TYPE_BUTT) {\r
+        return NULL;\r
+    }\r
+    return &g_tiot_xmit_ops_map[type];\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit_ops.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_internal/tiot_board_xmit_ops.h
new file mode 100644 (file)
index 0000000..fa8bca9
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: Board transmit io common ops. \n
+ *
+ * History: \n
+ * 2023-06-13, Create file. \n
+ */
+#ifndef TIOT_BOARD_XMIT_OPS_H
+#define TIOT_BOARD_XMIT_OPS_H
+
+#include "tiot_board_xmit.h"
+#ifdef CONFIG_XMIT_WITH_UART
+#include "tiot_board_uart_port.h"
+#endif
+#ifdef CONFIG_XMIT_WITH_SPI
+#include "tiot_board_spi_port.h"
+#endif
+#ifdef CONFIG_XMIT_WITH_I2C
+#include "tiot_board_i2c_port.h"
+#endif
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_interface_board_internal_xmit Board Transmit Ops
+ * @ingroup  tiot_common_interface_board_internal
+ * @{
+ */
+
+/**
+ * @brief  TIoT support transmit type.
+ */
+typedef enum {
+#ifdef CONFIG_XMIT_WITH_UART
+    TIOT_XMIT_TYPE_UART,
+#endif
+#ifdef CONFIG_XMIT_WITH_SPI
+    TIOT_XMIT_TYPE_SPI,
+#endif
+#ifdef CONFIG_XMIT_WITH_I2C
+    TIOT_XMIT_TYPE_I2C,
+#endif
+    TIOT_XMIT_TYPE_BUTT
+} tiot_xmit_type;
+
+/**
+ * @brief  TIoT Transmit rx mode.
+ */
+typedef enum {
+    TIOT_XMIT_RX_MODE_BUFFED,  /* TIoT Transmit rx mode with circular buffer. */
+    TIOT_XMIT_RX_MODE_POLL,    /* TIoT Transmit rx mode without buffer, read data direct from io. */
+} tiot_xmit_rx_mode;
+
+/**
+ * @brief  Transmit operations.
+ */
+typedef struct {
+    int32_t (*open)(tiot_xmit *xmit, tiot_xmit_callbacks *cbs);                 /*!< Port open interface. */
+    void (*close)(tiot_xmit *xmit);                                             /*!< Port close interface. */
+    int32_t (*write)(tiot_xmit *xmit, const uint8_t *buff, uint32_t len);       /*!< Port write interface. */
+    int32_t (*read)(tiot_xmit *xmit, uint8_t *buff, uint32_t len);              /*!< Port read interface. */
+    int32_t (*set_config)(tiot_xmit *xmit, struct tiot_xmit_config *config);    /*!< Port config interface. */
+    const uint16_t rx_mode;
+} tiot_xmit_ops;
+
+/**
+ * @brief  Get selected transmit operations.
+ * @return const tiot_xmit_ops* Selected transmit operations.
+ */
+const tiot_xmit_ops *tiot_xmit_get_ops(tiot_xmit_type type);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/gnss_board_port.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/gnss_board_port.h
new file mode 100644 (file)
index 0000000..3667f94
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: GNSS board port head. \n
+ *
+ * History: \n
+ * 2023-06-13, Create file. \n
+ */
+#ifndef GNSS_BOARD_PORT_H
+#define GNSS_BOARD_PORT_H
+
+#include "tiot_types.h"
+#include "tiot_board_pin_port.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_device_gnss_board_port  GNSS Board Port
+ * @ingroup  tiot_device_gnss
+ * @{
+ */
+
+/**
+ * @brief  GNSS pm pins.
+ */
+typedef enum {
+    GNSS_PIN_POWER_CTRL,            /*!< GNSS power control pin. */
+    GNSS_PIN_HOST_WAKEUP_DEVICE,    /*!< GNSS host wakeup device pin. */
+    GNSS_PIN_DEVICE_WAKEUP_HOST,    /*!< GNSS device wakeup host pin. */
+    GNSS_PIN_NUM,                   /*!< GNSS pin max. */
+    GNSS_PIN_NONE = TIOT_PIN_NONE   /*!< GNSS pin none. */
+} gnss_pm_pins;
+
+/**
+ * @brief  GNSS board hardware info.
+ */
+typedef struct {
+    uintptr_t xmit_id;
+    uint32_t pm_info[GNSS_PIN_NUM];
+} gnss_board_hw_info;
+
+/**
+ * @brief  GNSS board info.
+ */
+typedef struct {
+    const char *cfg_path;            /*!< cfg file path, NULL for file array. */
+    gnss_board_hw_info *hw_infos;    /*!< Pointer to array of GNSS hardware infos. */
+} gnss_board_info;
+
+/**
+ * @brief  Board provides resource informations, including pin indexs, ids, file paths, etc.
+ * @return Provided resource information.
+ */
+const gnss_board_info *gnss_board_get_info(void);
+
+/**
+ * @brief  Board porting init, request board resources, including hardware io, interrupt,etc.
+ * @param  param user customsize parameters, like device num.
+ * @return zero if OK;
+ *         non-zero if FAIL.
+ */
+int32_t gnss_board_init(void *param);
+
+/**
+ * @brief  Board porting deinit, release board resources, including hardware io, interrupt,etc.
+ * @param  param user customsize parameters, like device num.
+ */
+void gnss_board_deinit(void *param);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_misc_port.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_misc_port.h
new file mode 100644 (file)
index 0000000..55f976c
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: Board misc porting header. \n
+ *
+ * History: \n
+ * 2023-03-24, Create file. \n
+ */
+#ifndef TIOT_BOARD_MISC_PORT_H
+#define TIOT_BOARD_MISC_PORT_H
+
+#include "tiot_types.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_interface_board_porting_misc Board Misc Port
+ * @ingroup  tiot_common_interface_board_porting
+ * @{
+ */
+
+/**
+ * @if Eng
+ * @brief Board wake lock struct.
+ * @else
+ * @brief 板级唤醒锁结构体。
+ * @endif
+ */
+typedef struct {
+    void *lock;
+} tiot_board_wakelock;
+
+/**
+ * @if Eng
+ * @brief Board wake lock initialization interface.
+ * @param  [out] lock wake lock to be initialized.
+ * @return if OK return 0, else return -1.
+ * @note if board has no sleep or just enter wfi, implement as empty function.
+ * @else
+ * @brief 板级唤醒锁初始化接口。
+ * @param  [out] lock 待初始化的唤醒锁。
+ * @return 初始化成功返回0,否则返回-1。
+ * @note 如果板级不睡眠或仅进入wfi,实现为空函数即可。
+ * @endif
+ */
+int32_t tiot_board_wake_lock_init(tiot_board_wakelock *lock);
+
+/**
+ * @if Eng
+ * @brief Board wake lock interface.
+ * @param  [in] lock wake lock to be locked.
+ * @note if board has no sleep or just enter wfi, implement as empty function.
+ * @else
+ * @brief 板级唤醒锁接口。
+ * @param  [in] lock 待上锁的唤醒锁。
+ * @note 如果板级不睡眠或仅进入wfi,实现为空函数即可。
+ * @endif
+ */
+void tiot_board_wake_lock(tiot_board_wakelock *lock);
+
+/**
+ * @if Eng
+ * @brief Board wake unlock interface.
+ * @param  [in]  lock wake lock to be unlocked.
+ * @note if board has no sleep or just enter wfi, implement as empty function.
+ * @else
+ * @brief 板级唤醒解锁接口。
+ * @param  [in]  lock 待解锁的唤醒锁。
+ * @note 如果板级不睡眠或仅进入wfi,实现为空函数即可。
+ * @endif
+ */
+void tiot_board_wake_unlock(tiot_board_wakelock *lock);
+
+/**
+ * @if Eng
+ * @brief Board wake lock destroy interface.
+ * @param  [in]  lock wake lock to be destroyed.
+ * @note if board has no sleep or just enter wfi, implement as empty function.
+ * @else
+ * @brief 板级唤醒锁销毁接口。
+ * @param  [in]  lock 待销毁的唤醒锁.
+ * @note 如果板级不睡眠或仅进入wfi,实现为空函数即可。
+ * @endif
+ */
+void tiot_board_wake_lock_destroy(tiot_board_wakelock *lock);
+
+/**
+ * @if Eng
+ * @brief  Board μs level delay.
+ * @param  [in]  us μs count.
+ * @else
+ * @brief  板级微秒级delay接口。
+ * @param  [in]  us 微秒。
+ * @endif
+ */
+void tiot_board_udelay(uint32_t us);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_pin_port.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_pin_port.h
new file mode 100644 (file)
index 0000000..e2a88b2
--- /dev/null
@@ -0,0 +1,100 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board pin porting header. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-24, Create file. \n\r
+ */\r
+#ifndef TIOT_BOARD_PIN_PORT_H\r
+#define TIOT_BOARD_PIN_PORT_H\r
+\r
+#include "tiot_types.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_interface_board_porting_pin Board Pin Port\r
+ * @ingroup  tiot_common_interface_board_porting\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief  Pin none, board port should use this macro if pin is not connected.\r
+ */\r
+#define TIOT_PIN_NONE        0xFFFFFFFFU\r
+#define TIOT_PIN_UART_WAKEUP_NUM    0x80000000U    /* 用于uart rx唤醒. */\r
+\r
+/**\r
+ * @brief  Pin level enum.\r
+ */\r
+typedef enum {\r
+    TIOT_PIN_LEVEL_LOW,     /*!< 0: Pin level low. */\r
+    TIOT_PIN_LEVEL_HIGH     /*!< 1: Pin level high. */\r
+} tiot_pin_level;\r
+\r
+/**\r
+ * @brief  Pin interrupt enable enum.\r
+ */\r
+typedef enum {\r
+    TIOT_PIN_INT_DISABLE,   /*!< 0: Pin interrupt disable. */\r
+    TIOT_PIN_INT_ENABLE     /*!< 1: Pin interrupt enable. */\r
+} tiot_pin_int_enable;\r
+\r
+/**\r
+ * @brief  Pin interrupt callback type, need input corresponding pin.\r
+ */\r
+typedef void (* tiot_pin_int_callback)(uint32_t pin);\r
+\r
+/**\r
+ * @brief  Board set pin level interface.\r
+ * @param  [in] pin   Pin id.\r
+ * @param  [in] level Pin level, see @ref tiot_pin_level.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_set_level(uint32_t pin, uint8_t level);\r
+\r
+/**\r
+ * @brief  Board get current pin level interface.\r
+ * @param  [in]  pin   Pin id.\r
+ * @param  [out] level Current pin level, see @ref tiot_pin_level.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_get_level(uint32_t pin, uint8_t *level);\r
+\r
+/**\r
+ * @brief  Board pin interrupt enable interface.\r
+ * @param  [in] pin         Pin id.\r
+ * @param  [in] int_enable  Interrupt enable or disable, see @ref tiot_pin_int_enable.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_enable_int(uint32_t pin, uint8_t int_enable);\r
+\r
+/**\r
+ * @brief  Board pin interrupt callback register interface.\r
+ * @note   Porting should ensure this callback is called when enters pin irq if interrupt enabled.\r
+ * @param  [in] pin     Pin id.\r
+ * @param  [in] int_cb  Registed interrupt callback, see @ref tiot_pin_int_callback.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_register_int_callback(uint32_t pin, tiot_pin_int_callback int_cb);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_uart_port.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/board_porting/tiot_board_uart_port.h
new file mode 100644 (file)
index 0000000..406cb48
--- /dev/null
@@ -0,0 +1,122 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board UART porting header. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-24, Create file. \n\r
+ */\r
+#ifndef TIOT_BOARD_UART_PORT_H\r
+#define TIOT_BOARD_UART_PORT_H\r
+\r
+#include "tiot_board_xmit.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_interface_board_porting_uart Board UART Port\r
+ * @ingroup  tiot_common_interface_board_porting\r
+ * @{\r
+ */\r
+\r
+#define TIOT_UART_ATTR_DATABIT_8    0 /*!< UART word length is 8 data bits per frame. */\r
+#define TIOT_UART_ATTR_DATABIT_7    1 /*!< UART word length is 7 data bits per frame. */\r
+#define TIOT_UART_ATTR_DATABIT_6    2 /*!< UART word length is 6 data bits per frame. */\r
+#define TIOT_UART_ATTR_DATABIT_5    3 /*!< UART word length is 5 data bits per frame. */\r
+#define TIOT_UART_ATTR_DATABIT_BUTT 4 /*!< UART word length butt. */\r
+\r
+#define TIOT_UART_ATTR_PARITY_NONE  0 /*!< no UART parity bit. */\r
+#define TIOT_UART_ATTR_PARITY_ODD   1 /*!< odd UART parity bit. */\r
+#define TIOT_UART_ATTR_PARITY_EVEN  2 /*!< even UART parity bit. */\r
+#define TIOT_UART_ATTR_PARITY_MARK  3 /*!< UART parity bit is always 1. */\r
+#define TIOT_UART_ATTR_PARITY_SPACE 4 /*!< UART parity bit is always 0. */\r
+#define TIOT_UART_ATTR_PARITY_BUTT  5 /*!< UART parity bit butt. */\r
+\r
+#define TIOT_UART_ATTR_STOPBIT_1    0 /*!< UART has 1 stop bit. */\r
+#define TIOT_UART_ATTR_STOPBIT_1P5  1 /*!< UART has 1.5 stop bits. */\r
+#define TIOT_UART_ATTR_STOPBIT_2    2 /*!< UART has 2 stop bits. */\r
+#define TIOT_UART_ATTR_STOPBIT_BUTT 3 /*!< UART stop bits butt. */\r
+\r
+#define TIOT_UART_ATTR_FLOW_CTRL_DISABLE  0 /*!< UART flow control is disabled. */\r
+#define TIOT_UART_ATTR_FLOW_CTRL_ENABLE   1 /*!< UART flow control enabled. */\r
+\r
+/**\r
+ * @brief Uart attribute.\r
+ *\r
+ */\r
+typedef struct {\r
+    uint16_t data_bits : 4;\r
+    uint16_t parity    : 4;\r
+    uint16_t stop_bits : 4;\r
+    uint16_t flow_ctrl : 4;\r
+    uint16_t reserved  : 16;\r
+} tiot_uart_attr;\r
+\r
+/**\r
+ * @brief Uart config.\r
+ *\r
+ */\r
+typedef struct tiot_xmit_config {\r
+    uint32_t baudrate;   /*!< UART baudrate. */\r
+    tiot_uart_attr attr; /*!< UART attribute. */\r
+} tiot_uart_config;\r
+\r
+/**\r
+ * @brief  Board UART open interface.\r
+ * @param  [in]  xmit Transmit object.\r
+ * @param  [in]  cb   Transmit callbacks.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_uart_open(tiot_xmit *xmit, tiot_xmit_callbacks *cb);\r
+\r
+/**\r
+ * @brief  Board UART close interface.\r
+ * @param  [in]  xmit Transmit object.\r
+ */\r
+void    tiot_board_uart_close(tiot_xmit *xmit);\r
+\r
+/**\r
+ * @brief  Board UART write interface.\r
+ * @param  [in] xmit Transmit object.\r
+ * @param  [in] buff Data buff.\r
+ * @param  [in] len  Data length.\r
+ * @return zero or postive for writen OK length;\r
+ *         negtive if write FAIL.\r
+ */\r
+int32_t tiot_board_uart_write(tiot_xmit *xmit, const uint8_t *buff, uint32_t len);\r
+\r
+/**\r
+ * @brief  Board UART blocking read interface.\r
+ * @param  [in] xmit Transmit object.\r
+ * @param  [in] buff Read buff.\r
+ * @param  [in] len  Expected read length.\r
+ * @return zero or postive for read OK length;\r
+ *         negtive if read FAIL or cannot implemented.\r
+ */\r
+int32_t tiot_board_uart_read(tiot_xmit *xmit, uint8_t *buff, uint32_t len);\r
+\r
+/**\r
+ * @brief  Board UART config interface.\r
+ * @param  [in] xmit   Transmit object.\r
+ * @param  [in] config UART config, see @ref tiot_uart_config.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_uart_set_config(tiot_xmit *xmit, tiot_uart_config *config);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/board_interface/osal_porting/tiot_osal.h b/code/sdk/zhihui/gnss/driver/common/interface/board_interface/osal_porting/tiot_osal.h
new file mode 100644 (file)
index 0000000..0a78cb1
--- /dev/null
@@ -0,0 +1,436 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT osal interface. \n
+ *
+ * History: \n
+ * 2023-05-31, Create file. \n
+ */
+#ifndef TIOT_OSAL_H
+#define TIOT_OSAL_H
+
+#ifdef CONFIG_OSAL_DEFINED
+#include "soc_osal.h"
+#else
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_interface_osal TIoT Osal Interface
+ * @ingroup  tiot_common_interface
+ * @{
+ */
+
+#define OSAL_SUCCESS 0
+#define OSAL_FAILURE (-1)
+#define OSAL_EOVERFLOW (-75)
+
+#define OSAL_WAIT_FOREVER 0xFFFFFFFF
+#define OSAL_WAIT_CONDITION_TRUE 1
+
+#define OSAL_GFP_ZERO (0x1)
+#define OSAL_GFP_ATOMIC (0x1 << 1)
+#define OSAL_GFP_DMA (0x1 << 2)
+#define OSAL_GFP_KERNEL (0x1 << 3)
+
+#define OSAL_O_RDONLY 00000000
+#define OSAL_O_WRONLY 00000001
+#define OSAL_O_RDWR 00000002
+#define OSAL_O_ACCMODE 00000003
+
+#define OSAL_O_CREAT 00000100
+#define OSAL_O_EXCL 00000200
+#define OSAL_O_TRUNC 00001000
+#define OSAL_O_APPEND 00002000
+#define OSAL_O_CLOEXEC 02000000
+
+#define OSAL_SEEK_SET 0
+#define OSAL_SEEK_CUR 1
+#define OSAL_SEEK_END 2
+
+/* Osal string. */
+#ifdef __KERNEL__
+#define osal_strtol(cp, endp, base)    simple_strtol(cp, endp, base)
+#else
+#define osal_strtol(cp, endp, base)    strtol(cp, endp, base)
+#endif
+
+typedef struct {
+    void *lock;
+} osal_spinlock;
+
+typedef struct {
+    void *mutex;
+} osal_mutex;
+
+typedef struct {
+    void *wait;
+} osal_wait;
+
+typedef struct {
+    void *task;
+} osal_task;
+
+typedef int (*osal_kthread_handler)(void *data);
+
+/* return value is a bool type */
+typedef int (*osal_wait_condition_func)(const void *param);
+
+/**
+ * @ingroup osal_timer
+ * @brief sleep waiting for signals.
+ *
+ * @par Description:
+ * sleep waiting for signals.
+ *
+ * @param msecs [in] Time in milliseconds to sleep for.
+ *
+ * @return Returns 0 when the timer has expired otherwise the remaining time in ms will be returned.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+unsigned long osal_msleep(unsigned int msecs);
+
+/**
+ * @ingroup osal_addr
+ * @brief Alloc dynamic memory.
+ *
+ * @par Description:
+ * This API is used to alloc a memory block of which the size is specified.
+ *
+ * @param size [in] How many bytes of memory are required.
+ * @param osal_gfp_flag [in] The type of memory to alloc. This parameter is not used in liteos and freertos.
+ * In linux, it must include one of the following access modes: OSAL_GFP_ATOMIC, OSAL_GFP_DMA, OSAL_GFP_KERNEL.
+ * OSAL_GFP_ZERO can be bitwise-or'd in flags, Then, the memory is set to zero.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+void *osal_kmalloc(unsigned long size, unsigned int osal_gfp_flag);
+
+/**
+ * @ingroup osal_addr
+ * @brief Free dynamic memory.
+ *
+ * @par Description:
+ * This API is used to free specified dynamic memory that has been allocd and update module mem used.
+ *
+ * @param addr [in] Starting address of the memory block to be freed.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+void osal_kfree(void *addr);
+
+/**
+ * @ingroup osal_spinlock
+ * @brief Initialize a spin lock.
+ *
+ * @par Description:
+ * This API is used to initialization of spin_lock.
+ *
+ * @param lock [out] the lock to be initialized.
+ *
+ * @attention
+ * must be free with osal_spin_lock_destroy, other wise will lead to memory leak;
+ *
+ * @return OSAL_SUCCESS/OSAL_FAILURE
+ *
+ * @par Support System:
+ * linux liteos.
+ */
+int osal_spin_lock_init(osal_spinlock *lock);
+
+/**
+ * @ingroup osal_spinlock
+ * @brief acquire the spin_lock.
+ *
+ * @par Description:
+ * Saves the current IRQ status of the CPU, obtains the specified spin_lock, and disables the interrupts of the CPU.
+ *
+ * @param lock [in] the lock to be acquired.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+void osal_spin_lock_irqsave(osal_spinlock *lock, unsigned long *flags);
+
+/**
+ * @ingroup osal_spinlock
+ * @brief release the spin_lock.
+ *
+ * @par Description:
+ * Releases the specified spin_lock and restores the interrupt status of the CPU, and enables the interrupts of the CPU.
+ *
+ * @param lock [in] the lock to be released.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+void osal_spin_unlock_irqrestore(osal_spinlock *lock, unsigned long *flags);
+
+/**
+ * @ingroup osal_spinlock
+ * @brief Destroy the spin_lock.
+ *
+ * @par Description:
+ * Destroy the spin_lock.
+ *
+ * @param lock [in] The lock to be destroyed.
+ *
+ * @attention
+ * must be called when kmod exit, other wise will lead to memory leak;
+ * this API will free memory, lock must be from osal_spin_lock_init returns
+ *
+ * @par Support System:
+ * linux liteos.
+ */
+void osal_spin_lock_destroy(osal_spinlock *lock);
+
+/**
+ * @ingroup osal_mutex
+ * @brief Initialize the mutex.
+ *
+ * @par Description:
+ * This API is used to initialize the mutex.
+ *
+ * @param mutex [in] the mutex to be initialized.
+ *
+ * @return OSAL_FAILURE/OSAL_SUCCESS
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+int osal_mutex_init(osal_mutex *mutex);
+
+/**
+ * @ingroup osal_mutex
+ * @brief Acquire the mutex.
+ *
+ * @par Description:
+ * Acquire the mutex. Lock the mutex exclusively for this task.
+ * If the mutex is not available right now, it will sleep until it can get it.
+ *
+ * @param mutex [in] the mutex to be initialized.
+ *
+ * @return OSAL_FAILURE/OSAL_SUCCESS
+ *
+ * @note
+ * The mutex must later on be released by the same task that acquired it. Recursive locking is not allowed.
+ * The task may not exit without first unlocking the mutex.
+ * Also, kernel memory where the mutex resides must not be freed with the mutex still locked.
+ * The mutex must first be initialized (or statically defined) before it can be locked.
+ * memset()-ing the mutex to 0 is not allowed.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ * @par System Differ: Only LiteOS supports the nested lock feature.
+ */
+int osal_mutex_lock(osal_mutex *mutex);
+
+/**
+ * @ingroup osal_mutex
+ * @brief Release the mutex.
+ *
+ * @par Description:
+ * Release the mutex. Unlock a mutex that has been locked by this task previously.
+ * This function must not be used in interrupt context. Unlocking of a not locked mutex is not allowed.
+ *
+ * @param mutex [in] the mutex to be released.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+void osal_mutex_unlock(osal_mutex *mutex);
+
+/**
+ * @ingroup osal_mutex
+ * @brief Destroy the mutex.
+ *
+ * @par Description:
+ * This API is used to destroy the mutex.
+ *
+ * @param mutex [in] The mutex to be destroyed.
+ *
+ * @attention
+ * must be called when kmod exit, otherwise will lead to memory leak; osal_mutex_destroy will free memory,
+ * caller should clear pointer to be NULL after called.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+void osal_mutex_destroy(osal_mutex *mutex);
+
+/**
+ * @ingroup osal_wait
+ * @brief Initialize a waiting queue.
+ *
+ * @par Description:
+ * This API is used to Initialize a waiting queue.
+ *
+ * @param wait [out] The wait queue to be initialized.
+ *
+ * @par Support System:
+ * linux liteos.
+ */
+int osal_wait_init(osal_wait *wait);
+
+/**
+ * @ingroup osal_wait
+ * @brief sleep until a condition gets true or a timeout elapses.
+ *
+ * @par Description:
+ * sleep until a condition gets true or a timeout elapses.
+ * The process is put to sleep (TASK_INTERRUPTIBLE) until the @func returned true or a signal is received.
+ * Return value of the @func is checked each time the waitqueue @wait is woken up.
+ *
+ * @param wait [in] the waitqueue to wait on.
+ * @param wait [in] a C expression for the event to wait for.
+ * @param wait [in] timeout, in ms.
+ *
+ * @par Support System:
+ * linux liteos.
+ */
+int osal_wait_timeout_interruptible(osal_wait *wait, osal_wait_condition_func func, const void *param,
+    unsigned long ms);
+
+/**
+ * @ingroup osal_wait
+ * @brief wake up threads blocked on a waitqueue.
+ *
+ * @par Description:
+ * Wake-up wait queue,pair to @wait_event_interruptible.
+ *
+ * @param wait [in] The wait to be wake up.
+ *
+ * @par Support System:
+ * linux liteos.
+ */
+void osal_wait_wakeup_interruptible(osal_wait *wait); // same as osal_wait_wakeup on liteos
+
+/**
+ * @ingroup osal_wait
+ * @brief to destroy the wait.
+ *
+ * @par Description:
+ * This API is used to destroy the wait.
+ *
+ * @param wait [in] The wait to be destroyed.
+ *
+ * @attention this api may free memory, wait should be from osal_complete_init.
+ * @par Support System:
+ * linux liteos.
+ */
+void osal_wait_destroy(osal_wait *wait);
+
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+/**
+ * @ingroup osal_task
+ *
+ * @brief Provides an interface for creating a thread and invokes kthread_run for creating a kernel thread.
+ *
+ * @par Description:
+ * Provides an interface for creating a thread and invokes kthread_run for creating a kernel thread.
+ *
+ * @param stack_size [in] Size of the stack space of the thread. 0 means default.
+ * @param handler [in] Functions to be processed by the thread
+ * @param data [in] Function handler data.
+ * @param name [in] Thread name displayed.
+ *
+ * @retval   osal_task*  If the thread is successfully created, the pointer of the thread is returned.
+ * @retval   NULL        If the thread fails to be created, NULL is returned.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+osal_task *osal_kthread_create(osal_kthread_handler handler, void *data, const char *name, unsigned int stack_size);
+
+/**
+ * @ingroup osal_task
+ *
+ * @brief Used to destroy the threads you created.
+ *
+ * @par Description:
+ * Stops a specified kernel thread.
+ *
+ * @attention osal_kthread_destroy will free memory of task, caller should clear pointer to be NULL.
+ * Note that if you want to destroy a thread, the thread cannot end before calling this function,
+ * Or something terrible will happen.
+ * When you call the Kthread_stop function, the thread function cannot be finished, otherwise it will oops.
+ * @task may be free in api, @task should be from osal_kthread_create.
+ *
+ * @param task  [in] Threads you want to destroy.
+ * @param stop_flag [in] Indicates whether the current thread exits. If the value of stop_flag is 0,
+ * The current thread does not exit. The stop flag is not 0.
+ *
+ * @par Support System:
+ * linux liteos freertos.
+ */
+void osal_kthread_destroy(osal_task *task, unsigned int stop_flag);
+#endif
+
+#ifndef CONFIG_FILE_BY_ARRAY
+/**
+ * @ingroup osal_fileops
+ * @brief open file and return file pointer.
+ * @param file [in] the filename of file
+ * @param flag [in] the opreation flag example: OSAL_O_CREAT
+ * @param mode [in] the mode example: OSAL_O_RDONLY
+ * @return void* / null
+ *
+ * @par Support System:
+ * linux liteos seliteos freertos.
+ */
+void *osal_klib_fopen(const char *file, int flags, int mode);
+
+/**
+ * @ingroup osal_fileops
+ * @brief close file.
+ * @param filp [in] the result of osal_klib_fopen
+ * @par Support System:
+ * linux liteos seliteos freertos.
+ */
+void osal_klib_fclose(void *filp);
+
+/**
+ * @ingroup osal_fileops
+ * @brief Kernel read function.
+ * @param buf [out] the buffer you want to read in
+ * @param size [in] the size of buffer
+ * @param filp [in] the result of osal_klib_fopen
+ * @return The length that has been read.
+ *
+ * @par Support System:
+ * linux liteos seliteos freertos.
+ */
+int osal_klib_fread(char *buf, unsigned long size, void *filp);
+
+/**
+ * @ingroup osal_fileops
+ * @brief Kernel file seek function.
+ * @param offset [in] the new position of file
+ * @param whence [in] the method of lseek,example:OSAL_SEEK_SET
+ * @param filp [in] the result of osal_klib_fopen
+ * @par Support System:
+ * linux liteos seliteos.
+ */
+int osal_klib_fseek(long long offset, int whence, void *filp);
+#endif
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif /* CONFIG_OSAL_DEFINED */
+
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface.c b/code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface.c
new file mode 100644 (file)
index 0000000..643b39a
--- /dev/null
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-10-28, Create file. \n
+ */
+
+#include "tiot_service_interface.h"
+#include "tiot_service_interface_ext.h"
+#include "tiot_controller.h"
+#include "tiot_pm_wakelock.h"
+#include "tiot_board_log.h"
+#ifdef CONFIG_DEV_GNSS
+#include "gnss_service.h"
+#endif
+#ifdef CONFIG_DEV_W33
+#include "w33_service.h"
+#endif
+#ifdef CONFIG_DEV_CAXX
+#include "caxx_service.h"
+#endif
+#ifdef CONFIG_DEV_BSXX
+#include "bsxx_service.h"
+#endif
+#ifdef CONFIG_DEV_TIOT_SLAVE
+#include "tiot_slave_service.h"
+#endif
+
+typedef struct {
+    int32_t (* init)(void);
+    void (* deinit)(void);
+} tiot_service_entry;
+
+typedef struct {
+    const char *name;
+    uint8_t dev_max;
+    uintptr_t (* get_ctrl)(uint8_t dev_id);
+} tiot_service_desc;
+
+static const tiot_service_entry tiot_service_list[] = {
+#ifdef CONFIG_DEV_GNSS
+    { gnss_service_init, gnss_service_deinit },
+#endif
+#ifdef CONFIG_DEV_W33
+    { w33_service_init, w33_service_deinit },
+#endif
+#ifdef CONFIG_DEV_CAXX
+    { caxx_service_init, caxx_service_deinit },
+#endif
+#ifdef CONFIG_DEV_BSXX
+    { bsxx_service_init, bsxx_service_deinit },
+#endif
+#ifdef CONFIG_DEV_TIOT_SLAVE
+    { tiot_slave_service_init, tiot_slave_service_deinit },
+#endif
+};
+
+static const tiot_service_desc tiot_service_desc_list[] = {
+#ifdef CONFIG_DEV_GNSS
+    { "gn71", CONFIG_GNSS_DEV_NUM, gnss_service_get_ctrl },
+    { "gnss01", CONFIG_GNSS_DEV_NUM, gnss_service_get_ctrl },
+#endif
+#ifdef CONFIG_DEV_W33
+    { "w33", CONFIG_W33_DEV_NUM, w33_service_get_ctrl },
+#endif
+#ifdef CONFIG_DEV_CAXX
+    { "ca01", CONFIG_CAXX_DEV_NUM, caxx_service_get_ctrl },
+#endif
+#ifdef CONFIG_DEV_BSXX
+    { "bs21", CONFIG_BSXX_DEV_NUM, bsxx_service_get_ctrl },
+    { "bs25", CONFIG_BSXX_DEV_NUM, bsxx_service_get_ctrl },
+#endif
+#ifdef CONFIG_DEV_TIOT_SLAVE
+    { "tiot_slave", CONFIG_TIOT_SLAVE_DEV_NUM, tiot_slave_service_get_ctrl },
+#endif
+};
+
+static const tiot_service_desc *tiot_service_get_description(const char *device_name, uint8_t *dev_id)
+{
+    uint32_t i;
+    uint32_t len = strlen(device_name);
+    uint32_t name_len = 0;
+    for (i = 0; i < (sizeof(tiot_service_desc_list) / sizeof(tiot_service_desc)); i++) {
+        name_len = strlen(tiot_service_desc_list[i].name);
+        /* devcie_name长度小于描述名时不可能匹配,避免memcmp对device_name访问溢出. */
+        if (len < name_len) {
+            continue;
+        }
+        if (memcmp(device_name, tiot_service_desc_list[i].name, name_len) == 0) {
+            break;
+        }
+    }
+    if (i == (sizeof(tiot_service_desc_list) / sizeof(tiot_service_desc))) {
+        tiot_print_err("[TIoT]invalid device_name string %s.\r\n", device_name);
+        return NULL;
+    }
+    /* device_name格式 */
+    /* "xxxx" 其中xxxx为对应device名字, dev_id默认为0 */
+    /* "xxxx,n" 其中n为单个数字字符,n < 10,dev_id设为n */
+    if (len > name_len) {
+        if (len - name_len != 2) { // n为单个字符,加上分隔符,长度固定为2
+            tiot_print_err("[TIoT]device_name length %d invalid.\r\n", len);
+            return NULL;
+        }
+        if (device_name[name_len] != ',') {
+            tiot_print_err("[TIoT]device_name seprator invalid %c.\r\n", device_name[name_len]);
+            return NULL;
+        }
+        if ((device_name[name_len + 1] < '0') || (device_name[name_len + 1] > '9')) {
+            tiot_print_err("[TIoT]dev id invalid %c.\r\n", device_name[name_len + 1]);
+            return NULL;
+        }
+        *dev_id = device_name[name_len + 1] - '0';
+    }
+    if (*dev_id >= tiot_service_desc_list[i].dev_max) {
+        tiot_print_err("[TIoT]device_name dev id exceed max %c.\r\n", device_name[name_len + 1]);
+        return NULL;
+    }
+    return &tiot_service_desc_list[i];
+}
+
+int32_t tiot_service_init(void)
+{
+    int32_t ret;
+    uint32_t i;
+    uint32_t j;
+    if (tiot_pm_wake_lock_init() != 0) {
+        return -1;
+    }
+    for (i = 0; i < (sizeof(tiot_service_list) / sizeof(tiot_service_entry)); i++) {
+        ret = tiot_service_list[i].init();
+        if (ret != 0) {
+            tiot_print_err("[TIoT]service init fail @%d\n", i);
+            goto fail;
+        }
+    }
+    return 0;
+fail:
+    for (j = 0; j < i; j++) {
+        tiot_service_list[j].deinit();
+    }
+    tiot_pm_wake_lock_destroy();
+    return ret;
+}
+
+void tiot_service_deinit(void)
+{
+    uint32_t i;
+    for (i = 0; i < (sizeof(tiot_service_list) / sizeof(tiot_service_entry)); i++) {
+        tiot_service_list[i].deinit();
+    }
+    tiot_pm_wake_lock_destroy();
+}
+
+tiot_handle tiot_service_open(const char *device_name, void *param)
+{
+    tiot_controller *ctrl = NULL;
+    uint8_t dev_id = 0;
+    const tiot_service_desc *desc;
+    if (device_name == NULL) {
+        tiot_print_err("[TIoT]device_name is NULL.\r\n");
+        return 0;
+    }
+    desc = tiot_service_get_description(device_name, &dev_id);
+    if (desc == NULL) {
+        return 0;
+    }
+    ctrl = (tiot_controller *)desc->get_ctrl(dev_id);
+    if (tiot_controller_open(ctrl, param) != 0) {
+        ctrl = NULL;
+    }
+    return (tiot_handle)ctrl;
+}
+
+void tiot_service_close(tiot_handle handle)
+{
+    tiot_controller *ctrl = (tiot_controller *)handle;
+    tiot_controller_close(ctrl);
+}
+
+int32_t tiot_service_write_ext(tiot_handle handle, const uint8_t *data,
+                               uint32_t len, const tiot_service_tx_param *param)
+{
+    tiot_controller *ctrl = (tiot_controller *)handle;
+    if ((data == NULL) || (len == 0)) {
+        tiot_print_dbg("[TIoT]send data invalid.\n");
+        return -1;
+    }
+    if (tiot_controller_check_opened(ctrl) != true) {
+        return -1;
+    }
+    return ctrl->ops.write(ctrl, data, len, (const tiot_xfer_tx_param *)param);
+}
+
+int32_t tiot_service_write(tiot_handle handle, const uint8_t *data, uint32_t len)
+{
+    /* 默认发送subsys为0的数据 */
+    const tiot_service_tx_param param = { 0 };
+    return tiot_service_write_ext(handle, data, len, &param);
+}
+
+int32_t tiot_service_read_ext(tiot_handle handle, uint8_t *buff, uint32_t buff_len, const tiot_service_rx_param *param)
+{
+    int32_t buff_invalid;
+    tiot_controller *ctrl = (tiot_controller *)handle;
+    if (param == NULL) {
+        tiot_print_dbg("[TIoT]rx param invalid.\n");
+        return -1;
+    }
+    buff_invalid = (buff == NULL) || (buff_len == 0);
+#ifdef __KERNEL__
+    /* 用作poll接口时,buff & buff_len可以为空. */
+    if (((param->filp == NULL) || (param->poll_wait == NULL)) && (buff_invalid != 0)) {
+#else
+    if (buff_invalid != 0) {
+#endif
+        tiot_print_dbg("[TIoT]read buff invalid.\n");
+        return -1;
+    }
+    if (tiot_controller_check_opened(ctrl) != true) {
+        return -1;
+    }
+    return ctrl->ops.read(ctrl, buff, buff_len, (const tiot_xfer_rx_param *)param);
+}
+
+int32_t tiot_service_read(tiot_handle handle, uint8_t *buff, uint32_t buff_len, uint32_t timeout_ms)
+{
+    /* 默认接收queueID为0的数据 */
+    /* tiot_service_rx_para结构体有kernel编译宏区分, 不能列表初始化, 否则参数未知. */
+    tiot_service_rx_param param = { 0 };
+    param.timeout_ms = timeout_ms;
+    return tiot_service_read_ext(handle, buff, buff_len, &param);
+}
+
+int32_t tiot_service_pm_ctrl(tiot_handle handle, tiot_service_pm_ctrl_cmd cmd)
+{
+    tiot_controller *ctrl = (tiot_controller *)handle;
+    if (tiot_controller_check_opened(ctrl) != true) {
+        return -1;
+    }
+    if (ctrl->ops.pm_ctrl == NULL) {
+        tiot_print_err("[TIoT]not support pm_ctrl.\n");
+        return -1;
+    }
+    return ctrl->ops.pm_ctrl(ctrl, (uint8_t)cmd);
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface.h b/code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface.h
new file mode 100644 (file)
index 0000000..506a0f5
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-10-24, Create file. \n
+ */
+#ifndef TIOT_SERVICE_INTERFACE_H
+#define TIOT_SERVICE_INTERFACE_H
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/poll.h>
+#else
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_interface_service Service Interface
+ * @ingroup  tiot_common_interface
+ * @{
+ */
+
+#define TIOT_READ_TIMEOUT_FOREVER  0xFFFFFFFU  /*!< Read wait timeout forever. */
+
+typedef uintptr_t tiot_handle;
+
+typedef struct {
+    uint8_t *buff; /* 用户需要创建静态buff */
+    uint32_t buff_len;
+    void (*rx_callback)(const uint8_t *buff, uint32_t len);
+    uint32_t flags;
+} tiot_service_open_param;
+
+/**
+ * @brief  TIoT Service Init interface.
+ * @return zero if OK;
+ *         -1 if FAIL.
+ * @note Init for all driver and board.
+ */
+int32_t tiot_service_init(void);
+
+/**
+ * @brief  TIoT Service Deinit interface.
+ * @note Deinit for all driver and board.
+ */
+void tiot_service_deinit(void);
+
+/**
+ * @brief  TIoT Service Open interface.
+ * @param  [in]  device_name TIoT device compatible string.
+ * @param  [in]  param User/Service defined params.
+ * @return valid handle if OK;
+ *         zero if FAIL.
+ * @note   Must write/read after open.
+ */
+tiot_handle tiot_service_open(const char *device_name, void *param);
+
+/**
+ * @brief  TIoT Service Close interface.
+ * @note   Meaningless to return error.
+ */
+void tiot_service_close(tiot_handle handle);
+
+/**
+ * @brief  TIoT Service Write Message interface.
+ * @param  [in]  data Data need to send.
+ * @param  [in]  len Data length.
+ * @return zero or postive for writen OK length;
+ *         negtive if write FAIL.
+ * @note   Will return after data is sent to board uart interface.
+ */
+int32_t tiot_service_write(tiot_handle handle, const uint8_t *data, uint32_t len);
+
+/**
+ * @brief  TIoT Service Read Message interface.
+ * @param  [in/out] buff User read buff.
+ * @param  [in]  buff_len User read buff size.
+ * @param  [in]  timeout_ms Wait timeout ms.
+ * @return if read wait timeout(nothing to read), return 0.
+ *         if read fail, return -1.
+ *         if support ASCII message, message type(2 bytes, ASCII or BINARY) and message will be copied to buff,
+ *         else only message will be copied to buff,
+ *         return read length.
+ * @note   This interface will return only single complete message once,
+ *         for continous message read, call this interface repeatly.
+ */
+int32_t tiot_service_read(tiot_handle handle, uint8_t *buff, uint32_t buff_len, uint32_t timeout_ms);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface_ext.h b/code/sdk/zhihui/gnss/driver/common/interface/device_interface/tiot_service_interface_ext.h
new file mode 100644 (file)
index 0000000..37bcd41
--- /dev/null
@@ -0,0 +1,98 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ *\r
+ * Description:  \n\r
+ *\r
+ * History: \n\r
+ * 2024-01-29, Create file. \n\r
+ */\r
+#ifndef TIOT_SERVICE_INTERFACE_EXT_H\r
+#define TIOT_SERVICE_INTERFACE_EXT_H\r
+\r
+#include "tiot_service_interface.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_interface_service_ext Service Interface Ext\r
+ * @ingroup  tiot_common_interface\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief  TIoT Tx param, for tiot_service_write_ext.\r
+ */\r
+typedef struct {\r
+    uint32_t subsys;     /*!< Write for which sub system, varies for different device. */\r
+} tiot_service_tx_param;\r
+\r
+/**\r
+ * @brief  TIoT Rx param, for tiot_service_read_ext.\r
+ */\r
+typedef struct {\r
+    uint32_t timeout_ms; /*!< Wait timeout ms. */\r
+    uint32_t subsys;     /*!< Read for which sub system, varies for different device. */\r
+#ifdef __KERNEL__\r
+    struct file *filp;     /*!< for poll */\r
+    poll_table *poll_wait; /*!< for poll */\r
+#endif\r
+} tiot_service_rx_param;\r
+\r
+typedef enum {\r
+    TIOT_PM_CTRL_SUSPEND_PREPARE,\r
+    TIOT_PM_CTRL_SUSPEND,\r
+    TIOT_PM_CTRL_RESUME_PREPARE,\r
+    TIOT_PM_CTRL_RESUME,\r
+    TIOT_PM_CTRL_BUTT\r
+} tiot_service_pm_ctrl_cmd;\r
+\r
+/**\r
+ * @brief  TIoT Service Write Message extende interface.\r
+ * @param  [in]  data Data need to send.\r
+ * @param  [in]  len Data length.\r
+ * @param  [in]  param Write Param, see @ref tiot_service_tx_param.\r
+ * @return zero or postive for writen OK length;\r
+ *         negtive if write FAIL.\r
+ * @note   Will return after data is sent to board uart interface.\r
+ */\r
+int32_t tiot_service_write_ext(tiot_handle handle, const uint8_t *data,\r
+                               uint32_t len, const tiot_service_tx_param *param);\r
+\r
+/**\r
+ * @brief  TIoT Service Read Message extended interface.\r
+ * @param  [in/out] buff User read buff.\r
+ * @param  [in]  buff_len User read buff size.\r
+ * @param  [in]  param Read Param, see @ref tiot_service_rx_param.\r
+ * @return if read wait timeout(nothing to read), return 0.\r
+ *         if read fail, return -1.\r
+ *         if support ASCII message, message type(2 bytes, ASCII or BINARY) and message will be copied to buff,\r
+ *         else only message will be copied to buff,\r
+ *         return read length.\r
+ * @note   This interface will return only single complete message once,\r
+ *         for continous message read, call this interface repeatly.\r
+ */\r
+int32_t tiot_service_read_ext(tiot_handle handle, uint8_t *buff, uint32_t buff_len, const tiot_service_rx_param *param);\r
+\r
+/**\r
+ * @brief  TIoT Service Pm Control interface.\r
+ * @param  [in]  handle Service instance handle, should be return by tiot_service_open.\r
+ * @param  [in]  cmd Service pm ctrl cmd.\r
+ * @return return 0 if success else return -1.\r
+ */\r
+int32_t tiot_service_pm_ctrl(tiot_handle handle, tiot_service_pm_ctrl_cmd cmd);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/pm/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6d6660d
--- /dev/null
@@ -0,0 +1,18 @@
+#===============================================================================\r
+# @brief    cmake make file\r
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+#===============================================================================\r
+set(\r
+    tiot_pm_src_list\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_pm.c\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_pm_wakelock.c\r
+)\r
+\r
+add_subdirectory(pm_default)\r
+\r
+if(DEFINED CONFIG_DEV_TIOT_SLAVE)\r
+add_subdirectory(pm_slave)\r
+endif()\r
+\r
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)\r
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_pm_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/pm_default/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/pm/pm_default/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3f3d898
--- /dev/null
@@ -0,0 +1,7 @@
+set(
+    tiot_pm_default_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_pm_default.c
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_pm_default_src_list}" CACHE INTERNAL "tiot src list" FORCE)
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/pm_default/tiot_pm_default.c b/code/sdk/zhihui/gnss/driver/common/pm/pm_default/tiot_pm_default.c
new file mode 100644 (file)
index 0000000..01a60ef
--- /dev/null
@@ -0,0 +1,288 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT pm default. \n
+ *
+ * History: \n
+ * 2023-06-09, Create file. \n
+ */
+
+#include "tiot_pm_default.h"
+#include "tiot_pm_wakelock.h"
+#include "tiot_board_pin_port.h"
+#include "tiot_board_log.h"
+#include "tiot_controller.h"
+#include "tiot_xfer_utils.h"
+#include "tiot_board.h"
+#include "tiot_sys_msg_types.h"
+#ifdef CONFIG_PM_WAKEUP_BY_UART
+#include "tiot_board_uart_port.h"
+#endif
+
+tiot_pm_retcode tiot_pm_default_power_off(tiot_pm *pm)
+{
+    if (tiot_board_pin_set_level(pm->pm_info[TIOT_PIN_POWER_CTRL], TIOT_PIN_LEVEL_LOW) != 0) {
+        return TIOT_PM_EVTRET_FAIL;
+    }
+    /* 下电时unlock。 */
+    tiot_pm_wake_unlock();
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_default_power_on(tiot_pm *pm)
+{
+    tiot_controller *ctrl = tiot_container_of(pm, tiot_controller, pm);
+    const tiot_device_timings *timings = &ctrl->dev_info->timings;
+    uint32_t power_ctrl_pin = pm->pm_info[TIOT_PIN_POWER_CTRL];
+    int32_t ret = 0;
+    do {
+        ret = tiot_board_pin_set_level(power_ctrl_pin, TIOT_PIN_LEVEL_LOW);
+        if (ret != 0) {
+            tiot_print_err("[TIoT][pm]set pwr pin level low fail.\n");
+            break;
+        }
+        osal_msleep(timings->power_on_wait_ms);
+        ret = tiot_board_pin_set_level(power_ctrl_pin, TIOT_PIN_LEVEL_HIGH);
+        if (ret != 0) {
+            tiot_print_err("[TIoT][pm]set pwr pin level high fail.\n");
+            break;
+        }
+        osal_msleep(timings->boot_time_ms);
+    } while (0);
+
+    if (ret != 0) {
+        tiot_print_err("[TIoT:pm]power on fail.\n");
+        return TIOT_PM_EVTRET_FAIL;
+    }
+    /* 上电时lock。 */
+    tiot_pm_wake_lock();
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+/* 不可在中断环境下使用. */
+int32_t tiot_pm_check_sleeped(uint32_t wakein_pin, uint8_t check_times)
+{
+    int32_t ret;
+    uint8_t level;
+    uint8_t i;
+    const uint8_t sleep_check = check_times;      /* 等待睡眠,重试check_times次. */
+    const uint8_t sleep_wait_ms = 2;     /* 等待睡眠,每次等待2ms. */
+    /* 唤醒时,如果wakein_pin存在,检查wakein_pin拉低后再发送唤醒, 确保主机已休眠. */
+    if (wakein_pin == TIOT_PIN_NONE) {
+        return 0;
+    }
+    for (i = 0; i < sleep_check; i++) {
+        ret = tiot_board_pin_get_level(wakein_pin, &level);
+        if (ret != 0) {
+            tiot_print_err("[TIoT:pm]wakein pin level get error.\n");
+            return -1;
+        }
+        if (level == TIOT_PIN_LEVEL_LOW) {
+            return 0;
+        }
+        osal_msleep(sleep_wait_ms);
+    }
+    /* 此时device侧可能又重新拉高管脚通知有数据上报,保持状态即可, 响应event即转成work. */
+    tiot_print_warning("[TIoT:pm]wakein pin level high after check (%d) times.\n", sleep_check);
+    return -1;
+}
+
+#ifdef CONFIG_PM_WAKEUP_BY_UART
+tiot_pm_retcode tiot_pm_default_wakeup_device_by_uart(tiot_pm *pm)
+{
+    tiot_controller *ctrl = tiot_container_of(pm, tiot_controller, pm);
+    int32_t ret;
+    tiot_print_info("[TIoT][pm]wakeup device enter.\n");
+    const uint32_t wakeup_baudrate = 115200;    /* UART唤醒时设为115200波特率. */
+    const uint8_t wakeup_cmd = 0x00;
+    const uint8_t check_times = 10;
+    tiot_xfer_manager *xfer = &ctrl->transfer;
+    ret = tiot_pm_check_sleeped(pm->pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST], check_times);
+    if (ret != 0) {
+        return TIOT_PM_EVTRET_KEEP_STATE;
+    }
+
+    tiot_uart_config old_config = { 0 };
+    tiot_uart_config wakeup_config = { wakeup_baudrate,
+        { .data_bits = TIOT_UART_ATTR_DATABIT_8, .parity = TIOT_UART_ATTR_PARITY_NONE,
+          .stop_bits = TIOT_UART_ATTR_STOPBIT_1, .flow_ctrl = TIOT_UART_ATTR_FLOW_CTRL_DISABLE } };
+    (void)tiot_xfer_get_config(xfer, &old_config);
+    (void)tiot_xfer_set_config(xfer, &wakeup_config);
+    ret = tiot_xfer_direct_send(xfer, &wakeup_cmd, sizeof(uint8_t));
+    (void)tiot_xfer_set_config(xfer, &old_config);
+    if (ret != sizeof(uint8_t)) {
+        return TIOT_PM_EVTRET_FAIL;
+    }
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+#endif
+
+tiot_pm_retcode tiot_pm_default_wakeup_device_by_gpio(tiot_pm *pm)
+{
+    int32_t ret;
+    tiot_controller *ctrl = tiot_container_of(pm, tiot_controller, pm);
+    const tiot_device_timings *timings = &ctrl->dev_info->timings;
+    uint32_t wakeup_device_pin = pm->pm_info[TIOT_PIN_HOST_WAKEUP_DEVICE];
+    const uint8_t check_times = 10;
+
+    tiot_print_info("[TIoT][pm]wakeup device enter.\n");
+    if (wakeup_device_pin == TIOT_PIN_NONE) {
+        tiot_print_err("[TIoT][pm]wakeup pin not set.\n");
+        return TIOT_PM_EVTRET_FAIL;
+    }
+
+    ret = tiot_pm_check_sleeped(pm->pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST], check_times);
+    if (ret != 0) {
+        return TIOT_PM_EVTRET_KEEP_STATE;
+    }
+
+    do {
+        ret = tiot_board_pin_set_level(wakeup_device_pin, TIOT_PIN_LEVEL_LOW);
+        if (ret != 0) {
+            tiot_print_err("[TIoT][pm]set wakeup pin level low fail.\n");
+            break;
+        }
+        osal_msleep(timings->wakeup_pulse_ms);
+        ret = tiot_board_pin_set_level(wakeup_device_pin, TIOT_PIN_LEVEL_HIGH);
+        if (ret != 0) {
+            tiot_print_err("[TIoT][pm]set wakeup pin level high fail.\n");
+            break;
+        }
+        osal_msleep(timings->wakeup_pulse_ms);
+        ret = tiot_board_pin_set_level(wakeup_device_pin, TIOT_PIN_LEVEL_LOW);
+        if (ret != 0) {
+            tiot_print_err("[TIoT][pm]set wakeup pin level low fail.\n");
+            break;
+        }
+    } while (0);
+
+    if (ret != 0) {
+        return TIOT_PM_EVTRET_FAIL;
+    }
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+#ifdef CONFIG_PM_MANAGE_LOWPOWER
+tiot_pm_retcode tiot_pm_default_request_sleep_handle(tiot_pm *pm)
+{
+    const uint8_t allow_sleep_command[] = { 0x7e, 0x00, 0x06, 0x00,
+                                            SYS_PL_BFGNI_HOST_ASKTO_SLP,
+                                            0x7e };
+    int32_t ret;
+    tiot_controller *ctrl = NULL;
+    tiot_xfer_manager *xfer = NULL;
+    if (pm->work_vote == 1) {
+        return TIOT_PM_EVTRET_KEEP_STATE;
+    }
+    ctrl = tiot_container_of(pm, tiot_controller, pm);
+    xfer = &ctrl->transfer;
+    ret = xfer->xmit_ops->write(&xfer->xmit, allow_sleep_command, sizeof(allow_sleep_command));
+    if (ret != sizeof(allow_sleep_command)) {
+        tiot_print_alert("[TIoT:fatal]send allow sleep msg fail.\r\n");
+        return TIOT_PM_EVTRET_FAIL;
+    }
+    tiot_print_info("[TIoT][pm]allow device sleep.\n");
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_default_sleep_ack_handle(tiot_pm *pm)
+{
+    tiot_unused(pm);
+    /* device侧睡眠时可睡眠 */
+    tiot_pm_wake_unlock();
+    tiot_print_info("[TIoT][pm]goes to sleep.\n");
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+/*
+ * 非S3状态,由于在中断中无法等待Sleep Ack(dev wkup host gpio拉低),
+ * 所以在下发allow sleep消息后,就立刻释放唤醒锁进入睡眠。
+ */
+tiot_pm_retcode tiot_pm_default_request_sleep_ack_handle(tiot_pm *pm)
+{
+    tiot_pm_retcode ret = tiot_pm_default_request_sleep_handle(pm);
+    if (ret != TIOT_PM_EVTRET_NEXT_STATE) {
+        return ret;
+    }
+    return tiot_pm_default_sleep_ack_handle(pm);
+}
+
+int32_t tiot_pm_send_disallow_sleep(tiot_xfer_manager *xfer)
+{
+    const uint8_t disallow_sleep_command[] = { 0x7e, 0x00, 0x06, 0x00,
+                                               SYS_PL_BFGNI_HOST_DISALLOW_DEVSLP,
+                                               0x7e };
+    int32_t ret;
+    ret = xfer->xmit_ops->write(&xfer->xmit, disallow_sleep_command, sizeof(disallow_sleep_command));
+    if (ret != sizeof(disallow_sleep_command)) {
+        tiot_print_alert("[TIoT:fatal]send disallow msg fail.\r\n");
+        return -1;
+    }
+    return 0;
+}
+
+tiot_pm_retcode tiot_pm_default_wakeup_ack_handle(tiot_pm *pm)
+{
+    int32_t ret;
+    uint8_t input_level = TIOT_PIN_LEVEL_LOW;
+    uint16_t pre_state = pm->state;
+    tiot_controller *ctrl = tiot_container_of(pm, tiot_controller, pm);
+    tiot_xfer_manager *xfer = &ctrl->transfer;
+    uint32_t wakeup_host_pin = pm->pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST];
+
+    if (wakeup_host_pin == TIOT_PIN_NONE) {
+        tiot_print_err("[TIoT][pm]wakeup ack event called but dev_wk_host pin is none.\n");
+        return TIOT_PM_EVTRET_KEEP_STATE;
+    }
+
+    /*
+     * host上电后处于INIT状态时,此时接收到device拉高wakeup_host gpio,则不能下发disallow消息,
+     * 否则会多lock()一次,导致host后续无法睡下去。
+     */
+    if (pre_state == TIOT_PM_STATE_INIT) {
+        /* INIT -> WORK */
+        return TIOT_PM_EVTRET_NEXT_STATE;
+    }
+
+    /* 有数据上报时不睡眠 */
+    /* 自唤醒流程: device_wake_out --> wake_lock -......-> request_sleep --> wake_unlock */
+    /* 当前在唤醒中断内持锁,并直接回复disallow消息。 */
+
+    /* check wakeup_ack */
+    ret = tiot_board_pin_get_level(wakeup_host_pin, &input_level);
+    if ((ret != 0) || (input_level == TIOT_PIN_LEVEL_LOW)) {
+        tiot_print_err("[TIoT][pm]get dev_wk_host pin level fail or false positive [state:0x%x].\n", pre_state);
+        return TIOT_PM_EVTRET_KEEP_STATE;
+    }
+    /* 使用临时flag区分suspend. */
+    if (xfer->xmit_suspend & TIOT_XFER_SUSPEND) {
+        tiot_print_info("[TIoT:pm]delay disallow msg [state:0x%x].\n", pre_state);
+        xfer->xmit_suspend |= TIOT_XFER_DELAY_MSG;
+    } else {
+        tiot_print_info("[TIoT][pm]send disallow sleep msg [state:0x%x].\n", pre_state);
+        if (tiot_pm_send_disallow_sleep(xfer) != 0) {
+            return TIOT_PM_EVTRET_FAIL;
+        }
+    }
+    if ((pre_state == TIOT_PM_STATE_SLEEP) || (pre_state == TIOT_PM_STATE_WAKING)) {
+        tiot_pm_wake_lock();
+    }
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_default_work_vote_up(tiot_pm *pm)
+{
+    /* 发送时不睡眠 */
+    tiot_pm_wake_lock();
+    pm->work_vote = 1;
+    return TIOT_PM_EVTRET_KEEP_STATE;
+}
+
+tiot_pm_retcode tiot_pm_default_work_vote_down(tiot_pm *pm)
+{
+    pm->work_vote = 0;
+    /* 发送结束后可睡眠 */
+    tiot_pm_wake_unlock();
+    return TIOT_PM_EVTRET_KEEP_STATE;
+}
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/pm_default/tiot_pm_default.h b/code/sdk/zhihui/gnss/driver/common/pm/pm_default/tiot_pm_default.h
new file mode 100644 (file)
index 0000000..b9d4f9f
--- /dev/null
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT pm default. \n
+ *
+ * History: \n
+ * 2023-06-09, Create file. \n
+ */
+#ifndef TIOT_PM_DEFAULT_H
+#define TIOT_PM_DEFAULT_H
+
+#include "tiot_pm.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_pm_default PM Default Handlers
+ * @ingroup  tiot_common_pm
+ * @{
+ */
+
+/**
+ * @brief  Default power off handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_power_off(tiot_pm *pm);
+
+/**
+ * @brief  Default power on handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_power_on(tiot_pm *pm);
+
+#ifdef CONFIG_PM_WAKEUP_BY_UART
+/**
+ * @brief  Default wakeup by uart handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_wakeup_device_by_uart(tiot_pm *pm);
+#endif
+
+/**
+ * @brief  Default wakeup by gpio handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_wakeup_device_by_gpio(tiot_pm *pm);
+
+#ifdef CONFIG_PM_MANAGE_LOWPOWER
+/**
+ * @brief  Default request sleep handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_request_sleep_handle(tiot_pm *pm);
+
+/**
+ * @brief  Default sleep ack handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_sleep_ack_handle(tiot_pm *pm);
+
+/**
+ * @brief  Default request sleep ack handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_request_sleep_ack_handle(tiot_pm *pm);
+
+/**
+ * @brief  Default wakeup ack handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_wakeup_ack_handle(tiot_pm *pm);
+
+/**
+ * @brief  Default work vote up handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_work_vote_up(tiot_pm *pm);
+
+/**
+ * @brief  Default work vote down handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_default_work_vote_down(tiot_pm *pm);
+#endif
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/pm_slave/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/pm/pm_slave/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cdc63ca
--- /dev/null
@@ -0,0 +1,7 @@
+set(
+    tiot_pm_slave_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_pm_slave.c
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_pm_slave_src_list}" CACHE INTERNAL "tiot src list" FORCE)
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/pm_slave/tiot_pm_slave.c b/code/sdk/zhihui/gnss/driver/common/pm/pm_slave/tiot_pm_slave.c
new file mode 100644 (file)
index 0000000..7e8669b
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description: TIoT pm slave. \n
+ *
+ * History: \n
+ * 2024-02-28, Create file. \n
+ */
+#include "tiot_pm_slave.h"
+#include "tiot_pm_wakelock.h"
+#include "tiot_board_pin_port.h"
+#include "tiot_board_log.h"
+#include "tiot_controller.h"
+#include "tiot_sys_msg_types.h"
+#include "tiot_packet.h"
+#include "tiot_board.h"
+
+tiot_pm_retcode tiot_pm_slave_power_off(tiot_pm *pm)
+{
+    tiot_unused(pm);
+    tiot_pm_wake_unlock();
+    tiot_print_info("[TIoT][pm]power off.\r\n");
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_slave_power_on(tiot_pm *pm)
+{
+    tiot_unused(pm);
+    tiot_pm_wake_lock();
+    tiot_print_info("[TIoT][pm]power on.\r\n");
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_slave_wakeup_handle(tiot_pm *pm)
+{
+    /* Only SLEEP -> WAKING */
+    uint32_t wakeup_in_pin;
+    uint32_t wakeup_out_pin;
+    tiot_controller *ctrl = tiot_container_of(pm, tiot_controller, pm);
+    const tiot_device_timings *timings = &ctrl->dev_info->timings;
+
+    if (pm->state != TIOT_PM_STATE_SLEEP) {
+        return TIOT_PM_EVTRET_KEEP_STATE;
+    }
+
+    tiot_pm_wake_lock();
+
+    wakeup_out_pin = pm->pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST];
+    if (wakeup_out_pin != TIOT_PIN_NONE) {
+        if (tiot_board_pin_set_level(wakeup_out_pin, TIOT_PIN_LEVEL_LOW) != 0) {
+            tiot_print_err("[TIoT:pm]wakeout pin set level low fail.\r\n");
+            goto wakeout_fail;
+        }
+        osal_msleep(timings->wakeup_pulse_ms);
+        if (tiot_board_pin_set_level(wakeup_out_pin, TIOT_PIN_LEVEL_HIGH) != 0) {
+            tiot_print_err("[TIoT:pm]wakeout pin set level high fail.\r\n");
+            goto wakeout_fail;
+        }
+    } else {
+        tiot_print_warning("[TIoT][pm]wakeout pin is invalid.\r\n");
+    }
+    /* 唤醒host/唤醒ack后关闭唤醒源中断使能. */
+    wakeup_in_pin = pm->pm_info[TIOT_PIN_HOST_WAKEUP_DEVICE];
+    tiot_board_pin_enable_int(wakeup_in_pin, TIOT_PIN_INT_DISABLE);
+    return TIOT_PM_EVTRET_NEXT_STATE;
+wakeout_fail:
+    tiot_pm_wake_unlock();
+    return TIOT_PM_EVTRET_FAIL;
+}
+
+#ifdef CONFIG_PM_MANAGE_LOWPOWER
+/* 不允许在中断环境下调用 */
+tiot_pm_retcode tiot_pm_slave_request_sleep_handle(tiot_pm *pm)
+{
+    int32_t ret;
+    tiot_controller *ctrl = tiot_container_of(pm, tiot_controller, pm);
+    tiot_xfer_manager *xfer = &ctrl->transfer;
+    const uint8_t request_sleep_command = SYS_INF_REQUEST_SLEEP;
+    tiot_xfer_tx_param tx_param = { SUBSYS_SYS };
+
+    tiot_print_info("[TIoT][pm]request sleep enter.\n");
+
+    ret = tiot_xfer_send(xfer, &request_sleep_command, sizeof(request_sleep_command), &tx_param);
+    if (ret != sizeof(request_sleep_command)) {
+        tiot_print_err("[TIoT][pm]send request sleep msg fail.\r\n");
+        return TIOT_PM_EVTRET_FAIL;
+    }
+
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_slave_sleep_ack_handle(tiot_pm *pm)
+{
+    uint32_t wakeup_in_pin;
+    uint32_t wakeup_out_pin;
+    /* When we reporting msg, ignore allow sleep msg. */
+    if (pm->work_vote == 1) {
+        return TIOT_PM_EVTRET_KEEP_STATE;
+    }
+
+    wakeup_out_pin = pm->pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST];
+    /* 睡眠前,slave侧拉低唤醒主机管脚. */
+    if (wakeup_out_pin != TIOT_PIN_NONE) {
+        if (tiot_board_pin_set_level(wakeup_out_pin, TIOT_PIN_LEVEL_LOW) != 0) {
+            tiot_print_err("[TIoT][pm]wakeup_out_pin set low fail.\r\n");
+            return TIOT_PM_EVTRET_FAIL;
+        }
+    }
+    /* 进睡眠前 打开唤醒源中断使能. */
+    wakeup_in_pin = pm->pm_info[TIOT_PIN_HOST_WAKEUP_DEVICE];
+    tiot_board_pin_enable_int(wakeup_in_pin, TIOT_PIN_INT_ENABLE);
+    tiot_print_info("[TIoT][pm]goes to sleep.\r\n");
+    /* 移除否决票 */
+    tiot_pm_wake_unlock();
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_slave_wakeup_ack_handle(tiot_pm *pm)
+{
+    tiot_unused(pm);
+    tiot_print_info("[TIoT][pm]wakeup succ.\r\n");
+    return TIOT_PM_EVTRET_NEXT_STATE;
+}
+
+tiot_pm_retcode tiot_pm_slave_work_vote_up(tiot_pm *pm)
+{
+    /* Prevent sleeping while sending data. */
+    tiot_pm_wake_lock();
+    pm->work_vote = 1;
+    return TIOT_PM_EVTRET_KEEP_STATE;
+}
+
+tiot_pm_retcode tiot_pm_slave_work_vote_down(tiot_pm *pm)
+{
+    pm->work_vote = 0;
+    tiot_pm_wake_unlock();
+    return TIOT_PM_EVTRET_KEEP_STATE;
+}
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/pm_slave/tiot_pm_slave.h b/code/sdk/zhihui/gnss/driver/common/pm/pm_slave/tiot_pm_slave.h
new file mode 100644 (file)
index 0000000..7c15a97
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description: TIoT pm slave. \n
+ *
+ * History: \n
+ * 2024-02-28, Create file. \n
+ */
+#ifndef TIOT_PM_SLAVE_H
+#define TIOT_PM_SLAVE_H
+
+#include "tiot_pm.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_pm_slave PM Slave Handlers
+ * @ingroup  tiot_common_pm
+ * @{
+ */
+
+/**
+ * @brief  Slave power off handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_power_off(tiot_pm *pm);
+
+/**
+ * @brief  Slave power on handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_power_on(tiot_pm *pm);
+
+/**
+ * @brief  Slave wakeup by gpio handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_wakeup_handle(tiot_pm *pm);
+
+#ifdef CONFIG_PM_MANAGE_LOWPOWER
+/**
+ * @brief  Slave request sleep handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_request_sleep_handle(tiot_pm *pm);
+
+/**
+ * @brief  Slave sleep ack handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_sleep_ack_handle(tiot_pm *pm);
+
+/**
+ * @brief  Slave wakeup ack handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_wakeup_ack_handle(tiot_pm *pm);
+
+/**
+ * @brief  Slave work vote up handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_work_vote_up(tiot_pm *pm);
+
+/**
+ * @brief  Slave work vote down handler.
+ * @param  [in]  pm PM control block.
+ * @return see@ref tiot_pm_retcode.
+ */
+tiot_pm_retcode tiot_pm_slave_work_vote_down(tiot_pm *pm);
+
+#endif
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm.c b/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm.c
new file mode 100644 (file)
index 0000000..10a51fe
--- /dev/null
@@ -0,0 +1,149 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Power Manager module. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-27, Create file. \n\r
+ */\r
+\r
+#include "tiot_pm.h"\r
+#include "tiot_pm_wakelock.h"\r
+#include "tiot_osal.h"\r
+#include "securec.h"\r
+#include "tiot_controller.h"\r
+#include "tiot_board_log.h"\r
+\r
+typedef struct {\r
+    tiot_pm *pm;\r
+    uint16_t state;\r
+} pm_wait_state;\r
+\r
+/* 传入的event_map必须为静态申请数组 */\r
+int32_t tiot_pm_init(tiot_pm *pm, const uint32_t *pm_info,\r
+                     const tiot_pm_event_entry *event_map, uint8_t event_map_size)\r
+{\r
+    if ((pm == NULL) || (pm_info == NULL) || (event_map == NULL) || (event_map_size == 0)) {\r
+        tiot_print_dbg("[TIoT][pm]pm or pm info or event_map is NULL.\n");\r
+        return -1;\r
+    }\r
+    if (osal_wait_init(&pm->state_wait) != OSAL_SUCCESS) {\r
+        tiot_print_err("[TIoT][pm]pm wait init fail.\n");\r
+        return -1;\r
+    }\r
+\r
+    /* 外部确保为静态变量 */\r
+    pm->pm_info = pm_info;\r
+    pm->event_map = event_map;\r
+    pm->event_map_size = event_map_size;\r
+\r
+    /* 此队列仅用于处理中断内产生pm事件情况,按产生顺序排序,预计不会同时在多个中断内产生pm事件,预留8个已经足够. */\r
+    (void)memset_s(pm->event_queue_buff, TIOT_PM_EVENT_BUFF_MAX, 0, TIOT_PM_EVENT_BUFF_MAX);\r
+    tiot_circ_queue_init(&pm->event_queue, TIOT_PM_EVENT_BUFF_MAX,\r
+                         sizeof(tiot_pm_event), (uintptr_t)pm->event_queue_buff);\r
+    pm->is_in_event = 0;\r
+    pm->work_vote = 0;\r
+    pm->state = TIOT_PM_STATE_POWEROFF;\r
+    return 0;\r
+}\r
+\r
+static int32_t tiot_pm_handle_event(tiot_pm *pm, tiot_pm_event event)\r
+{\r
+    tiot_pm_retcode ret = TIOT_PM_EVTRET_NEXT_STATE;\r
+    /* 取对应事件的 [判断条件 - 执行处理 - 设置下个状态] 流程 */\r
+    const tiot_pm_event_entry *entry = &pm->event_map[event];\r
+\r
+    /* 当前状态不符合tag mask条件, 不需要处理,直接返回OK */\r
+    if ((pm->state & entry->condition_mask) == 0) {\r
+        tiot_print_dbg("[TIoT][pm]state %x not match condition %x, ignore event\n", pm->state, entry->condition_mask);\r
+        return 0;\r
+    }\r
+\r
+    /* pm处理过程持唤醒锁,防止pm未转换完状态就直接进sleep。 */\r
+    tiot_pm_wake_lock();\r
+\r
+    /* 当前状态符合tag mask条件,执行对应事件处理 */\r
+    /* 约定:handler为空不需要处理,例如上报业务消息说明芯片处于WORK状态,只需要切换状态即可 */\r
+    if (entry->handler != NULL) {\r
+        ret = entry->handler(pm);\r
+    }\r
+\r
+    if (ret == TIOT_PM_EVTRET_NEXT_STATE) {\r
+        /* 处理成功,设为下一个状态 */\r
+        tiot_print_dbg("[TIoT][pm]evt:%x, st:%x, next_st: %x.\n", event, pm->state, entry->next_state);\r
+        pm->state = entry->next_state;\r
+        /* 切换状态时保证设置event. */\r
+        osal_wait_wakeup_interruptible(&pm->state_wait);\r
+    } else if (ret == TIOT_PM_EVTRET_FAIL) {\r
+        /* 处理失败,返回false. */\r
+        tiot_print_dbg("[TIoT][pm]evt:%x, st:%x, event fail.\n", event, pm->state);\r
+        tiot_pm_wake_unlock();\r
+        return -1;\r
+    } else {   /* ret == TIOT_PM_EVTRET_KEEP_STATE */\r
+        /* 处理成功,保持当前状态 */\r
+        tiot_print_dbg("[TIoT][pm]evt:%x, st:%x, keep state.\n", event, pm->state);\r
+    }\r
+    tiot_pm_wake_unlock();\r
+\r
+    return 0;\r
+}\r
+\r
+int32_t tiot_pm_set_event(tiot_pm *pm, tiot_pm_event event)\r
+{\r
+    int32_t ret;\r
+    tiot_pm_event *event_node;\r
+\r
+    if ((pm == NULL) || (event >= TIOT_PM_EVENT_MAX) || (event >= pm->event_map_size)) {\r
+        tiot_print_dbg("[TIoT][pm]pm is NULL or illegal event.\n");\r
+        return -1;\r
+    }\r
+\r
+    tiot_circ_queue_enqueue(&pm->event_queue, (uintptr_t)&event);\r
+    /* 依靠队列防止pm事件处理嵌套,此处不使用互斥锁(可能在中断内产生事件),也不使用自旋锁(不能保证提供自旋锁) */\r
+    if (pm->is_in_event == 1) {\r
+        return 0;\r
+    }\r
+\r
+    do {\r
+        event_node = (tiot_pm_event *)tiot_circ_queue_dequeue(&pm->event_queue);\r
+        if (event_node == NULL) {\r
+            return 0;\r
+        }\r
+        pm->is_in_event = 1;\r
+        ret = tiot_pm_handle_event(pm, *event_node);\r
+        pm->is_in_event = 0;\r
+        if (ret != 0) {\r
+            tiot_circ_queue_clear(&pm->event_queue);\r
+            break;\r
+        }\r
+    } while (event_node != NULL);\r
+\r
+    return ret;\r
+}\r
+\r
+static int pm_wait_state_condition(const void *param)\r
+{\r
+    pm_wait_state *wait_state = (pm_wait_state *)param;\r
+    return (wait_state->pm->state == wait_state->state);\r
+}\r
+\r
+int32_t tiot_pm_wait_state(tiot_pm *pm, uint16_t state, uint32_t wait_timeout)\r
+{\r
+    pm_wait_state wait_state = { 0 };\r
+    if (state == TIOT_PM_STATE_INVALID) {\r
+        return -1;\r
+    }\r
+    wait_state.pm = pm;\r
+    wait_state.state = state;\r
+    return osal_wait_timeout_interruptible(&pm->state_wait, pm_wait_state_condition, &wait_state, wait_timeout);\r
+}\r
+\r
+void tiot_pm_deinit(tiot_pm *pm)\r
+{\r
+    tiot_circ_queue_clear(&pm->event_queue);\r
+    osal_spin_lock_destroy(&pm->event_queue.lock);\r
+    osal_wait_destroy(&pm->state_wait);\r
+    (void)memset_s(pm->event_queue_buff, TIOT_PM_EVENT_BUFF_MAX, 0, TIOT_PM_EVENT_BUFF_MAX);\r
+    pm->state = TIOT_PM_STATE_INVALID;\r
+    pm->work_vote = 0;\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm.h b/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm.h
new file mode 100644 (file)
index 0000000..587d6c7
--- /dev/null
@@ -0,0 +1,182 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Power Manager module header. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-27, Create file. \n\r
+ */\r
+#ifndef TIOT_PM_H\r
+#define TIOT_PM_H\r
+\r
+#include "tiot_types.h"\r
+#include "tiot_circ_queue.h"\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_pm Power Manager\r
+ * @ingroup  tiot_common\r
+ * @{\r
+ */\r
+\r
+#define TIOT_PM_EVENT_BUFF_MAX    8\r
+\r
+/**\r
+ * @brief  TIoT PM tags.\r
+ */\r
+typedef enum {\r
+    TIOT_PM_TAG_INVALID = 0,                     /*!< Invalid PM tag. */\r
+    TIOT_PM_TAG_POWEROFF = ((uint16_t)1 << 0),   /*!< Power off tag. */\r
+    TIOT_PM_TAG_POWERON  = ((uint16_t)1 << 1),   /*!< Power on tag. */\r
+    /* Low power tags. */\r
+    TIOT_PM_TAG_CAN_WORK  = ((uint16_t)1 << 2),  /*!< Low power can work tag. */\r
+    TIOT_PM_TAG_CAN_SLEEP = ((uint16_t)1 << 3),  /*!< Low power can sleep tag. */\r
+    TIOT_PM_TAG_CAN_WAKEUP = ((uint16_t)1 << 4), /*!< Low power can wakeup tag. */\r
+    TIOT_PM_TAG_CAN_ALLOW_SLEEP = ((uint16_t)1 << 5), /*!< Low power can allow sleep tag. */\r
+    TIOT_PM_TAG_MAX = (uint16_t)0xFFFF           /* PM tag max. */\r
+} tiot_pm_tag;\r
+\r
+/**\r
+ * @brief  TIoT PM states.\r
+ */\r
+typedef enum {\r
+    TIOT_PM_STATE_INVALID = 0,                        /*!< Invalid PM state. */\r
+    TIOT_PM_STATE_POWEROFF = TIOT_PM_TAG_POWEROFF,    /*!< Power off state. */\r
+    TIOT_PM_STATE_POWERON = TIOT_PM_TAG_POWERON,      /*!< Power on state. */\r
+    /* Low power states */\r
+    /*!< Low power init state, can work, can sleep. */\r
+    TIOT_PM_STATE_INIT = TIOT_PM_TAG_POWERON | TIOT_PM_TAG_CAN_WORK | TIOT_PM_TAG_CAN_SLEEP,\r
+    /*!< Low power work state, can sleep, can allow sleep. */\r
+    /*!< Host: WORK -> SLEEPING -> SLEEP (正常睡眠流程,等待sleep ack)\r
+               WORK -> SLEEP (非S3状态,不等待sleep ack)\r
+       Device: WORK -> SLEEPING -> SLEEP (Device主动请求睡眠)\r
+               WORK -> SLEEP (S3状态,Host强制要求睡眠) */\r
+    TIOT_PM_STATE_WORK = TIOT_PM_TAG_POWERON | TIOT_PM_TAG_CAN_SLEEP | TIOT_PM_TAG_CAN_ALLOW_SLEEP,\r
+    /*!< Low power sleep state, can work, can be waked up. */\r
+    TIOT_PM_STATE_SLEEP = TIOT_PM_TAG_POWERON | TIOT_PM_TAG_CAN_WORK | TIOT_PM_TAG_CAN_WAKEUP,\r
+    /*!< Low power waking state, can be waked up. */\r
+    TIOT_PM_STATE_WAKING = TIOT_PM_TAG_POWERON | TIOT_PM_TAG_CAN_WAKEUP,\r
+    /*!< Low power sleeping state, can allow sleep. */\r
+    TIOT_PM_STATE_SLEEPING = TIOT_PM_TAG_POWERON | TIOT_PM_TAG_CAN_SLEEP\r
+} tiot_pm_state;\r
+\r
+/**\r
+ * @brief Tiot PM event types.\r
+ */\r
+typedef enum {\r
+    /* OUTPUT */\r
+    TIOT_PM_EVENT_POWEROFF,       /*!< Power off. */\r
+    TIOT_PM_EVENT_POWERON,        /*!< Power on. */\r
+    TIOT_PM_EVENT_WAKEUP,         /*!< Host: wakeup device.\r
+                                     Device: wakeup host(pull up dev_wkup_host gpio). */\r
+    /* INPUT,for host to manage device lowpower */\r
+    TIOT_PM_EVENT_WAKEUP_ACK,     /*!< Host: send disallow sleep cmd to ack(device wakeup host).\r
+                                     Device: handle the ack of disallow sleep cmd. */\r
+    TIOT_PM_EVENT_REQUEST_SLEEP,  /*!< Host: send allow sleep cmd.\r
+                                     Device: send request sleep cmd to request sleep. */\r
+    TIOT_PM_EVENT_SLEEP_ACK,      /*!< Host: handle the ack of allow sleep cmd.\r
+                                     Device: pull down dev_wkup_host gpio to ack (host allow sleep cmd). */\r
+    TIOT_PM_EVENT_REQUEST_SLEEP_ACK, /*!< Combine TIOT_PM_EVENT_REQUEST_SLEEP and TIOT_PM_EVENT_SLEEP_ACK */\r
+    TIOT_PM_EVENT_REPORT_WORK,    /*!< Device transmit port report message. */\r
+    /* Vote */\r
+    TIOT_PM_EVENT_WORK_VOTE_UP,   /*!< Host keep device at work state. */\r
+    TIOT_PM_EVENT_WORK_VOTE_DOWN, /*!< Host not keep device at work state. */\r
+    TIOT_PM_EVENT_MAX\r
+} tiot_pm_event;\r
+\r
+/**\r
+ * @brief Tiot PM event retcode.\r
+ */\r
+typedef enum {\r
+    TIOT_PM_EVTRET_FAIL = -1,         /* Event handle failed. */\r
+    TIOT_PM_EVTRET_NEXT_STATE = 0,    /* Change to next state. */\r
+    TIOT_PM_EVTRET_KEEP_STATE = 1,    /* Keep current state. */\r
+} tiot_pm_retcode;\r
+\r
+struct _tiot_pm;\r
+\r
+/**\r
+ * @brief  Tiot PM event handler.\r
+ */\r
+typedef tiot_pm_retcode (* tiot_pm_event_handler)(struct _tiot_pm *pm);\r
+\r
+/**\r
+ * @brief Tiot PM event handle entry.\r
+ */\r
+typedef struct {\r
+    uint16_t condition_mask;        /*!< Enter event condition, could be combination of PM tags. */\r
+    uint16_t next_state;            /*!< Next PM state. */\r
+    tiot_pm_event_handler handler;  /*!< PM event handler, NULL mean this event don't need operation. */\r
+} tiot_pm_event_entry;\r
+\r
+/**\r
+ * @brief Tiot PM control block.\r
+ */\r
+typedef struct _tiot_pm {\r
+    uint16_t state;                        /*!< Current PM state. */\r
+    uint16_t work_vote;                    /*!< Host require device work vote. */\r
+    const uint32_t *pm_info;               /*!< PM board info, pin indexs. */\r
+    osal_wait state_wait;                  /*!< PM state wait, used for wait some state. */\r
+    tiot_circ_queue_t event_queue;         /*!< PM event queue for syncing events. */\r
+    /*!< PM event queue buffer. */\r
+    tiot_pm_event event_queue_buff[TIOT_PM_EVENT_BUFF_MAX];\r
+    volatile uint8_t is_in_event;          /*!< PM event processing. */\r
+    uint8_t event_map_size;                /*!< PM event handle map size. */\r
+    /*!< PM event handle map, must point to static allocated array. */\r
+    const tiot_pm_event_entry *event_map;\r
+} tiot_pm;\r
+\r
+/**\r
+ * @brief  PM control block init.\r
+ * @param  [in]  pm        PM control block.\r
+ * @param  [in]  pm_info   Pointer to board PM info, static allocated, from device saved board info.\r
+ * @param  [in]  event_map Registed PM event handle map, static allocated, from *_device_info.c.\r
+ * @param  [in]  event_map_size Registed PM event handle map size.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_pm_init(tiot_pm *pm, const uint32_t *pm_info,\r
+                     const tiot_pm_event_entry *event_map, uint8_t event_map_size);\r
+\r
+/**\r
+ * @brief  Set event to PM control block.\r
+ * @param  [in]  pm    PM control block.\r
+ * @param  [in]  event PM event.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_pm_set_event(tiot_pm *pm, tiot_pm_event event);\r
+\r
+/**\r
+ * @brief  PM control block wait for state.\r
+ * @param  [in]  pm    PM control block.\r
+ * @param  [in]  state PM state,caller must ensure state is valid.\r
+ * @param  [in]  wait_timeout Wait timeout, shound not be too long.\r
+ * @return negative if wait state fail;\r
+ *         zero if wait state timeout;\r
+ *         postive if wait state OK.\r
+ */\r
+int32_t tiot_pm_wait_state(tiot_pm *pm, uint16_t state, uint32_t wait_timeout);\r
+\r
+/**\r
+ * @brief  PM control block deinit.\r
+ * @param  [in]  pm        PM control block.\r
+ */\r
+void tiot_pm_deinit(tiot_pm *pm);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm_wakelock.c b/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm_wakelock.c
new file mode 100644 (file)
index 0000000..1101a77
--- /dev/null
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2024-03-01, Create file. \n
+ */
+#include "tiot_pm_wakelock.h"
+#include "tiot_board_misc_port.h"
+#include "tiot_board_log.h"
+#include "tiot_osal.h"
+
+/* 所有controller共享同一个wakelock, 只有所有controller未持锁时才允许睡眠. */
+static tiot_board_wakelock g_top_wakelock;
+static osal_spinlock g_top_wakelock_spinlock;
+static uint16_t g_top_lock_count;
+
+int32_t tiot_pm_wake_lock_init(void)
+{
+    if (tiot_board_wake_lock_init(&g_top_wakelock) != 0) {
+        return -1;
+    }
+    if (osal_spin_lock_init(&g_top_wakelock_spinlock) != OSAL_SUCCESS) {
+        tiot_board_wake_lock_destroy(&g_top_wakelock);
+        return -1;
+    }
+    g_top_lock_count = 0;
+    return 0;
+}
+
+void tiot_pm_wake_lock(void)
+{
+    unsigned long flags;
+    osal_spin_lock_irqsave(&g_top_wakelock_spinlock, &flags);
+    if (g_top_lock_count == 0) {
+        tiot_board_wake_lock(&g_top_wakelock);
+    }
+    g_top_lock_count++;
+    osal_spin_unlock_irqrestore(&g_top_wakelock_spinlock, &flags);
+}
+
+void tiot_pm_wake_unlock(void)
+{
+    unsigned long flags;
+    osal_spin_lock_irqsave(&g_top_wakelock_spinlock, &flags);
+    if (g_top_lock_count > 0) {
+        g_top_lock_count--;
+        /* 防止count为0时多次调用unlock接口。 */
+        if (g_top_lock_count == 0) {
+            tiot_board_wake_unlock(&g_top_wakelock);
+        }
+    }
+    osal_spin_unlock_irqrestore(&g_top_wakelock_spinlock, &flags);
+}
+
+void tiot_pm_wake_lock_destroy(void)
+{
+    /* 确保destroy时一定释放。 */
+    unsigned long flags;
+    osal_spin_lock_irqsave(&g_top_wakelock_spinlock, &flags);
+    if (g_top_lock_count > 0) {
+        tiot_print_err("[TIoT][wakelock]g_top_lock_count should be 0, but is %d\n", g_top_lock_count);
+        g_top_lock_count = 0;
+        tiot_board_wake_unlock(&g_top_wakelock);
+    }
+    osal_spin_unlock_irqrestore(&g_top_wakelock_spinlock, &flags);
+
+    tiot_board_wake_lock_destroy(&g_top_wakelock);
+    osal_spin_lock_destroy(&g_top_wakelock_spinlock);
+}
+
diff --git a/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm_wakelock.h b/code/sdk/zhihui/gnss/driver/common/pm/tiot_pm_wakelock.h
new file mode 100644 (file)
index 0000000..f29b86a
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2024-03-01, Create file. \n
+ */
+#ifndef TIOT_PM_WAKELOCK_H
+#define TIOT_PM_WAKELOCK_H
+
+#include "tiot_types.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_pm_wakelock PM Wake Lock
+ * @ingroup  tiot_common_pm
+ * @{
+ */
+
+/**
+ * @if Eng
+ * @brief PM wake lock initialization interface.
+ * @return if OK return 0, else return -1.
+ * @else
+ * @brief PM唤醒锁初始化接口。
+ * @return 初始化成功返回0,否则返回-1。
+ * @endif
+ */
+int32_t tiot_pm_wake_lock_init(void);
+
+/**
+ * @if Eng
+ * @brief PM wake lock interface, support nested, pair with unlock.
+ * @else
+ * @brief PM唤醒锁接口,支持嵌套使用,需要和unlock配对。
+ * @endif
+ */
+void tiot_pm_wake_lock(void);
+
+/**
+ * @if Eng
+ * @brief PM wake unlock interface, support nested, pair with unlock.
+ * @else
+ * @brief PM唤醒解锁接口,支持嵌套使用,需要和lock配对。
+ * @endif
+ */
+void tiot_pm_wake_unlock(void);
+
+/**
+ * @if Eng
+ * @brief PM wake lock destroy interface.
+ * @else
+ * @brief PM唤醒锁销毁接口。
+ * @endif
+ */
+void tiot_pm_wake_lock_destroy(void);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9631fb6
--- /dev/null
@@ -0,0 +1,14 @@
+set(
+    tiot_sys_msg_handler_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_sys_msg_handle.c
+)
+
+if(DEFINED CONFIG_DEV_TIOT_SLAVE)
+list(
+    APPEND tiot_sys_msg_handler_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_sys_msg_slave_handle.c
+)
+endif()
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_sys_msg_handler_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_handle.c b/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_handle.c
new file mode 100644 (file)
index 0000000..f72d88c
--- /dev/null
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-02-29, Create file. \n
+ */
+#include "tiot_sys_msg_handle.h"
+#include "tiot_sys_msg_types.h"
+#include "tiot_pm.h"
+#include "tiot_board_log.h"
+
+void tiot_pkt_sys_msg_handle(tiot_controller *ctrl, uint8_t code)
+{
+    if ((code == SYS_INF_GNSS_INIT) || (code == SYS_INF_GNSS_LPPE_INIT)) {
+        tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_REPORT_WORK);
+    } else if (code == SYS_INF_REQUEST_SLEEP) {
+        tiot_print_info("[TIoT:pkt]recv request sleep\n");
+        tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_REQUEST_SLEEP_ACK);
+    } else {
+        tiot_print_warning("[TIoT:pkt]recv unknown sys msg:0x%x\n", code);
+    }
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_handle.h b/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_handle.h
new file mode 100644 (file)
index 0000000..154645a
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-02-29, Create file. \n
+ */
+#ifndef TIOT_SYS_MSG_HANDLE_H
+#define TIOT_SYS_MSG_HANDLE_H
+
+#include "tiot_controller.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+void tiot_pkt_sys_msg_handle(tiot_controller *ctrl, uint8_t code);
+
+void tiot_pkt_sys_msg_slave_handle(tiot_controller *ctrl, uint8_t code);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_slave_handle.c b/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_slave_handle.c
new file mode 100644 (file)
index 0000000..7b359ff
--- /dev/null
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-02-29, Create file. \n
+ */
+#include "tiot_sys_msg_handle.h"
+#include "tiot_sys_msg_types.h"
+#include "tiot_slave_board_port.h"
+#include "tiot_pm_slave.h"
+#include "tiot_board_log.h"
+
+void tiot_pkt_sys_msg_slave_handle(tiot_controller *ctrl, uint8_t code)
+{
+    switch (code) {
+        case SYS_PL_BFGNI_HOST_ASKTO_SLP:
+            tiot_print_info("[TIoT:pkt]recv allow sleep.\n");
+            tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_SLEEP_ACK);
+            break;
+        case SYS_PL_BFGNI_HOST_DISALLOW_DEVSLP:
+            tiot_print_info("[TIoT:pkt]recv disallow sleep.\n");
+            tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_WAKEUP_ACK);
+            break;
+        default:
+            tiot_print_warning("[TIoT:pkt]recv unknown sys msg:0x%x\n", code);
+            break;
+    }
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_types.h b/code/sdk/zhihui/gnss/driver/common/sys_msg_handler/tiot_sys_msg_types.h
new file mode 100644 (file)
index 0000000..7c5cb36
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description: TIoT sys msg types. \n
+ *
+ * History: \n
+ * 2024-03-11, Create file. \n
+ */
+#ifndef TIOT_SYS_MSG_TYPES_H
+#define TIOT_SYS_MSG_TYPES_H
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_interface_types TIoT sys msg types.
+ * @ingroup  tiot_common_interface
+ * @{
+ */
+enum SYS_INF_MSG_VALUE_ENUM {
+    SYS_INF_PF_INIT = 0x00,                /* 平台软件初始化完成 */
+    SYS_INF_BT_INIT = 0x01,                /* BT软件初始化完成 */
+    SYS_INF_GNSS_INIT = 0x02,              /* GNSS软件初始化完成 */
+    SYS_INF_FM_INIT = 0x03,                /* FM软件初始化完成 */
+    SYS_INF_BT_DISABLE = 0x04,             /* BT禁能 */
+    SYS_INF_GNSS_DISABLE = 0x05,           /* GNSS禁能 */
+    SYS_INF_FM_DISABLE = 0x06,             /* FM禁能 */
+    SYS_INF_BT_EXIT = 0x07,                /* BT退出 */
+    SYS_INF_GNSS_EXIT = 0x08,              /* GNSS退出 */
+    SYS_INF_FM_EXIT = 0x09,                /* FM退出 */
+    SYS_INF_GNSS_WAIT_DOWNLOAD = 0x0A,     /* 等待GNSS代码下载 */
+    SYS_INF_GNSS_DOWNLOAD_COMPLETE = 0x0B, /* GNSS代码下载完毕 */
+    SYS_INF_BFG_HEART_BEAT = 0x0C,         /* 心跳信号 */
+    SYS_INF_DEV_AGREE_HOST_SLP = 0x0D,     /* device回复host可睡 */
+    SYS_INF_DEV_NOAGREE_HOST_SLP = 0x0E,   /* device回复host不可睡 */
+    SYS_INF_WIFI_OPEN = 0x0F,              /* WCPU上电完成 */
+    SYS_INF_IR_INIT = 0x10,                /* IR软件初始化完成 */
+    SYS_INF_IR_EXIT = 0x11,                /* IR退出 */
+    SYS_INF_NFC_INIT = 0x12,               /* NFC软件初始化完成 */
+    SYS_INF_NFC_EXIT = 0x13,               /* NFC退出 */
+    SYS_INF_WIFI_CLOSE = 0x14,             /* WCPU下电完成 */
+    SYS_INF_RF_TEMP_NORMAL = 0x15,         /* RF温度正常 */
+    SYS_INF_RF_TEMP_OVERHEAT = 0x16,       /* RF温度过热 */
+    SYS_INF_MEM_DUMP_COMPLETE = 0x17,      /* bfgx异常时,MEM DUMP已完成 */
+    SYS_INF_WIFI_MEM_DUMP_COMPLETE = 0X18, /* bfgx异常时,MEM DUMP已完成 */
+    SYS_INF_UART_HALT_WCPU = 0x19,         /* uart halt wcpu ok */
+    SYS_INF_UART_LOOP_SET_DONE = 0x1a,     /* device 设置uart环回ok */
+    SYS_INF_CHR_ERRNO_REPORT = 0x1b,       /* device向host上报CHR异常码 */
+
+    SYS_INF_FAKE_CLOSE_BT =  0x1c,         /* FAKE CLOSE BT的ACK */
+    SYS_INF_RSV1 = 0x1d,                   /* rsv */
+    SYS_INF_RSV2 = 0x1e,                   /* rsv */
+
+    SYS_INF_GNSS_LPPE_INIT = 0x1F,         /* MP13 GNSS 新增的线程初始化完成 */
+    SYS_INF_GNSS_LPPE_EXIT = 0x20,         /* MP13 GNSS 新增的线程退出 */
+    SYS_INF_GNSS_TRICKLE_SLEEP = 0x21,     /* MP13 GNSS_TRICKLE_SLEEP */
+    SYS_INF_ENABLE_GPIO_WKUP_BFG_RSP = 0x22, /* 配置uart or gpio唤醒 */
+    SYS_INF_BOOT_UP_ACK = 0x23,             /* device启动时通过消息回复ack的场景(通常是通过GPIO回复ack) */
+    SYS_INF_WAKE_UP_ACK = 0x24,             /* device被唤醒时通过消息回复ack的场景(通常是通过GPIO回复ack) */
+    SYS_INF_SLE_INIT = 0x25,                /* SLE软件初始化完成 */
+    SYS_INF_SLE_EXIT = 0x26,                /* SLE退出 */
+    SYS_INF_REQUEST_SLEEP = 0x27,           /* device请求睡眠 */
+
+    SYS_INF_BUTT /* 枚举定义最大不能超过127,因为128~255被用来当做心跳的时间戳 */
+};
+
+enum SYS_PL_MSG_VALUE_ENUM {
+    SYS_PL_OPEN_BT = 0x0,
+    SYS_PL_CLOSE_BT = 0x1,
+    SYS_PL_OPEN_GNSS = 0x2,
+    SYS_PL_CLOSE_GNSS = 0x3,
+    SYS_PL_OPEN_FM = 0x4,
+    SYS_PL_CLOSE_FM = 0x5,
+    SYS_PL_OPEN_NFC = 0x6,
+    SYS_PL_CLOSE_NFC = 0x7,
+    SYS_PL_OPEN_IR = 0x8,
+    SYS_PL_CLOSE_IR = 0x9,
+    SYS_PL_OPEN_WIFI = 0xa,                  /* host通过uart打开WCPU */
+    SYS_PL_CLOSE_WIFI = 0xb,                 /* host通过uart关闭WCPU */
+
+    SYS_PL_READ_STACK = 0xc,                 /* host通过uart读栈,心跳超时时使用 */
+    SYS_PL_QUERY_RF_TEMP = 0xd,              /* host通过uart查询rf温度 */
+
+    SYS_PL_BFGNI_HOST_ASKTO_SLP = 0xe,       /* host allow device sleep */
+    SYS_PL_BFGNI_HOST_DISALLOW_DEVSLP = 0xf, /* host disallow device sleep */
+
+    SYS_PL_BFGNI_SHUTDOWN = 0x10,
+    SYS_PL_ENABLE_PM = 0x11,                     /* enable plat dev lowpower feature */
+    SYS_PL_DISABLE_PM = 0x12,                    /* disable plat dev lowpower feature */
+    SYS_PL_BT_ENABLE_PM = 0x13,                  /* enable BT dev lowpower feature */
+    SYS_PL_BT_DISABLE_PM = 0x14,                 /* disable BT dev lowpower feature */
+    SYS_PL_GNSS_ENABLE_PM = 0x15,                /* enable GNSS dev lowpower feature */
+    SYS_PL_GNSS_DISABLE_PM = 0x16,               /* disable GNSS dev lowpower feature */
+    SYS_PL_NFC_ENABLE_PM = 0x17,                 /* enable NFC dev lowpower feature */
+    SYS_PL_NFC_DISABLE_PM = 0x18,                /* disable NFC dev lowpower feature */
+
+    SYS_PL_TEST_CAUSE_PANIC = 0x19,              /* HOST发命令,触发device进入exception */
+    SYS_PL_DUMP_RESET_WCPU = 0x1a,               /* host通过uart不掉电复位WCPU */
+
+    SYS_PL_HALT_WCPU = 0x1b,                     /* halt WCPU */
+    SYS_PL_READ_WLAN_PUB_REG = 0x1c,             /* 读取wcpu的公共寄存器 */
+    SYS_PL_READ_WLAN_PRIV_REG = 0x1d,            /* 读取wcpu的私有寄存器 */
+    SYS_PL_READ_WLAN_MEM = 0x1e,                 /* 读取wcpu的mem */
+
+    SYS_PL_EXCEP_RESET_WCPU = 0x1f,              /* wifi DFR WCPU复位 */
+
+    SYS_PL_SET_UART_LOOP_HANDLER = 0x20,         /* 设置device侧uart环回处理函数 */
+    SYS_PL_SET_UART_LOOP_FINISH = 0x21,          /* UART环回test ok,恢复gnss消息处理函数 */
+
+    SYS_PL_PM_DEBUG = 0x22,                      /* 低功耗维测开关 */
+    SYS_PL_BAUT_CHG_REQ_ACK = 0x23,              /* 波特率切换请求ACK */
+    SYS_PL_BAUT_CHG_COMPLETE = 0x24,             /* 波特率切换完成 */
+
+    SYS_PL_WIFI_OPEN_NOTIFY = 0x25,              /* wifi open  通知 */
+    SYS_PL_WIFI_CLOSE_NOTIFY = 0x26,             /* wifi close 通知 */
+
+    SYS_PL_CFG_OPEN_GLE  = 0x28,                 /* host通过uart打开GLE */
+    SYS_PL_CFG_CLOSE_GLE = 0x29,                 /* host通过uart打开GLE */
+
+    SYS_PL_PM_SET_WAKEUP_HOST_VALID = 0x30,     /* 根据板级连接配置device可以唤醒host */
+    SYS_PL_PM_SET_WAKEUP_HOST_INVALID = 0x31,   /* 根据板级连接配置device不需要唤醒host */
+
+    SYS_PL_BUTT
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/transfer/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7ca3278
--- /dev/null
@@ -0,0 +1,21 @@
+set(\r
+    tiot_transfer_src_list\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_xfer.c\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_xfer_utils.c\r
+)\r
+\r
+set(\r
+    tiot_transfer_header_list\r
+    ${CMAKE_CURRENT_SOURCE_DIR}\r
+)\r
+\r
+if(DEFINED CONFIG_XFER_PACKET_TIOT)\r
+add_subdirectory(packet_handle/tiot_packet)\r
+endif()\r
+\r
+if(DEFINED CONFIG_XFER_PACKET_NCI)\r
+add_subdirectory(packet_handle/nci_packet)\r
+endif()\r
+\r
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_transfer_src_list}" CACHE INTERNAL "tiot src list" FORCE)\r
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${tiot_transfer_header_list}" CACHE INTERNAL "tiot header list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5ec3271
--- /dev/null
@@ -0,0 +1,8 @@
+set(
+    tiot_packet_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_packet_manager.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_packet.c
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_packet_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet.c b/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet.c
new file mode 100644 (file)
index 0000000..746933f
--- /dev/null
@@ -0,0 +1,919 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-08-03, Create file. \n
+ */
+
+#include "tiot_packet.h"
+#include "tiot_sys_msg_handle.h"
+#include "tiot_controller.h"
+#include "tiot_board_log.h"
+#include "tiot_board_pin_port.h"
+#include "tiot_xfer_utils.h"
+#include "securec.h"
+
+typedef enum {
+    TIOT_PKT_FRAME_IDLE,
+    TIOT_PKT_FRAME_HEAD,
+    TIOT_PKT_FRAME_PAYLOAD,
+    TIOT_PKT_FRAME_TAIL
+} tiot_pkt_rx_frame;
+
+typedef enum {
+    TIOT_PKT_RX_SEPERATE_START,
+    TIOT_PKT_RX_SEPERATE_COMMON,
+    TIOT_PKT_RX_SEPERATE_LAST,
+    TIOT_PKT_RX_COMPLETE,
+} tiot_pkt_rx_sep_tag;
+
+typedef void (* tiot_pkt_msg_handler)(tiot_packet_context *ctx);
+
+static void tiot_packet_sys_func(tiot_packet_context *ctx);
+static void tiot_packet_recv_not_seperated_data(tiot_packet_context *ctx);
+static void tiot_packet_recv_seperated_data(tiot_packet_context *ctx);
+static int32_t tiot_packet_copy_from_queue(tiot_packet_context *ctx, tiot_packet_queue *queue,
+                                           uint8_t *buff, uint32_t buff_len);
+
+static tiot_pkt_msg_handler g_tiot_pkt_msg_handle[MSG_BUTT] = {
+    [SYS_MSG] = tiot_packet_sys_func,                      // SYS_MSG = 0x00,         系统串口消息
+    [GNSS_FIRST_MSG] = tiot_packet_recv_seperated_data,    // GNSS_FIRST_MSG = 0x02,  GNSS串口消息,第一个分段消息
+    [GNSS_COMMON_MSG] = tiot_packet_recv_seperated_data,   // GNSS_COMMON_MSG = 0x03, GNSS串口消息,中间分段消息
+    [GNSS_LAST_MSG] = tiot_packet_recv_seperated_data,     // GNSS_LAST_MSG = 0x04,   GNSS串口消息,最后一个分段消息
+    [OML_MSG] = tiot_packet_recv_not_seperated_data,       // OML_MSG = 0x0e,         OML串口消息
+    [SLE_MSG] = tiot_packet_recv_not_seperated_data,       // SLE_MSG = 0x15,         SLE串口消息
+};
+
+static const tiot_packet_subsys_info g_tiot_pkt_subsys_info[SUBSYS_BUTT] = {
+    { PKG_SEPRETED, GNSS_FIRST_MSG, GNSS_COMMON_MSG, GNSS_LAST_MSG },
+    { PKG_NOT_SEPRETED, OML_MSG, OML_MSG, OML_MSG },
+    { PKG_NOT_SEPRETED, SYS_MSG, SYS_MSG, SYS_MSG }
+};
+
+/* 将旧packet节点推入队列,若队列已满,则丢包. */
+static inline void tiot_cur_packet_to_queue(tiot_packet_context *ctx)
+{
+    tiot_packet_manager_enqueue_packet(&ctx->rx_manager, ctx->rx_queue_id);
+    ctx->frame_cnt = 0;
+    ctx->packet = NULL;
+}
+
+/* 丢包时释放packet节点,重置当前packet节点为空,收到新数据时重新获取对应节点. */
+static inline void tiot_cur_packet_discard(tiot_packet_context *ctx)
+{
+#ifndef CONFIG_BOARD_DYNAMIC_ALLOC
+    if (ctx->packet != NULL) {
+        circ_buf_update_read_pos(&(ctx->rx_buff.buf), ctx->packet->len);
+    }
+#endif
+    tiot_packet_manager_discard_packet(&ctx->rx_manager, ctx->rx_queue_id);
+    ctx->frame_cnt = 0;
+    ctx->packet = NULL;
+}
+
+/* 按照subsys code更新当前packet节点. */
+static inline void tiot_cur_packet_update(tiot_packet_context *ctx, uint8_t subsys_code)
+{
+    uint16_t queue_id = ctx->rx_manager.match(subsys_code);
+    if ((ctx->packet == NULL) || (queue_id != ctx->rx_queue_id)) {
+        ctx->rx_queue_id = queue_id;
+        ctx->packet = tiot_packet_manager_get_packet(&ctx->rx_manager, queue_id);
+    }
+}
+
+static inline void packet_frame_error(tiot_packet_context *ctx)
+{
+    ctx->frame_error = 1;
+    ctx->pos = NULL;
+}
+
+static void tiot_packet_report_work(tiot_packet_context *ctx)
+{
+    tiot_controller *ctrl;
+    tiot_xfer_manager *xfer;
+    uint32_t wakein_pin;
+    if (ctx == NULL) {
+        return;
+    }
+    xfer = ctx->xfer;
+    if (xfer == NULL) {
+        return;
+    }
+    ctrl = tiot_container_of(xfer, tiot_controller, transfer);
+    wakein_pin = ctrl->pm.pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST];
+    if (wakein_pin == TIOT_PIN_NONE) {
+        /* 没有dev_wkup_host管脚时,host不休眠(只是PM状态切换),通过上报消息来判断device状态 */
+        tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_REPORT_WORK);
+    }
+}
+
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+static inline tiot_packet_rx_node *tiot_packet_rx_node_malloc(uint32_t len)
+{
+    tiot_packet_rx_node *node = (tiot_packet_rx_node *)osal_kmalloc(sizeof(tiot_packet_rx_node) + len, OSAL_GFP_KERNEL);
+    if (node == NULL) {
+        tiot_print_err("[TIoT]pkt rx node malloc fail.");
+        return NULL;
+    }
+    node->data = (uint8_t *)node + sizeof(tiot_packet_rx_node);
+    node->len = len;
+    return node;
+}
+#endif
+
+int32_t tiot_packet_init(tiot_packet_context *ctx, tiot_xfer_manager *xfer, const tiot_packet_context_param *param)
+{
+    tiot_packet_buffer *buff;
+    if ((ctx == NULL) || (xfer == NULL) || (xfer->pkt_context != 0) || (param == NULL)) {
+        return -1;
+    }
+
+    /* 接收状态机初始状态均为0,只需要memset为0即可. */
+    (void)memset_s((void *)ctx, sizeof(tiot_packet_context), 0, sizeof(tiot_packet_context));
+    (void)memcpy_s((void *)&ctx->rx_manager, sizeof(tiot_packet_manager),
+                   &param->rx_manager_info, sizeof(tiot_packet_manager));
+
+    if (osal_mutex_init(&ctx->tx_packet_mutex) != OSAL_SUCCESS) {
+        tiot_print_err("[TIoT][pkt]tx packet mutex init failed.\n");
+        return -1;
+    }
+
+    if (tiot_packet_manager_init(&ctx->rx_manager) != 0) {
+        osal_mutex_destroy(&ctx->tx_packet_mutex);
+        return -1;
+    }
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    tiot_unused(buff);
+#else
+    buff = param->buff;
+    (void)memset_s(buff->start, buff->size, 0, buff->size);
+    circ_buf_init(&(ctx->rx_buff.buf), &(ctx->rx_buff.buff_write), &(ctx->rx_buff.buff_read), buff->start, buff->size);
+#endif
+    ctx->flags = param->flags;
+    ctx->xfer = xfer;
+    /* 调用tiot_xfer_install_packet后才注册到xfer内. */
+    return 0;
+}
+
+void tiot_packet_deinit(tiot_packet_context *ctx)
+{
+    if (ctx == NULL) {
+        return;
+    }
+    ctx->xfer = NULL;
+    ctx->packet = NULL;
+    tiot_packet_manager_deinit(&ctx->rx_manager);
+    osal_mutex_destroy(&ctx->tx_packet_mutex);
+}
+
+static void tiot_packet_sys_func(tiot_packet_context *ctx)
+{
+    uint8_t syschar = ctx->sys_msg;
+    tiot_xfer_manager *xfer = ctx->xfer;
+    tiot_controller *ctrl = tiot_container_of(xfer, tiot_controller, transfer);
+
+    if (ctrl->dev_info->pkt_sys_msg_handle != NULL) {
+        ctrl->dev_info->pkt_sys_msg_handle(ctrl, syschar);
+    } else {
+        tiot_print_warning("[TIoT][pkt]pkt_sys_msg_handle is NULL.\r\n");
+    }
+}
+
+static void tiot_packet_cums_recv_handle(tiot_packet_context *ctx)
+{
+    int32_t copy_len;
+    tiot_packet_queue *queue;
+    tiot_xfer_cbk_param rx_cbk_param = ctx->xfer->rx_cbk_param;
+
+    /* 直接使用上一次的rx_queue_id. */
+    queue = tiot_packet_manager_find_queue(&ctx->rx_manager, ctx->rx_queue_id);
+    if (queue == NULL) {
+        tiot_print_err("[TIoT:pkt]can't find subsys queue(%d).\r\n", ctx->rx_queue_id);
+        return;
+    }
+
+    if (rx_cbk_param.rx_callback != NULL) {
+        /* 用户注册了rx callback,直接就地处理 */
+        copy_len = tiot_packet_copy_from_queue(ctx, queue, rx_cbk_param.buff, rx_cbk_param.buff_len);
+        rx_cbk_param.rx_callback(rx_cbk_param.buff, copy_len);
+    } else {
+        /* 唤醒等待的reader */
+        osal_wait_wakeup_interruptible(&queue->rx_wait);
+    }
+}
+
+static void tiot_packet_recv_not_seperated_data(tiot_packet_context *ctx)
+{
+    /* 处理之前的包错误, 释放当前包 */
+    if (ctx->frame_error == 1) {
+        tiot_cur_packet_discard(ctx);
+        ctx->frame_error = 0;
+        return;
+    }
+    /* 正常完整包. */
+    ctx->packet->tag = TIOT_PKT_TAG_BINARY;
+    tiot_cur_packet_to_queue(ctx);
+    tiot_packet_cums_recv_handle(ctx);
+}
+
+static void tiot_packet_recv_seperated_data(tiot_packet_context *ctx)
+{
+    uint8_t subsys_code = ctx->head.subsys_code;
+    /* 包顺序检测 */
+    if (subsys_code == GNSS_FIRST_MSG) {
+        /* First 包必须为第一个包 */
+        if (ctx->frame_cnt != 1) {
+            tiot_print_err("[TIoT:pkt]parse error: expect first packet.\r\n");
+            packet_frame_error(ctx);
+        }
+        return;
+    }
+    if (subsys_code == GNSS_COMMON_MSG) {
+        /* 必须先有fisrt包再有common包,所以收到common包时frame_cnt最小为2 */
+        if (ctx->frame_cnt < 2) {
+            tiot_print_err("[TIoT:pkt]parse error: expect first-common packet.\r\n");
+            packet_frame_error(ctx);
+        }
+        return;
+    }
+    /* 收完Last包数据才处理之前的包序错误, 确保完整包被释放 */
+    if ((subsys_code == GNSS_LAST_MSG) && (ctx->frame_error == 1)) {
+        tiot_print_err("[TIoT:pkt]packet order error, discard the whole packet.\r\n");
+        tiot_cur_packet_discard(ctx);
+        ctx->frame_error = 0;
+        return;
+    }
+    /* 正常完整包. */
+    ctx->packet->tag = TIOT_PKT_TAG_BINARY;
+    tiot_cur_packet_to_queue(ctx);
+    tiot_packet_cums_recv_handle(ctx);
+}
+
+static int32_t tiot_packet_head_check(tiot_packet_head *head)
+{
+    /* 包头错误!!! */
+    if (head->head != TIOT_PKT_HEAD) {
+        tiot_print_err("[TIoT:pkt]head error: 0x%x\r\n", head->head);
+        return -1;
+    }
+    /* 子系统错误 */
+    if (head->subsys_code >= MSG_BUTT) {
+        tiot_print_err("[TIoT:pkt]subsys error: 0x%x\r\n", head->subsys_code);
+        return -1;
+    }
+    /* 系统消息特殊判断, 长度必须为0x6. */
+    if ((head->subsys_code == SYS_MSG) && (head->len != (TIOT_PKT_PKG_SIZE + sizeof(uint8_t)))) {
+        tiot_print_err("[TIoT:pkt]sys msg len error: 0x%x\r\n", head->len);
+        return -1;
+    }
+    /* payload大小 小于0 或大于最大包大小 */
+    if ((head->len <= TIOT_PKT_PKG_SIZE) ||
+        (head->len > (TIOT_PKT_PAYLOAD_MAX_SIZE + TIOT_PKT_PKG_SIZE))) {
+        tiot_print_err("[TIoT:pkt]payload error: 0x%x\r\n", head->len);
+        return -1;
+    }
+    return 0;
+}
+
+static int32_t tiot_packet_head_try_recovery(tiot_packet_context *ctx)
+{
+    uint8_t i;
+    uint8_t *head_data;
+    errno_t err;
+    head_data = (uint8_t *)&ctx->head;
+    /* 出现问题时,先把上一个起始标志位丢弃. */
+    for (i = 1; i < sizeof(tiot_packet_head); i++) {
+        /* 头部出现其他pkt_head时,可以尝试恢复. */
+        if (head_data[i] == TIOT_PKT_HEAD) {
+            break;
+        }
+    }
+    if (i == sizeof(tiot_packet_head)) {
+        return -1;
+    }
+    tiot_print_dbg("[TIoT][pkt]head: [%x %x %x %x].\r\n",
+                   head_data[0], head_data[1], head_data[2], head_data[3]);  /* 打印恢复前head数据. */
+    tiot_print_warning("[TIoT][pkt]head recovery.\r\n");
+    err = memmove_s((void *)&ctx->head, sizeof(tiot_packet_head), &head_data[i], sizeof(tiot_packet_head) - i);
+    if (err != EOK) {
+        tiot_print_err("[TIoT][pkt]memmove_s error.\r\n");
+        return -1;
+    }
+    /* 更新需要读取的个数 & 位置. */
+    ctx->frame_need_read = i;
+    ctx->pos = &head_data[sizeof(tiot_packet_head) - i];
+    return 0;
+}
+
+static void tiot_packet_head_done(tiot_packet_context *ctx)
+{
+    tiot_packet_head *head = &ctx->head;
+    uint16_t payload_len = head->len - TIOT_PKT_PKG_SIZE;
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    tiot_packet_rx_node *node = NULL;
+#endif
+    if (tiot_packet_head_check(head) != 0) {
+        if (tiot_packet_head_try_recovery(ctx) == 0) {
+            /* 恢复成功,继续处理. */
+            return;
+        }
+        goto discard;
+    }
+    /* 消息头校验OK时,认为work. */
+    tiot_packet_report_work(ctx);
+    /* 系统消息不分包特殊处理,避免申请内存. */
+    if (head->subsys_code == SYS_MSG) {
+        ctx->frame_need_read = sizeof(uint8_t);
+        ctx->pos = &ctx->sys_msg;
+        ctx->current_frame = TIOT_PKT_FRAME_PAYLOAD;
+        return;
+    }
+
+    tiot_cur_packet_update(ctx, head->subsys_code);
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    if (ctx->packet != NULL) {
+        node = tiot_packet_rx_node_malloc(payload_len);
+        if (node == NULL) {
+            packet_frame_error(ctx);
+        } else {
+            tiot_list_add_tail(&(node->node), ctx->packet->head);
+            ctx->pos = node->data;
+        }
+    } else {
+        tiot_print_err("[TIoT:rx]circ queue no space.\n");
+        packet_frame_error(ctx);
+    }
+#else
+    if ((ctx->packet == NULL) || (circ_buf_query_free(&(ctx->rx_buff.buf)) <= payload_len)) {
+        tiot_print_err("[TIoT:rx]circ queue or rx buff no space.\n");
+        packet_frame_error(ctx);
+    }
+    if (ctx->packet != NULL) {
+        ctx->packet->len += payload_len;
+    }
+#endif
+    ctx->frame_need_read = payload_len;
+    ctx->frame_cnt++;
+    ctx->current_frame = TIOT_PKT_FRAME_PAYLOAD;
+    return;
+
+discard:
+    tiot_cur_packet_discard(ctx);
+    ctx->current_frame = TIOT_PKT_FRAME_IDLE;
+}
+
+static void tiot_packet_payload_done(tiot_packet_context *ctx)
+{
+    ctx->current_frame = TIOT_PKT_FRAME_TAIL;
+    ctx->frame_need_read = TIOT_PKT_TAIL_SIZE;
+    ctx->pos = &ctx->tail;
+}
+
+static void tiot_packet_tail_done(tiot_packet_context *ctx)
+{
+    uint8_t tail = ctx->tail;
+    uint8_t subsys_code;
+    if (tail != TIOT_PKT_TAIL) {
+        tiot_cur_packet_discard(ctx);
+        ctx->current_frame = TIOT_PKT_FRAME_IDLE;
+        ctx->frame_error = 0;
+        return;
+    }
+
+    /* 在head done内已经确保subsys_code正确 */
+    subsys_code = ctx->head.subsys_code;
+    if (g_tiot_pkt_msg_handle[subsys_code] != NULL) {
+        g_tiot_pkt_msg_handle[subsys_code](ctx);
+    }
+    ctx->current_frame = TIOT_PKT_FRAME_IDLE;
+}
+
+uint32_t tiot_packet_handle(tiot_packet_context *ctx, uint8_t *data, uint32_t data_len)
+{
+    uint16_t packet_len = (uint16_t)(data_len & 0xFFFF);  /* 取低16位,包格式只需要16位大小. */
+    uint32_t handle_len = packet_len < ctx->frame_need_read ? packet_len : ctx->frame_need_read;
+    ctx->frame_need_read -= handle_len;
+
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    if (ctx->pos != NULL) {
+        (void)memcpy_s(ctx->pos, handle_len, data, handle_len);
+        ctx->pos += handle_len;
+    } else {
+        tiot_print_dbg("[TIoT][rx]packet buff pos is NULL.\n");
+    }
+#else
+    /* 系统消息直接拷贝;buffer放不下时丢包处理,使用frame_error标识. */
+    if ((ctx->current_frame == TIOT_PKT_FRAME_PAYLOAD) &&
+        (ctx->head.subsys_code != SYS_MSG)) {
+        circ_buf_write_data(&(ctx->rx_buff.buf), data, handle_len, ctx->rx_buff.buff_write);
+        circ_buf_update_write_pos(&(ctx->rx_buff.buf), handle_len);
+    } else {
+        if (ctx->pos != NULL) {
+            (void)memcpy_s(ctx->pos, handle_len, data, handle_len);
+            ctx->pos += handle_len;
+        } else {
+            tiot_print_dbg("[TIoT][rx]packet buff pos is NULL.\n");
+        }
+    }
+#endif
+
+    if (ctx->frame_need_read != 0) {
+        return handle_len;
+    }
+
+    /* 完成一帧数据 */
+    switch (ctx->current_frame) {
+        case TIOT_PKT_FRAME_HEAD:
+            tiot_packet_head_done(ctx);
+            break;
+        case TIOT_PKT_FRAME_PAYLOAD:
+            tiot_packet_payload_done(ctx);
+            break;
+        case TIOT_PKT_FRAME_TAIL:
+            tiot_packet_tail_done(ctx);
+            break;
+        default:
+            tiot_print_dbg("[TIoT][rx]err frame: %d\n", ctx->current_frame);
+            break;
+    }
+    return handle_len;
+}
+
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+static inline void tiot_packet_ascii_line_store(tiot_packet_context *ctx, uint8_t *line_start, uint32_t line_len)
+{
+    tiot_packet_rx_node *node = tiot_packet_rx_node_malloc(line_len);
+    if (node == NULL) {
+        /* discard */
+        return;
+    }
+    (void)memcpy_s(node->data, line_len, line_start, line_len);
+    tiot_list_add_tail(&(node->node), ctx->packet->head);
+}
+#else
+static inline void tiot_packet_ascii_line_store(tiot_packet_context *ctx, uint8_t *line_start, uint32_t line_len)
+{
+    if (circ_buf_query_free(&(ctx->rx_buff.buf)) <= line_len) {
+        tiot_print_err("[TIoT][rx]rx buffer no space for data.");
+        return;
+    }
+    circ_buf_write(&(ctx->rx_buff.buf), line_start, line_len);
+    ctx->packet->len += line_len;
+}
+#endif
+
+static void tiot_packet_ascii_line_handle(tiot_packet_context *ctx, uint8_t *data, uint32_t handle_len)
+{
+    uint8_t *left = data;
+    uint8_t *right = data;
+    uint32_t line_len = 0;
+    while (right < (data + handle_len)) {
+        if (*right != '\n') {
+            right++;
+            continue;
+        }
+        /* 找到行尾. */
+        line_len = right - left + 1; /* 当前字符也复制 '\n'. */
+        tiot_cur_packet_update(ctx, MSG_BUTT); /* ASCII消息使用MSG_BUTT,避免重复. */
+        if (ctx->packet != NULL) {
+            tiot_packet_ascii_line_store(ctx, left, line_len);
+            ctx->packet->tag = TIOT_PKT_TAG_ASCII;
+            tiot_cur_packet_to_queue(ctx);
+            tiot_packet_cums_recv_handle(ctx);
+        } else {
+            tiot_print_err("[TIoT:rx]circ queue no space, discard: 0x%x\r\n", line_len);
+        }
+        left = right + 1;  /* 下一行起始 */
+        right = left;
+    }
+    /* 最后一段没有结尾的情况 */
+    line_len = (data + handle_len) - left;
+    if (line_len == 0) {
+        return;
+    }
+    tiot_cur_packet_update(ctx, MSG_BUTT); /* ASCII消息使用MSG_BUTT,避免重复. */
+    if (ctx->packet != NULL) {
+        tiot_packet_ascii_line_store(ctx, left, line_len);
+        /* ASCII字符串结束判断. */
+        if (ctx->current_frame == TIOT_PKT_FRAME_HEAD) {
+            ctx->packet->tag = TIOT_PKT_TAG_ASCII;
+            tiot_cur_packet_to_queue(ctx);
+            tiot_packet_cums_recv_handle(ctx);
+        }
+    } else {
+        tiot_print_err("[TIoT:rx]circ queue no space, discard: 0x%x\r\n", line_len);
+    }
+}
+
+uint32_t tiot_packet_ascii_handle(tiot_packet_context *ctx, uint8_t *data, uint32_t data_len)
+{
+    /* ascii字符串处理 */
+    uint32_t handle_len = 0;
+    uint8_t *tmp = data;
+    /* 寻找包头起始 */
+    while (handle_len < data_len) {
+        if (*tmp == 0x7e) {
+            break;
+        }
+        tmp++;
+        handle_len++;
+    }
+
+    if (handle_len < data_len) {
+        /* 找到包头 */
+        ctx->current_frame = TIOT_PKT_FRAME_HEAD;
+        ctx->frame_need_read = TIOT_PKT_HEAD_SIZE;
+        ctx->pos = (uint8_t *)&ctx->head;
+    }
+
+    if ((handle_len == 0) || !(ctx->flags & TIOT_PKT_FLAGS_SUPPORT_ASCII)) {
+        /* 1. 第一个字节即0x7e, 不需要处理. */
+        /* 2. 不支持上报ascii数据,直接丢包处理. */
+        goto discard;
+    }
+    /* 支持上报ascii数据时,有数据认为work. */
+    tiot_packet_report_work(ctx);
+    tiot_packet_ascii_line_handle(ctx, data, handle_len);
+discard:
+    return handle_len;
+}
+
+void tiot_packet_rx_data_parse(tiot_packet_context *ctx, uint8_t *data, uint32_t len)
+{
+    uint8_t *buff = data;
+    uint32_t handle_len = 0;
+    uint32_t total_len = len;
+
+    while (total_len) {
+        if (ctx->current_frame == TIOT_PKT_FRAME_IDLE) {
+            handle_len = tiot_packet_ascii_handle(ctx, buff, total_len);
+        } else {
+            handle_len = tiot_packet_handle(ctx, buff, total_len);
+        }
+        buff += handle_len;
+        total_len -= handle_len;
+    }
+}
+
+void tiot_packet_rx_data_store(tiot_xfer_manager *xfer, uint8_t *data, uint32_t len)
+{
+    tiot_packet_context *ctx = NULL;
+    /* 入参已在调用处判空 */
+    ctx = (tiot_packet_context *)xfer->pkt_context;
+    tiot_packet_rx_data_parse(ctx, data, len);
+}
+
+static int tiot_packet_read_out_check(const void *param)
+{
+    int check;
+    tiot_packet_manager_query *query = (tiot_packet_manager_query *)param;
+    tiot_xfer_manager *xfer = query->xfer;
+    tiot_packet_context *ctx = (tiot_packet_context *)xfer->pkt_context;
+    if (ctx == NULL) {
+        tiot_print_warning("[TIoT][rx]read out check: pkt_context is NULL\n");
+        return 1;
+    }
+    check = (xfer->rx_wait_func(xfer) != 0) ||
+            (tiot_packet_manager_has_data(&ctx->rx_manager, query->queue_id));
+    return check;
+}
+
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+static int32_t tiot_packet_is_valid(tiot_packet *packet)
+{
+    uint16_t frame_cnt = 0;
+    tiot_packet_rx_node *pos;
+    if (packet->head == NULL) {
+        return -1;
+    }
+    tiot_list_for_each_entry(pos, packet->head, node, tiot_packet_rx_node) {
+        if ((pos->data == NULL) || (pos->len == 0)) {
+            return -1;
+        }
+        frame_cnt++;
+    }
+    if (frame_cnt == 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static int32_t tiot_packet_copy_from_queue(tiot_packet_context *ctx, tiot_packet_queue *queue,
+                                           uint8_t *buff, uint32_t buff_len)
+{
+    tiot_packet *packet = NULL;
+    uint8_t *tmp_buff = buff;
+    uint32_t copy_len;
+    tiot_packet_rx_node *pos;
+
+    do {
+        copy_len = 0;
+        packet = (tiot_packet *)tiot_circ_queue_dequeue(&queue->queue);
+        if (packet == NULL) {
+            tiot_print_info("[TIoT][rx]packet queue is empty.\n");
+            break;
+        }
+        if (tiot_packet_is_valid(packet) != 0) {
+            tiot_print_err("[TIoT][rx]invalid packet.");
+            tiot_packet_free_packet(packet);
+            continue;
+        }
+
+        tiot_list_for_each_entry(pos, packet->head, node, tiot_packet_rx_node) {
+            copy_len += pos->len;
+        }
+        if (ctx->flags & TIOT_PKT_FLAGS_SUPPORT_ASCII) {
+            copy_len += sizeof(uint16_t);
+        }
+        if (copy_len > buff_len) {
+            tiot_print_info("[TIoT][rx]not enough buff len:%d for this packet: %d.", buff_len, copy_len);
+            tiot_packet_free_packet(packet);
+            continue;
+        }
+        /* 完整包正常, 复制一包到用户buffer后退出. */
+        if (ctx->flags & TIOT_PKT_FLAGS_SUPPORT_ASCII) {
+            (void)memcpy_s((void *)tmp_buff, sizeof(uint16_t), (void *)&packet->tag, sizeof(uint16_t));
+            tmp_buff += sizeof(uint16_t);
+        }
+        tiot_list_for_each_entry(pos, packet->head, node, tiot_packet_rx_node) {
+            (void)memcpy_s((void *)tmp_buff, pos->len, (void *)pos->data, pos->len);
+            tmp_buff += pos->len;
+        }
+        tiot_packet_free_packet(packet);
+        break;
+    } while (packet != NULL);
+
+    return copy_len;
+}
+#else
+static int32_t tiot_packet_copy_from_queue(tiot_packet_context *ctx, tiot_packet_queue *queue,
+                                           uint8_t *buff, uint32_t buff_len)
+{
+    uint32_t copy_len;
+    uint8_t *tmp_buff = buff;
+    tiot_packet *packet;
+    do {
+        copy_len = 0;
+        packet = (tiot_packet *)tiot_circ_queue_dequeue(&queue->queue);
+        if (packet == NULL) {
+            tiot_print_info("[TIoT][rx]packet queue is empty.");
+            break;
+        }
+        copy_len = packet->len;
+        if (ctx->flags & TIOT_PKT_FLAGS_SUPPORT_ASCII) {
+            copy_len += sizeof(uint16_t);
+        }
+        if (copy_len > buff_len) {
+            tiot_print_info("[TIoT][rx]not enough buff len:%d for this packet: %d.", buff_len, copy_len);
+            (void)circ_buf_update_read_pos(&(ctx->rx_buff.buf), packet->len);
+            continue;
+        }
+        /* 完整包正常, 复制一包到用户buffer后退出. */
+        if (ctx->flags & TIOT_PKT_FLAGS_SUPPORT_ASCII) {
+            (void)memcpy_s((void *)tmp_buff, sizeof(uint16_t), (void *)&packet->tag, sizeof(uint16_t));
+            tmp_buff += sizeof(uint16_t);
+        }
+        /* 按顺序读即可,不需要记录起始. */
+        (void)circ_buf_read(&(ctx->rx_buff.buf), tmp_buff, packet->len);
+        break;
+    } while (packet != NULL);
+    return copy_len;
+}
+#endif
+
+#ifdef __KERNEL__
+static int32_t packet_poll(tiot_packet_manager_query *query, tiot_packet_queue *queue, const tiot_xfer_rx_param *param)
+{
+    if (tiot_packet_read_out_check(query) != 0) {
+        return 1;
+    }
+
+    poll_wait(param->filp, (wait_queue_head_t *)(queue->rx_wait.wait), param->poll_wait);
+
+    if (tiot_packet_read_out_check(query) != 0) {
+        return 1;
+    }
+    return 0;
+}
+#endif
+
+int32_t tiot_packet_read_out(tiot_xfer_manager *xfer, uint8_t *buff, uint32_t len, const tiot_xfer_rx_param *param)
+{
+    int32_t read_ret;
+    tiot_packet_queue *queue;
+    tiot_packet_manager_query query;
+    tiot_packet_context *ctx = (tiot_packet_context *)xfer->pkt_context;
+    if (ctx == NULL) {
+        return -1;
+    }
+    queue = tiot_packet_manager_find_queue(&ctx->rx_manager, param->subsys); /* 对应queue_id */
+    if (queue == NULL) {
+        return -1;
+    }
+    query.xfer = xfer;
+    query.queue_id = param->subsys;  /* 对应queue_id. */
+
+#ifdef __KERNEL__
+    if (param->filp != NULL && param->poll_wait != NULL) { /* poll mode */
+        return packet_poll(&query, queue, param);
+    }
+#endif
+
+    if (param->timeout == 0) { /* 非阻塞. */
+        /* 没有数据直接返回. */
+        if (tiot_packet_read_out_check(&query) == 0) {
+            tiot_print_dbg("[TIoT:pkt][%d]no data to read.\r\n", param->subsys);
+            return 0;
+        }
+    } else { /* 阻塞. */
+        if (queue->flags & TIOT_PACKET_QUEUE_RX_WAITING) {
+            tiot_print_err("[TIoT:pkt][%d]there's already a thread blocking read().\r\n", param->subsys);
+            return -1;
+        }
+        queue->flags |= TIOT_PACKET_QUEUE_RX_WAITING;
+        /* 等待接收到一个完整包. */
+        read_ret = osal_wait_timeout_interruptible(&queue->rx_wait, tiot_packet_read_out_check, &query, param->timeout);
+        if (xfer->pkt_context == 0) {
+            read_ret = 0;
+        }
+        queue->flags &= ~TIOT_PACKET_QUEUE_RX_WAITING;
+        if (read_ret <= 0) {
+            tiot_print_warning("[TIoT:pkt][%d]osal_wait timeout.\r\n", param->subsys);
+            return read_ret;
+        }
+    }
+
+    return tiot_packet_copy_from_queue(ctx, queue, buff, len);
+}
+
+#ifdef CONFIG_XFER_SUPPORT_TX_TASK
+static int32_t tiot_tx_packet_fill(uint8_t *dest, uint8_t *payload, uint16_t payload_len, uint8_t subsys_code)
+{
+    uint16_t packet_len = payload_len + TIOT_PKT_PKG_SIZE;
+    uint8_t *packet_buff = dest;
+
+    tiot_packet_head *head = (tiot_packet_head *)packet_buff;
+    head->head = TIOT_PKT_HEAD;
+    head->subsys_code = subsys_code;
+    head->len = packet_len;
+
+    if (memcpy_s(&packet_buff[TIOT_PKT_HEAD_SIZE], payload_len, payload, payload_len) != EOK) {
+        tiot_print_err("[TIoT][tx]packet memcpy err.\r\n");
+        return -1;
+    }
+    packet_buff[packet_len - 1] = TIOT_PKT_TAIL;
+    return 0;
+}
+
+int32_t tiot_packet_tx_push(tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len,
+                            const tiot_xfer_tx_param *param)
+{
+    int32_t ret;
+    uint16_t payload_len;
+    uint32_t total_len;
+    const uint8_t *buff;
+    uint8_t packet_count;
+    const tiot_packet_subsys_info *subsys_info;
+    tiot_xfer_tx_data new_data;
+
+    /* data外部已验证 */
+    if ((param == NULL) || (len == 0)) {
+        tiot_print_err("[TIoT:pkt]tx param is NULL or len is 0.\r\n");
+        return -1;
+    }
+
+    total_len = len;
+    subsys_info = &g_tiot_pkt_subsys_info[param->subsys];
+    /* 分包个数: tx_len / 4095 + (tx_len % 4095 ? 1 : 0) ==> (tx_len + (4095 - 1)) / 4095。 */
+    packet_count = (total_len + TIOT_PKT_PAYLOAD_MAX_SIZE - 1) / TIOT_PKT_PAYLOAD_MAX_SIZE;
+    /* 预先申请 */
+    packet_buff = osal_kmalloc(total_len + packet_count * (TIOT_PKT_PKG_SIZE));
+    if (packet_buff == NULL) {
+        return -1;
+    }
+    tmp = packet_buff;
+
+    for (i = 0; i < packet_count - 1; i++) {
+        payload_len = TIOT_PKT_PAYLOAD_MAX_SIZE;
+        if (i == 0) {
+            ret = tiot_tx_packet_fill(tmp, buff, payload_len, subsys_info->common);
+        } else {
+            ret = tiot_tx_packet_fill(tmp, buff, payload_len, subsys_info->first);
+        }
+        if (ret != 0) {
+            /* 复制数据出错,释放buffer */
+            osal_kfree(packet_buff);
+            return -1;
+        }
+        tmp += payload_len + TIOT_PKT_PKG_SIZE;
+        buff += payload_len;
+    }
+
+    payload_len = total_len - (packet_count - 1) * TIOT_PKT_PAYLOAD_MAX_SIZE;
+    ret = tiot_tx_packet_fill(tmp, buff, payload_len, subsys_info->last);
+    if (ret != 0) {
+        /* 复制数据出错,释放buffer */
+        osal_kfree(packet_buff);
+        return -1;
+    }
+
+    new_data.data = packet_buff;
+    new_data.len = total_len + packet_count * (TIOT_PKT_PKG_SIZE);
+    if (tiot_circ_queue_enqueue(&xfer->tx_queue, (uintptr_t)&new_data) != 0) {
+        osal_kfree(packet_buff);
+        return -1;
+    }
+    return (ret >= 0) ? total_len : (-1);
+}
+#else
+static int32_t tiot_tx_packet_push(tiot_xfer_manager *xfer, const uint8_t *payload,
+                                   uint16_t payload_len, uint8_t subsys_code)
+{
+    int32_t ret = 0;
+    uint16_t packet_len = payload_len + TIOT_PKT_PKG_SIZE;
+    const uint8_t tail = TIOT_PKT_TAIL;
+    tiot_packet_head head = { TIOT_PKT_HEAD, subsys_code, packet_len };
+
+    do {
+        ret = tiot_xfer_direct_send(xfer, (uint8_t *)&head, sizeof(tiot_packet_head));
+        if (ret != sizeof(tiot_packet_head)) {
+            ret = -1;
+            break;
+        }
+        ret = tiot_xfer_direct_send(xfer, payload, payload_len);
+        if (ret != payload_len) {
+            ret = -1;
+            break;
+        }
+        ret = tiot_xfer_direct_send(xfer, &tail, sizeof(uint8_t));
+        if (ret != sizeof(uint8_t)) {
+            ret = -1;
+            break;
+        }
+    } while (0);
+
+    return (ret >= 0) ? (int32_t)packet_len : (-1);
+}
+
+int32_t tiot_packet_tx_push(tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len,
+                            const tiot_xfer_tx_param *param)
+{
+    int32_t ret;
+    uint16_t payload_len;
+    uint32_t total_len;
+    const uint8_t *buff;
+    uint8_t packet_count;
+    uint8_t i;
+    const tiot_packet_subsys_info *subsys_info;
+    tiot_packet_context *pkt_ctx;
+
+    /* data外部已验证 */
+    if ((param == NULL) || (len == 0)) {
+        tiot_print_err("[TIoT:pkt]tx param is NULL or len is 0.\r\n");
+        return -1;
+    }
+
+    pkt_ctx = (tiot_packet_context*)(xfer->pkt_context);
+    if (pkt_ctx == NULL) {
+        tiot_print_err("[TIoT][pkt]packet context is NULL.\r\n");
+        return -1;
+    }
+
+    total_len = len;
+    buff = data;
+    /* 分包个数: tx_len / 4095 + (tx_len % 4095 ? 1 : 0) ==> (tx_len + (4095 - 1)) / 4095。 */
+    packet_count = (total_len + TIOT_PKT_PAYLOAD_MAX_SIZE - 1) / TIOT_PKT_PAYLOAD_MAX_SIZE;
+    subsys_info = &g_tiot_pkt_subsys_info[param->subsys];
+
+    /*
+     * 多线程并发情况下,必须保证每个线程完整地发完整个packet,中间不能插入同类型的其他packet
+     * thread1:  gnss-first           gnss-last
+     * thread2:            gnss-first
+     * 像如上情况就会出现first-first-last,导致解包出现错误
+     */
+    osal_mutex_lock(&pkt_ctx->tx_packet_mutex);
+
+    for (i = 0; i < packet_count - 1; i++) {
+        payload_len = TIOT_PKT_PAYLOAD_MAX_SIZE;
+        if (i == 0) {
+            ret = tiot_tx_packet_push(xfer, buff, payload_len, subsys_info->first);
+        } else {
+            ret = tiot_tx_packet_push(xfer, buff, payload_len, subsys_info->common);
+        }
+
+        if (ret == -1) {
+            osal_mutex_unlock(&pkt_ctx->tx_packet_mutex);
+            return -1;
+        }
+        buff += payload_len;
+    }
+    payload_len = total_len - (packet_count - 1) * TIOT_PKT_PAYLOAD_MAX_SIZE;
+    ret = tiot_tx_packet_push(xfer, buff, payload_len, subsys_info->last);
+
+    osal_mutex_unlock(&pkt_ctx->tx_packet_mutex);
+
+    return (ret >= 0) ? (int32_t)total_len : (-1);
+}
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet.h b/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet.h
new file mode 100644 (file)
index 0000000..9fa18d7
--- /dev/null
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-07-21, Create file. \n
+ */
+#ifndef TIOT_PACKET_H
+#define TIOT_PACKET_H
+
+#include "tiot_types.h"
+#include "tiot_xfer.h"
+#include "tiot_list.h"
+#include "tiot_packet_manager.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_transfer_packet_handle_tiot_packet Packet Handle
+ * @ingroup  tiot_common_transfer_packet_handle
+ * @{
+ */
+
+#define TIOT_PKT_FLAGS_SUPPORT_ASCII       0x1U
+
+#define TIOT_PKT_PAYLOAD_MAX_SIZE 4095U
+#define TIOT_PKT_HEAD_SIZE 4
+#define TIOT_PKT_TAIL_SIZE 1
+#define TIOT_PKT_PKG_SIZE  (TIOT_PKT_HEAD_SIZE + TIOT_PKT_TAIL_SIZE)
+
+#define TIOT_PKT_HEAD  0x7e
+#define TIOT_PKT_TAIL  0x7e
+
+/* 重新定义, 暂时只需要这些 */
+typedef enum {
+    SUBSYS_GNSS = 0x00,
+    SUBSYS_OM  = 0x01,
+    SUBSYS_SYS  = 0x02,
+    SUBSYS_BUTT
+} subsys_type_enum;
+
+typedef enum {
+    TIOT_PKT_TAG_BINARY,
+    TIOT_PKT_TAG_ASCII
+} tiot_pkt_rx_tag;
+
+typedef enum {
+    PKG_NOT_SEPRETED = 0,
+    PKG_SEPRETED = 1,
+} pkg_sepreted_state;
+
+enum TIOT_PKT_DATA_MSG_TYPE_ENUM {
+    SYS_MSG = 0x00,         /* 系统串口消息 */
+    BT_MSG = 0x01,          /* BT串口消息 */
+    GNSS_FIRST_MSG = 0x02,  /* GNSS串口消息,第一个分段消息 */
+    GNSS_COMMON_MSG = 0x03, /* GNSS串口消息,中间分段消息 */
+    GNSS_LAST_MSG = 0x04,   /* GNSS串口消息,最后一个分段消息 */
+    FM_FIRST_MSG = 0x05,    /* FM串口消息,第一个分段消息 */
+    FM_COMMON_MSG = 0x06,   /* FM串口消息,中间分段消息 */
+    FM_LAST_MSG = 0x07,     /* FM串口消息,最后一个分段消息 */
+    IR_FIRST_MSG = 0x08,    /* 红外串口消息,第一个分段消息 */
+    IR_COMMON_MSG = 0x09,   /* 红外串口消息,中间分段消息 */
+    IR_LAST_MSG = 0x0A,     /* 红外串口消息,最后一个分段消息 */
+    NFC_FIRST_MSG = 0x0B,   /* NFC串口消息,第一个分段消息 */
+    NFC_COMMON_MSG = 0x0C,  /* NFC串口消息,中间分段消息 */
+    NFC_LAST_MSG = 0x0D,    /* NFC串口消息,最后一个分段消息 */
+    OML_MSG = 0x0E,         /* 可维可测消息 */
+    MEM_DUMP_SIZE = 0x0f,   /* bfgx异常时,要dump的mem长度消息 */
+    MEM_DUMP = 0x10,        /* bfgx异常时,内存dump消息 */
+    WIFI_MEM_DUMP = 0x11,   /* UART READ WIFI MEM,内存dump消息 */
+    BFGX_CALI_MSG = 0x12,   /* BFGX 校准数据上报 */
+
+    /* GF_CPU消息 */
+    GF_SYS_MSG = 0x13,      /* GF系统串口消息 */
+    GF_OML_MSG = 0x14,      /* GF可维可测消息 */
+
+    SLE_MSG = 0x15,         /* SLE串口消息 */
+
+    MSG_BUTT,
+};
+
+typedef struct {
+    uint8_t seperated;
+    uint8_t first;
+    uint8_t common;
+    uint8_t last;
+} tiot_packet_subsys_info;
+
+typedef struct {
+    uint8_t head;
+    uint8_t subsys_code;
+    uint16_t len;
+} tiot_packet_head;
+
+typedef struct {
+    uint8_t *start;
+    uint32_t size;
+    uint32_t recv_cnt;
+} tiot_packet_buffer;
+
+#ifndef CONFIG_BOARD_DYNAMIC_ALLOC
+typedef struct {
+    tiot_circ_buf buf;
+    uint32_t buff_write;
+    uint32_t buff_read;
+} tiot_packet_circ_buffer;
+#endif
+
+typedef struct {
+    uint32_t flags;              /*!< Control behave. */
+    tiot_packet_manager rx_manager_info;
+    tiot_packet_buffer *buff;
+} tiot_packet_context_param;
+
+/**
+ * @brief  Packet parser context.
+ */
+typedef struct {
+    tiot_packet_manager rx_manager;
+    tiot_packet *packet;
+    uint32_t flags;              /*!< Control behave. */
+    osal_mutex tx_packet_mutex;
+#ifndef CONFIG_BOARD_DYNAMIC_ALLOC
+    tiot_packet_circ_buffer rx_buff;
+#endif
+    /* Rx State machine. */
+    uint8_t *pos;
+    tiot_packet_head head;
+    uint8_t tail;
+    uint8_t sys_msg;
+    uint8_t frame_error;
+    uint16_t frame_cnt;
+    uint16_t current_frame;
+    uint16_t frame_need_read;
+    uint16_t rx_queue_id;
+
+    tiot_xfer_manager *xfer;  /*!< Connect transfer manager. */
+} tiot_packet_context;
+
+typedef struct {
+    tiot_xfer_tx_data data;
+    uint16_t subsys;
+} tiot_packet_tx_data;
+
+/**
+ * @brief  Packet context init.
+ * @param  [in]  ctx   packet context.
+ * @param  [in]  xfer  Transfer manager.
+ * @param  [in]  flags control flags.
+ * @return if OK, return 0, else return -1.
+ */
+int32_t tiot_packet_init(tiot_packet_context *ctx, tiot_xfer_manager *xfer, const tiot_packet_context_param *param);
+
+/**
+ * @brief  Packet context deinit.
+ * @param  [in]  ctx packet context.
+ */
+void tiot_packet_deinit(tiot_packet_context *ctx);
+
+/**
+ * @brief  tx packet push.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [out] data Caller send data.
+ * @param  [in]  len  Caller data len.
+ * @param  [in]  param Caller send param, must.
+ * @return if OK, return sent data, else return -1.
+ */
+int32_t tiot_packet_tx_push(tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len,
+                            const tiot_xfer_tx_param *param);
+
+/**
+ * @brief  rx data store.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [in]  data Received data.
+ * @param  [in]  len  Received data length.
+ */
+void tiot_packet_rx_data_store(tiot_xfer_manager *xfer, uint8_t *data, uint32_t len);
+
+/**
+ * @brief  rx data read out, copy uint16_t data_tag and single complete packet into user buffer.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [out] buff User buffer.
+ * @param  [in]  len  Max read length.
+ * @param  [in]  param Caller receive param.
+ * @return int32_t if OK, return readout length;if wait timeout, return 0; if err, return -1.
+ * @note   First two bytes copyed to buff indicate data type, ASCII or BINARY.
+ */
+int32_t tiot_packet_read_out(tiot_xfer_manager *xfer, uint8_t *buff, uint32_t len, const tiot_xfer_rx_param *param);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet_manager.c b/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet_manager.c
new file mode 100644 (file)
index 0000000..9f11492
--- /dev/null
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2024-01-27, Create file. \n
+ */
+
+#include "tiot_packet_manager.h"
+#include "tiot_osal.h"
+
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+void tiot_packet_free_packet(tiot_packet *packet)
+{
+    tiot_packet_rx_node *pos, *next;
+    tiot_list_head_create(tmp_head);
+    if ((packet == NULL) || (packet->head == NULL)) {
+        return;
+    }
+    tiot_list_replace(packet->head, &tmp_head);
+    /* 使用临时节点遍历删除. */
+    tiot_list_for_each_entry_safe(pos, next, &tmp_head, node, tiot_packet_rx_node, tiot_packet_rx_node) {
+        if (pos != NULL) {
+            tiot___list_del_entry(&pos->node);
+            osal_kfree(pos);
+        }
+    }
+    osal_kfree(packet->head);
+}
+#endif
+
+void tiot_packet_queue_deinit(tiot_packet_queue *queue)
+{
+    /* 唤醒并等待可能的blocking-read()线程正常退出 */
+    osal_wait_wakeup_interruptible(&queue->rx_wait);
+    while (queue->flags & TIOT_PACKET_QUEUE_RX_WAITING) {
+        osal_msleep(1);
+    }
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    /* 动态申请buffer时才需要清除. */
+    /* 释放所有未处理缓存数据. */
+    tiot_packet *packet = NULL;
+    tiot_packet_free_packet(&queue->active_node);
+    do {
+        packet = (tiot_packet *)tiot_circ_queue_dequeue(&queue->queue);
+        if (packet == NULL) {
+            break;
+        }
+        tiot_packet_free_packet(packet);
+    } while (packet != NULL);
+#endif
+    osal_spin_lock_destroy(&queue->queue.lock);
+    osal_wait_destroy(&queue->rx_wait);
+}
+
+tiot_packet *tiot_packet_manager_get_packet(tiot_packet_manager *manager, uint16_t queue_id)
+{
+    tiot_packet_queue *queue = tiot_packet_manager_find_queue(manager, queue_id);
+    if (queue == NULL) {
+        return NULL;
+    }
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    if (queue->active_node.head == NULL) {
+        queue->active_node.head = (struct tiot_list_head *)osal_kmalloc(sizeof(struct tiot_list_head), OSAL_GFP_KERNEL);
+        if (queue->active_node.head == NULL) {
+            return NULL;
+        }
+        tiot_init_list_head(queue->active_node.head);
+    }
+#endif
+    return &queue->active_node;
+}
+
+int32_t tiot_packet_manager_init(tiot_packet_manager *manager)
+{
+    uint16_t i, j;
+    if (manager->match == NULL) {
+        return -1;
+    }
+    for (i = 0; i < manager->queue_num; i++) {
+        if (tiot_packet_queue_init((tiot_packet_queue *)&(manager->queues[i])) != 0) {
+            for (j = 0; j < i; j++) { /* 释放之前已初始化的queue */
+                tiot_packet_queue_deinit((tiot_packet_queue *)&manager->queues[j]);
+            }
+            return -1;
+        }
+    }
+    return 0;
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet_manager.h b/code/sdk/zhihui/gnss/driver/common/transfer/packet_handle/tiot_packet/tiot_packet_manager.h
new file mode 100644 (file)
index 0000000..29605bb
--- /dev/null
@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+ *
+ * Description: TIoT Packet Manager. \n
+ *
+ * History: \n
+ * 2024-01-13, Create file. \n
+ */
+#ifndef TIOT_PACKET_MANAGER_H
+#define TIOT_PACKET_MANAGER_H
+
+#include "tiot_types.h"
+#include "tiot_xfer.h"
+#include "tiot_circ_queue.h"
+#include "tiot_list.h"
+#include "tiot_board_log.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_transfer_packet_handle_tiot_packet_manager Packet Manager
+ * @ingroup  tiot_common_transfer_packet_handle_tiot_packet
+ * @{
+ */
+
+#define TIOT_PACKET_QUEUE_RX_WAITING    0x1
+
+/**
+ * @brief  TIOT Complete Packet, simple replace for skb_queue.
+ */
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+typedef struct {
+    struct tiot_list_head *head;  /* Dynamic Allocated. */
+    uint16_t tag;                 /* BINARY | ASCII. */
+} tiot_packet;
+
+typedef struct {
+    struct tiot_list_head node;
+    uint8_t *data;
+    uint32_t len;
+} tiot_packet_rx_node;
+#else
+typedef struct {
+    uint32_t len;
+    uint16_t tag;        /* BINARY | ASCII. */
+} tiot_packet;
+#endif
+
+typedef struct {
+    tiot_circ_queue_t queue;
+    const tiot_packet *queue_nodes;
+    uint16_t queue_size;
+    uint8_t flags;
+    tiot_packet active_node;
+    osal_wait rx_wait;
+} tiot_packet_queue;
+
+typedef uint16_t (* tiot_packet_match_func)(uint32_t msg_type);
+
+typedef struct {
+    const tiot_packet_queue *queues;
+    uint16_t queue_num;
+    tiot_packet_match_func match;
+} tiot_packet_manager;
+
+typedef struct {
+    tiot_xfer_manager *xfer;
+    uint16_t queue_id;
+} tiot_packet_manager_query;
+
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+/**
+ * @if Eng
+ * @brief  Free TIoT packlet.
+ * @param  packet Pointer to TIoT packet.
+ * @else
+ * @brief  释放TIoT消息包。
+ * @param  packet TIoT消息包指针。
+ * @endif
+ */
+void tiot_packet_free_packet(tiot_packet *packet);
+#endif
+
+/**
+ * @if Eng
+ * @brief  Deinit packet queue.
+ * @param  queue Pointer to TIoT packet queue.
+ * @else
+ * @brief  去初始化包格式队列。
+ * @param  queue 包格式队列指针。
+ * @endif
+ */
+void tiot_packet_queue_deinit(tiot_packet_queue *queue);
+
+/**
+ * @if Eng
+ * @brief  Get packet pointer for queue_id, from packet manager.
+ * @param  manager Packet manager.
+ * @param  queue_id The index of queue in packet manager.
+ * @return Return packet pointer for queue_id,if no such queue or malloc fail, return NULL.
+ * @else
+ * @brief  从包管理器中获取指定队列ID的包。
+ * @param  manager 包管理器。
+ * @param  queue_id 包管理器内队列ID。
+ * @return 返回指定队列ID的包的指针,如果没有对应队列,或内存申请失败则返回NULL。
+ * @endif
+ */
+tiot_packet *tiot_packet_manager_get_packet(tiot_packet_manager *manager, uint16_t queue_id);
+
+/**
+ * @if Eng
+ * @brief  init packet manager.
+ * @param  manager Packet manager.
+ * @else
+ * @brief  初始化包包管理器。
+ * @param  manager 包管理器。
+ * @endif
+ */
+int32_t tiot_packet_manager_init(tiot_packet_manager *manager);
+
+static inline int32_t tiot_packet_queue_init(tiot_packet_queue *queue)
+{
+    const uint32_t queue_mem_size = queue->queue_size * sizeof(tiot_packet);
+    tiot_circ_queue_init(&queue->queue, queue->queue_size, sizeof(tiot_packet), (uintptr_t)queue->queue_nodes);
+    (void)memset_s((void *)queue->queue_nodes, queue_mem_size, 0, queue_mem_size);
+    (void)memset_s((void *)&queue->active_node, sizeof(tiot_packet), 0, sizeof(tiot_packet));
+    queue->flags = 0;
+    if (osal_wait_init(&queue->rx_wait) != OSAL_SUCCESS) {
+        return -1;
+    }
+    return 0;
+}
+
+static inline void tiot_packet_manager_deinit(tiot_packet_manager *manager)
+{
+    uint16_t i;
+    for (i = 0; i < manager->queue_num; i++) {
+        tiot_packet_queue_deinit((tiot_packet_queue *)&manager->queues[i]);
+    }
+}
+
+static inline tiot_packet_queue *tiot_packet_manager_find_queue(tiot_packet_manager *manager, uint16_t queue_id)
+{
+    tiot_packet_queue *queue = NULL;
+    if (manager == NULL) {
+        return queue;
+    }
+    if (queue_id < manager->queue_num) {
+        queue = (tiot_packet_queue *)&manager->queues[queue_id];
+    }
+    return queue;
+}
+
+static inline void tiot_packet_manager_enqueue_packet(tiot_packet_manager *manager, uint16_t queue_id)
+{
+    tiot_packet_queue *queue = tiot_packet_manager_find_queue(manager, queue_id);
+    if (queue == NULL) {
+        return;
+    }
+    if (tiot_circ_queue_enqueue(&queue->queue, (uintptr_t)&queue->active_node) != 0) {
+        tiot_print_err("[TIoT:rx]circ queue [%d] no space.\r\n", queue_id);
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+        tiot_packet_free_packet(&queue->active_node);
+#endif
+    }
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    /* 指针转移至循环队列内或已释放. */
+    queue->active_node.head = NULL;
+#else
+    queue->active_node.len = 0;
+#endif
+}
+
+static inline void tiot_packet_manager_discard_packet(tiot_packet_manager *manager, uint16_t queue_id)
+{
+    tiot_packet_queue *queue = tiot_packet_manager_find_queue(manager, queue_id);
+    if (queue == NULL) {
+        return;
+    }
+#ifdef CONFIG_BOARD_DYNAMIC_ALLOC
+    tiot_packet_free_packet(&queue->active_node);
+    /* 指针已释放. */
+    queue->active_node.head = NULL;
+#else
+    queue->active_node.len = 0;
+#endif
+}
+
+static inline int32_t tiot_packet_manager_has_data(tiot_packet_manager *manager, uint16_t queue_id)
+{
+    tiot_packet_queue *queue;
+    queue = tiot_packet_manager_find_queue(manager, queue_id);
+    if (queue == NULL) {
+        return 0;
+    }
+    return (tiot_circ_queue_empty(&queue->queue) == 0);
+}
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer.c b/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer.c
new file mode 100644 (file)
index 0000000..1b82ac8
--- /dev/null
@@ -0,0 +1,493 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT transfer module. \n
+ *
+ * History: \n
+ * 2023-04-18, Create file. \n
+ */
+#include "tiot_xfer.h"
+#include "tiot_xfer_utils.h"
+#include "tiot_board_log.h"
+
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+#define TIOT_XFER_MANAGER_MAX   16
+
+typedef enum {
+    TIOT_XFER_TASK_UNINIT,
+    TIOT_XFER_TASK_INIT,
+    TIOT_XFER_TASK_ABORT,
+} tiot_xfer_task_state;
+
+typedef struct {
+    osal_task *task;
+    tiot_xfer_manager *xfer_list[TIOT_XFER_MANAGER_MAX];
+    volatile uint16_t xfer_count;
+    volatile uint16_t state;
+    osal_wait tx_wait;
+} tiot_xfer_send_task;
+
+/* 单线程 */
+static tiot_xfer_send_task g_tiot_xfer_send_task = { 0 };
+
+static int32_t tiot_xfer_send_task_init(tiot_xfer_manager *xfer);
+static void tiot_xfer_send_task_quit(tiot_xfer_manager *xfer);
+
+static int32_t tiot_xfer_send_task_queue_init(tiot_xfer_manager *xfer)
+{
+    /* 仅单一发送队列 */
+    const uint32_t tx_queue_node_num = CONFIG_XFER_TX_NODE_NUM;
+    uint32_t tx_queue_mem_size = sizeof(tiot_xfer_tx_data) * tx_queue_node_num;
+    xfer->tx_queue_mem = (uintptr_t)osal_kmalloc(tx_queue_mem_size, OSAL_GFP_KERNEL);
+    if (xfer->tx_queue_mem == 0) {
+        tiot_print_err("[TIoT][xfer]tx queue malloc failed.\n");
+        return -1;
+    }
+    (void)memset_s((void *)xfer->tx_queue_mem, tx_queue_mem_size, 0, tx_queue_mem_size);
+    tiot_circ_queue_init(&xfer->tx_queue, tx_queue_node_num, sizeof(tiot_xfer_tx_data), xfer->tx_queue_mem);
+    return 0;
+}
+
+static void tiot_xfer_send_task_queue_deinit(tiot_xfer_manager *xfer)
+{
+    if (xfer->tx_queue_mem != 0) {
+        osal_kfree((void *)xfer->tx_queue_mem);
+        xfer->tx_queue_mem = 0;
+    }
+}
+#endif
+
+static inline int32_t tiot_xfer_default_rx_buff_init(tiot_xfer_manager *xfer)
+{
+#ifdef CONFIG_XFER_DEFAULT_RX_BUFF
+    (void)memset_s((void *)xfer->rx_buff_mem, CONFIG_XFER_RX_BUFF_SIZE, 0, CONFIG_XFER_RX_BUFF_SIZE);
+    circ_buf_init(&xfer->rx_buff, &xfer->rx_buff_write, &xfer->rx_buff_read,
+                  (void *)xfer->rx_buff_mem, CONFIG_XFER_RX_BUFF_SIZE);
+    return 0;
+#else
+    tiot_unused(xfer);
+    tiot_print_err("[TIoT][xfer]no rx buff, check tiot_autoconfig.h.\n");
+    return -1;
+#endif
+}
+
+int32_t tiot_xfer_init(tiot_xfer_manager *xfer, uintptr_t xmit_id, const tiot_xfer_device_info *dev_info)
+{
+    int32_t ret = 0;
+    const tiot_xmit_ops *xmit_ops;
+    /* 等待函数必须不为空,否则osal_wait_timeout_interruptible不能正常工作. */
+    if ((xfer == NULL) || (dev_info == NULL) || (dev_info->rx_wait_func == NULL)) {
+        return -1;
+    }
+    xmit_ops = tiot_xmit_get_ops(dev_info->xmit_type);
+    if (xmit_ops == NULL) {
+        tiot_print_dbg("[TIoT][xfer]transmit type invalid.\n");
+        return -1;
+    }
+    xfer->tx_queue_mem = 0;
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+    /* 仅单一发送队列 */
+    ret = tiot_xfer_send_task_init(xfer);
+    if (ret != 0) {
+        goto rx_wait_err;
+    }
+#endif
+    if ((xmit_ops->rx_mode == TIOT_XMIT_RX_MODE_BUFFED) && (tiot_xfer_default_rx_buff_init(xfer) != 0)) {
+        goto rx_wait_err;
+    }
+    if (osal_wait_init(&xfer->rx_wait) != OSAL_SUCCESS) {
+        tiot_print_err("[TIoT][xfer]rx wait init failed.\n");
+        goto rx_wait_err;
+    }
+    if (osal_mutex_init(&xfer->dev_mutex) != OSAL_SUCCESS) {
+        tiot_print_err("[TIoT][xfer]device mutex init failed.\n");
+        goto dev_mutex_err;
+    }
+    if (osal_mutex_init(&xfer->read_mutex) != OSAL_SUCCESS) {
+        tiot_print_err("[TIoT][xfer]read mutex init failed.\n");
+        goto read_mutex_err;
+    }
+
+    /* Transmit实例初始化. */
+    xfer->xmit_ops = xmit_ops;
+    xfer->xmit.id = xmit_id;
+    xfer->xmit_state = TIOT_XMIT_STATE_CLOSE;
+    /* 接收初始化 */
+    xfer->rx_wait_func = dev_info->rx_wait_func;
+    (void)memset_s(&xfer->config, sizeof(struct tiot_xmit_config), 0, sizeof(struct tiot_xmit_config));
+     /* 包格式处理初始化 */
+    (void)memset_s(&xfer->pkt_ops, sizeof(tiot_xfer_packet_ops), 0, sizeof(tiot_xfer_packet_ops));
+    tiot_print_suc("[TIoT][xfer]transfer manager init succ.\n");
+    return ret;
+read_mutex_err:
+    osal_mutex_destroy(&xfer->dev_mutex);
+dev_mutex_err:
+    osal_wait_destroy(&xfer->rx_wait);
+rx_wait_err:
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+    tiot_xfer_send_task_quit(xfer);
+#endif
+    return -1;
+}
+
+void tiot_xfer_deinit(tiot_xfer_manager *xfer)
+{
+    if (xfer == NULL) {
+        tiot_print_dbg("[TIoT][xfer]transfer manager is NULL.\n");
+        return;
+    }
+
+    tiot_print_info("[TIoT][xfer]transfer manager deinit.\n");
+    /* 先关闭xfer保证硬件不再发送接收 */
+    tiot_xfer_close(xfer);
+
+    /* Transmit实例去初始化. */
+    (void)memset_s(&xfer->xmit, sizeof(tiot_xmit), 0, sizeof(tiot_xmit));
+    (void)memset_s(&xfer->config, sizeof(struct tiot_xmit_config), 0, sizeof(struct tiot_xmit_config));
+    xfer->xmit_ops = NULL;
+
+    tiot_xfer_uninstall_packet(xfer);
+
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+    tiot_xfer_send_task_quit(xfer);
+#endif
+    osal_wait_destroy(&xfer->rx_wait);
+
+    /* 互斥锁初始化 */
+    osal_mutex_destroy(&xfer->dev_mutex);
+    osal_mutex_destroy(&xfer->read_mutex);
+}
+
+int32_t tiot_xfer_install_packet(tiot_xfer_manager *xfer, tiot_xfer_packet_ops *pkt_ops, uintptr_t pkt_context)
+{
+    if (xfer == NULL) {
+        tiot_print_dbg("[TIoT][xfer]transfer manager is NULL.\n");
+        return -1;
+    }
+
+    osal_mutex_lock(&xfer->dev_mutex);
+    (void)memcpy_s(&xfer->pkt_ops, sizeof(tiot_xfer_packet_ops), pkt_ops, sizeof(tiot_xfer_packet_ops));
+    xfer->pkt_context = pkt_context;
+    osal_mutex_unlock(&xfer->dev_mutex);
+    return 0;
+}
+
+void tiot_xfer_uninstall_packet(tiot_xfer_manager *xfer)
+{
+    if (xfer == NULL) {
+        tiot_print_dbg("[TIoT][xfer]transfer manager is NULL.\n");
+        return;
+    }
+
+    osal_mutex_lock(&xfer->dev_mutex);
+    xfer->pkt_context = 0;
+    memset_s(&xfer->pkt_ops, sizeof(tiot_xfer_packet_ops), 0, sizeof(tiot_xfer_packet_ops));
+    osal_mutex_unlock(&xfer->dev_mutex);
+}
+
+int32_t tiot_xfer_open(tiot_xfer_manager *xfer, tiot_xfer_open_param *param)
+{
+    int32_t ret;
+    tiot_xmit_callbacks cbs = { tiot_xfer_rx_notify };
+    if (xfer == NULL) {
+        tiot_print_dbg("[TIoT][xfer]transfer manager is NULL.\n");
+        return -1;
+    }
+
+    osal_mutex_lock(&xfer->dev_mutex);
+    if (xfer->xmit_state != TIOT_XMIT_STATE_CLOSE) {
+        osal_mutex_unlock(&xfer->dev_mutex);
+        tiot_print_err("[TIoT][xfer]transmit state already opened.\n");
+        return -1;
+    }
+    ret = xfer->xmit_ops->open(&xfer->xmit, &cbs);
+    if (ret != 0) {
+        osal_mutex_unlock(&xfer->dev_mutex);
+        tiot_print_err("[TIoT][xfer]transmit open failed.\n");
+        return ret;
+    }
+
+    if ((xfer->xmit_ops->rx_mode == TIOT_XMIT_RX_MODE_BUFFED) && (param != NULL)) {
+        (void)memcpy_s(&xfer->rx_cbk_param, sizeof(tiot_xfer_cbk_param),
+                       &param->rx_cbk_param, sizeof(tiot_xfer_cbk_param));
+    } else {
+        xfer->rx_cbk_param.rx_callback = NULL;
+    }
+
+    xfer->xmit_state = TIOT_XMIT_STATE_OPEN;
+
+    osal_mutex_unlock(&xfer->dev_mutex);
+    return ret;
+}
+
+int32_t tiot_xfer_set_config(tiot_xfer_manager *xfer, struct tiot_xmit_config *config)
+{
+    int32_t ret;
+    if ((xfer == NULL) || (config == NULL)) {
+        tiot_print_dbg("[TIoT][xfer]transfer manager or config is NULL.\n");
+        return -1;
+    }
+    (void)osal_mutex_lock(&xfer->dev_mutex);
+    if (xfer->xmit_state == TIOT_XMIT_STATE_CLOSE) {
+        tiot_print_dbg("[TIoT][xfer]transmit state closed, cannot set config.\n");
+        (void)osal_mutex_unlock(&xfer->dev_mutex);
+        return -1;
+    }
+    ret = xfer->xmit_ops->set_config(&xfer->xmit, config);
+    if (ret == 0) {
+        (void)memcpy_s(&xfer->config, sizeof(struct tiot_xmit_config), config, sizeof(struct tiot_xmit_config));
+    }
+    (void)osal_mutex_unlock(&xfer->dev_mutex);
+    return ret;
+}
+
+int32_t tiot_xfer_get_config(tiot_xfer_manager *xfer, struct tiot_xmit_config *config)
+{
+    if ((xfer == NULL) || (config == NULL)) {
+        tiot_print_dbg("[TIoT][xfer]transfer manager or config is NULL.\n");
+        return -1;
+    }
+
+    (void)memcpy_s(config, sizeof(struct tiot_xmit_config), &xfer->config, sizeof(struct tiot_xmit_config));
+    return 0;
+}
+
+void tiot_xfer_close(tiot_xfer_manager *xfer)
+{
+    if (xfer == NULL) {
+        tiot_print_dbg("[TIoT][xfer]transfer manager is NULL.\n");
+        return;
+    }
+
+    (void)osal_mutex_lock(&xfer->dev_mutex);
+    if (xfer->xmit_state == TIOT_XMIT_STATE_CLOSE) {
+        (void)osal_mutex_unlock(&xfer->dev_mutex);
+        tiot_print_dbg("[TIoT][xfer]transmit state already closed.\n");
+        return;
+    }
+
+    xfer->xmit_ops->close(&xfer->xmit);
+    (void)memset_s(&xfer->rx_cbk_param, sizeof(tiot_xfer_cbk_param), 0, sizeof(tiot_xfer_cbk_param));
+
+    xfer->xmit_state = TIOT_XMIT_STATE_CLOSE;
+#ifdef CONFIG_XFER_DEFAULT_RX_BUFF
+    (void)memset_s((void *)xfer->rx_buff_mem, CONFIG_XFER_RX_BUFF_SIZE, 0, CONFIG_XFER_RX_BUFF_SIZE);
+    circ_buf_flush(&xfer->rx_buff);
+#endif
+    (void)osal_mutex_unlock(&xfer->dev_mutex);
+    return;
+}
+
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+static int tiot_xfer_send_task_wait_condition(void *param)
+{
+    tiot_xfer_send_task *send_task = &g_tiot_xfer_send_task;
+    if (send_task->state == TIOT_XFER_TASK_ABORT) {
+        return OSAL_WAIT_CONDITION_TRUE;
+    }
+
+    uint16_t xfer_count = g_tiot_xfer_send_task.xfer_count;
+    for (uint16_t i = 0; i < xfer_count; i++) {
+        if (tiot_circ_queue_empty(&xfer_list[i]->tx_queue) == 0) {
+            return OSAL_WAIT_CONDITION_TRUE;
+        }
+    }
+    return 0;
+}
+
+static void tiot_xfer_send_schedule(tiot_xfer_manager *xfer)
+{
+    if ((xfer == NULL) || (xfer->xmit_state == TIOT_XMIT_STATE_CLOSE)) {
+        tiot_print_info("[TIoT][xfer]xfer is null or xmit close.");
+        return;
+    }
+    tiot_xfer_tx_data *node = NULL;
+    do {
+        node = (tiot_xfer_tx_data *)tiot_circ_queue_dequeue(&xfer->tx_queue);
+        if (node != NULL) {
+            tiot_xfer_direct_send(xfer, node->data, node->len);
+        } else {
+            tiot_print_info("[TIoT][xfer]tx queue is empty.");
+        }
+    } while (node != NULL);
+}
+
+static void tiot_xfer_send_task_handle(void *param)
+{
+    (void)param;
+    tiot_xfer_manager **xfer_list = g_tiot_xfer_send_task.xfer_list;
+    uint16_t xfer_count;
+    for (;;) {
+        /* 等待某个transfer manager有数据或退出 */
+        osal_wait_timeout_interruptible(&g_tiot_xfer_send_task.tx_wait, tiot_xfer_send_task_wait_condition,
+                                        NULL, OSAL_WAIT_FOREVER);
+        if (g_tiot_xfer_send_task.state == TIOT_XFER_TASK_ABORT) {
+            break;
+        }
+        xfer_count = g_tiot_xfer_send_task.xfer_count;
+        for (uint16_t i = 0; i < xfer_count; i++) {
+            tiot_xfer_send_schedule(xfer_list[i]);
+        }
+    }
+
+    /* 退出流程. */
+    g_tiot_xfer_send_task.state = TIOT_XFER_TASK_UNINIT;
+    osal_wait_wakeup(&g_tiot_xfer_send_task.tx_wait);
+}
+
+static int32_t tiot_xfer_send_task_init(tiot_xfer_manager *xfer)
+{
+    const uint32_t stack_size = 2048;
+    tiot_xfer_send_task *send_task = &g_tiot_xfer_send_task;
+    if (send_task->xfer_count == 0) {
+        if (osal_wait_init(&send_task->tx_wait) != OSAL_SUCCESS) {
+            tiot_print_err("[TIoT][xfer]send task wait init failed.\n");
+            return -1;
+        }
+        send_task->task = osal_kthread_create(tiot_xfer_send_task_handle, NULL, "tiot_tx", stack_size);
+        if (send_task->task == NULL) {
+            osal_wait_destroy(&send_task->tx_wait);
+            tiot_print_err("[TIoT][xfer]send task init failed.\n");
+            return -1;
+        }
+    }
+    if (tiot_xfer_send_task_queue_init(xfer) != 0) {
+        return -1;
+    }
+    send_task->xfer_count++;
+    send_task->xfer_list[send_task->xfer_count] = xfer;
+    return 0;
+}
+
+static int tiot_xfer_send_task_quit_wait_condition(void *param)
+{
+    if (g_tiot_xfer_send_task.state == TIOT_XFER_TASK_UNINIT) {
+        return OSAL_WAIT_CONDITION_TRUE;
+    }
+    return 0;
+}
+
+/* Transfer manager去初始化时调用 */
+static void tiot_xfer_send_task_quit(tiot_xfer_manager *xfer)
+{
+    tiot_xfer_send_task *send_task = &g_tiot_xfer_send_task;
+    uint16_t xfer_count = send_task->xfer_count;
+    uint16_t i = 0;
+    for (; i < xfer_count; i++) {
+        if (send_task->xfer_list[i] == xfer) {
+            send_task->xfer_list[i] = NULL;
+            break;
+        }
+    }
+    tiot_xfer_send_task_queue_deinit(xfer);
+    if (i == xfer_count) {
+        /* 未注册 */
+        return;
+    }
+    send_task->xfer_count--;
+    /* 当所有transfer manager均去初始化时,释放task */
+    if (send_task->xfer_count == 0) {
+        g_tiot_xfer_send_task.state = TIOT_XFER_TASK_ABORT;
+        osal_wait_wakeup(&g_tiot_xfer_send_task.tx_wait);
+        /* 等待任务退出 */
+        osal_wait_timeout_interruptible(&g_tiot_xfer_send_task.tx_wait,
+                                        tiot_xfer_send_task_quit_wait_condition, NULL, OSAL_WAIT_FOREVER);
+        osal_kthread_destroy(g_tiot_xfer_send_task.task, 0);
+        g_tiot_xfer_send_task.task = NULL;
+        (void)memset_s(&g_tiot_xfer_send_task, sizeof(tiot_xfer_send_task), 0, sizeof(tiot_xfer_send_task));
+    }
+}
+#endif
+
+int32_t tiot_xfer_send(tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len, const tiot_xfer_tx_param *param)
+{
+    int32_t ret;
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+    tiot_xfer_tx_data node = { data, len };
+#endif
+    if ((xfer == NULL) || (data == NULL)) {
+        tiot_print_err("[TIoT][xfer]transfer manager is NULL or input data is NULL.");
+        return -1;
+    }
+
+    if (xfer->pkt_ops.tx_push != NULL) {
+        ret = xfer->pkt_ops.tx_push(xfer, data, len, param);
+    } else {
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+        ret = tiot_circ_queue_enqueue(&xfer->tx_queue, (uintptr_t)&node);
+#else
+        ret = tiot_xfer_direct_send(xfer, data, len);
+#endif
+    }
+
+#ifdef CONFIG_XFER_TX_SUPPORT_TASK
+    tiot_xfer_send_task *send_task = &g_tiot_xfer_send_task;
+    if (ret == 0) {
+        osal_wait_wakeup(&send_task->tx_wait);
+    }
+#endif
+    return ret;
+}
+
+void tiot_xfer_rx_notify(tiot_xmit *xmit, uint8_t *data, uint32_t len)
+{
+    int32_t ret = 0;
+    tiot_xfer_manager *xfer = (tiot_xfer_manager *)xmit;
+    if (xfer == NULL) {
+        tiot_print_err("[TIoT][rx]notified transmit is NULL.\n");
+        return;
+    }
+
+    /* 可能中断内被调用 */
+    if (xfer->xmit_state == TIOT_XMIT_STATE_CLOSE) {
+        tiot_print_dbg("[TIoT][rx]transmit state closed.\n");
+        return;
+    }
+
+    if (xfer->xmit_ops->rx_mode == TIOT_XMIT_RX_MODE_BUFFED) {
+        if ((data == NULL) || (len == 0)) {
+            tiot_print_err("[TIoT][rx]notified data is NULL or len is 0.\n");
+            return;
+        }
+        if (xfer->pkt_ops.rx_data_store != NULL) {
+            /* 由包格式决定什么时候唤醒rx_wait */
+            xfer->pkt_ops.rx_data_store(xfer, data, len);
+            return;
+        } else {
+            /* 存入默认buffer */
+            ret = tiot_xfer_read_store(&xfer->rx_buff, data, len);
+        }
+    }
+
+    if (ret == 0) {
+        osal_wait_wakeup_interruptible(&xfer->rx_wait);
+    } else {
+        tiot_print_err("[TIoT][rx]circ buff not stored.\n");
+    }
+}
+
+int32_t tiot_xfer_recv(tiot_xfer_manager *xfer, uint8_t *buff, uint32_t len, const tiot_xfer_rx_param *param)
+{
+    int32_t ret;
+    if ((xfer == NULL) || (param == NULL)) {
+        tiot_print_dbg("[TIoT][rx]transfer manager is NULL or param is NULL.\n");
+        return -1;
+    }
+
+    osal_mutex_lock(&xfer->dev_mutex);
+    if (xfer->xmit_state == TIOT_XMIT_STATE_CLOSE) {
+        osal_mutex_unlock(&xfer->dev_mutex);
+        tiot_print_dbg("[TIoT][rx]transmit state closed.\n");
+        return -1;
+    }
+    osal_mutex_unlock(&xfer->dev_mutex);
+
+    if (xfer->pkt_ops.read_out != NULL) {
+        ret =  xfer->pkt_ops.read_out(xfer, buff, len, param);
+    } else {
+        /* 默认读取路径,固件加载时使用. */
+        ret = tiot_xfer_read_out(xfer, buff, len, param->timeout);
+    }
+
+    return ret;
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer.h b/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer.h
new file mode 100644 (file)
index 0000000..d9866bf
--- /dev/null
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT transfer module. \n
+ *
+ * History: \n
+ * 2023-04-18, Create file. \n
+ */
+#ifndef TIOT_XFER_H
+#define TIOT_XFER_H
+
+#include "tiot_board_xmit.h"
+#include "tiot_board_xmit_ops.h"
+#include "tiot_circ_queue.h"
+#include "tiot_circ_buf.h"
+#include "tiot_osal.h"
+#include "tiot_board_uart_port.h"
+
+#ifdef __KERNEL__
+#include <linux/poll.h>
+#endif
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_transfer Transfer
+ * @ingroup  tiot_common
+ * @{
+ */
+
+/* 临时flags, 用于拆分低功耗持锁 & disallow消息. */
+#define TIOT_XFER_RESUME                0U
+#define TIOT_XFER_SUSPEND               ((uint16_t)1 << 1)
+#define TIOT_XFER_DELAY_MSG             ((uint16_t)1 << 2)
+
+#define TIOT_XFER_RECV_NO_WAIT       ((uint32_t)0)
+#define TIOT_XFER_RECV_WAIT_FOREVER  ((uint32_t)0xFFFFFFF)
+
+/**
+ * @brief  TIoT Transmit port state.
+ */
+typedef enum {
+    TIOT_XMIT_STATE_CLOSE,  /* TIoT Transmit state close. */
+    TIOT_XMIT_STATE_OPEN,   /* TIoT Transmit state open. */
+    TIOT_XMIT_STATE_BUSY    /* TIoT Transmit state busy for reading or writing. */
+} tiot_xmit_state;
+
+/**
+ * @brief  TIoT Transfer send node, cound be exetend by packet ops with other attributes.
+ */
+typedef struct {
+    const uint8_t *data;    /* Pointer to send buff. */
+    uint32_t len;     /* Send len. */
+} tiot_xfer_tx_data;
+
+/**
+ * @brief  TIoT Transfer send param, cound be exetend by packet ops with other attributes.
+ */
+typedef struct {
+    uint32_t subsys;     /* subsys info. */
+} tiot_xfer_tx_param;
+
+/**
+ * @brief  TIoT Transfer receive param, cound be exetend by packet ops with other attributes.
+ */
+typedef struct {
+    uint32_t timeout;    /* Read timeout by ms, 0 timeout means no wait. */
+    uint32_t subsys;     /* subsys info. */
+#ifdef __KERNEL__
+    struct file *filp;
+    poll_table *poll_wait;
+#endif
+} tiot_xfer_rx_param;
+
+struct _tiot_xfer_manager;
+struct _tiot_xfer_packet;
+
+/**
+ * @brief  TIoT Transfer packet operations.
+ */
+typedef struct {
+    /*!< Packet parse tx node, and push to transmit or tx queue. */
+    int32_t (* tx_push)(struct _tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len,
+                        const tiot_xfer_tx_param *param);
+    /*!< Read data out to caller buffer, same as tiot_xfer_recv. */
+    int32_t (* read_out)(struct _tiot_xfer_manager *xfer, uint8_t *buff, uint32_t len, const tiot_xfer_rx_param *param);
+    /*!< For async read, store data from board transmit isr. */
+    void (* rx_data_store)(struct _tiot_xfer_manager *xfer, uint8_t *data, uint32_t len);
+} tiot_xfer_packet_ops;
+
+/**
+ * @brief  TIoT Transfer device info.
+ */
+typedef struct {
+    tiot_xmit_type xmit_type;
+    osal_wait_condition_func rx_wait_func;  /*!< Device related read wait func, could be gpio level. */
+} tiot_xfer_device_info;
+
+typedef struct {
+    uint8_t *buff;
+    uint32_t buff_len;
+    void (*rx_callback)(const uint8_t *buff, uint32_t len);
+} tiot_xfer_cbk_param;
+
+typedef struct {
+    tiot_xfer_cbk_param rx_cbk_param;
+} tiot_xfer_open_param;
+
+/**
+ * @brief  TIoT Transfer manager.
+ */
+typedef struct _tiot_xfer_manager {
+    /* Board transmit infos. */
+    tiot_xmit xmit;                   /*!< Board transmit instance. */
+    const tiot_xmit_ops *xmit_ops;    /*!< Board transmit operations. */
+    struct tiot_xmit_config config;   /*!< Board transmit config saved. */
+    uint16_t xmit_state;              /*!< Board transmit state, close or open. */
+    uint16_t xmit_suspend;            /*!< Tmp flag for suspend, will merge to state. */
+
+    /* Mutexes */
+    osal_mutex dev_mutex;             /*!< Transmit device mutex. */
+    osal_mutex read_mutex;            /*!< Transmit read mutex. */
+
+    /* Send */
+    tiot_circ_queue_t tx_queue;       /*!< Tx circular queue, with tiot_xfer_tx_node as node. */
+    uintptr_t tx_queue_mem;           /*!< Tx circular queue allocated memory. */
+
+    /* Recieve */
+    osal_wait rx_wait;
+    osal_wait_condition_func rx_wait_func;  /*!< Registed read wait func, could be gpio level. */
+
+    tiot_circ_buf rx_buff;            /*!< Rx circular buff. */
+    uint32_t rx_buff_write;           /*!< Rx circular buff write index. */
+    uint32_t rx_buff_read;            /*!< Rx circular buff read index. */
+#ifdef CONFIG_XFER_DEFAULT_RX_BUFF
+    /*!< Rx circular buff memory. */
+    uint8_t rx_buff_mem[CONFIG_XFER_RX_BUFF_SIZE];
+#endif
+
+    /* Packet */
+    tiot_xfer_packet_ops pkt_ops;    /*!< Packet operation, tx & rx data packet parse. */
+    uintptr_t pkt_context;           /*!< Packet operation used context. */
+
+    tiot_xfer_cbk_param rx_cbk_param;
+} tiot_xfer_manager;
+
+/**
+ * @brief  TIoT Transfer manager init.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [in]  xmit_id Board Transmit id.
+ * @param  [in]  dev_info Device Transfer related info.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_xfer_init(tiot_xfer_manager *xfer, uintptr_t xmit_id, const tiot_xfer_device_info *dev_info);
+
+/**
+ * @brief  TIoT Transfer manager deinit.
+ * @param  [in]  xfer Transfer manager.
+ */
+void tiot_xfer_deinit(tiot_xfer_manager *xfer);
+
+/**
+ * @brief  TIoT Transfer manager install packet.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [in]  pkt_ops Transfer packet ops.
+ * @param  [in]  pkt_context Transfer packet context.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_xfer_install_packet(tiot_xfer_manager *xfer, tiot_xfer_packet_ops *pkt_ops, uintptr_t pkt_context);
+
+/**
+ * @brief  TIoT Transfer manager uninstall packet.
+ * @param  [in]  xfer Transfer manager.
+ */
+void tiot_xfer_uninstall_packet(tiot_xfer_manager *xfer);
+
+/**
+ * @brief  TIoT Transfer manager open, with packet installed.
+ * @param  [in]  xfer Transfer manager.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_xfer_open(tiot_xfer_manager *xfer, tiot_xfer_open_param *param);
+
+/**
+ * @brief  TIoT Transfer manager close.
+ * @param  [in]  xfer Transfer manager.
+ */
+void tiot_xfer_close(tiot_xfer_manager *xfer);
+
+/**
+ * @brief  TIoT Transfer manager set config.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [in]  config New config to be set.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_xfer_set_config(tiot_xfer_manager *xfer, struct tiot_xmit_config *config);
+
+/**
+ * @brief  TIoT Transfer manager get config.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [out] config copy old transmit config to caller.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_xfer_get_config(tiot_xfer_manager *xfer, struct tiot_xmit_config *config);
+
+/**
+ * @brief  TIoT Transfer manager send.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [out] data Caller send data.
+ * @param  [in]  len  Caller data len.
+ * @param  [in]  param Caller send param, optional.
+ * @return if Send OK return actual send len, else return -1.
+ */
+int32_t tiot_xfer_send(tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len, const tiot_xfer_tx_param *param);
+
+/**
+ * @brief  TIoT Transfer RX read notify.
+ * @param  [in]  xmit Transmit instance, will be extend to Transfer manager instance.
+ * @param  [in]  data RX data need to read, could be NULL for sync read.
+ * @param  [in]  len  Rx data len need to read, 0 indicates sync read.
+ */
+void tiot_xfer_rx_notify(tiot_xmit *xmit, uint8_t *data, uint32_t len);
+
+/**
+ * @brief  TIoT Transfer receive.
+ * @param  [in]  xfer Transfer manager.
+ * @param  [out] data Caller read buff.
+ * @param  [in]  len  Caller expected read len.
+ * @param  [in]  param Caller receive param.
+ * @return if Read OK return actual read len, if timeout, return 0, else return -1.
+ */
+int32_t tiot_xfer_recv(tiot_xfer_manager *xfer, uint8_t *data, uint32_t len, const tiot_xfer_rx_param *param);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer_utils.c b/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer_utils.c
new file mode 100644 (file)
index 0000000..0393775
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-04-26, Create file. \n
+ */
+
+#include "tiot_xfer_utils.h"
+
+int32_t tiot_xfer_direct_send(tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len)
+{
+    int32_t ret;
+    const uint8_t *buff = data;
+    uint32_t remain_len = len;
+    while (remain_len) {
+        /* 板级接口可能有单次发送限制. */
+        (void)osal_mutex_lock(&xfer->dev_mutex);
+        if (xfer->xmit_state != TIOT_XMIT_STATE_OPEN) {
+            ret = -1;
+        } else {
+            ret = xfer->xmit_ops->write(&xfer->xmit, buff, remain_len);
+        }
+        (void)osal_mutex_unlock(&xfer->dev_mutex);
+        /* 阻塞式接口,发送结果为0情况时继续发送 */
+        if (ret < 0) {
+            return -1;
+        }
+
+        remain_len -= ret;
+        buff += ret;
+    }
+    return len;
+}
+
+int32_t tiot_xfer_read_store(tiot_circ_buf *cb, uint8_t *data, uint32_t len)
+{
+    int32_t ret;
+    if ((cb == NULL) || (circ_buf_query_free(cb) < len)) {
+        return -1;
+    }
+    ret = circ_buf_write(cb, data, len);
+    if (ret == 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static int tiot_xfer_read_out_check(const void *param)
+{
+    tiot_xfer_manager *xfer = (tiot_xfer_manager *)param;
+    if ((xfer->rx_wait_func(xfer) != 0) ||
+        ((xfer->xmit_ops->rx_mode == TIOT_XMIT_RX_MODE_BUFFED) && (circ_buf_query_busy(&xfer->rx_buff) != 0))) {
+        return 1;
+    }
+    return 0;
+}
+
+int32_t tiot_xfer_read_out(tiot_xfer_manager *xfer, uint8_t *buff, uint32_t len, uint32_t timeout_ms)
+{
+    int32_t read_len;
+    int32_t timeout = osal_wait_timeout_interruptible(&xfer->rx_wait, tiot_xfer_read_out_check,
+                                                      (const void *)xfer, timeout_ms);
+    /* 超时返回 0, 失败返回-1 */
+    if (timeout <= 0) {
+        return timeout;
+    }
+    osal_mutex_lock(&xfer->dev_mutex);
+
+    if (xfer->xmit_ops->rx_mode == TIOT_XMIT_RX_MODE_BUFFED) {
+        uint32_t buff_data_len = circ_buf_query_busy(&xfer->rx_buff);
+        read_len = buff_data_len < len ? buff_data_len : len;
+        read_len = circ_buf_read(&xfer->rx_buff, buff, read_len);
+        if (read_len == 0) {
+            read_len = -1;
+        }
+    } else {
+        read_len = xfer->xmit_ops->read(&xfer->xmit, buff, len);
+    }
+
+    osal_mutex_unlock(&xfer->dev_mutex);
+    return read_len;
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer_utils.h b/code/sdk/zhihui/gnss/driver/common/transfer/tiot_xfer_utils.h
new file mode 100644 (file)
index 0000000..748e53f
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-04-26, Create file. \n
+ */
+#ifndef TIOT_XFER_UTILS_H
+#define TIOT_XFER_UTILS_H
+
+#include "tiot_xfer.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_transfer_utils Transfer Utils
+ * @ingroup  tiot_common_transfer
+ * @{
+ */
+
+int32_t tiot_xfer_direct_send(tiot_xfer_manager *xfer, const uint8_t *data, uint32_t len);
+
+int32_t tiot_xfer_read_store(tiot_circ_buf *cb, uint8_t *data, uint32_t len);
+
+int32_t tiot_xfer_read_out(tiot_xfer_manager *xfer, uint8_t *buff, uint32_t len, uint32_t timeout_ms);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/utils/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7f5d5bc
--- /dev/null
@@ -0,0 +1,15 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+set(
+    utils_header_lists
+    "${CMAKE_CURRENT_SOURCE_DIR}"
+    "${CMAKE_CURRENT_SOURCE_DIR}/circ_buf"
+    "${CMAKE_CURRENT_SOURCE_DIR}/list"
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${utils_header_lists}" CACHE INTERNAL "tiot header list" FORCE)
+add_subdirectory(circ_queue)
+add_subdirectory(fileops)
+add_subdirectory(misc)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/circ_buf/tiot_circ_buf.h b/code/sdk/zhihui/gnss/driver/common/utils/circ_buf/tiot_circ_buf.h
new file mode 100644 (file)
index 0000000..d1e538d
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd.. 2019-2024. All rights reserved.
+ * Description: audio circle buffer function
+ * Author: audio
+ * Create: 2019-05-30
+ */
+
+#ifndef TIOT_CIRC_BUF_H
+#define TIOT_CIRC_BUF_H
+
+#include "securec.h"
+#include "tiot_types.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif /* __cplusplus */
+
+typedef struct {
+    volatile uint32_t *write; /* circle buffer write pointer */
+    volatile uint32_t *read;  /* circle buffer read pointer */
+    uint8_t *data;            /* circle buffer data virtual address */
+    uint32_t size;            /* circle buffer size */
+} tiot_circ_buf;
+
+static inline uint32_t circ_buf_min(uint32_t x, uint32_t y)
+{
+    return (x <= y) ? x : y;
+}
+
+static inline uint32_t saturate_add(uint32_t x, uint32_t y, uint32_t saturation)
+{
+    /* add x and y, saturate to saturation */
+    uint32_t x_temp = x + y;
+
+    return (x_temp >= saturation) ? (x_temp - saturation) : x_temp;
+}
+
+static inline void circ_buf_init(tiot_circ_buf *cb, uint32_t *write, uint32_t *read, void *data, uint32_t len)
+{
+    cb->write = write;
+    cb->read = read;
+    cb->data = (uint8_t*)data;
+    cb->size = len;
+
+    *cb->write = 0;
+    *cb->read = 0;
+}
+
+static inline void circ_buf_flush(tiot_circ_buf *cb)
+{
+    *cb->read = 0;
+    *cb->write = 0;
+}
+
+static inline uint32_t circ_buf_data_size(uint32_t write, uint32_t read, uint32_t size)
+{
+    return (write >= read) ? (write - read) : (size - read + write);
+}
+
+static inline uint32_t circ_buf_free_size(uint32_t write, uint32_t read, uint32_t size)
+{
+    return size - circ_buf_data_size(write, read, size);
+}
+
+static inline uint32_t __circ_buf_read_data(const tiot_circ_buf *cb, uint8_t *to, uint32_t len, uint32_t off)
+{
+    if ((len == 0) || (memcpy_s(to, len * sizeof(uint8_t), cb->data + off, len) != EOK)) {
+        return 0;
+    }
+
+    return len;
+}
+
+/* read data from circle buffer */
+static inline uint32_t circ_buf_read_data(const tiot_circ_buf *cb, uint8_t *to, uint32_t len, uint32_t off)
+{
+    uint32_t l = circ_buf_min(len, cb->size - off);
+
+    if (to == NULL) {
+        /* dump data in circle buffer */
+        return len;
+    }
+
+    return __circ_buf_read_data(cb, to, l, off) + __circ_buf_read_data(cb, to + l, len - l, 0);
+}
+
+static inline uint32_t __circ_buf_write_zero(tiot_circ_buf *cb, const uint8_t *from, uint32_t len, uint32_t off)
+{
+    if ((len == 0) || (memset_s(cb->data + off, len, 0, len) != EOK)) {
+        return 0;
+    }
+    (void)from;
+    return len;
+}
+
+static inline uint32_t __circ_buf_write_data(tiot_circ_buf *cb, const uint8_t *from, uint32_t len, uint32_t off)
+{
+    if ((len == 0) || (memcpy_s(cb->data + off, cb->size - off, from, len) != EOK)) {
+        return 0;
+    }
+
+    return len;
+}
+
+/*
+ * circ_buf_write_data - puts some data from kernel space into the circle buffer
+ * @cb: address of the circle buffer to be used
+ * @from: pointer to the data to be added
+ * @len: the length of the data to be added
+ * @off: data write offset in circle buffer
+ *
+ * Note: Check free space in circle buffer before calling this function
+ */
+static inline uint32_t circ_buf_write_data(tiot_circ_buf *cb, const uint8_t *from, uint32_t len, uint32_t off)
+{
+    uint32_t l = circ_buf_min(len, cb->size - off);
+
+    /* generate mute data if input buffer is NULL */
+    uint32_t (*action)(tiot_circ_buf *, const uint8_t *, uint32_t, uint32_t) =
+        (from == NULL) ? __circ_buf_write_zero : __circ_buf_write_data;
+
+    return action(cb, from, l, off) + action(cb, from + l, len - l, 0);
+}
+
+static inline uint32_t circ_buf_query_busy(const tiot_circ_buf *cb)
+{
+    return circ_buf_data_size(*cb->write, *cb->read, cb->size);
+}
+
+static inline uint32_t circ_buf_query_free(const tiot_circ_buf *cb)
+{
+    return circ_buf_free_size(*cb->write, *cb->read, cb->size);
+}
+
+/* read data from circle buffer */
+static inline uint32_t circ_buf_read(tiot_circ_buf *cb, uint8_t *to, uint32_t len)
+{
+    uint32_t read = *cb->read;
+
+    if ((len == 0) || (circ_buf_data_size(*cb->write, read, cb->size) < len) ||
+        (circ_buf_read_data(cb, to, len, read) != len)) {
+        return 0;
+    }
+
+    *cb->read = saturate_add(read, len, cb->size);
+    return len;
+}
+
+/* write data into circle buffer */
+static inline uint32_t circ_buf_write(tiot_circ_buf *cb, const uint8_t *from, uint32_t len)
+{
+    uint32_t write = *cb->write;
+
+    if ((len == 0) || (circ_buf_write_data(cb, from, len, write) != len)) {
+        return 0;
+    }
+
+    *cb->write = saturate_add(write, len, cb->size);
+    return len;
+}
+
+static inline uint32_t circ_buf_update_read_pos(tiot_circ_buf *cb, uint32_t len)
+{
+    *cb->read = saturate_add(*cb->read, len, cb->size);
+    return len;
+}
+
+static inline uint32_t circ_buf_update_write_pos(tiot_circ_buf *cb, uint32_t len)
+{
+    *cb->write = saturate_add(*cb->write, len, cb->size);
+    return len;
+}
+
+static inline uint32_t circ_buf_cast_read(const tiot_circ_buf *cb, uint32_t *data_offset, uint32_t len)
+{
+    uint32_t read = *cb->read;
+
+    if (circ_buf_data_size(*cb->write, read, cb->size) < len) {
+        *data_offset = 0;
+        return 0;
+    }
+
+    *data_offset = read;
+    return len;
+}
+
+static inline uint32_t circ_buf_cast_relese(tiot_circ_buf *cb, uint32_t len)
+{
+    uint32_t read = *cb->read;
+    uint32_t data_size = circ_buf_data_size(*cb->write, read, cb->size);
+    uint32_t len_temp;
+
+    len_temp = circ_buf_min(data_size, len);
+    *cb->read = saturate_add(read, len_temp, cb->size);
+
+    return len_temp;
+}
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/circ_queue/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/utils/circ_queue/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4b0bdb4
--- /dev/null
@@ -0,0 +1,11 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+set(
+    tiot_circ_queue_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_circ_queue.c
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_circ_queue_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/circ_queue/tiot_circ_queue.c b/code/sdk/zhihui/gnss/driver/common/utils/circ_queue/tiot_circ_queue.c
new file mode 100644 (file)
index 0000000..f56f4a6
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: Tiot Circular queue header. \n
+ *
+ * History: \n
+ * 2023-04-18, Create file. \n
+ */
+#include "tiot_circ_queue.h"
+#ifdef __KERNEL__
+#include <linux/compiler.h>
+#endif
+#include "securec.h"
+
+#ifndef __KERNEL__
+#if (defined(__GNUC__))
+#define likely(_expr)      __builtin_expect(!!(_expr), 1)
+#define unlikely(_expr)    __builtin_expect(!!(_expr), 0)
+#else
+#define likely(_expr)   (_expr)
+#define unlikely(_expr) (_expr)
+#endif
+#endif
+
+static inline uint16_t tiot_circ_queue_mask(const tiot_circ_queue_t *queue)
+{
+    return (queue->size - 1);
+}
+
+static inline uintptr_t tiot_circ_queue_node(const tiot_circ_queue_t *queue, uint16_t idx)
+{
+    return (queue->mem_addr + ((idx & tiot_circ_queue_mask(queue)) * queue->node_bytes));
+}
+
+static inline uint16_t _tiot_circ_queue_space(tiot_circ_queue_t *queue)
+{
+    return ((queue->tail - (queue->head + 1)) & tiot_circ_queue_mask(queue));
+}
+
+void tiot_circ_queue_init(tiot_circ_queue_t *queue, uint16_t size, uint16_t node_bytes, uintptr_t mem_addr)
+{
+    if (unlikely((queue == NULL) || (size == 0) || (node_bytes == 0) || (mem_addr == 0))) {
+        return;
+    }
+
+    /* 队列大小应为2的幂次方 */
+    if ((size & (size - 1)) != 0) {
+        return;
+    }
+
+    osal_spin_lock_init(&queue->lock);
+
+    queue->head = 0;
+    queue->tail = 0;
+    queue->size = size;
+    queue->node_bytes = node_bytes;
+    queue->mem_addr = mem_addr;
+}
+
+/*
+ * 功能描述: 入队列一个节点
+ */
+int32_t tiot_circ_queue_enqueue(tiot_circ_queue_t *queue, uintptr_t src_node)
+{
+    uintptr_t dis_node;
+    unsigned long flags;
+
+    osal_spin_lock_irqsave(&queue->lock, &flags);
+
+    // 检查队列是否已满
+    if (_tiot_circ_queue_space(queue) == 0) {
+        osal_spin_unlock_irqrestore(&queue->lock, &flags);
+        return -1;
+    }
+
+    // 保存节点内容
+    dis_node = tiot_circ_queue_node(queue, queue->head);
+    if (memcpy_s((void *)dis_node, queue->node_bytes, (void *)src_node, queue->node_bytes) != EOK) {
+        osal_spin_unlock_irqrestore(&queue->lock, &flags);
+        return -1;
+    }
+
+    // 索引更新到下一位置
+    queue->head = (queue->head + 1) & tiot_circ_queue_mask(queue);
+
+    osal_spin_unlock_irqrestore(&queue->lock, &flags);
+    return 0;
+}
+
+/*
+ * 功能描述: 从循环队列中,取出最早入队列的节点
+ */
+uintptr_t tiot_circ_queue_dequeue(tiot_circ_queue_t *queue)
+{
+    uintptr_t node;
+    unsigned long flags;
+
+    osal_spin_lock_irqsave(&queue->lock, &flags);
+
+    // 检查是否为空
+    if (queue->head == queue->tail) {
+        osal_spin_unlock_irqrestore(&queue->lock, &flags);
+        return 0;
+    }
+
+    node = tiot_circ_queue_node(queue, queue->tail);
+
+    // 索引更新到下一位置
+    queue->tail = (queue->tail + 1) & tiot_circ_queue_mask(queue);
+
+    osal_spin_unlock_irqrestore(&queue->lock, &flags);
+    return node;
+}
+
+uint16_t tiot_circ_queue_space(tiot_circ_queue_t *queue)
+{
+    uint16_t space;
+    unsigned long flags;
+
+    osal_spin_lock_irqsave(&queue->lock, &flags);
+    space = _tiot_circ_queue_space(queue);
+    osal_spin_unlock_irqrestore(&queue->lock, &flags);
+    return space;
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/circ_queue/tiot_circ_queue.h b/code/sdk/zhihui/gnss/driver/common/utils/circ_queue/tiot_circ_queue.h
new file mode 100644 (file)
index 0000000..5d2d668
--- /dev/null
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: Tiot Circular queue header. \n
+ *
+ * History: \n
+ * 2023-04-18, Create file. \n
+ */
+#ifndef TIOT_CIRC_QUEUE_H
+#define TIOT_CIRC_QUEUE_H
+
+#include "tiot_types.h"
+#include "tiot_osal.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_util_tiot_circ_queue Circular Queue
+ * @ingroup  tiot_common_util
+ * @{
+ */
+
+typedef struct {
+    uint16_t head; // 队列头索引,入队索引
+    uint16_t tail; // 队列尾索引,出队索引
+    uint16_t size; // 队列总大小,深度
+    uint16_t node_bytes; // 每个节点的长度
+    uintptr_t mem_addr; // 队列管理的内存空间(size * node_bytes)起始地址
+    osal_spinlock lock;
+} tiot_circ_queue_t;
+
+/**
+ * @brief  TIoT circ queue empty or not.
+ * @param  [in]  queue Circular queue.
+ * @return if empty return 1, else return 0.
+ */
+static inline int32_t tiot_circ_queue_empty(tiot_circ_queue_t *queue)
+{
+    int32_t ret;
+    unsigned long flags;
+    osal_spin_lock_irqsave(&queue->lock, &flags);
+    ret = (queue->head == queue->tail);
+    osal_spin_unlock_irqrestore(&queue->lock, &flags);
+    return ret;
+}
+
+/**
+ * @brief  TIoT circ queue clear.
+ * @param  queue Circular queue.
+ */
+static inline void tiot_circ_queue_clear(tiot_circ_queue_t *queue)
+{
+    unsigned long flags;
+    osal_spin_lock_irqsave(&queue->lock, &flags);
+    queue->head = 0;
+    queue->tail = 0;
+    osal_spin_unlock_irqrestore(&queue->lock, &flags);
+}
+
+/**
+ * @brief  TIoT circ queue init.
+ * @param  [in]  queue Circular queue.
+ * @param  [in]  size  Queue size, nodes number max is size - 1, must be power of 2.
+ * @param  [in]  node_bytes Fixed node size.
+ * @param  [in]  mem_addr   Queue memory start address, ensure has init outside, length should be size * node_bytes.
+ */
+void tiot_circ_queue_init(tiot_circ_queue_t *queue, uint16_t size, uint16_t node_bytes, uintptr_t mem_addr);
+
+/**
+ * @brief  TIoT circ queue enqueue.
+ * @param  [in]  queue Circular queue.
+ * @param  [in]  src_node Node to be enqueued, will be copyed in queue memory.
+ * @return if OK return 0, else return -1.
+ */
+int32_t tiot_circ_queue_enqueue(tiot_circ_queue_t *queue, uintptr_t src_node);
+
+/**
+ * @brief  TIoT circ queue dequeue.
+ * @param  [in]  queue Circular queue.
+ * @return Pointer to deequeued node.
+ */
+uintptr_t tiot_circ_queue_dequeue(tiot_circ_queue_t *queue);
+
+/**
+ * @brief  TIoT circ queue space.
+ * @param  [in]  queue Circular queue.
+ * @return Circ queue avalible space for nodes.
+ */
+uint16_t tiot_circ_queue_space(tiot_circ_queue_t *queue);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/fileops/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/utils/fileops/CMakeLists.txt
new file mode 100644 (file)
index 0000000..40434cf
--- /dev/null
@@ -0,0 +1,11 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+set(
+    tiot_fileops_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_fileops.c
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_fileops_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/fileops/tiot_fileops.c b/code/sdk/zhihui/gnss/driver/common/utils/fileops/tiot_fileops.c
new file mode 100644 (file)
index 0000000..c2179c1
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT file ops. \n
+ *
+ * History: \n
+ * 2023-04-13, Create file. \n
+ */
+
+#include "tiot_fileops.h"
+#include "tiot_board_log.h"
+#include "tiot_osal.h"
+#include "securec.h"
+#include "tiot_types.h"
+
+#ifdef CONFIG_FILE_BY_ARRAY
+tiot_file *tiot_file_open(const tiot_file_path *path, const char *file_name, int flags, int mode)
+{
+    unsigned int i;
+    const tiot_file *file_list;
+    /* 非只读文件 */
+    tiot_unused(mode);
+    if (flags != OSAL_O_RDONLY) {
+        tiot_print_dbg("[TIoT][file]rw file\n");
+        return NULL;
+    }
+    if (path == NULL) {
+        tiot_print_dbg("[TIoT][file]array file path is NULL\n");
+        return NULL;
+    }
+
+    file_list = path->file_list;  /* 文件数组生成保证不为NULL. */
+    for (i = 0; i < path->file_num; i++) {
+        if (strcmp(file_list->name, file_name) == 0) {
+            return (tiot_file *)file_list;
+        }
+        file_list++;
+    }
+    return NULL;
+}
+
+int tiot_file_read(tiot_file *filp, char *buf, unsigned long size, int offset)
+{
+    uint32_t remain_size;
+    uint32_t copy_size;
+    int ret;
+    if (buf == NULL) {
+        return -1;
+    }
+    /* 偏移值需在文件数据范围内. */
+    if ((offset < 0) || (offset > filp->len)) {
+        tiot_print_err("[TIoT][file]exceed file range!\n");
+        return -1;
+    }
+
+    remain_size = filp->len - offset;
+    copy_size = size > remain_size ? remain_size : size;
+    if (copy_size == 0) {
+        /* 处于文件末尾 */
+        return 0;
+    }
+    ret = memcpy_s(buf, copy_size, &filp->data[offset], copy_size);
+    if (ret != EOK) {
+        return -1;
+    }
+    return copy_size;
+}
+#else
+tiot_file *tiot_file_open(const tiot_file_path *path, const char *file_name, int flags, int mode)
+{
+    (void)path;
+    return (tiot_file *)osal_klib_fopen(file_name, flags, mode);
+}
+
+void tiot_file_close(tiot_file *filp)
+{
+    osal_klib_fclose((void *)filp);
+}
+
+int tiot_file_read(tiot_file *filp, char *buf, unsigned long size, int offset)
+{
+    if (buf == NULL) {
+        tiot_print_err("[TIoT][file]read buff is NULL!\n");
+        return -1;
+    }
+    if (osal_klib_fseek(offset, OSAL_SEEK_SET, (void *)filp) < 0) {
+        tiot_print_err("[TIoT][file]fseek error!\n");
+        return -1;
+    }
+    return osal_klib_fread(buf, size, (void *)filp);
+}
+#endif
+
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/fileops/tiot_fileops.h b/code/sdk/zhihui/gnss/driver/common/utils/fileops/tiot_fileops.h
new file mode 100644 (file)
index 0000000..131269c
--- /dev/null
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: Tiot file types. \n
+ *
+ * History: \n
+ * 2023-04-12, Create file. \n
+ */
+#ifndef TIOT_FILEOPS_H
+#define TIOT_FILEOPS_H
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_utils_file_ops File Ops
+ * @ingroup  tiot_common_utils
+ * @{
+ */
+
+#ifdef CONFIG_FILE_BY_ARRAY
+#define TIOT_FILE_NAME_MAX  16
+
+/**
+ * @brief  TIoT file struct for file array, read only.
+ */
+typedef struct {
+    const char name[TIOT_FILE_NAME_MAX];
+    int len;
+    const char *data;
+} tiot_file;
+
+/**
+ * @brief  TIoT file search path, set for search file array, read only.
+ */
+typedef struct {
+    const tiot_file *file_list;   /* A list of file array, read only. */
+    const unsigned int file_num;  /* File array num, read only. */
+} tiot_file_path;
+#else
+typedef void *tiot_file;          /*!< Dummy type for filp when board has file system. */
+typedef char tiot_file_path;      /*!< Dummy type for path when board has file system. */
+#endif
+
+#ifdef CONFIG_FILE_BY_ARRAY
+#define tiot_file_close(filp)   /*!< No need to close for file array. */
+#else
+/**
+ * @brief  TIoT file open, redirect to osal_klib_fclose.
+ * @param  [in]  filp File handle.
+ */
+void tiot_file_close(tiot_file *filp);
+#endif
+
+/**
+ * @brief  TIoT file open, for file system see @ref osal_klib_fopen, path is ignored.
+ *                         for file array, search in file name in the tiot_file_path.
+ * @param  [in]  path File array path, ignore for file system.
+ * @param  [in]  file_name File name.
+ * @param  [in]  flags File flags, like: OSAL_O_RDONLY.
+ * @param  [in]  mode File rwx mode, like: 0644.
+ * @return if OK return file handle, else return NULL.
+ */
+tiot_file *tiot_file_open(const tiot_file_path *path, const char *file_name, int flags, int mode);
+
+/**
+ * @brief  TIoT file read, for file system read to buf->buff.
+ *                         for file array, only move the buff pointer to offset.
+ * @param  [in]  filp   TIoT file handle.
+ * @param  [in]  buf    TIoT file readbuf.
+ * @param  [in]  size   Required read size.
+ * @param  [in]  offset Read offset of file.
+ * @return The length that has been read, could less than required size, or -1 if fail.
+ */
+int tiot_file_read(tiot_file *filp, char *buf, unsigned long size, int offset);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/list/tiot_list.h b/code/sdk/zhihui/gnss/driver/common/utils/list/tiot_list.h
new file mode 100644 (file)
index 0000000..717b5ba
--- /dev/null
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: TIoT list. \n
+ *
+ * History: \n
+ * 2023-08-03, Create file. \n
+ */
+#ifndef TIOT_LIST_H
+#define TIOT_LIST_H
+
+#include "tiot_types.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_util_tiot_list List
+ * @ingroup  tiot_common_util
+ * @{
+ */
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct tiot_list_head {
+    struct tiot_list_head *next, *prev;
+};
+
+#define tiot_list_head_init(name) \
+    {                             \
+        &(name), &(name)          \
+    }
+
+#define tiot_list_head_create(name) \
+    struct tiot_list_head name = tiot_list_head_init(name)
+
+static inline void tiot_init_list_head(struct tiot_list_head *list)
+{
+    if (list == NULL) {
+        return;
+    }
+    list->next = list;
+    list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void tiot___list_add(struct tiot_list_head *_new,
+    struct tiot_list_head *prev,
+    struct tiot_list_head *next)
+{
+    if (_new == NULL || prev == NULL || next == NULL) {
+        return;
+    }
+    next->prev = _new;
+    _new->next = next;
+    _new->prev = prev;
+    prev->next = _new;
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void tiot_list_add_tail(struct tiot_list_head *cur, struct tiot_list_head *head)
+{
+    tiot___list_add(cur, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void tiot___list_del(struct tiot_list_head *prev, struct tiot_list_head *next)
+{
+    if (prev == NULL || next == NULL) {
+        return;
+    }
+
+    next->prev = prev;
+    prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void tiot___list_del_entry(struct tiot_list_head *entry)
+{
+    if (entry == NULL) {
+        return;
+    }
+    tiot___list_del(entry->prev, entry->next);
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void tiot_list_replace(struct tiot_list_head *old,
+    struct tiot_list_head *_new)
+{
+    _new->next = old->next;
+    _new->next->prev = _new;
+    _new->prev = old->prev;
+    _new->prev->next = _new;
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:    the &struct list_head pointer.
+ * @type:    the type of the struct this is embedded in.
+ * @member:    the name of the list_struct within the struct.
+ */
+#define tiot_list_entry(ptr, type, member) \
+    tiot_container_of(ptr, type, member)
+
+/**
+ * list_for_each_entry    -    iterate over list of given type
+ * @pos:    the type * to use as a loop cursor.
+ * @head:    the head for your list.
+ * @member:  the name of the list_struct within the struct.
+ * @pos_type:  type of the struct which the list_node in.
+ */
+#define tiot_list_for_each_entry(pos, head, member, pos_type)            \
+    for ((pos) = tiot_list_entry((head)->next, pos_type, member);        \
+         &(pos)->member != (head);                                         \
+         (pos) = tiot_list_entry((pos)->member.next, pos_type, member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:    the type * to use as a loop cursor.
+ * @n:        another type * to use as temporary storage
+ * @head:    the head for your list.
+ * @member:    the name of the list_struct within the struct.
+ * @pos_type:  type of pos.
+ * @n_type:    type of n.
+ */
+#define tiot_list_for_each_entry_safe(pos, n, head, member, pos_type, n_type)         \
+    for ((pos) = tiot_list_entry((head)->next, pos_type, member),                     \
+        (n) = tiot_list_entry((pos)->member.next, pos_type, member);                  \
+         &(pos)->member != (head);                                                      \
+         (pos) = (n), (n) = tiot_list_entry((n)->member.next, n_type, member))
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/misc/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/common/utils/misc/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d20f3a5
--- /dev/null
@@ -0,0 +1,11 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+#===============================================================================
+set(
+    tiot_misc_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_misc.c
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_misc_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/misc/tiot_misc.c b/code/sdk/zhihui/gnss/driver/common/utils/misc/tiot_misc.c
new file mode 100644 (file)
index 0000000..2e2c61f
--- /dev/null
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. \n
+ *
+ * Description: TIoT miscellaneous file. \n
+ *
+ * History: \n
+ * 2024-06-20, Create file. \n
+ */
+
+#include "tiot_misc.h"
+
+#define TIOT_HEX_RADIX           16
+#define TIOT_CONVERT_BASIC_LEN   1
+#define TIOT_CONVERT_STR_MIN_LEN 4
+
+// For example, if 3200 is entered, 0xC80 is displayed.
+int32_t tiot_num_to_hex(uint32_t num, char* str_buff, uint32_t str_buff_len)
+{
+    int right = 0;
+    int str_num = 0;
+    uint32_t number = num;
+    int left = 2; // 跳过前两个字符"0x".
+    const char map[] = "0123456789ABCDEF";
+
+    if (str_buff == NULL || str_buff_len < TIOT_CONVERT_STR_MIN_LEN) {
+        return -1;
+    }
+
+    str_buff[str_num++] = '0';
+    str_buff[str_num++] = 'x';
+
+    // Conversion part.
+    do {
+        str_buff[str_num++] = map[number % TIOT_HEX_RADIX];
+        number /= TIOT_HEX_RADIX;
+
+        // 确保有空间存放结束符'\0'.
+        if ((uint32_t)(str_num + TIOT_CONVERT_BASIC_LEN) > str_buff_len) {
+            str_buff[0] = '\0';
+            return -1;
+        }
+    } while (number);
+
+    // Inverting Data
+    right = str_num - TIOT_CONVERT_BASIC_LEN;
+    while (right > left) {
+        char tmp = str_buff[left];
+        str_buff[left] = str_buff[right];
+        str_buff[right] = tmp;
+        left++;
+        right--;
+    }
+    str_buff[str_num++] = '\0';
+    return 0;
+}
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/misc/tiot_misc.h b/code/sdk/zhihui/gnss/driver/common/utils/misc/tiot_misc.h
new file mode 100644 (file)
index 0000000..4f7e441
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved. \n
+ *
+ * Description: Tiot miscellaneous header file. \n
+ *
+ * History: \n
+ * 2024-06-20, Create file. \n
+ */
+#ifndef TIOT_MISC_H
+#define TIOT_MISC_H
+
+#include "tiot_types.h"
+#include "tiot_osal.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_common_utils_tiot_misc TIOT miscellaneous function
+ * @ingroup  tiot_common_utils
+ * @{
+ */
+
+/**
+ * @brief  TIoT converts a non-negative integer to a hexadecimal string.
+ * @param  [in]  num   Nonnegative integer.
+ * @param  [in]  str_buff   String after conversion num.
+ * @param  [in]  str_buff_len Length of str_buff.
+ * @return 0 is returned if Conversion succeeded. Otherwise, -1 is returned.
+ */
+int32_t tiot_num_to_hex(uint32_t num, char* str_buff, uint32_t str_buff_len);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/common/utils/tiot_types.h b/code/sdk/zhihui/gnss/driver/common/utils/tiot_types.h
new file mode 100644 (file)
index 0000000..4854c71
--- /dev/null
@@ -0,0 +1,66 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: TIoT types. \n\r
+ *\r
+ * History: \n\r
+ * 2023-06-01, Create file. \n\r
+ */\r
+#ifndef TIOT_TYPES_H\r
+#define TIOT_TYPES_H\r
+\r
+#ifdef __KERNEL__\r
+/* 内核类型可能与编译器stdint.h冲突. */\r
+#include <linux/kernel.h>\r
+#include <linux/version.h>\r
+#else\r
+#include <stdint.h>\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_common_interface_types TIoT types.\r
+ * @ingroup  tiot_common_interface\r
+ * @{\r
+ */\r
+#ifndef NULL\r
+#define NULL ((void*)0)\r
+#endif\r
+\r
+/* container */\r
+#undef tiot_offsetof\r
+#ifdef __compiler_offsetof\r
+#define tiot_offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)\r
+#else\r
+#define tiot_offsetof(TYPE, MEMBER) ((int)(unsigned long)&((TYPE *)0)->MEMBER)\r
+#endif\r
+\r
+#ifdef _MSC_VER\r
+#define tiot_container_of(ptr, type, member) ((type *)((char *)(const void *){ptr} - tiot_offsetof(type, member)))\r
+#else\r
+#define tiot_container_of(ptr, type, member) ({                 \\r
+    const __typeof__( ((type *)0)->member ) *__mptr = (ptr);    \\r
+    (type *)((char *)__mptr - tiot_offsetof(type, member)); })\r
+#endif\r
+\r
+#define tiot_unused(var) \\r
+    do {                 \\r
+        (void)(var);       \\r
+    } while (0)\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/device/gnss/CMakeLists.txt
new file mode 100644 (file)
index 0000000..adbe7fb
--- /dev/null
@@ -0,0 +1,31 @@
+#===============================================================================\r
+# @brief    cmake make file\r
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+#===============================================================================\r
+if(DEFINED CONFIG_DEV_GNSS)\r
+set(\r
+    device_include_list\r
+    "${CMAKE_CURRENT_SOURCE_DIR}"\r
+)\r
+\r
+set(\r
+    device_src_list\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/gnss_device_info.c\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/gnss_service.c\r
+)\r
+\r
+if(DEFINED CONFIG_FILE_BY_ARRAY)\r
+list(\r
+    APPEND device_src_list\r
+    ${CMAKE_CURRENT_SOURCE_DIR}/firmware/gnss_fw_file_array.c\r
+)\r
+\r
+list(\r
+    APPEND device_include_list\r
+    "${CMAKE_CURRENT_SOURCE_DIR}/firmware"\r
+)\r
+endif()\r
+\r
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${device_include_list}" CACHE INTERNAL "tiot header list" FORCE)\r
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${device_src_list}" CACHE INTERNAL "tiot src list" FORCE)\r
+endif()\r
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/Makefile b/code/sdk/zhihui/gnss/driver/device/gnss/Makefile
new file mode 100644 (file)
index 0000000..fc03118
--- /dev/null
@@ -0,0 +1,16 @@
+# GNSS Makefile
+ifeq ($(CONFIG_DEV_GNSS), y)
+tiot-gnss-objs += gnss_device_info.o gnss_service.o
+
+ifeq ($(CONFIG_FILE_BY_ARRAY), y)
+ifneq (,$(wildcard $(TIOT_DRIVER_PATH)/device/gnss/firmware/gnss_fw_file_array.c))
+tiot-gnss-objs += firmware/gnss_fw_file_array.o
+TIOT_HEADER_LIST += -I$(TIOT_DRIVER_PATH)/device/gnss/firmware
+endif
+endif
+
+tiot-gnss-objs := $(addprefix device/gnss/,$(tiot-gnss-objs))
+tiot_driver-objs += $(tiot-gnss-objs)
+
+TIOT_HEADER_LIST += -I$(TIOT_DRIVER_PATH)/device/gnss
+endif
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_cfg.bin b/code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_cfg.bin
new file mode 100644 (file)
index 0000000..e11d8f2
--- /dev/null
@@ -0,0 +1,905 @@
+0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x20, 0x30, 0x78, 0x30, 0x30,
+0x30, 0x39, 0x38, 0x30, 0x30, 0x30, 0x20, 0x05, 0x04, 0x01, 0x01, 0xfe, 0xef, 0xb2, 0x48, 0x6a,
+0xae, 0x84, 0x2a, 0x84, 0xef, 0x02, 0xd9, 0x0d, 0x40, 0x99, 0x2a, 0x84, 0xef, 0x82, 0x54, 0x4a,
+0x08, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x00, 0xef, 0x12, 0x92, 0x18, 0xef, 0x42, 0x42, 0x16,
+0x01, 0x8a, 0x13, 0x01, 0x82, 0x80, 0x00, 0x00, 0xef, 0x02, 0xd4, 0x69, 0x70, 0x6e, 0x00, 0x00,
+0xef, 0xa2, 0x11, 0x53, 0xef, 0x82, 0x44, 0x3c, 0x22, 0x2c, 0x31, 0xcd, 0x82, 0x80, 0x00, 0x00,
+0xef, 0x72, 0xd5, 0x68, 0xef, 0x92, 0x56, 0x10, 0x03, 0x45, 0xc5, 0xd9, 0xef, 0x92, 0xd6, 0x10,
+0x03, 0x45, 0xc5, 0xd9, 0xef, 0x32, 0xd5, 0x24, 0x53, 0x15, 0x05, 0xc2, 0x3c, 0x99, 0x00, 0x00,
+0xef, 0x12, 0x56, 0x57, 0xef, 0x22, 0x06, 0x02, 0xef, 0xe0, 0x40, 0x37, 0xef, 0xf2, 0x92, 0x35,
+0x03, 0x06, 0xa6, 0xb4, 0xa0, 0x99, 0x00, 0x00, 0xef, 0xf2, 0x01, 0x57, 0x20, 0x99, 0x00, 0x00,
+0xef, 0xf2, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf2, 0xc1, 0x3e, 0x20, 0x99, 0x00, 0x00,
+0xef, 0xf2, 0xc1, 0x33, 0xef, 0xa2, 0x41, 0x4c, 0x13, 0xb6, 0x16, 0x00, 0xef, 0xa2, 0x01, 0x2a,
+0x01, 0xdb, 0x27, 0x30, 0x20, 0x99, 0x00, 0x00, 0xef, 0x92, 0x51, 0x48, 0xef, 0xb2, 0xc1, 0x40,
+0xae, 0x84, 0x2a, 0x89, 0xef, 0x22, 0x93, 0x5d, 0xb5, 0x00, 0x03, 0x26, 0x82, 0x80, 0x00, 0x00,
+0xef, 0xb2, 0xd2, 0x1f, 0xef, 0xb2, 0x52, 0x04, 0x2e, 0x86, 0x2a, 0x84, 0xa4, 0x99, 0x00, 0x00,
+0xef, 0xb2, 0xd2, 0x21, 0x82, 0x80, 0x00, 0x00, 0xef, 0x72, 0xc6, 0x47, 0xef, 0x42, 0x06, 0x5f,
+0x8b, 0xdb, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xef, 0x42, 0xc6, 0x42, 0x3f, 0xf9, 0x00, 0x00,
+0xef, 0xe2, 0x45, 0x09, 0xef, 0xe2, 0x05, 0x63, 0x8b, 0x84, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
+0xef, 0xe2, 0x85, 0x7b, 0xef, 0xe2, 0x45, 0x7a, 0x23, 0x10, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xef, 0xd2, 0xd5, 0x7c, 0xef, 0xe2, 0x55, 0x19, 0x05, 0x07, 0x2e, 0x85, 0x00, 0x00, 0x00, 0x00,
+0xef, 0x42, 0xd6, 0x2a, 0xef, 0x52, 0xc6, 0x4d, 0x37, 0xc5, 0x08, 0x00, 0x82, 0x80, 0x00, 0x00,
+0xef, 0xc2, 0xd3, 0x53, 0x82, 0x80, 0x00, 0x00, 0xef, 0xc2, 0x13, 0x51, 0xef, 0x82, 0x13, 0x5e,
+0x04, 0x20, 0x13, 0x04, 0xef, 0xe2, 0xc8, 0x07, 0x7f, 0x9f, 0x13, 0x84, 0xef, 0x12, 0x15, 0x69,
+0xb0, 0x42, 0x11, 0xc1, 0xef, 0xa2, 0xd6, 0x18, 0x2a, 0x89, 0x37, 0x44, 0xef, 0x62, 0x44, 0x32,
+0x15, 0x02, 0x2a, 0x86, 0xef, 0x52, 0x94, 0x43, 0xef, 0xd0, 0xcf, 0x90, 0xef, 0x42, 0x84, 0x70,
+0xef, 0x50, 0xd2, 0x44, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf2, 0x54, 0x46, 0x00, 0x00, 0x00, 0x00,
+0xef, 0x22, 0xc1, 0x61, 0xef, 0x62, 0x50, 0x4c, 0x37, 0x35, 0x09, 0x00, 0x82, 0x80, 0x00, 0x00,
+0xef, 0xe2, 0xc5, 0x37, 0xef, 0xe2, 0xd6, 0x01, 0xaa, 0x84, 0xef, 0xe0, 0xef, 0x72, 0x86, 0x71,
+0x05, 0x44, 0xef, 0xd0, 0xef, 0x32, 0xd6, 0x69, 0x37, 0xd5, 0x08, 0x00, 0xef, 0x22, 0x43, 0x55,
+0x83, 0xd6, 0x86, 0xb2, 0xa0, 0x98, 0x00, 0x00, 0xef, 0x62, 0x94, 0x29, 0x00, 0x00, 0x00, 0x00,
+0xef, 0xd2, 0x51, 0x16, 0xef, 0xe2, 0xd2, 0x75, 0x26, 0xa0, 0x2a, 0x84, 0xef, 0xf2, 0x52, 0x0b,
+0x32, 0x89, 0x8b, 0x87, 0xef, 0x22, 0x54, 0x2a, 0x2a, 0x86, 0x0d, 0x45, 0x00, 0x00, 0x00, 0x00,
+0xef, 0xf2, 0xc7, 0x6b, 0xef, 0x92, 0x11, 0x65, 0x04, 0x20, 0x07, 0x30, 0xef, 0xa2, 0xc3, 0x76,
+0xb7, 0xb5, 0x04, 0x20, 0x20, 0x98, 0x00, 0x00, 0xef, 0x62, 0x54, 0x48, 0xef, 0x72, 0x03, 0x6c,
+0xef, 0xe0, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xef, 0x72, 0x88, 0x07, 0xef, 0x82, 0x98, 0x32,
+0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x31, 0x05, 0x04,
+0x01, 0x02, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x43, 0x00, 0x00, 0x00, 0x09,
+0xd0, 0x00, 0x00, 0x31, 0x7d, 0x00, 0x00, 0xe9, 0x09, 0x05, 0x00, 0x79, 0x8e, 0x07, 0x00, 0xe1,
+0x65, 0x07, 0x00, 0xa9, 0x8d, 0x05, 0x00, 0x99, 0x01, 0x08, 0x00, 0xd1, 0x13, 0x05, 0x00, 0x09,
+0x16, 0x04, 0x00, 0xd1, 0xf0, 0x02, 0x00, 0x21, 0xf1, 0x02, 0x00, 0xd1, 0x5a, 0x04, 0x00, 0x39,
+0x72, 0x03, 0x00, 0x09, 0x70, 0x03, 0x00, 0xe9, 0xa5, 0x06, 0x00, 0x91, 0xb4, 0x07, 0x00, 0x71,
+0xb5, 0x07, 0x00, 0xf1, 0xb6, 0x07, 0x00, 0x11, 0xb8, 0x07, 0x00, 0x91, 0x07, 0x08, 0x00, 0xa9,
+0x0a, 0x08, 0x00, 0x71, 0x14, 0x08, 0x00, 0x71, 0xfb, 0x07, 0x00, 0x59, 0x71, 0x06, 0x00, 0xc9,
+0xec, 0x06, 0x00, 0x61, 0xeb, 0x06, 0x00, 0xf1, 0xeb, 0x06, 0x00, 0x31, 0x16, 0x03, 0x00, 0x29,
+0x46, 0x03, 0x00, 0x41, 0x48, 0x03, 0x00, 0x99, 0xb0, 0x03, 0x00, 0xd1, 0xab, 0x03, 0x00, 0x41,
+0xa9, 0x03, 0x00, 0x31, 0xa9, 0x03, 0x00, 0x81, 0xb2, 0x03, 0x00, 0x59, 0xa9, 0x03, 0x00, 0x79,
+0x42, 0x03, 0x00, 0xe9, 0x39, 0x03, 0x00, 0xe9, 0xcf, 0x05, 0x00, 0x79, 0xd0, 0x05, 0x00, 0xb1,
+0x10, 0x06, 0x00, 0x09, 0xa6, 0x00, 0x00, 0x09, 0x77, 0x04, 0x00, 0x31, 0xdf, 0x02, 0x00, 0xe1,
+0x34, 0x05, 0x00, 0x49, 0x3c, 0x05, 0x00, 0x61, 0x53, 0x05, 0x00, 0x39, 0x99, 0x04, 0x00, 0xd1,
+0x8b, 0x08, 0x00, 0x09, 0x27, 0x09, 0x00, 0x99, 0xaf, 0x03, 0x00, 0x29, 0x9f, 0x02, 0x00, 0xc9,
+0x13, 0x03, 0x00, 0x61, 0x50, 0x03, 0x00, 0x61, 0x7a, 0x06, 0x00, 0x21, 0x2e, 0x05, 0x00, 0xb9,
+0xd2, 0x07, 0x00, 0xd1, 0xb2, 0x06, 0x00, 0x01, 0xa9, 0x06, 0x00, 0xa1, 0x70, 0x05, 0x00, 0x11,
+0x90, 0x01, 0x00, 0x71, 0x13, 0x08, 0x00, 0x81, 0x0a, 0x06, 0x00, 0xd9, 0x2c, 0x05, 0x00, 0x09,
+0x28, 0x06, 0x00, 0xe1, 0x15, 0x01, 0x00, 0x49, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+0x98, 0xef, 0xf0, 0x66, 0xee, 0xb7, 0x25, 0x00, 0x40, 0x03, 0xd5, 0xc5, 0x54, 0x13, 0x76, 0x15,
+0x00, 0x13, 0x85, 0x01, 0x24, 0x01, 0xc6, 0x23, 0x9a, 0x05, 0x60, 0x7a, 0x1d, 0x19, 0x46, 0x23,
+0xa0, 0xc1, 0x3c, 0x93, 0x85, 0x81, 0xf7, 0x85, 0x46, 0x23, 0x93, 0xd5, 0x00, 0x23, 0x97, 0xd5,
+0x00, 0x23, 0x9b, 0xc5, 0x00, 0x93, 0x85, 0x81, 0x05, 0xf2, 0x15, 0xe2, 0x19, 0xf2, 0x1d, 0xe6,
+0x11, 0xc1, 0x65, 0x93, 0x85, 0x15, 0x9c, 0x6c, 0xc1, 0x20, 0x98, 0x00, 0x00, 0x00, 0x00, 0x7b,
+0xe8, 0x00, 0x70, 0x37, 0x25, 0x00, 0x40, 0x85, 0x45, 0x23, 0x10, 0xb5, 0x20, 0x82, 0x80, 0x00,
+0x00, 0x00, 0x00, 0xc0, 0x98, 0x2a, 0x84, 0xef, 0x40, 0x57, 0x84, 0x7b, 0xe8, 0xa0, 0x70, 0xfb,
+0xca, 0x81, 0x9e, 0xa0, 0x98, 0x00, 0x00, 0xc0, 0x98, 0xef, 0x10, 0xb7, 0xf7, 0x2a, 0x84, 0xef,
+0xf0, 0x56, 0x97, 0x03, 0x55, 0x44, 0x01, 0x0c, 0x48, 0x10, 0x4c, 0x2e, 0x95, 0x08, 0xc8, 0x02,
+0x96, 0xef, 0xf0, 0xf6, 0x93, 0x5c, 0x4c, 0x22, 0x85, 0x80, 0x98, 0x82, 0x87, 0x00, 0x00, 0xc0,
+0x99, 0x32, 0x89, 0xae, 0x84, 0x2a, 0x84, 0xef, 0xf0, 0xd6, 0x94, 0x22, 0x85, 0xa6, 0x85, 0x4a,
+0x86, 0xef, 0x30, 0xb7, 0xdd, 0x2a, 0x84, 0xef, 0xf0, 0x96, 0x91, 0x22, 0x85, 0xa0, 0x99, 0x00,
+0x00, 0x00, 0x00, 0xc4, 0x99, 0x83, 0x44, 0xc5, 0x01, 0x2e, 0x84, 0x01, 0x46, 0xd4, 0x4d, 0xa9,
+0x45, 0xb3, 0xf5, 0xb4, 0x02, 0x13, 0x07, 0xc0, 0x17, 0xb3, 0x37, 0xd7, 0x00, 0x13, 0xb7, 0x15,
+0x00, 0xf9, 0x8f, 0x9d, 0x90, 0xa9, 0xe7, 0x03, 0x46, 0x05, 0x00, 0x93, 0x07, 0xc0, 0x12, 0xb3,
+0xb6, 0xd7, 0x00, 0x64, 0x9f, 0xf9, 0x8e, 0x79, 0x16, 0x33, 0x36, 0xc0, 0x00, 0x55, 0x8e, 0x1d,
+0xe6, 0x03, 0x49, 0x15, 0x00, 0x2e, 0x85, 0xef, 0x10, 0x08, 0xd6, 0x0d, 0xc1, 0x13, 0x05, 0xf1,
+0x00, 0xef, 0x10, 0xe8, 0xbb, 0x01, 0xcd, 0x03, 0x46, 0xf1, 0x00, 0x26, 0x85, 0xa2, 0x85, 0xca,
+0x86, 0xef, 0x10, 0xa8, 0xa9, 0x7d, 0x15, 0x13, 0x36, 0x15, 0x00, 0x11, 0xa0, 0x01, 0x46, 0x32,
+0x85, 0xa4, 0x99, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x9a, 0x39, 0xcd, 0xaa, 0x84, 0xef, 0x00, 0xa9,
+0x99, 0x2a, 0x84, 0x13, 0x86, 0x44, 0x00, 0x0a, 0x85, 0x91, 0x45, 0xa2, 0x86, 0xef, 0x50, 0xe7,
+0xb5, 0xfb, 0x25, 0x00, 0x81, 0x2a, 0x86, 0x13, 0x35, 0x15, 0x00, 0x93, 0xb5, 0x15, 0x00, 0x4d,
+0x8d, 0x19, 0xe9, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x24, 0x93,
+0x85, 0x25, 0x64, 0xef, 0x60, 0x97, 0xa2, 0xb7, 0xf9, 0x01, 0x20, 0x03, 0xc5, 0x89, 0xad, 0x05,
+0x4a, 0x93, 0x84, 0x89, 0xad, 0x05, 0xc9, 0x8b, 0x18, 0x15, 0x01, 0x03, 0x45, 0x11, 0x00, 0xcc,
+0x50, 0x4d, 0x8d, 0x39, 0xe9, 0xb1, 0xa8, 0x7b, 0x25, 0x00, 0x81, 0x19, 0xc9, 0x37, 0x05, 0x23,
+0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x18, 0x93, 0x85, 0x25, 0x64, 0xef, 0x60, 0xb7,
+0x99, 0x01, 0x44, 0xd5, 0xa8, 0x03, 0x45, 0x01, 0x00, 0x0b, 0x1c, 0x05, 0x01, 0x7b, 0x25, 0x00,
+0x81, 0xa3, 0x83, 0x44, 0x01, 0x0b, 0x49, 0x05, 0x03, 0x7b, 0x26, 0x09, 0xf6, 0x37, 0x05, 0x23,
+0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x28, 0x93, 0x85, 0x25, 0x6c, 0xef, 0x60, 0xf7,
+0x9b, 0x03, 0xc5, 0x89, 0xad, 0x8b, 0x09, 0xe5, 0x01, 0x03, 0xc5, 0x84, 0x00, 0x8b, 0x1b, 0x05,
+0x03, 0xef, 0x70, 0xf3, 0xc0, 0x05, 0x04, 0x01, 0x03, 0xfc, 0x69, 0xe2, 0x7b, 0x25, 0x00, 0x81,
+0x0b, 0x48, 0x05, 0x03, 0x03, 0xc6, 0x84, 0x00, 0xfb, 0x26, 0x09, 0xf6, 0x37, 0x05, 0x23, 0x00,
+0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x32, 0x93, 0x85, 0x25, 0x6c, 0xef, 0x60, 0xf7, 0x9d,
+0x92, 0x10, 0x83, 0x46, 0x01, 0x00, 0x03, 0x05, 0x11, 0x00, 0x03, 0x56, 0x21, 0x00, 0x23, 0x8c,
+0xd9, 0xac, 0x23, 0x85, 0xa4, 0x00, 0x8b, 0x49, 0x06, 0x04, 0x7b, 0x25, 0x00, 0x81, 0x09, 0xcd,
+0x7b, 0x27, 0x09, 0xf6, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x39,
+0x93, 0x85, 0x25, 0x64, 0xef, 0x60, 0x37, 0xa0, 0x01, 0x46, 0x29, 0x90, 0x83, 0xa5, 0x41, 0x7a,
+0x81, 0xc5, 0x32, 0x85, 0x82, 0x95, 0x19, 0xa0, 0x13, 0x05, 0x60, 0x22, 0xef, 0x60, 0xe9, 0xdf,
+0x26, 0x85, 0xef, 0x20, 0x89, 0xe3, 0x7b, 0x25, 0x00, 0x81, 0xa3, 0x8c, 0x49, 0xad, 0x0b, 0x4c,
+0x05, 0x03, 0x03, 0xc6, 0x89, 0xad, 0xfb, 0x25, 0x09, 0xf6, 0xfb, 0x26, 0x0f, 0x26, 0x7b, 0x27,
+0x09, 0xf6, 0x83, 0x57, 0x21, 0x00, 0xb3, 0x86, 0xd5, 0x40, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05,
+0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x49, 0x93, 0x85, 0x25, 0x6c, 0xef, 0x60, 0xd7, 0xa0, 0x22, 0x85,
+0xa0, 0x9a, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x9a, 0xae, 0x89, 0x2a, 0x89, 0x37, 0x44, 0x02, 0x40,
+0x13, 0x05, 0x44, 0x20, 0x89, 0x45, 0xef, 0x50, 0x89, 0xe1, 0x13, 0x05, 0x44, 0x23, 0xc1, 0x45,
+0xef, 0x50, 0xe9, 0xe0, 0x13, 0x04, 0x04, 0x20, 0x93, 0x05, 0x00, 0x0a, 0x22, 0x85, 0xef, 0x50,
+0x09, 0xe1, 0x93, 0x05, 0x00, 0x0a, 0x22, 0x85, 0xef, 0x50, 0x69, 0xdf, 0x37, 0x45, 0x10, 0x40,
+0x4c, 0x55, 0x41, 0x66, 0xd1, 0x8d, 0x4c, 0xd5, 0x37, 0x6a, 0x02, 0x40, 0x13, 0x04, 0x4a, 0x20,
+0x93, 0x05, 0x00, 0x20, 0x22, 0x85, 0xef, 0x50, 0x89, 0xde, 0x93, 0x04, 0x0a, 0x12, 0x93, 0x05,
+0x00, 0x10, 0x26, 0x85, 0xef, 0x50, 0xa9, 0xdd, 0x83, 0xd5, 0x41, 0x56, 0x26, 0x85, 0xef, 0x50,
+0x09, 0xdc, 0x93, 0x05, 0x00, 0x10, 0x26, 0x85, 0xef, 0x50, 0x69, 0xdb, 0x93, 0x75, 0xf9, 0x03,
+0x13, 0x05, 0x0a, 0x20, 0xef, 0x50, 0x29, 0xda, 0x8d, 0x45, 0x22, 0x85, 0xef, 0x50, 0x29, 0xdb,
+0x93, 0x95, 0x09, 0x01, 0xc1, 0x81, 0x13, 0x05, 0x8a, 0x20, 0xef, 0x50, 0xc9, 0xd8, 0x93, 0xd5,
+0x09, 0x01, 0x13, 0x05, 0xca, 0x20, 0xef, 0x50, 0x09, 0xd8, 0x83, 0xd5, 0x81, 0x56, 0x13, 0x05,
+0x0a, 0x21, 0xef, 0x50, 0x49, 0xd7, 0x83, 0xd5, 0xa1, 0x56, 0x13, 0x05, 0x4a, 0x21, 0xef, 0x50,
+0x89, 0xd6, 0x83, 0xd5, 0xc1, 0x56, 0x13, 0x05, 0x8a, 0x21, 0xef, 0x50, 0xc9, 0xd5, 0x83, 0xd5,
+0xe1, 0x56, 0x13, 0x05, 0xca, 0x21, 0xef, 0x50, 0x09, 0xd5, 0x93, 0x05, 0x00, 0x08, 0x22, 0x85,
+0xef, 0x50, 0xe9, 0xd4, 0x93, 0x05, 0x00, 0x20, 0x22, 0x85, 0xef, 0x50, 0x49, 0xd4, 0x93, 0x05,
+0x00, 0x10, 0x22, 0x85, 0xef, 0x50, 0xa9, 0xd3, 0x7b, 0x25, 0x00, 0x81, 0x19, 0xcd, 0x83, 0x56,
+0x4a, 0x20, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x01, 0x49, 0x93, 0x85,
+0x25, 0x54, 0x22, 0x86, 0x80, 0x9a, 0x6f, 0x60, 0x57, 0x83, 0xa0, 0x9a, 0x00, 0x00, 0x37, 0x55,
+0x03, 0x20, 0x03, 0x45, 0xc5, 0xd9, 0xb7, 0xb5, 0x09, 0x00, 0x83, 0xc5, 0x45, 0x70, 0x4d, 0x8d,
+0x11, 0xcd, 0x7b, 0x25, 0x00, 0x81, 0x0b, 0x4f, 0x05, 0x03, 0x7b, 0x26, 0x09, 0xf6, 0x37, 0x05,
+0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x16, 0x05, 0xa0, 0x7b, 0x25, 0x00, 0x81,
+0x09, 0x46, 0x7b, 0x66, 0xcf, 0x2e, 0x0b, 0x47, 0x05, 0x03, 0x7b, 0x26, 0x09, 0xf6, 0x37, 0x05,
+0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x14, 0x93, 0x85, 0x25, 0x4c, 0x6f, 0x60,
+0x47, 0xf8, 0x82, 0x80, 0x00, 0x00, 0x37, 0x55, 0x03, 0x20, 0x03, 0x45, 0xc5, 0xd9, 0xb7, 0xb5,
+0x09, 0x00, 0x83, 0xc5, 0x45, 0x70, 0x7d, 0x15, 0x33, 0x35, 0xa0, 0x00, 0xfd, 0x15, 0xb3, 0x35,
+0xb0, 0x00, 0x6d, 0x8d, 0x0d, 0xed, 0x37, 0xf5, 0x01, 0x20, 0x93, 0x05, 0x85, 0xad, 0x03, 0x85,
+0x65, 0x00, 0x7b, 0x26, 0x00, 0x81, 0x85, 0x46, 0xd4, 0xc9, 0x05, 0x05, 0x23, 0x83, 0xa5, 0x00,
+0x0b, 0x41, 0x16, 0x03, 0x08, 0x92, 0xfb, 0x26, 0x09, 0xf6, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05,
+0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x20, 0x93, 0x85, 0x25, 0x4c, 0x6f, 0x60, 0x07, 0xf8, 0x7b, 0x25,
+0x00, 0x81, 0x09, 0x46, 0x7b, 0x66, 0xcf, 0x2e, 0x0b, 0x47, 0x05, 0x03, 0x7b, 0x26, 0x09, 0xf6,
+0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x23, 0x93, 0x85, 0x25, 0x4c,
+0x6f, 0x60, 0x27, 0xf0, 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x15, 0x08, 0x91, 0x8b, 0x54,
+0x05, 0x02, 0x03, 0x45, 0x86, 0x00, 0x0b, 0x15, 0x05, 0x01, 0x33, 0x35, 0xb0, 0x00, 0x82, 0x80,
+0xa3, 0x15, 0x06, 0x00, 0x93, 0x05, 0xd6, 0x00, 0x21, 0xa0, 0x1a, 0x12, 0x93, 0x05, 0xb6, 0x00,
+0x05, 0x45, 0x82, 0x11, 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x9b, 0xaa, 0x84, 0x05, 0x44,
+0xef, 0x60, 0xa9, 0xbf, 0x01, 0xe5, 0x03, 0xc5, 0x24, 0x00, 0x19, 0xc1, 0x22, 0x85, 0xa8, 0x9b,
+0x03, 0x95, 0x04, 0x00, 0x2c, 0x08, 0x10, 0x08, 0x34, 0x00, 0x13, 0x07, 0xf1, 0x01, 0xef, 0x80,
+0x49, 0xa1, 0x2a, 0x89, 0x32, 0x45, 0xa2, 0x45, 0x92, 0x1c, 0x13, 0x06, 0x09, 0xfe, 0x05, 0x44,
+0x0b, 0x23, 0x06, 0x00, 0x81, 0x4a, 0x33, 0x1a, 0xc4, 0x00, 0x21, 0xa0, 0x01, 0x4a, 0xb3, 0x1a,
+0x24, 0x01, 0xb3, 0xf5, 0x55, 0x01, 0x33, 0x75, 0x45, 0x01, 0x4d, 0x8d, 0x61, 0xd1, 0x37, 0x55,
+0x00, 0x20, 0x13, 0x05, 0x85, 0x88, 0x54, 0x51, 0x10, 0x51, 0x7b, 0x25, 0x09, 0xf6, 0xe2, 0x47,
+0x1d, 0x8d, 0x93, 0x05, 0xc0, 0x44, 0x63, 0x4c, 0xb5, 0x06, 0x7b, 0x25, 0x00, 0x81, 0xb7, 0x45,
+0x01, 0x20, 0x93, 0x84, 0x05, 0xa3, 0x8b, 0x4a, 0x05, 0x03, 0x03, 0x45, 0xf1, 0x01, 0x2b, 0x85,
+0xa4, 0x06, 0x18, 0x41, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x00, 0x57,
+0x93, 0x85, 0x25, 0x7c, 0x01, 0x46, 0xca, 0x86, 0xef, 0x60, 0xe7, 0xf3, 0x7b, 0x25, 0x00, 0x81,
+0x83, 0x45, 0xf1, 0x01, 0xab, 0x85, 0xb4, 0x06, 0xd0, 0x41, 0x94, 0x41, 0x13, 0xc7, 0xfa, 0xff,
+0x93, 0x47, 0xfa, 0xff, 0x7d, 0x8e, 0x75, 0x8f, 0x98, 0xc1, 0xd0, 0xc1, 0x0b, 0x44, 0xd5, 0x03,
+0xfb, 0x27, 0x09, 0xf6, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x00, 0x5a,
+0x93, 0x85, 0x25, 0x7c, 0x01, 0x46, 0xca, 0x86, 0xef, 0x60, 0xe7, 0xef, 0x05, 0xbf, 0xd2, 0x45,
+0x42, 0x45, 0x33, 0xc8, 0xb6, 0x00, 0xb3, 0x37, 0xa6, 0x00, 0xe4, 0x9f, 0x33, 0xb7, 0xb6, 0x00,
+0x64, 0x9f, 0x2b, 0xe7, 0x07, 0x21, 0x0d, 0xe7, 0x7b, 0x25, 0x00, 0x81, 0x0b, 0x44, 0xc5, 0x02,
+0x83, 0x96, 0x04, 0x00, 0x7b, 0x27, 0x09, 0xf6, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17,
+0xb7, 0xb5, 0x00, 0x60, 0x93, 0x85, 0x25, 0x78, 0x01, 0x46, 0x02, 0x72, 0x05, 0x04, 0x01, 0x04,
+0xfb, 0xef, 0x60, 0xc7, 0xe5, 0xfd, 0xb5, 0x26, 0x87, 0xef, 0x80, 0x49, 0xef, 0x7d, 0x15, 0x13,
+0x34, 0x15, 0x00, 0xc5, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0x25, 0x00, 0x8b, 0xdc, 0x05,
+0x06, 0x05, 0x46, 0xb3, 0x15, 0xb6, 0x00, 0x93, 0xf5, 0x55, 0x02, 0x95, 0xc1, 0x83, 0x05, 0x05,
+0x07, 0xfd, 0x15, 0x8c, 0x91, 0x8b, 0xd4, 0x05, 0x02, 0x83, 0x45, 0xd5, 0x03, 0x13, 0xf6, 0x35,
+0x00, 0x19, 0xce, 0x5e, 0x1d, 0x39, 0xa0, 0x3e, 0x1d, 0xa3, 0x1e, 0x05, 0x02, 0x39, 0xa0, 0x83,
+0x45, 0xd5, 0x03, 0x93, 0xf5, 0x75, 0x0e, 0xa3, 0x0e, 0xb5, 0x02, 0x01, 0x45, 0x82, 0x80, 0x83,
+0x45, 0xc5, 0x03, 0xe5, 0xfd, 0x03, 0x45, 0xb5, 0x03, 0x13, 0x35, 0x15, 0x00, 0x82, 0x80, 0x00,
+0x00, 0x40, 0x99, 0x2a, 0x84, 0x83, 0x44, 0x25, 0x00, 0xef, 0xb0, 0x59, 0xb8, 0x0b, 0x0a, 0x15,
+0x01, 0x03, 0x25, 0x44, 0x09, 0x83, 0x25, 0x44, 0x08, 0x83, 0x06, 0x04, 0x07, 0xa3, 0x0c, 0x04,
+0x06, 0x13, 0x06, 0x15, 0x00, 0x03, 0x25, 0x04, 0x0b, 0xfd, 0x16, 0x94, 0x92, 0x23, 0x2a, 0xc4,
+0x08, 0x8b, 0xdf, 0x06, 0x02, 0x2b, 0x86, 0xb5, 0xbe, 0xab, 0x35, 0xb6, 0xbe, 0x15, 0x46, 0xef,
+0xb0, 0xf9, 0xeb, 0xb7, 0xb5, 0x09, 0x00, 0x93, 0x85, 0xc5, 0x20, 0xab, 0x85, 0x95, 0x04, 0x8c,
+0x41, 0x23, 0x28, 0xa4, 0x0a, 0x63, 0x60, 0xb5, 0x02, 0x23, 0x08, 0x04, 0x06, 0x0d, 0x45, 0xa3,
+0x0c, 0xa4, 0x06, 0x23, 0x28, 0x04, 0x0a, 0x23, 0x2a, 0x04, 0x08, 0x3a, 0x1c, 0x20, 0x99, 0x01,
+0xc5, 0x23, 0x28, 0x04, 0x0a, 0x20, 0x99, 0x8b, 0x4e, 0x06, 0x32, 0x22, 0x85, 0xef, 0xb0, 0x99,
+0xc0, 0x75, 0xf9, 0x09, 0x45, 0x23, 0x08, 0xa4, 0x06, 0x37, 0xb5, 0x09, 0x00, 0x13, 0x05, 0xc5,
+0x20, 0x2b, 0x05, 0x95, 0x04, 0x08, 0x41, 0x85, 0x45, 0x03, 0x06, 0xd4, 0x03, 0xa3, 0x0c, 0xb4,
+0x06, 0x05, 0x81, 0x23, 0x28, 0xa4, 0x0a, 0x13, 0x65, 0x06, 0x02, 0xa3, 0x0e, 0xa4, 0x02, 0x20,
+0x99, 0x23, 0x08, 0x04, 0x06, 0x20, 0x99, 0x00, 0x00, 0x40, 0x99, 0xae, 0x84, 0x2a, 0x84, 0x13,
+0x05, 0x00, 0x20, 0x2a, 0xc0, 0x0a, 0x85, 0xef, 0xb0, 0x29, 0xd3, 0x03, 0x45, 0x04, 0x07, 0x8b,
+0x03, 0x15, 0x02, 0x0b, 0x12, 0x35, 0x01, 0x82, 0x45, 0x13, 0x05, 0x90, 0x6c, 0x2e, 0x86, 0x83,
+0x26, 0x84, 0x09, 0x77, 0x96, 0xa4, 0xc4, 0x13, 0x07, 0x00, 0x40, 0x33, 0x45, 0xe6, 0x02, 0x36,
+0x95, 0x05, 0x66, 0x13, 0x06, 0xd6, 0x24, 0xae, 0x86, 0xf7, 0x96, 0xc4, 0xc4, 0x03, 0x26, 0xc4,
+0x09, 0x23, 0x2c, 0xa4, 0x08, 0xb3, 0xc6, 0xe6, 0x02, 0x36, 0x95, 0x32, 0x95, 0x23, 0x2e, 0xa4,
+0x08, 0x19, 0x66, 0x13, 0x06, 0x66, 0x1e, 0xf7, 0x95, 0xc4, 0xc4, 0xa1, 0xa8, 0x82, 0x45, 0x13,
+0x05, 0x90, 0x6c, 0x2e, 0x86, 0x77, 0x96, 0xa4, 0xc4, 0x03, 0x25, 0x84, 0x09, 0x85, 0x66, 0x13,
+0x87, 0x06, 0xa0, 0x33, 0x46, 0xe6, 0x02, 0x32, 0x95, 0x23, 0x2c, 0xa4, 0x08, 0x13, 0x86, 0xd6,
+0x24, 0xae, 0x86, 0xf7, 0x96, 0xc4, 0xc4, 0x13, 0x06, 0x00, 0x40, 0xb3, 0xc6, 0xc6, 0x02, 0x36,
+0x95, 0x83, 0x26, 0xc4, 0x09, 0x0a, 0x05, 0x29, 0x47, 0x33, 0x45, 0xe5, 0x02, 0x36, 0x95, 0x23,
+0x2e, 0xa4, 0x08, 0x99, 0x66, 0x93, 0x86, 0x66, 0x1e, 0xf7, 0x95, 0xd4, 0xc4, 0xb3, 0xc5, 0xc5,
+0x02, 0x8a, 0x05, 0xb3, 0xc5, 0xe5, 0x02, 0x50, 0x48, 0x2e, 0x95, 0x93, 0x55, 0xf6, 0x41, 0xc2,
+0x05, 0xab, 0xa5, 0xc5, 0x60, 0x93, 0x16, 0x06, 0x01, 0xab, 0x85, 0xa5, 0xbe, 0x2b, 0x05, 0xc5,
+0x20, 0x33, 0x36, 0xd5, 0x00, 0xb2, 0x95, 0x08, 0xcc, 0x4c, 0xcc, 0x20, 0x99, 0x00, 0x00, 0x00,
+0x00, 0x5c, 0x98, 0x79, 0x71, 0xef, 0x10, 0x50, 0x5e, 0xfb, 0x05, 0x2f, 0x2e, 0x64, 0x9d, 0xfd,
+0x15, 0xb3, 0x35, 0xb0, 0x00, 0x4d, 0x8d, 0x29, 0xe5, 0x37, 0xb5, 0x09, 0x00, 0x93, 0x05, 0x85,
+0x22, 0x28, 0x00, 0x13, 0x06, 0x20, 0x0a, 0xef, 0x80, 0xe6, 0xed, 0x37, 0x65, 0x02, 0x20, 0x13,
+0x05, 0x85, 0xd9, 0x93, 0x05, 0x20, 0x0a, 0x30, 0x00, 0x93, 0x06, 0x20, 0x0a, 0xef, 0x40, 0xd7,
+0xc6, 0xfb, 0x25, 0x00, 0x81, 0x2a, 0x86, 0x13, 0x35, 0x15, 0x00, 0x93, 0xb5, 0x15, 0x00, 0x4d,
+0x8d, 0x39, 0xed, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x01, 0xf2, 0xa1,
+0xa0, 0x37, 0xb5, 0x09, 0x00, 0x93, 0x05, 0xa5, 0x2c, 0x28, 0x00, 0x13, 0x06, 0x20, 0x0a, 0xef,
+0x80, 0x66, 0xe9, 0x37, 0x65, 0x02, 0x20, 0x13, 0x05, 0x85, 0xd9, 0x93, 0x05, 0x20, 0x0a, 0x30,
+0x00, 0x93, 0x06, 0x20, 0x0a, 0xef, 0x40, 0x57, 0xc2, 0xfb, 0x25, 0x00, 0x81, 0x2a, 0x86, 0x13,
+0x35, 0x15, 0x00, 0x93, 0xb5, 0x15, 0x00, 0x4d, 0x8d, 0x19, 0xe9, 0x37, 0x05, 0x23, 0x00, 0x13,
+0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x05, 0x1d, 0x93, 0x85, 0x25, 0x64, 0xef, 0x60, 0xe7, 0xae, 0x45,
+0x61, 0x3c, 0x98, 0x00, 0x00, 0x5c, 0x98, 0x79, 0x71, 0x37, 0xb5, 0x09, 0x00, 0x93, 0x05, 0xc5,
+0x36, 0x28, 0x00, 0x13, 0x06, 0x20, 0x0a, 0xef, 0x80, 0xe6, 0xe3, 0x37, 0x65, 0x02, 0x20, 0x13,
+0x05, 0xa5, 0xe3, 0x93, 0x05, 0x20, 0x0a, 0x30, 0x00, 0x93, 0x06, 0x20, 0x0a, 0xef, 0x40, 0xd7,
+0xbc, 0x05, 0x37, 0x01, 0x45, 0xef, 0xf0, 0x98, 0x9d, 0x45, 0x61, 0x3c, 0x98, 0x5c, 0x98, 0x79,
+0x71, 0xef, 0x10, 0x90, 0x4f, 0xfb, 0x05, 0x2f, 0x2e, 0x64, 0x9d, 0xfd, 0x15, 0xb3, 0x35, 0xb0,
+0x00, 0x4d, 0x8d, 0x29, 0xe5, 0x37, 0xb5, 0x09, 0x00, 0x93, 0x05, 0xe5, 0x40, 0x28, 0x00, 0x13,
+0x06, 0x20, 0x0a, 0xef, 0x80, 0x26, 0xdf, 0x37, 0x65, 0x02, 0x20, 0x13, 0x05, 0xc5, 0xed, 0x93,
+0x05, 0x20, 0x0a, 0x30, 0x00, 0x93, 0x06, 0x20, 0x0a, 0xef, 0x40, 0x17, 0xb8, 0xfb, 0x25, 0x00,
+0x81, 0x2a, 0x86, 0x13, 0x35, 0x15, 0x00, 0x93, 0xb5, 0x15, 0x00, 0x4d, 0x8d, 0x39, 0xed, 0x37,
+0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x00, 0x42, 0xa1, 0xa0, 0x37, 0xb5, 0x09,
+0x00, 0x93, 0x05, 0x05, 0x4b, 0x28, 0x00, 0x13, 0x06, 0x20, 0x0a, 0xef, 0x80, 0xa6, 0xda, 0x37,
+0x65, 0x02, 0x20, 0x13, 0x05, 0xc5, 0xed, 0x93, 0x05, 0x20, 0x0a, 0x30, 0x00, 0x93, 0x06, 0x20,
+0x0a, 0xef, 0x40, 0x97, 0xb3, 0xfb, 0x25, 0x00, 0x81, 0x2a, 0x86, 0x13, 0x35, 0x15, 0x00, 0x93,
+0xb5, 0x15, 0x00, 0x4d, 0x8d, 0x19, 0xe9, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7,
+0xb5, 0x00, 0x6d, 0x93, 0x85, 0x25, 0x64, 0xef, 0x60, 0x27, 0xa0, 0x45, 0x61, 0x3c, 0x98, 0x00,
+0x00, 0xc0, 0x98, 0x37, 0x54, 0x03, 0x20, 0x03, 0x45, 0xc4, 0xd9, 0x8b, 0x18, 0x15, 0x01, 0xef,
+0xa0, 0xba, 0x84, 0x37, 0x05, 0x03, 0x20, 0x83, 0x45, 0x05, 0x24, 0x8b, 0x91, 0x15, 0x01, 0x23,
+0x00, 0x05, 0x24, 0x13, 0x06, 0x05, 0x24, 0x37, 0x05, 0x03, 0x20, 0x13, 0x05, 0x05, 0x2a, 0x93,
+0x05, 0x00, 0x06, 0x93, 0x06, 0x00, 0x06, 0xef, 0x40, 0x37, 0xad, 0xfb, 0x25, 0x00, 0x81, 0x2a,
+0x86, 0x13, 0x35, 0x15, 0x00, 0x93, 0xb5, 0x15, 0x00, 0x4d, 0x8d, 0x19, 0xe9, 0x37, 0x05, 0x23,
+0x00, 0xec, 0x7d, 0x05, 0x04, 0x01, 0x05, 0xfa, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x03, 0x2d,
+0x93, 0x85, 0x25, 0x44, 0xef, 0x60, 0xc7, 0x99, 0x23, 0x0e, 0x04, 0xd8, 0x37, 0xb5, 0x09, 0x00,
+0x23, 0x02, 0x05, 0x70, 0x37, 0x55, 0x03, 0x20, 0xa3, 0x0e, 0x05, 0xd8, 0xa0, 0x98, 0x00, 0x00,
+0x44, 0x99, 0x37, 0xb5, 0x09, 0x00, 0x85, 0x45, 0x23, 0x02, 0xb5, 0x70, 0x08, 0x08, 0xef, 0xc0,
+0xaa, 0xb4, 0xef, 0xd0, 0xb9, 0xd4, 0xef, 0xe0, 0x69, 0x86, 0xef, 0xd0, 0x79, 0xcf, 0x37, 0x54,
+0x03, 0x20, 0x03, 0x26, 0x44, 0xdb, 0xb7, 0x54, 0x03, 0x20, 0x03, 0xa5, 0xc4, 0xdb, 0x83, 0x25,
+0x44, 0xdb, 0x63, 0x64, 0xc5, 0x00, 0x0d, 0x8d, 0x19, 0xa0, 0x33, 0x85, 0xa5, 0x40, 0x93, 0x05,
+0x00, 0x10, 0x63, 0x6a, 0xb5, 0x02, 0x37, 0x55, 0x03, 0x20, 0x03, 0x25, 0x85, 0xdb, 0x03, 0x26,
+0x44, 0xdb, 0x83, 0x25, 0x44, 0xdb, 0x63, 0x67, 0xa6, 0x00, 0x33, 0x85, 0xa5, 0x40, 0x0b, 0x53,
+0x05, 0x3c, 0x11, 0xa8, 0x0d, 0x8d, 0x0b, 0x44, 0x05, 0x3c, 0xef, 0x20, 0x29, 0x83, 0x03, 0x25,
+0x44, 0xdb, 0x23, 0xae, 0xa4, 0xda, 0xef, 0xd0, 0x79, 0xef, 0x68, 0x00, 0xef, 0xc0, 0xca, 0xad,
+0x42, 0x45, 0xb2, 0x45, 0xef, 0xc0, 0x0a, 0xb2, 0xb7, 0x55, 0x03, 0x20, 0x93, 0x85, 0x85, 0xe0,
+0x90, 0x4d, 0x63, 0x73, 0xa6, 0x00, 0x88, 0xcd, 0xb7, 0x55, 0x03, 0x20, 0x03, 0xa6, 0x85, 0xdf,
+0x32, 0x95, 0x23, 0xac, 0xa5, 0xde, 0x24, 0x99, 0x00, 0x00, 0x00, 0x00, 0x40, 0x99, 0x2e, 0x84,
+0xaa, 0x84, 0xef, 0x30, 0xbc, 0xc6, 0x03, 0x45, 0xc5, 0x0e, 0x93, 0x05, 0x60, 0x0e, 0x13, 0x06,
+0x30, 0x11, 0x2b, 0xe6, 0xa5, 0x20, 0x23, 0x90, 0xc4, 0x00, 0x09, 0x45, 0x23, 0x10, 0xa4, 0x00,
+0x20, 0x99, 0x00, 0x00, 0xc0, 0x99, 0x2e, 0x89, 0xaa, 0x84, 0xef, 0x10, 0x70, 0x2f, 0x93, 0x05,
+0x20, 0x1c, 0x13, 0x04, 0x00, 0x14, 0x2b, 0xe4, 0xa5, 0x22, 0xef, 0x30, 0x3c, 0xc3, 0x03, 0x45,
+0xc5, 0x0e, 0x93, 0x05, 0x60, 0x0e, 0x2b, 0xe4, 0xa5, 0x20, 0x23, 0x90, 0x84, 0x00, 0x0d, 0x45,
+0x23, 0x10, 0xa9, 0x00, 0xa0, 0x99, 0x00, 0x00, 0x40, 0x9a, 0x69, 0xc5, 0x2a, 0x84, 0xef, 0x10,
+0x30, 0x2c, 0x83, 0x05, 0x04, 0x07, 0xaa, 0x89, 0x03, 0x29, 0xc4, 0x2a, 0x13, 0x85, 0xf5, 0xff,
+0x88, 0x91, 0x13, 0x05, 0xf0, 0x0f, 0x8b, 0xcd, 0x05, 0x02, 0x83, 0x44, 0xa4, 0x03, 0xef, 0x30,
+0xfc, 0xbe, 0x03, 0x45, 0xc5, 0x0e, 0x93, 0x35, 0x15, 0x00, 0x8b, 0x93, 0x04, 0x01, 0x13, 0x06,
+0x60, 0x0e, 0x13, 0x05, 0x30, 0x11, 0x09, 0xa8, 0x13, 0x06, 0x20, 0x1c, 0x13, 0x05, 0x00, 0x14,
+0x2b, 0x65, 0x36, 0x23, 0x13, 0x06, 0x60, 0x0e, 0x2b, 0x65, 0xb6, 0x22, 0x83, 0x55, 0x44, 0x27,
+0x63, 0x6c, 0xb5, 0x02, 0x03, 0x45, 0x14, 0x03, 0x0b, 0x1c, 0x05, 0x01, 0x03, 0x45, 0x04, 0x2a,
+0x0b, 0x1a, 0x05, 0x01, 0x03, 0x45, 0x14, 0x2a, 0x05, 0xe1, 0x03, 0x25, 0x44, 0x08, 0xab, 0x05,
+0xa5, 0xbe, 0x2b, 0xb5, 0xa5, 0xbe, 0x95, 0x65, 0x93, 0x85, 0x65, 0x55, 0x23, 0x20, 0x04, 0x0a,
+0x63, 0x64, 0xb5, 0x00, 0x23, 0x22, 0x04, 0x08, 0x03, 0x45, 0xc4, 0x07, 0x0b, 0x19, 0x05, 0x01,
+0x09, 0x45, 0x23, 0x0e, 0xa4, 0x06, 0x23, 0x20, 0x04, 0x08, 0x23, 0x22, 0x04, 0x08, 0x13, 0x05,
+0x44, 0x23, 0x93, 0x05, 0x40, 0x03, 0x93, 0x06, 0x40, 0x03, 0x01, 0x46, 0xef, 0x40, 0xd7, 0xee,
+0x63, 0x0a, 0x09, 0x00, 0x03, 0x45, 0x39, 0x00, 0x0b, 0x13, 0x05, 0x05, 0x23, 0x20, 0x04, 0x08,
+0x23, 0x22, 0x04, 0x08, 0x20, 0x9a, 0x00, 0x00, 0xc0, 0x9a, 0x32, 0x8a, 0x2e, 0x89, 0xaa, 0x84,
+0xef, 0x10, 0x10, 0x1f, 0x13, 0x04, 0x40, 0x15, 0x93, 0x09, 0xa0, 0x0f, 0x0b, 0x87, 0x04, 0x03,
+0x93, 0x05, 0x40, 0x1f, 0x13, 0x04, 0xe0, 0x15, 0x2b, 0xe4, 0xa5, 0x22, 0xef, 0x30, 0x1c, 0xb2,
+0x03, 0x45, 0xc5, 0x0e, 0x2b, 0xe4, 0xa9, 0x20, 0x23, 0x10, 0x8a, 0x00, 0x0b, 0x16, 0x09, 0x01,
+0xef, 0x30, 0xdc, 0xb0, 0x03, 0x45, 0xc5, 0x0e, 0x93, 0x05, 0xb0, 0x12, 0xab, 0xe5, 0xa9, 0x20,
+0x23, 0x10, 0xba, 0x00, 0xa0, 0x9a, 0x00, 0x00, 0x40, 0x9a, 0x49, 0xc5, 0xae, 0x89, 0x2a, 0x84,
+0xef, 0x10, 0x10, 0x1a, 0x93, 0x05, 0x20, 0x1c, 0x03, 0x29, 0x44, 0x02, 0x93, 0x04, 0x00, 0x14,
+0xab, 0xe4, 0xa5, 0x22, 0xa3, 0x0c, 0x34, 0x03, 0xef, 0x30, 0x5c, 0xad, 0x03, 0x45, 0xc5, 0x0e,
+0x93, 0x05, 0x60, 0x0e, 0xab, 0xe4, 0xa5, 0x20, 0x63, 0x77, 0x99, 0x02, 0x09, 0x45, 0xa3, 0x08,
+0xa4, 0x02, 0x8b, 0x59, 0x09, 0xfb, 0x93, 0x05, 0x04, 0x03, 0x11, 0x45, 0xa3, 0x08, 0xa4, 0x02,
+0x8b, 0x81, 0x19, 0x02, 0x0b, 0x93, 0x09, 0x01, 0x2e, 0x85, 0xca, 0x85, 0xef, 0x10, 0x5a, 0xfb,
+0xef, 0x50, 0xd9, 0xc5, 0x25, 0xa0, 0x22, 0x1c, 0xef, 0x50, 0x59, 0xc5, 0x64, 0x9d, 0x93, 0x85,
+0xe9, 0xff, 0xb3, 0x35, 0xb0, 0x00, 0x4d, 0x8d, 0x11, 0xe9, 0x03, 0x45, 0x14, 0x03, 0x0b, 0x02,
+0x05, 0x04, 0x8b, 0x12, 0x05, 0x02, 0x05, 0x05, 0xa3, 0x08, 0xa4, 0x02, 0xef, 0x10, 0x19, 0xfe,
+0x11, 0xc1, 0x22, 0x1c, 0x20, 0x9a, 0x22, 0x85, 0x4a, 0x86, 0xef, 0x10, 0x7a, 0xf8, 0xe9, 0xb7,
+0x00, 0x00, 0x00, 0x00, 0xaa, 0x86, 0x03, 0x05, 0x05, 0x07, 0x7d, 0x15, 0x08, 0x93, 0x2e, 0x85,
+0x8b, 0x52, 0x07, 0x02, 0xb2, 0x85, 0x6f, 0x10, 0xea, 0xe1, 0x83, 0xc5, 0xa6, 0x03, 0x8b, 0x92,
+0x05, 0x01, 0xb2, 0x85, 0x6f, 0x10, 0x4a, 0xe2, 0xb2, 0x85, 0x6f, 0x10, 0x2a, 0xe3, 0x00, 0x00,
+0x40, 0x9a, 0xb6, 0x84, 0xb2, 0x89, 0x2e, 0x89, 0x2a, 0x84, 0xef, 0x50, 0xf9, 0xbb, 0x4d, 0xc1,
+0x8b, 0x9b, 0x04, 0x01, 0x0b, 0x47, 0x24, 0x03, 0xef, 0x70, 0x19, 0x9d, 0x7b, 0x06, 0x2f, 0x2e,
+0x93, 0x05, 0xc0, 0x12, 0x0b, 0x05, 0x06, 0x01, 0x13, 0x45, 0xc5, 0x2b, 0x13, 0x06, 0x40, 0x06,
+0x93, 0x05, 0x80, 0x0c, 0xab, 0x65, 0xa6, 0x20, 0x23, 0x10, 0xb9, 0x00, 0x20, 0x9a, 0xef, 0x70,
+0xb9, 0x9a, 0x13, 0x05, 0x45, 0xd4, 0x33, 0x35, 0xa0, 0x00, 0x93, 0x35, 0x34, 0x00, 0x4d, 0x8d,
+0x11, 0xe5, 0x8b, 0x11, 0x14, 0x03, 0x13, 0x05, 0x00, 0x05, 0x89, 0xa0, 0xef, 0x70, 0xd9, 0x98,
+0x13, 0x45, 0x65, 0x22, 0x93, 0x45, 0x34, 0x00, 0x4d, 0x8d, 0x1d, 0xe9, 0x83, 0xd5, 0xa9, 0x00,
+0x13, 0x06, 0x20, 0x12, 0x09, 0x45, 0x63, 0x65, 0xb6, 0x00, 0x05, 0x45, 0x0b, 0xc4, 0x05, 0xf1,
+0x83, 0x55, 0x09, 0x00, 0x33, 0xd5, 0xa5, 0x00, 0x23, 0x10, 0xa9, 0x00, 0xef, 0x10, 0x50, 0x05,
+0x01, 0xc9, 0x13, 0x05, 0x00, 0x14, 0x19, 0xa0, 0x13, 0x05, 0x00, 0x0a, 0x23, 0x10, 0xa9, 0x00,
+0x7b, 0x05, 0x2f, 0x2e, 0x0b, 0x13, 0x05, 0x01, 0x13, 0x05, 0x00, 0x14, 0x23, 0x10, 0xa9, 0x00,
+0x20, 0x9a, 0x00, 0x00, 0xc0, 0x99, 0x01, 0x44, 0x37, 0x35, 0x09, 0x00, 0x13, 0x09, 0x05, 0xa7,
+0x37, 0x86, 0x02, 0x40, 0xb7, 0x84, 0x02, 0x40, 0x03, 0x25, 0x09, 0x00, 0x5b, 0xa2, 0xa4, 0xc0,
+0xdb, 0x26, 0x49, 0x80, 0x01, 0x45, 0xa2, 0x85, 0xef, 0x50, 0x0a, 0xa9, 0x05, 0x04, 0x26, 0x86,
+0x0b, 0x1a, 0xf4, 0x46, 0x37, 0x85, 0x02, 0x40, 0x18, 0x99, 0x05, 0x04, 0x01, 0x06, 0xf9, 0x93,
+0x05, 0x10, 0x10, 0x23, 0x28, 0xb5, 0x0e, 0x85, 0x65, 0x93, 0x85, 0xa5, 0xa0, 0x23, 0x2a, 0xb5,
+0x0e, 0xa0, 0x99, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x98, 0x2a, 0x84, 0x03, 0x45, 0x65, 0x00, 0x8b,
+0x1e, 0x05, 0x02, 0x03, 0x47, 0x44, 0x00, 0xa3, 0x01, 0xe4, 0x00, 0x10, 0x5c, 0x54, 0x5c, 0x7b,
+0x25, 0x00, 0x81, 0x10, 0xd8, 0x54, 0xd8, 0x72, 0x1c, 0x7a, 0x1c, 0x0b, 0x47, 0x05, 0x04, 0xfb,
+0x27, 0x09, 0xf6, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x01, 0x25, 0x93,
+0x85, 0x25, 0x4c, 0xef, 0x50, 0x97, 0xe6, 0x0e, 0x10, 0xa0, 0x98, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x47, 0x45, 0x00, 0xa3, 0x01, 0xe5, 0x00, 0x10, 0x5d, 0x54, 0x5d, 0xfb, 0x25, 0x00, 0x81, 0x10,
+0xd9, 0x54, 0xd9, 0x72, 0x1d, 0x7a, 0x1d, 0x0b, 0xc7, 0x05, 0x03, 0xfb, 0x27, 0x09, 0xf6, 0x37,
+0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x01, 0x34, 0x93, 0x85, 0x25, 0x4c, 0x6f,
+0x50, 0xd7, 0xe2, 0x82, 0x80, 0x00, 0x00, 0xc0, 0x99, 0x37, 0x05, 0x00, 0x04, 0xb7, 0x45, 0x10,
+0x40, 0xec, 0x55, 0x37, 0x16, 0x03, 0x20, 0x13, 0x04, 0x06, 0xb1, 0x50, 0x54, 0x13, 0x09, 0xf5,
+0xff, 0x2b, 0xe5, 0x05, 0x74, 0x48, 0xd0, 0xb3, 0x24, 0xc5, 0x00, 0x22, 0x85, 0xa9, 0x3f, 0x03,
+0x45, 0x64, 0x00, 0x0b, 0x16, 0x05, 0x01, 0x03, 0x45, 0x54, 0x00, 0x13, 0x35, 0x15, 0x00, 0x65,
+0x8d, 0x93, 0x15, 0x15, 0x00, 0xa9, 0x8c, 0x23, 0x03, 0xb4, 0x00, 0x48, 0x50, 0x2a, 0x10, 0x48,
+0xd4, 0x37, 0x86, 0x12, 0x40, 0x03, 0x25, 0x06, 0x0b, 0x83, 0x25, 0x46, 0x0b, 0x03, 0x26, 0xc6,
+0x0b, 0x69, 0x82, 0xb3, 0xe6, 0xa5, 0x00, 0xb3, 0xf6, 0x26, 0x01, 0x23, 0x02, 0xc4, 0x00, 0x99,
+0xc6, 0xb3, 0xf5, 0x25, 0x01, 0x33, 0x75, 0x25, 0x01, 0x08, 0xdc, 0x4c, 0xdc, 0x81, 0xc4, 0x22,
+0x85, 0x80, 0x99, 0xb1, 0xb7, 0xa0, 0x99, 0x00, 0x00, 0x00, 0x00, 0x40, 0x98, 0x22, 0xa0, 0x53,
+0x15, 0x05, 0xc2, 0x53, 0x00, 0x05, 0xd2, 0x53, 0x74, 0x05, 0x0a, 0xef, 0x30, 0x8e, 0xb0, 0x31,
+0xc1, 0xef, 0x30, 0x2e, 0xb0, 0x13, 0x45, 0x45, 0x00, 0x93, 0x05, 0x40, 0x06, 0x13, 0x06, 0x80,
+0x0c, 0x2b, 0xe6, 0xa5, 0x20, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x85, 0x5a, 0x53, 0x15, 0x04,
+0xc2, 0xd3, 0x00, 0x05, 0xd2, 0xd3, 0x70, 0x14, 0x0a, 0xd3, 0xf0, 0x00, 0x12, 0x53, 0x95, 0x00,
+0xc2, 0xb3, 0x65, 0xc5, 0x02, 0x0d, 0x8d, 0x53, 0x01, 0x05, 0xd2, 0xd3, 0xf0, 0x20, 0x0a, 0x53,
+0xf4, 0x00, 0x1a, 0xef, 0xf0, 0x5d, 0xd5, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x85, 0x55, 0x53,
+0x15, 0x85, 0xa2, 0x43, 0x70, 0x05, 0x42, 0x2b, 0x64, 0xa0, 0x3a, 0x53, 0x05, 0x84, 0x22, 0x02,
+0x24, 0x20, 0x98, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xd0, 0x8a, 0xea, 0x00, 0x00, 0x00, 0x00, 0xcc,
+0x9a, 0x22, 0xb8, 0x26, 0xb4, 0x36, 0x89, 0x32, 0x84, 0x53, 0x84, 0xb5, 0x22, 0xae, 0x89, 0xd3,
+0x04, 0xa5, 0x22, 0xaa, 0x84, 0xef, 0xe0, 0xea, 0xb0, 0x2a, 0x8a, 0x03, 0x55, 0x05, 0x0d, 0x69,
+0xc1, 0x13, 0x06, 0x84, 0x07, 0x93, 0x06, 0x94, 0x07, 0xa4, 0x91, 0x0d, 0x45, 0xef, 0xd0, 0xeb,
+0xe6, 0x02, 0xd2, 0x02, 0xd0, 0x08, 0x10, 0x53, 0x85, 0x94, 0x22, 0xef, 0xe0, 0x9e, 0xe5, 0x26,
+0x85, 0xef, 0x30, 0xec, 0xf6, 0x02, 0x35, 0x8b, 0x13, 0x05, 0x01, 0x52, 0x85, 0xa2, 0x85, 0xef,
+0xe0, 0xda, 0xa4, 0x29, 0xa0, 0x52, 0x85, 0xa2, 0x85, 0xef, 0xe0, 0xba, 0x9c, 0x07, 0x30, 0x84,
+0x01, 0x82, 0x30, 0x53, 0xf0, 0x00, 0x0a, 0x02, 0xb0, 0x53, 0x05, 0x84, 0x22, 0x22, 0x85, 0xce,
+0x85, 0x4a, 0x86, 0xef, 0x00, 0x0b, 0x94, 0x13, 0x05, 0x84, 0x03, 0x13, 0x06, 0xc4, 0x02, 0x93,
+0x06, 0x84, 0x02, 0xce, 0x85, 0xef, 0x80, 0xfe, 0xa6, 0x08, 0xa0, 0xef, 0xa0, 0x0c, 0xf8, 0x48,
+0x74, 0x0c, 0x74, 0x02, 0x36, 0x53, 0x05, 0x05, 0x42, 0xd3, 0x85, 0x05, 0x42, 0xce, 0x85, 0xef,
+0x80, 0x4e, 0xf6, 0x53, 0x04, 0xa5, 0x22, 0x0a, 0x85, 0x93, 0x05, 0x00, 0x02, 0x93, 0x06, 0x00,
+0x02, 0x01, 0x46, 0xef, 0x40, 0xd7, 0xa7, 0x8a, 0x85, 0x4e, 0x85, 0xef, 0x50, 0x1b, 0xc0, 0x08,
+0x74, 0xc2, 0x25, 0x53, 0x05, 0x05, 0x42, 0xef, 0x80, 0x5e, 0x9b, 0xd3, 0x05, 0xa5, 0x22, 0x37,
+0xb5, 0x09, 0x00, 0x07, 0x36, 0x05, 0x56, 0x22, 0x85, 0x53, 0x05, 0x84, 0x22, 0xef, 0x00, 0x2b,
+0x8a, 0xa2, 0x34, 0x42, 0x34, 0xac, 0x9a, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x99, 0x37, 0xb5, 0x09,
+0x00, 0x93, 0x05, 0x85, 0x56, 0x13, 0x05, 0x51, 0x02, 0x6d, 0x46, 0x13, 0x04, 0x51, 0x02, 0xef,
+0x70, 0x56, 0xe7, 0x37, 0xb5, 0x09, 0x00, 0x93, 0x05, 0x35, 0x58, 0x13, 0x05, 0xa1, 0x00, 0x6d,
+0x46, 0x93, 0x04, 0xa1, 0x00, 0xef, 0x70, 0xf6, 0xe5, 0xef, 0x30, 0xbc, 0x97, 0xab, 0x64, 0xa4,
+0x20, 0x37, 0xb5, 0x00, 0x20, 0x13, 0x04, 0x05, 0xf2, 0x93, 0x05, 0x40, 0x02, 0x93, 0x06, 0x40,
+0x02, 0x13, 0x09, 0x40, 0x02, 0x22, 0x85, 0x01, 0x46, 0xef, 0x40, 0x77, 0x9f, 0x26, 0x85, 0xef,
+0x80, 0x46, 0xb9, 0xaa, 0x86, 0x93, 0x05, 0x40, 0x02, 0x22, 0x85, 0x26, 0x86, 0xef, 0x40, 0xa7,
+0xbc, 0x19, 0xcd, 0x7b, 0x25, 0x00, 0x81, 0x41, 0xcd, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5,
+0x17, 0xb7, 0xb5, 0x01, 0x38, 0x93, 0x85, 0x25, 0x34, 0xef, 0x50, 0xb7, 0xa4, 0xb0, 0x99, 0x26,
+0x85, 0xef, 0x80, 0x26, 0xb6, 0xaa, 0x84, 0x8b, 0x28, 0x05, 0x1f, 0x7b, 0x25, 0x00, 0x81, 0x25,
+0xc9, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x01, 0x3d, 0x93, 0x85, 0x25,
+0x34, 0x26, 0x86, 0xef, 0x50, 0x57, 0xa7, 0xb0, 0x99, 0xef, 0x80, 0x67, 0xa4, 0xaa, 0x86, 0x33,
+0x85, 0x84, 0x00, 0xb3, 0x05, 0x99, 0x40, 0x37, 0xb6, 0x09, 0x00, 0x13, 0x06, 0xe6, 0x59, 0xef,
+0x10, 0x57, 0xb3, 0x0b, 0x22, 0x05, 0x00, 0xaa, 0x94, 0x31, 0xa8, 0x7b, 0x25, 0x00, 0x81, 0x19,
+0xc9, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x01, 0x44, 0x93, 0x85, 0x25,
+0x34, 0xef, 0x50, 0x37, 0x9e, 0x13, 0x06, 0x40, 0x02, 0x22, 0x85, 0xa6, 0x85, 0xef, 0x70, 0x7e,
+0x87, 0x93, 0x85, 0x34, 0x00, 0x13, 0x06, 0x40, 0x02, 0x22, 0x85, 0xef, 0x70, 0x1e, 0x8f, 0xb0,
+0x99, 0x00, 0x00, 0xc0, 0x98, 0xef, 0x20, 0xfe, 0xef, 0x3d, 0xc1, 0x2a, 0x84, 0x37, 0xb5, 0x00,
+0x20, 0x03, 0x15, 0x85, 0x6a, 0x85, 0x65, 0x95, 0x05, 0x23, 0x10, 0xb4, 0x00, 0x93, 0x05, 0x85,
+0x00, 0x23, 0x13, 0xb4, 0x00, 0x13, 0x05, 0x84, 0x00, 0xac, 0x91, 0xef, 0xf0, 0xdd, 0xae, 0x23,
+0x11, 0xa4, 0x00, 0xef, 0xf0, 0x9d, 0x91, 0xfb, 0x25, 0x00, 0x81, 0x23, 0x12, 0xa4, 0x00, 0x0b,
+0xc8, 0x05, 0x03, 0x03, 0x56, 0x64, 0x00, 0x83, 0x56, 0x24, 0x00, 0x37, 0x05, 0x23, 0x00, 0x13,
+0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x00, 0x25, 0x93, 0x85, 0x25, 0x4c, 0xef, 0x50, 0x57, 0xa1, 0x03,
+0x55, 0x64, 0x00, 0x93, 0x05, 0x85, 0x00, 0x22, 0x85, 0x80, 0x98, 0x6f, 0xf0, 0xdd, 0x96, 0x9f,
+0x1f, 0x05, 0x04, 0x01, 0x07, 0xf8, 0xa0, 0x98, 0x00, 0x00, 0x40, 0x98, 0x0b, 0x94, 0x15, 0x01,
+0x2a, 0x86, 0x13, 0x05, 0xb1, 0x00, 0x85, 0x45, 0x85, 0x46, 0xef, 0x40, 0x47, 0xaa, 0x03, 0x46,
+0xb1, 0x00, 0x8b, 0x1f, 0x06, 0x01, 0x37, 0x55, 0x00, 0x20, 0x13, 0x05, 0x85, 0x88, 0x0c, 0x51,
+0x48, 0x51, 0xfb, 0x26, 0x00, 0x81, 0x37, 0xb7, 0x09, 0x00, 0x23, 0x26, 0xa7, 0x70, 0x23, 0x24,
+0xb7, 0x70, 0x0b, 0xc6, 0x06, 0x03, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5,
+0x02, 0x30, 0x93, 0x85, 0x25, 0x5c, 0xef, 0x50, 0x97, 0x95, 0x20, 0x98, 0x85, 0x45, 0x39, 0xa8,
+0x7b, 0x25, 0x00, 0x81, 0x19, 0xc9, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5,
+0x02, 0x2b, 0x93, 0x85, 0x25, 0x54, 0xef, 0x50, 0x97, 0x93, 0x89, 0x45, 0x7b, 0x6e, 0xb5, 0x6c,
+0x20, 0x98, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x98, 0x2a, 0x84, 0xef, 0x70, 0x4b, 0xcd, 0xaa, 0x85,
+0x05, 0x45, 0x85, 0xc5, 0x0b, 0x54, 0x04, 0x0a, 0x85, 0x45, 0xb3, 0x95, 0x85, 0x00, 0x93, 0xf5,
+0x85, 0x23, 0x81, 0xed, 0xfd, 0x75, 0xfd, 0x15, 0xa2, 0x95, 0x8b, 0xd4, 0x05, 0x09, 0x05, 0x46,
+0xb3, 0x15, 0xb6, 0x00, 0x93, 0xf5, 0x15, 0x14, 0x91, 0xc1, 0xa0, 0x98, 0x01, 0x45, 0xa0, 0x98,
+0x00, 0x00, 0xc0, 0x98, 0x8b, 0x9f, 0x05, 0x02, 0x2a, 0x86, 0x0a, 0x85, 0x89, 0x45, 0x89, 0x46,
+0x09, 0x44, 0xef, 0x40, 0xc7, 0x9e, 0x03, 0x46, 0x01, 0x00, 0x0b, 0x4c, 0x06, 0x02, 0x7b, 0x25,
+0x00, 0x81, 0x09, 0xcd, 0x83, 0x46, 0x11, 0x00, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17,
+0xb7, 0xb5, 0x02, 0x4b, 0x93, 0x85, 0x25, 0x54, 0xef, 0x50, 0xf7, 0x90, 0x7b, 0x6e, 0x85, 0x6c,
+0xa0, 0x98, 0x85, 0x45, 0x7b, 0x6e, 0xb5, 0x6c, 0xa0, 0x98, 0xef, 0x30, 0x0c, 0xc4, 0x2a, 0x84,
+0x83, 0x45, 0x01, 0x00, 0x03, 0x25, 0x45, 0x11, 0x2c, 0xc8, 0x0b, 0x97, 0x05, 0x01, 0x13, 0x65,
+0x05, 0x04, 0x23, 0x2a, 0xa4, 0x10, 0xef, 0x30, 0x4c, 0xf1, 0x13, 0x35, 0x15, 0x00, 0x05, 0x05,
+0x23, 0x0a, 0xa4, 0x04, 0x29, 0xa0, 0x13, 0x75, 0xf5, 0xfb, 0x23, 0x2a, 0xa4, 0x10, 0x7b, 0x25,
+0x00, 0x81, 0x0b, 0x48, 0x05, 0x03, 0x03, 0x46, 0x01, 0x00, 0x83, 0x46, 0x11, 0x00, 0x37, 0x05,
+0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x02, 0x5a, 0x93, 0x85, 0x25, 0x5c, 0xef, 0x50,
+0x97, 0x8a, 0xa0, 0x98, 0x00, 0x00, 0x4c, 0x98, 0x0b, 0x92, 0x25, 0x1c, 0x2a, 0x86, 0x08, 0x10,
+0xf1, 0x45, 0xf1, 0x46, 0xef, 0x40, 0xa7, 0x94, 0x83, 0x46, 0x01, 0x02, 0x37, 0xb5, 0x09, 0x00,
+0x83, 0x05, 0x15, 0x6d, 0x36, 0x86, 0x2b, 0xe6, 0xd5, 0x20, 0xa3, 0x08, 0xc5, 0x6c, 0x03, 0x47,
+0x11, 0x02, 0x83, 0x47, 0x21, 0x02, 0x7b, 0x25, 0x00, 0x81, 0xb7, 0xb5, 0x09, 0x00, 0x23, 0x88,
+0xe5, 0x70, 0x93, 0x85, 0x05, 0x71, 0xa3, 0x80, 0xf5, 0x00, 0x0b, 0x41, 0x15, 0x03, 0x03, 0x48,
+0x31, 0x02, 0x83, 0x58, 0x41, 0x02, 0x83, 0x52, 0x61, 0x02, 0x03, 0x53, 0x81, 0x02, 0x83, 0x53,
+0xa1, 0x02, 0x32, 0x5e, 0x42, 0x55, 0xd2, 0x55, 0x62, 0x56, 0x32, 0xcc, 0x2e, 0xca, 0x2a, 0xc8,
+0x72, 0xc6, 0x1e, 0xc4, 0x1a, 0xc2, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5,
+0x02, 0x73, 0x93, 0x85, 0x25, 0x5c, 0x31, 0x46, 0x16, 0xc0, 0xef, 0x50, 0xd7, 0x93, 0x2c, 0x98,
+0x85, 0x45, 0x7b, 0x6e, 0xb5, 0x6c, 0x2c, 0x98, 0x00, 0x00, 0x40, 0x98, 0x22, 0xa0, 0x33, 0xc8,
+0xb6, 0x00, 0xb3, 0x38, 0xc5, 0x00, 0x33, 0xb7, 0xd5, 0x00, 0x2b, 0xe7, 0x08, 0x21, 0x33, 0x38,
+0xa6, 0x00, 0xb3, 0x87, 0xb6, 0x40, 0xb3, 0x87, 0x07, 0x41, 0x33, 0x08, 0xa6, 0x40, 0x95, 0x8d,
+0xb3, 0x85, 0x15, 0x41, 0x11, 0x8d, 0xab, 0xe5, 0xe7, 0x22, 0x2b, 0x65, 0xe8, 0x22, 0x41, 0x81,
+0x2b, 0x26, 0xb5, 0x20, 0x93, 0xd6, 0x05, 0x01, 0x33, 0x35, 0xc0, 0x00, 0x2b, 0x05, 0xb5, 0x60,
+0xe8, 0x8d, 0x70, 0x8d, 0x2b, 0x65, 0xe6, 0x22, 0xab, 0xe5, 0xe6, 0x22, 0xef, 0xd0, 0xa6, 0xbf,
+0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x85, 0x5a, 0x53, 0x74, 0x05, 0x12, 0xef, 0x50, 0xeb, 0xe5,
+0xef, 0xd0, 0x66, 0xbe, 0x53, 0x75, 0xa4, 0x1a, 0x02, 0x24, 0x20, 0x98, 0x00, 0x00, 0xc0, 0x98,
+0xef, 0x10, 0x6e, 0xd4, 0x2a, 0x84, 0xef, 0x50, 0x5e, 0xc4, 0x37, 0xb6, 0x09, 0x00, 0x83, 0x25,
+0xc6, 0x70, 0x03, 0x27, 0x86, 0x70, 0x33, 0x66, 0xb7, 0x00, 0x01, 0xca, 0x74, 0x49, 0x30, 0x49,
+0x3a, 0x85, 0xa5, 0x37, 0x53, 0x15, 0x15, 0xc2, 0x11, 0xa0, 0x01, 0x45, 0x08, 0xc0, 0xef, 0xb0,
+0x4e, 0xd5, 0x23, 0x02, 0xa4, 0x00, 0xef, 0x50, 0x4e, 0xbc, 0xb7, 0xc5, 0x04, 0x20, 0x93, 0x85,
+0x85, 0xf6, 0x07, 0xb0, 0x05, 0x73, 0x53, 0x75, 0x10, 0x40, 0x53, 0x06, 0x05, 0xe0, 0xa3, 0x28,
+0xc4, 0x00, 0x07, 0xb0, 0x05, 0x14, 0x53, 0x75, 0x10, 0x40, 0x53, 0x06, 0x05, 0xe0, 0xa3, 0x26,
+0xc4, 0x00, 0x03, 0xa6, 0x85, 0x71, 0x83, 0xa5, 0x05, 0x1d, 0x23, 0x03, 0xa4, 0x00, 0xa3, 0x13,
+0xc4, 0x00, 0xa3, 0x24, 0xb4, 0x00, 0xef, 0x10, 0x4e, 0xcc, 0x2a, 0x84, 0x05, 0x65, 0x2d, 0x05,
+0x23, 0x10, 0xa4, 0x00, 0x55, 0x45, 0x23, 0x13, 0xa4, 0x00, 0xef, 0xf0, 0x8d, 0xde, 0x83, 0x55,
+0x64, 0x00, 0x23, 0x12, 0xa4, 0x00, 0x13, 0x05, 0x84, 0x00, 0xef, 0xf0, 0x4d, 0xfa, 0x2a, 0x87,
+0x23, 0x11, 0xa4, 0x00, 0x7b, 0x25, 0x00, 0x81, 0x0b, 0x48, 0x05, 0x03, 0x03, 0x56, 0x04, 0x00,
+0x83, 0x56, 0x64, 0x00, 0x37, 0x05, 0x23, 0x00, 0x13, 0x05, 0xe5, 0x17, 0xb7, 0xb5, 0x03, 0x45,
+0x93, 0x85, 0x25, 0x5c, 0xef, 0x50, 0xe7, 0xf2, 0x03, 0x55, 0x64, 0x00, 0x93, 0x05, 0x85, 0x00,
+0x22, 0x85, 0x80, 0x98, 0x6f, 0xf0, 0xad, 0xe2, 0x00, 0x00, 0x40, 0x99, 0x03, 0xc6, 0xb5, 0x00,
+0x2a, 0x84, 0x0d, 0x45, 0x0b, 0x03, 0x16, 0x01, 0x83, 0xc4, 0x95, 0x00, 0x33, 0x85, 0xb4, 0x00,
+0x03, 0x45, 0x25, 0x00, 0x0b, 0xcf, 0x04, 0x03, 0x0b, 0x0e, 0x05, 0x02, 0x0b, 0x0d, 0x05, 0x04,
+0xef, 0x10, 0xe0, 0x08, 0x4c, 0x44, 0x53, 0x80, 0x05, 0xd2, 0xd3, 0x80, 0x14, 0xd2, 0x11, 0xc5,
+0x37, 0xb5, 0x09, 0x00, 0x07, 0x31, 0x85, 0x5b, 0x29, 0xa0, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x31,
+0x05, 0x5b, 0xd3, 0xf0, 0x20, 0x12, 0xd3, 0x85, 0x00, 0xa2, 0x15, 0x45, 0x91, 0xe1, 0x11, 0x45,
+0x20, 0x99, 0x00, 0x00, 0x00, 0x00, 0x83, 0x45, 0xf5, 0x02, 0x13, 0xf6, 0x05, 0x02, 0x53, 0x05,
+0x00, 0xd2, 0x59, 0xca, 0x54, 0x45, 0x18, 0x45, 0x37, 0xb6, 0x09, 0x00, 0x07, 0x30, 0x06, 0x5c,
+0x03, 0x46, 0x15, 0x02, 0xd3, 0x80, 0x16, 0xd2, 0x53, 0x01, 0x17, 0xd2, 0x43, 0x70, 0x01, 0x0a,
+0x0b, 0x53, 0x16, 0x06, 0x85, 0x46, 0xb3, 0x96, 0xc6, 0x00, 0x93, 0xf6, 0x96, 0x02, 0x9d, 0xce,
+0xab, 0xe6, 0x35, 0x44, 0x11, 0xca, 0x03, 0x05, 0x05, 0x02, 0x0b, 0x17, 0x06, 0x03, 0x37, 0x07,
+0x04, 0x20, 0x13, 0x07, 0x07, 0xde, 0x21, 0xa8, 0x03, 0x05, 0x05, 0x02, 0x37, 0x57, 0x04, 0x20,
+0x13, 0x07, 0x07, 0xcf, 0x29, 0xa0, 0xdf, 0xbc, 0x05, 0x04, 0x01, 0x08, 0xf7, 0x37, 0x57, 0x04,
+0x20, 0x13, 0x07, 0x07, 0xcc, 0x3a, 0x95, 0x89, 0xca, 0x03, 0x45, 0x05, 0x00, 0x11, 0xc5, 0x63,
+0x82, 0xa6, 0x02, 0x53, 0x05, 0x00, 0x22, 0x82, 0x80, 0x01, 0x45, 0x13, 0x36, 0x16, 0x00, 0x8d,
+0x89, 0x93, 0xc6, 0x35, 0x00, 0xab, 0x65, 0xd0, 0x20, 0x2b, 0xe5, 0xc5, 0x22, 0x09, 0xc9, 0x0b,
+0x19, 0xf5, 0x01, 0x37, 0xb5, 0x09, 0x00, 0x87, 0x30, 0x85, 0x5c, 0x53, 0x75, 0x10, 0x02, 0x82,
+0x80, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x99, 0x2a, 0x84, 0x03, 0x06, 0x05, 0x02, 0x03, 0x45, 0x15,
+0x02, 0xae, 0x84, 0x23, 0x90, 0xc5, 0x02, 0xa3, 0x86, 0xa5, 0x02, 0xb2, 0x85, 0xef, 0x90, 0xce,
+0xe6, 0x83, 0xd5, 0x04, 0x02, 0x03, 0xc6, 0xd4, 0x02, 0x23, 0x91, 0xa4, 0x02, 0x2e, 0x89, 0x8b,
+0x15, 0x06, 0x01, 0x37, 0x15, 0x00, 0x20, 0x13, 0x05, 0x85, 0x01, 0x2b, 0x05, 0xb5, 0x04, 0x08,
+0x41, 0x13, 0x09, 0x75, 0x00, 0x03, 0x05, 0x04, 0x03, 0x23, 0x88, 0xa4, 0x02, 0xec, 0x91, 0x32,
+0x85, 0xef, 0xf0, 0x1e, 0xdf, 0xa3, 0x89, 0xa4, 0x02, 0x03, 0xc5, 0xd4, 0x02, 0x02, 0xc4, 0x02,
+0xc2, 0x02, 0xc0, 0x93, 0x15, 0x09, 0x01, 0xc1, 0x81, 0x0a, 0x86, 0xef, 0x80, 0x3e, 0xa4, 0x02,
+0x45, 0x83, 0x05, 0x44, 0x02, 0x03, 0x06, 0xb4, 0x02, 0x23, 0x83, 0xa4, 0x02, 0x23, 0x86, 0xb4,
+0x02, 0xa3, 0x82, 0xc4, 0x02, 0x03, 0x05, 0xe4, 0x01, 0x83, 0x05, 0x34, 0x02, 0x03, 0x06, 0x74,
+0x02, 0x83, 0x06, 0x24, 0x02, 0x23, 0x82, 0xa4, 0x02, 0xa3, 0x83, 0xb4, 0x02, 0xa3, 0x88, 0xc4,
+0x02, 0x13, 0x85, 0xd6, 0xff, 0x88, 0x91, 0x93, 0xb5, 0xa5, 0x00, 0x13, 0x06, 0x10, 0x21, 0x33,
+0x55, 0xa6, 0x00, 0x6d, 0x8d, 0x4c, 0x44, 0x10, 0x44, 0xb7, 0xb6, 0x09, 0x00, 0x07, 0xb0, 0x06,
+0x5c, 0x23, 0x8a, 0xa4, 0x02, 0xd3, 0x80, 0x05, 0xd2, 0x53, 0x01, 0x16, 0xd2, 0x43, 0x70, 0x01,
+0x0a, 0x27, 0xb8, 0x04, 0x00, 0x22, 0x85, 0x59, 0x35, 0x03, 0x05, 0xf4, 0x02, 0x88, 0xa8, 0x23,
+0x87, 0xa4, 0x02, 0xa4, 0x99, 0x40, 0x99, 0xef, 0x30, 0xac, 0x81, 0x2a, 0x84, 0x13, 0x05, 0xf0,
+0x0f, 0x23, 0x12, 0xa4, 0x00, 0xef, 0x30, 0xcc, 0xaf, 0x93, 0x05, 0x10, 0x24, 0x93, 0x04, 0x10,
+0x20, 0x13, 0x06, 0x10, 0x20, 0x2b, 0xe6, 0xa5, 0x20, 0x23, 0x2a, 0xc4, 0x10, 0xef, 0x30, 0x4c,
+0xae, 0x83, 0x25, 0x44, 0x11, 0x13, 0x35, 0x15, 0x00, 0x05, 0x05, 0x13, 0xf6, 0x05, 0x04, 0xa3,
+0x0a, 0xa4, 0x04, 0x09, 0xc6, 0x05, 0x46, 0x30, 0xc8, 0x23, 0x0a, 0xa4, 0x04, 0x13, 0xf5, 0x05,
+0x20, 0x23, 0x0b, 0x04, 0x04, 0x11, 0xc5, 0xef, 0x30, 0xac, 0xab, 0x19, 0xe1, 0x23, 0x1c, 0x94,
+0x04, 0x23, 0x01, 0x04, 0x14, 0x20, 0x99, 0x00, 0x00, 0x40, 0x98, 0xef, 0x20, 0x7c, 0xfb, 0x89,
+0x45, 0x23, 0x05, 0xb5, 0x00, 0xb7, 0xd5, 0x4c, 0x3f, 0x93, 0x85, 0xd5, 0xcc, 0x23, 0x26, 0xb5,
+0x12, 0x20, 0x98, 0x00, 0x00, 0xc0, 0x98, 0xef, 0x50, 0x2d, 0xbb, 0x79, 0xed, 0x37, 0xb5, 0x04,
+0x20, 0x93, 0x05, 0x05, 0x6b, 0xc8, 0x49, 0x09, 0xc9, 0x07, 0xb0, 0x85, 0x00, 0x05, 0x05, 0xd3,
+0x00, 0x15, 0xd2, 0x53, 0x15, 0x10, 0xa2, 0x69, 0xe1, 0xef, 0x50, 0xce, 0x81, 0xb7, 0xc5, 0x04,
+0x20, 0x13, 0x84, 0x85, 0xf6, 0x83, 0x25, 0x04, 0x16, 0x13, 0x35, 0x15, 0x00, 0x93, 0xb5, 0x15,
+0x00, 0x4d, 0x8d, 0x5d, 0xe1, 0xef, 0x20, 0xdc, 0xf5, 0x03, 0x45, 0xc5, 0x0e, 0x0b, 0x17, 0x25,
+0x01, 0xef, 0x50, 0x0e, 0x87, 0x07, 0x30, 0x84, 0x12, 0xb7, 0xb5, 0x09, 0x00, 0x87, 0xb0, 0x05,
+0x66, 0xd3, 0x95, 0x00, 0xa2, 0x37, 0xb6, 0x09, 0x00, 0x13, 0x06, 0x86, 0x5d, 0xab, 0x05, 0xb6,
+0x06, 0x07, 0xb0, 0x05, 0x00, 0xb7, 0xb5, 0x09, 0x00, 0x87, 0xb0, 0x05, 0x5d, 0xb7, 0xb5, 0x09,
+0x00, 0x83, 0xc5, 0x05, 0x71, 0x13, 0x35, 0x15, 0x00, 0x2b, 0xe0, 0xa0, 0x3a, 0x07, 0x25, 0x04,
+0x1d, 0x13, 0xb5, 0x15, 0x00, 0xd3, 0x80, 0x15, 0xd2, 0xab, 0x60, 0xa0, 0x3a, 0x53, 0x00, 0x05,
+0x42, 0x53, 0x95, 0x00, 0xa2, 0x05, 0xc9, 0x23, 0x20, 0x04, 0x16, 0x23, 0x20, 0x04, 0x18, 0x13,
+0x05, 0x84, 0x1f, 0x93, 0x05, 0x00, 0x29, 0x93, 0x06, 0x00, 0x29, 0x01, 0x46, 0xef, 0x40, 0x07,
+0xa7, 0x13, 0x05, 0x84, 0x48, 0x93, 0x05, 0x00, 0x29, 0x93, 0x06, 0x00, 0x29, 0x01, 0x46, 0x80,
+0x98, 0x6f, 0x40, 0xc7, 0xa5, 0x03, 0x45, 0x14, 0x72, 0x0b, 0x14, 0x05, 0x02, 0xef, 0x40, 0x5e,
+0xfe, 0x79, 0xd1, 0xef, 0x40, 0xbd, 0xa3, 0x61, 0xd1, 0xa0, 0x98, 0x00, 0x00, 0xc0, 0x98, 0x37,
+0x24, 0x04, 0x20, 0x83, 0x25, 0x44, 0xe3, 0x37, 0xb5, 0x09, 0x00, 0x03, 0x45, 0x15, 0x6d, 0xb3,
+0x35, 0xb0, 0x00, 0x13, 0x06, 0xd5, 0xfd, 0x13, 0x36, 0x16, 0x00, 0xd1, 0x8d, 0x99, 0xe5, 0xef,
+0x20, 0x3c, 0xd2, 0x13, 0x05, 0x44, 0xe3, 0x85, 0x45, 0x0c, 0xc1, 0xed, 0x35, 0x80, 0x98, 0x6f,
+0x00, 0x30, 0x54, 0x00, 0x00, 0x40, 0x99, 0x2a, 0x84, 0xef, 0x60, 0x1d, 0xbc, 0xaa, 0x84, 0xef,
+0x40, 0x7e, 0xf3, 0x05, 0xc1, 0x37, 0xb5, 0x09, 0x00, 0x03, 0x45, 0x15, 0x71, 0x93, 0x75, 0x05,
+0x08, 0x91, 0xe5, 0x13, 0x75, 0x05, 0x04, 0x11, 0xc5, 0x09, 0x45, 0x11, 0xa0, 0x05, 0x45, 0x23,
+0x8c, 0xa4, 0x00, 0x03, 0xc5, 0x84, 0x01, 0x93, 0x65, 0x25, 0x00, 0x8b, 0x93, 0x05, 0x02, 0x22,
+0x85, 0xef, 0x70, 0x0d, 0xc5, 0x03, 0xc5, 0x84, 0x01, 0x8b, 0x14, 0x05, 0x01, 0x09, 0x45, 0x23,
+0x8c, 0xa4, 0x00, 0x22, 0x85, 0xef, 0x70, 0xcd, 0xc3, 0x11, 0xc1, 0x20, 0x99, 0x05, 0x45, 0x23,
+0x8c, 0xa4, 0x00, 0x22, 0x85, 0x00, 0x99, 0x6f, 0x70, 0xad, 0xc2, 0x00, 0x00, 0x40, 0x99, 0x2a,
+0x84, 0x05, 0x65, 0xb3, 0x05, 0xa4, 0x00, 0x83, 0xa5, 0x85, 0xb0, 0x13, 0x05, 0x05, 0xb0, 0x0b,
+0x98, 0x05, 0x01, 0xb7, 0xd5, 0x4c, 0x3f, 0x93, 0x85, 0xd5, 0xcc, 0x23, 0x26, 0xb4, 0x0e, 0xb7,
+0x05, 0x40, 0x40, 0x23, 0x28, 0xb4, 0x0e, 0xb7, 0x05, 0x00, 0x40, 0x23, 0x24, 0xb4, 0x0e, 0xb3,
+0x04, 0xa4, 0x00, 0xef, 0x20, 0xfc, 0xdd, 0x03, 0x45, 0xc5, 0x0e, 0x15, 0xcd, 0xef, 0x20, 0x5c,
+0xdd, 0x03, 0x45, 0xc5, 0x0e, 0x0d, 0xe1, 0x07, 0x30, 0x84, 0x05, 0x37, 0xb5, 0x09, 0x00, 0x87,
+0x30, 0x85, 0x5e, 0x53, 0x15, 0x10, 0xa2, 0x01, 0xc9, 0x37, 0x05, 0x00, 0x40, 0x23, 0x26, 0xa4,
+0x0e, 0x37, 0x05, 0x80, 0x3f, 0x31, 0xa0, 0x88, 0x40, 0x0b, 0x15, 0x05, 0x01, 0x37, 0x05, 0x80,
+0x40, 0x23, 0x28, 0xa4, 0x0e, 0x21, 0xa0, 0x03, 0xc5, 0x84, 0x01, 0x69, 0xd1, 0x20, 0x99, 0x00,
+0x00, 0x50, 0x9e, 0xa2, 0xa0, 0x26, 0xbc, 0x4a, 0xb8, 0x4e, 0xb4, 0x52, 0xb0, 0x56, 0xac, 0x5a,
+0xa8, 0x5e, 0xa4, 0x32, 0x84, 0xae, 0x89, 0x2a, 0xc2, 0xef, 0x00, 0xd0, 0x42, 0x64, 0x9d, 0x93,
+0x25, 0x14, 0x00, 0x4d, 0x8d, 0x63, 0x19, 0x05, 0x14, 0x81, 0x44, 0x09, 0x65, 0x13, 0x05, 0x05,
+0x86, 0xb3, 0x8a, 0xa9, 0x00, 0x05, 0x65, 0x13, 0x0b, 0x85, 0xc6, 0xb3, 0x8b, 0x69, 0x01, 0x13,
+0x8c, 0x89, 0x12, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xa4, 0x05, 0x5f, 0xb7, 0xb5, 0x78, 0x80, 0x05,
+0x04, 0x01, 0x09, 0xf6, 0x09, 0x00, 0x87, 0xa4, 0x45, 0x5f, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xb9,
+0x05, 0x6a, 0xb7, 0xb5, 0x09, 0x00, 0x87, 0xb9, 0x85, 0x60, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xaa,
+0x85, 0x5f, 0xb7, 0xb5, 0x09, 0x00, 0x87, 0xaa, 0xc5, 0x5f, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xbb,
+0x05, 0x60, 0x93, 0x0c, 0x05, 0xc6, 0x13, 0x0d, 0x45, 0xc6, 0xd3, 0x0b, 0x00, 0xf0, 0xab, 0x8d,
+0x99, 0x04, 0x13, 0x8a, 0x8d, 0x2a, 0x52, 0x85, 0x53, 0x05, 0x84, 0x20, 0xef, 0x40, 0x5d, 0xdd,
+0x13, 0x85, 0x8d, 0x36, 0x53, 0x85, 0x94, 0x20, 0xef, 0x40, 0x9d, 0xdc, 0x81, 0x45, 0x01, 0x45,
+0x01, 0x49, 0x2b, 0x86, 0x99, 0x0a, 0x33, 0x08, 0x96, 0x01, 0xb3, 0x08, 0xa6, 0x01, 0x33, 0x07,
+0x66, 0x01, 0xe2, 0x87, 0x5e, 0x86, 0x53, 0x05, 0x00, 0xf0, 0x63, 0x87, 0xb4, 0x04, 0xb3, 0x86,
+0xba, 0x00, 0x83, 0xc6, 0x06, 0x00, 0xa9, 0xc2, 0x87, 0x25, 0x08, 0x00, 0x07, 0x26, 0x86, 0xff,
+0x87, 0xa6, 0x08, 0x00, 0x07, 0x27, 0xc6, 0xff, 0x1c, 0x63, 0x07, 0x28, 0x06, 0x00, 0xd3, 0xf6,
+0xe6, 0x10, 0xc3, 0xf5, 0xc5, 0x68, 0xc3, 0xf5, 0x07, 0x59, 0x53, 0x80, 0x05, 0x42, 0xd3, 0x06,
+0x0b, 0xa2, 0x99, 0xc6, 0x90, 0x63, 0x05, 0x05, 0x53, 0x76, 0xb6, 0x18, 0x53, 0x75, 0xc5, 0x00,
+0xd3, 0x86, 0x75, 0xa1, 0x91, 0xc2, 0x05, 0x09, 0x85, 0x05, 0x13, 0x06, 0x06, 0x02, 0x91, 0x07,
+0xe3, 0x15, 0xb4, 0xfa, 0x1d, 0xc1, 0x87, 0xa5, 0x8d, 0x12, 0x53, 0x76, 0x05, 0xd0, 0x53, 0x75,
+0xc5, 0x18, 0x53, 0x75, 0x45, 0x01, 0x53, 0x15, 0xb5, 0xa0, 0x01, 0xc9, 0x53, 0xf5, 0xb5, 0x10,
+0x53, 0x75, 0x55, 0x11, 0x52, 0x85, 0xef, 0x40, 0xbd, 0xd2, 0x8b, 0x3b, 0x09, 0x03, 0x12, 0x45,
+0x2b, 0x75, 0x95, 0x58, 0x48, 0x75, 0x53, 0x00, 0x05, 0x42, 0x53, 0x70, 0x20, 0x13, 0x53, 0x15,
+0x30, 0xa3, 0x19, 0xc9, 0x07, 0xa5, 0x8d, 0x12, 0x53, 0x15, 0xaa, 0xa0, 0x11, 0xc5, 0x53, 0x75,
+0xa5, 0x10, 0x52, 0x85, 0xef, 0x40, 0xdd, 0xcf, 0x85, 0x04, 0xe3, 0x9a, 0x84, 0xf0, 0xa2, 0x2b,
+0x42, 0x2b, 0xe2, 0x2a, 0x02, 0x3a, 0xa2, 0x39, 0x42, 0x39, 0xe2, 0x34, 0x06, 0x24, 0x30, 0x9e,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x99, 0x2e, 0x84, 0xaa, 0x84, 0xef, 0x20, 0xfc, 0xbf, 0x03, 0x45,
+0xc5, 0x0e, 0x25, 0xc1, 0x05, 0x65, 0x26, 0x95, 0x03, 0x05, 0xa5, 0xb4, 0x75, 0x15, 0x08, 0x91,
+0x8b, 0x54, 0x15, 0x02, 0x8b, 0x23, 0x14, 0x01, 0x01, 0x46, 0xb3, 0x25, 0x80, 0x00, 0x09, 0x65,
+0x93, 0x06, 0x05, 0x86, 0xa6, 0x96, 0x22, 0x87, 0x83, 0xc7, 0x06, 0x00, 0x81, 0xc7, 0x83, 0xc7,
+0x06, 0x03, 0x3e, 0x96, 0x7d, 0x17, 0x85, 0x06, 0x65, 0xfb, 0x13, 0x26, 0x86, 0x00, 0xe4, 0x9d,
+0xd1, 0x8d, 0x85, 0xe1, 0x13, 0x05, 0x05, 0x89, 0x26, 0x95, 0x83, 0x45, 0x05, 0xfd, 0x81, 0xc5,
+0x83, 0x45, 0x05, 0x00, 0x81, 0xe5, 0x23, 0x08, 0x05, 0xfc, 0x02, 0x11, 0x7d, 0x14, 0x05, 0x05,
+0x6d, 0xf4, 0x20, 0x99, 0x00, 0x00, 0x00, 0x00, 0x44, 0x9a, 0x22, 0xa8, 0x26, 0xa4, 0xb2, 0x89,
+0x8b, 0x86, 0x06, 0x02, 0x8b, 0x98, 0x16, 0x01, 0x89, 0x65, 0x93, 0x85, 0x05, 0x89, 0xb3, 0x04,
+0xb5, 0x00, 0x13, 0x04, 0x85, 0x1e, 0x21, 0x05, 0x01, 0xa8, 0x89, 0x65, 0x93, 0x85, 0x05, 0x86,
+0xb3, 0x04, 0xb5, 0x00, 0x13, 0x04, 0x85, 0x12, 0x00, 0x21, 0xef, 0x00, 0x30, 0x21, 0x0b, 0xae,
+0x09, 0x01, 0x2a, 0x89, 0xd3, 0x04, 0x00, 0xf0, 0x03, 0xc5, 0x04, 0x00, 0x05, 0xc1, 0x08, 0x60,
+0x53, 0x05, 0x05, 0x42, 0xef, 0x90, 0xa6, 0x80, 0x53, 0x15, 0xa4, 0xa2, 0x63, 0x06, 0x09, 0x00,
+0x11, 0xc5, 0x08, 0x60, 0x53, 0x95, 0xa4, 0xa0, 0x11, 0xc1, 0x82, 0x10, 0xfd, 0x19, 0x11, 0x04,
+0x85, 0x04, 0xe3, 0x9b, 0x09, 0xfc, 0xa2, 0x24, 0x42, 0x24, 0x24, 0x9a, 0x00, 0x00, 0x00, 0x00,
+0xc8, 0x99, 0x22, 0xac, 0x26, 0xa8, 0x4a, 0xa4, 0x2a, 0x84, 0x05, 0x65, 0x13, 0x05, 0xa5, 0xb2,
+0xb3, 0x04, 0xa4, 0x00, 0x07, 0xb0, 0x64, 0x0b, 0x87, 0xb0, 0xe4, 0x0a, 0x09, 0x65, 0x53, 0x75,
+0x10, 0x40, 0xd3, 0xf5, 0x10, 0x40, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xb0, 0x05, 0x61, 0xb7, 0xb5,
+0x09, 0x00, 0x87, 0xb0, 0x85, 0x61, 0x83, 0xd5, 0x04, 0x00, 0x53, 0x81, 0x05, 0x42, 0x53, 0x71,
+0x01, 0x12, 0xd3, 0x01, 0x05, 0x42, 0x53, 0x82, 0x15, 0xd2, 0x53, 0x72, 0x12, 0x12, 0x43, 0xf0,
+0x01, 0x22, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xa5, 0x85, 0x62, 0x87, 0x31, 0x04, 0x0a, 0x13, 0x05,
+0xd5, 0x8c, 0x53, 0x74, 0x10, 0x40, 0xd3, 0x05, 0x85, 0xa0, 0x43, 0xf0, 0x11, 0x12, 0x8d, 0xe9,
+0xb7, 0xb5, 0x09, 0x00, 0x07, 0xa5, 0xc5, 0x62, 0x53, 0x06, 0xa4, 0xa0, 0xb7, 0xb5, 0x09, 0x00,
+0x0d, 0xe6, 0x37, 0xb6, 0x09, 0x00, 0x07, 0x25, 0x46, 0x63, 0x87, 0xa5, 0x05, 0x63, 0xb7, 0xb5,
+0x09, 0x00, 0x07, 0xa6, 0x85, 0x63, 0x53, 0x75, 0xa4, 0x00, 0x43, 0x75, 0xc5, 0x58, 0x01, 0xa8,
+0xb7, 0xb5, 0x09, 0x00, 0x07, 0xa5, 0xc5, 0x67, 0x19, 0xa0, 0x07, 0xa5, 0x05, 0x63, 0x83, 0x85,
+0x04, 0x02, 0xd3, 0x74, 0x10, 0x40, 0xf5, 0x15, 0x8c, 0x91, 0x33, 0x09, 0xa4, 0x00, 0x8b, 0xc8,
+0x05, 0x02, 0x53, 0x79, 0x95, 0x10, 0xef, 0x00, 0x70, 0x10, 0x0d, 0xc1, 0x28, 0x34, 0xef, 0x80,
+0x16, 0xf1, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x05, 0x62, 0x53, 0x15, 0x05, 0xa2, 0x19, 0xc5,
+0xef, 0x30, 0x5d, 0x8b, 0x07, 0x30, 0x05, 0x46, 0x53, 0x79, 0x10, 0x40, 0x37, 0xb5, 0x09, 0x00,
+0x07, 0x25, 0xc5, 0x63, 0x03, 0x45, 0x09, 0x00, 0xd3, 0x15, 0xa9, 0xa0, 0x37, 0xb6, 0x09, 0x00,
+0x07, 0x30, 0x86, 0x66, 0x13, 0x35, 0x65, 0x00, 0x6d, 0x8d, 0xd3, 0x00, 0x09, 0x42, 0xab, 0x60,
+0xa0, 0x3a, 0x27, 0x38, 0x14, 0x04, 0x53, 0x00, 0x04, 0x42, 0x27, 0xbb, 0x04, 0x0a, 0x27, 0xb3,
+0x14, 0x0a, 0x53, 0x80, 0x04, 0x42, 0x27, 0xb7, 0x04, 0x0a, 0xef, 0x40, 0xad, 0xd2, 0xaa, 0x84,
+0x48, 0x71, 0x0c, 0x61, 0x30, 0x65, 0x53, 0x75, 0xa5, 0x10, 0x43, 0xf5, 0xb5, 0x50, 0x43, 0x75,
+0xc6, 0x50, 0x53, 0x05, 0x05, 0x42, 0xef, 0xa0, 0x76, 0xac, 0x87, 0xa5, 0x84, 0x0d, 0x07, 0xa6,
+0x44, 0x0b, 0x87, 0xa6, 0xc4, 0x0f, 0x08, 0xb4, 0x53, 0xf5, 0xb5, 0x10, 0x43, 0x75, 0xc6, 0x50,
+0x43, 0xf5, 0xd6, 0x50, 0x53, 0x05, 0x05, 0x42, 0xef, 0xa0, 0x56, 0xaa, 0x08, 0xb0, 0x22, 0x29,
+0xc2, 0x24, 0x62, 0x24, 0xa8, 0x99, 0x00, 0x00, 0xc0, 0x99, 0x2e, 0x86, 0x2a, 0x84, 0x05, 0x65,
+0x07, 0x30, 0x84, 0x05, 0xb7, 0xb5, 0x09, 0x00, 0x87, 0xb0, 0x05, 0x64, 0xb3, 0x05, 0xa4, 0x00,
+0x83, 0xc5, 0x85, 0xb1, 0x13, 0x05, 0x85, 0xb0, 0xd3, 0x96, 0x00, 0xa2, 0xb3, 0x04, 0xa4, 0x00,
+0x81, 0xc6, 0x99, 0xc1, 0x81, 0x45, 0x82, 0x14, 0x32, 0x85, 0xef, 0x40, 0xad, 0xee, 0xcc, 0x44,
+0x05, 0x49, 0x8b, 0x81, 0x05, 0x01, 0x2a, 0x89, 0x07, 0x30, 0x84, 0x05, 0x37, 0xb5, 0x09, 0x00,
+0x87, 0x30, 0x85, 0x65, 0x53, 0x15, 0x10, 0xa2, 0x01, 0xcd, 0xef, 0x20, 0xad, 0x93, 0x8b, 0x14,
+0x05, 0x01, 0xef, 0x40, 0x3d, 0xde, 0x05, 0x04, 0x01, 0x0a, 0xf5, 0x7d, 0xd7, 0x8b, 0x02, 0x05,
+0x02, 0x05, 0x49, 0x23, 0x88, 0x24, 0x01, 0x22, 0x85, 0xef, 0x40, 0xad, 0xef, 0xaa, 0x85, 0x01,
+0x45, 0x8b, 0x81, 0x05, 0x01, 0x4a, 0x85, 0x8c, 0x40, 0x0b, 0x96, 0x05, 0x01, 0x83, 0xc5, 0x24,
+0x04, 0x0b, 0x84, 0x05, 0x02, 0xef, 0x40, 0x3d, 0x86, 0x8b, 0x12, 0x05, 0x01, 0x01, 0x45, 0x82,
+0x14, 0xa0, 0x99, 0x01, 0x45, 0xa0, 0x99, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x99, 0x22, 0xac, 0x26,
+0xa8, 0x4a, 0xa4, 0x32, 0x84, 0x08, 0x22, 0x2e, 0x89, 0xaa, 0x84, 0xef, 0x80, 0x66, 0x9d, 0x07,
+0x30, 0x04, 0x00, 0x53, 0x04, 0xa5, 0x22, 0x53, 0x05, 0x00, 0x22, 0xef, 0x80, 0x86, 0x82, 0x07,
+0x30, 0x84, 0x00, 0xd3, 0x04, 0xa5, 0x22, 0x53, 0x05, 0x00, 0x22, 0xef, 0x80, 0x66, 0x9b, 0x07,
+0x30, 0x84, 0x00, 0x53, 0x09, 0xa5, 0x22, 0x53, 0x05, 0x00, 0x22, 0xef, 0x80, 0x86, 0x80, 0x07,
+0xb0, 0x84, 0x00, 0x87, 0xb0, 0x04, 0x00, 0x53, 0x11, 0x84, 0x22, 0x87, 0xb1, 0x04, 0x01, 0x53,
+0x70, 0x20, 0x12, 0xd3, 0x70, 0x19, 0x12, 0xc7, 0x70, 0x05, 0x0a, 0x53, 0xf1, 0x34, 0x12, 0xc3,
+0x70, 0x25, 0x0a, 0x27, 0x30, 0x19, 0x00, 0x87, 0xb0, 0x04, 0x00, 0xd3, 0x70, 0x15, 0x12, 0x43,
+0x70, 0x09, 0x0a, 0x43, 0x70, 0x29, 0x02, 0x27, 0x34, 0x09, 0x00, 0x07, 0xb0, 0x84, 0x00, 0x88,
+0x4c, 0x53, 0xf0, 0x04, 0x12, 0x43, 0x70, 0x34, 0x02, 0x27, 0x38, 0x09, 0x00, 0x23, 0x2c, 0xa9,
+0x00, 0x22, 0x29, 0xc2, 0x24, 0x62, 0x24, 0xa8, 0x99, 0x00, 0x00, 0xdc, 0x99, 0x59, 0x71, 0xa2,
+0xad, 0xa6, 0xa9, 0x2a, 0x84, 0x07, 0x30, 0x05, 0x00, 0x87, 0x30, 0x85, 0x00, 0x07, 0x31, 0x05,
+0x01, 0x53, 0x84, 0xb5, 0x22, 0xd3, 0x04, 0xa5, 0x22, 0xae, 0x84, 0x02, 0xb9, 0x06, 0xbd, 0x8a,
+0xa1, 0x05, 0x49, 0xca, 0xc5, 0x08, 0x19, 0x8c, 0x18, 0xef, 0x40, 0xfb, 0xd4, 0x07, 0x30, 0x84,
+0x02, 0x87, 0x30, 0x04, 0x03, 0x07, 0x31, 0x84, 0x03, 0x02, 0xa9, 0x06, 0xad, 0x0a, 0xb1, 0x4a,
+0xd5, 0x28, 0x10, 0x0c, 0x09, 0x13, 0x06, 0x00, 0x02, 0xef, 0x60, 0x76, 0xfe, 0x28, 0x00, 0x8c,
+0x18, 0x13, 0x06, 0x00, 0x02, 0xef, 0x60, 0xb6, 0xfd, 0x28, 0x10, 0x2c, 0x00, 0x90, 0x08, 0xb4,
+0x00, 0xef, 0x40, 0x7b, 0xee, 0x46, 0x20, 0xe6, 0x20, 0x53, 0x70, 0x90, 0x12, 0x82, 0xa8, 0x53,
+0xf0, 0x90, 0x12, 0x82, 0xac, 0x88, 0x08, 0x0c, 0x09, 0x90, 0x18, 0xc5, 0x35, 0x4a, 0x20, 0xea,
+0x20, 0x0a, 0x31, 0x27, 0x34, 0x04, 0x02, 0x27, 0x38, 0x14, 0x02, 0x27, 0x3c, 0x24, 0x02, 0x07,
+0x30, 0x04, 0x00, 0x87, 0xb0, 0x04, 0x00, 0x53, 0x70, 0x10, 0x0a, 0x87, 0x30, 0x84, 0x00, 0x07,
+0xb1, 0x84, 0x00, 0x87, 0x31, 0x04, 0x01, 0x07, 0xb2, 0x04, 0x01, 0x02, 0xa9, 0x53, 0xf0, 0x20,
+0x0a, 0x02, 0xad, 0x53, 0xf0, 0x41, 0x0a, 0x02, 0xb1, 0x4a, 0xd5, 0x28, 0x10, 0x0c, 0x09, 0x13,
+0x06, 0x00, 0x02, 0xef, 0x60, 0xd6, 0xf6, 0x28, 0x00, 0x8c, 0x18, 0x13, 0x06, 0x00, 0x02, 0xef,
+0x60, 0x16, 0xf6, 0x28, 0x10, 0x2c, 0x00, 0x90, 0x08, 0xb4, 0x00, 0xef, 0x40, 0xdb, 0xe6, 0x46,
+0x20, 0xe6, 0x20, 0x53, 0x70, 0x80, 0x12, 0x82, 0xa8, 0x53, 0xf0, 0x80, 0x12, 0x82, 0xac, 0x88,
+0x08, 0x0c, 0x09, 0x90, 0x18, 0x9d, 0x35, 0x07, 0xb0, 0x04, 0x00, 0xca, 0x20, 0x53, 0x70, 0x10,
+0x02, 0x27, 0x30, 0x04, 0x00, 0x07, 0xb0, 0x84, 0x00, 0xea, 0x20, 0x53, 0x70, 0x10, 0x02, 0x27,
+0x34, 0x04, 0x00, 0x07, 0xb0, 0x04, 0x01, 0x8a, 0x30, 0x53, 0x70, 0x10, 0x02, 0x27, 0x38, 0x04,
+0x00, 0xce, 0x24, 0x6e, 0x24, 0x65, 0x61, 0xbc, 0x99, 0x00, 0x00, 0x40, 0x9b, 0x2e, 0x8a, 0xaa,
+0x84, 0x05, 0x64, 0x13, 0x05, 0x04, 0xb1, 0xb3, 0x89, 0xa4, 0x00, 0xef, 0x20, 0x4c, 0xf2, 0x83,
+0x2a, 0x85, 0x0e, 0xef, 0x30, 0x8d, 0xd9, 0xaa, 0x85, 0x26, 0x85, 0x95, 0x3b, 0xb3, 0x85, 0x84,
+0x00, 0x83, 0xa5, 0x85, 0xb3, 0x25, 0x46, 0xb3, 0x35, 0xb6, 0x00, 0x33, 0x35, 0xa0, 0x00, 0x6d,
+0x8d, 0x15, 0xe1, 0x13, 0x05, 0x84, 0xb7, 0x26, 0x95, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xb5, 0x05,
+0x65, 0xd2, 0x85, 0xef, 0x40, 0x4d, 0xfd, 0x23, 0xa0, 0x09, 0x00, 0x37, 0x55, 0x04, 0x20, 0x23,
+0x2e, 0x05, 0x72, 0x20, 0x9b, 0x13, 0x05, 0x84, 0xb7, 0x33, 0x89, 0xa4, 0x00, 0x63, 0x8a, 0x0a,
+0x00, 0x53, 0x05, 0x00, 0xd2, 0x52, 0x85, 0xca, 0x85, 0xef, 0x40, 0xed, 0xfa, 0x05, 0x45, 0x2d,
+0xa0, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x35, 0x85, 0x5c, 0x37, 0xb5, 0x09, 0x00, 0x87, 0x35, 0x85,
+0x64, 0x52, 0x85, 0xca, 0x85, 0x99, 0x35, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x35, 0x05, 0x65, 0x4a,
+0x85, 0xd2, 0x85, 0xef, 0x40, 0x4d, 0xf8, 0x01, 0x45, 0x23, 0xa0, 0xa9, 0x00, 0xb7, 0x55, 0x04,
+0x20, 0x23, 0xae, 0xa5, 0x72, 0x52, 0x85, 0xa6, 0x85, 0x00, 0x9b, 0x6f, 0xf0, 0x1c, 0x92, 0x00,
+0x00, 0x00, 0x00, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x05, 0x65, 0x53, 0x95, 0x05, 0xa2, 0x11,
+0xc5, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x85, 0x65, 0xb9, 0xa8, 0x53, 0x15, 0x05, 0xa2, 0x01,
+0xc9, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x85, 0x5c, 0x53, 0x70, 0x05, 0x02, 0xa9, 0xa0, 0x37,
+0xb5, 0x09, 0x00, 0x07, 0x30, 0x05, 0x66, 0x53, 0x15, 0x05, 0xa2, 0x01, 0xcd, 0x37, 0xb5, 0x09,
+0x00, 0x07, 0x30, 0x85, 0x5c, 0x37, 0xb5, 0x09, 0x00, 0x87, 0x30, 0x85, 0x5e, 0x43, 0x70, 0x15,
+0x02, 0x1d, 0xa0, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x85, 0x66, 0x53, 0x15, 0x05, 0xa2, 0x01,
+0xc9, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x30, 0x85, 0x5c, 0x53, 0x70, 0x05, 0x12, 0x29, 0xa0, 0x37,
+0xb5, 0x09, 0x00, 0x07, 0x30, 0x05, 0x67, 0x53, 0x75, 0xc0, 0x12, 0x82, 0x80, 0x00, 0x00, 0xc0,
+0x9b, 0x37, 0xbb, 0x09, 0x00, 0x93, 0x04, 0x4b, 0x6d, 0xdc, 0x40, 0xba, 0x89, 0x36, 0x89, 0x32,
+0x8a, 0x2e, 0x84, 0xaa, 0x8a, 0x05, 0x65, 0x93, 0x05, 0x05, 0xa0, 0x3e, 0x85, 0x01, 0x46, 0xae,
+0x86, 0xef, 0x30, 0xb7, 0x96, 0x03, 0x25, 0x4b, 0x6d, 0x93, 0x05, 0x80, 0x2d, 0x93, 0x06, 0x80,
+0x2d, 0x01, 0x46, 0xef, 0x30, 0x97, 0x95, 0x22, 0x85, 0xef, 0xb0, 0xbd, 0xe1, 0x83, 0x26, 0x4b,
+0x6d, 0xd8, 0x40, 0x05, 0x45, 0xd6, 0x85, 0x22, 0x86, 0xef, 0x90, 0x2d, 0xd5, 0x05, 0xc5, 0x03,
+0x25, 0x4b, 0x6d, 0x93, 0x95, 0x29, 0x00, 0x13, 0x06, 0x05, 0x1e, 0x93, 0x06, 0x40, 0x0c, 0x52,
+0x85, 0xef, 0x30, 0x27, 0xb1, 0xd0, 0x40, 0x22, 0x85, 0xd2, 0x85, 0xca, 0x86, 0xef, 0x80, 0xbd,
+0xdd, 0x33, 0x35, 0xa0, 0x00, 0xa0, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x2f, 0x05, 0x01, 0x81,
+0x48, 0x33, 0x28, 0xb0, 0x00, 0x13, 0x13, 0x25, 0x00, 0x93, 0x92, 0x25, 0x00, 0x63, 0x01, 0x08,
+0x02, 0xb2, 0x83, 0x36, 0x8e, 0xba, 0x8e, 0xae, 0x87, 0x5b, 0xa5, 0x43, 0xa0, 0xdb, 0x25, 0x4e,
+0xa0, 0x53, 0x75, 0xb5, 0x10, 0x27, 0xa0, 0xae, 0x00, 0xfd, 0x17, 0x9a, 0x9e, 0xf5, 0xf7, 0x85,
+0x08, 0x11, 0x07, 0x16, 0x96, 0xe3, 0x9c, 0xa8, 0xfc, 0x82, 0x80, 0x7e, 0x95, 0x05, 0x04, 0x01,
+0x0b, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x48, 0x9e, 0x22, 0xb0, 0x26, 0xac, 0x80, 0x10, 0x83, 0x2a,
+0x44, 0x00, 0x83, 0x2d, 0x04, 0x00, 0x2a, 0x89, 0x37, 0xb5, 0x09, 0x00, 0x63, 0xd5, 0xba, 0x01,
+0x07, 0x24, 0x85, 0x67, 0xa1, 0xaa, 0xc6, 0x89, 0xbe, 0x84, 0x36, 0x8c, 0x2e, 0x8b, 0x23, 0x24,
+0xe4, 0xfa, 0x23, 0x26, 0x04, 0xfb, 0x23, 0x28, 0xc4, 0xfa, 0x23, 0x2a, 0x24, 0xfa, 0x3d, 0x45,
+0xab, 0x05, 0x55, 0x05, 0xc1, 0x99, 0x33, 0x0a, 0xb1, 0x40, 0x52, 0x81, 0xb3, 0x85, 0xba, 0x03,
+0xab, 0x05, 0xb5, 0x04, 0xc1, 0x99, 0x33, 0x0d, 0xb1, 0x40, 0x6a, 0x81, 0xb3, 0x0c, 0xb1, 0x40,
+0x66, 0x81, 0xab, 0x05, 0xb5, 0x05, 0xc1, 0x99, 0xb3, 0x05, 0xb1, 0x40, 0x23, 0x22, 0xb4, 0xfa,
+0x2e, 0x81, 0xb3, 0x85, 0xbd, 0x03, 0x2b, 0x05, 0xb5, 0x04, 0x41, 0x99, 0xb3, 0x0b, 0xa1, 0x40,
+0x5e, 0x81, 0x93, 0x95, 0x2a, 0x00, 0x52, 0x85, 0x01, 0x46, 0xae, 0x86, 0xef, 0x30, 0x77, 0x84,
+0x6a, 0x85, 0xe2, 0x85, 0x56, 0x86, 0xee, 0x86, 0x5a, 0x87, 0xef, 0xe0, 0xcd, 0x95, 0x0b, 0xa9,
+0x0a, 0x01, 0x13, 0x05, 0xf9, 0xff, 0x13, 0x35, 0x15, 0x00, 0xd6, 0x85, 0x52, 0x86, 0x5b, 0xa5,
+0x44, 0xa0, 0xd3, 0x75, 0xa5, 0x10, 0xab, 0x65, 0xa5, 0x38, 0xfd, 0x15, 0x5b, 0x22, 0xb6, 0xe0,
+0xfd, 0xf5, 0x6e, 0x85, 0xd6, 0x85, 0x6a, 0x86, 0xd2, 0x86, 0x66, 0x87, 0xdd, 0x3d, 0x37, 0xb5,
+0x09, 0x00, 0x87, 0x24, 0xc5, 0x67, 0xd3, 0x05, 0x00, 0xf0, 0x53, 0x04, 0x00, 0xf0, 0x01, 0x45,
+0xee, 0x85, 0x6e, 0x86, 0xd6, 0x86, 0x53, 0x85, 0x94, 0x20, 0x66, 0x87, 0xea, 0x87, 0x5e, 0x88,
+0xef, 0xe0, 0xed, 0x8a, 0x5e, 0x85, 0xee, 0x85, 0xef, 0xe0, 0xad, 0xca, 0x11, 0xc5, 0x37, 0xb5,
+0x09, 0x00, 0x07, 0x24, 0x85, 0x67, 0xb1, 0xa8, 0x8b, 0xa7, 0x0d, 0x01, 0x11, 0x45, 0x2b, 0x05,
+0xb5, 0x05, 0x53, 0x04, 0x00, 0xf0, 0xde, 0x85, 0x6e, 0x86, 0x88, 0x61, 0x53, 0x74, 0xa4, 0x00,
+0x7d, 0x16, 0xaa, 0x95, 0x7d, 0xfa, 0x05, 0x46, 0xd3, 0x05, 0x00, 0xf0, 0x01, 0x45, 0xee, 0x85,
+0xd6, 0x86, 0x53, 0x85, 0x94, 0x20, 0x66, 0x87, 0x83, 0x27, 0x84, 0xfa, 0x83, 0x24, 0x44, 0xfa,
+0x26, 0x88, 0xef, 0xe0, 0xcd, 0x85, 0x05, 0x46, 0xd3, 0x05, 0x00, 0xf0, 0x01, 0x45, 0xee, 0x85,
+0xee, 0x86, 0x53, 0x85, 0x94, 0x20, 0x5e, 0x87, 0xa6, 0x87, 0x03, 0x28, 0xc4, 0xfa, 0xef, 0xe0,
+0x0d, 0x84, 0x83, 0x24, 0x44, 0xfb, 0x63, 0x8a, 0x09, 0x00, 0x5e, 0x85, 0xce, 0x85, 0x6e, 0x86,
+0xee, 0x86, 0x03, 0x27, 0x04, 0xfb, 0xef, 0xe0, 0x8d, 0x8b, 0x26, 0x81, 0x53, 0x05, 0x84, 0x20,
+0x13, 0x01, 0x04, 0xfa, 0xe2, 0x24, 0x02, 0x34, 0x28, 0x9e, 0xc0, 0x98, 0x2a, 0x84, 0xef, 0x20,
+0x8c, 0xbb, 0x81, 0x45, 0x37, 0xb6, 0x09, 0x00, 0x13, 0x06, 0xc6, 0x6d, 0xb3, 0x86, 0xc5, 0x00,
+0x83, 0xc6, 0x06, 0x00, 0x63, 0x86, 0x86, 0x00, 0xa1, 0x05, 0x8b, 0x9c, 0xf5, 0x28, 0x01, 0xa8,
+0x08, 0x41, 0xb2, 0x95, 0xcc, 0x41, 0xe9, 0x8d, 0x05, 0x45, 0x91, 0xc1, 0xa0, 0x98, 0x01, 0x45,
+0xa0, 0x98, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x99, 0x2e, 0x84, 0xaa, 0x84, 0xef, 0xc0, 0x2b, 0x87,
+0x15, 0xc5, 0xef, 0x40, 0x0e, 0xae, 0x37, 0xb5, 0x09, 0x00, 0x87, 0x25, 0x05, 0x68, 0x53, 0x85,
+0xa5, 0xa0, 0x05, 0x49, 0x09, 0xed, 0xe0, 0x91, 0x26, 0x85, 0xef, 0x70, 0x9e, 0x9e, 0x37, 0xb5,
+0x09, 0x00, 0x07, 0x30, 0x85, 0x68, 0x53, 0x15, 0x05, 0xa2, 0x11, 0xc1, 0x01, 0x49, 0x4a, 0x85,
+0xa0, 0x99, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x9b, 0x0b, 0xc9, 0x15, 0xe4, 0xae, 0x89, 0x2a, 0x89,
+0x01, 0x45, 0xa5, 0x3f, 0x21, 0xcd, 0x31, 0x4a, 0x05, 0x44, 0x13, 0x0b, 0x40, 0x0e, 0xa0, 0x90,
+0x26, 0x85, 0xef, 0x90, 0xdc, 0xb2, 0xaa, 0x8a, 0x01, 0x45, 0xa6, 0x85, 0x69, 0x3f, 0x0b, 0x16,
+0x05, 0x01, 0x33, 0x05, 0x49, 0x01, 0xb3, 0x85, 0x49, 0x41, 0x93, 0x06, 0x80, 0x0d, 0x56, 0x86,
+0xef, 0x30, 0xa7, 0x87, 0x5a, 0x8a, 0x13, 0x35, 0x04, 0x02, 0x05, 0x04, 0x13, 0x0b, 0x8a, 0x0d,
+0xb3, 0xb5, 0x69, 0x01, 0xe4, 0x9d, 0x6d, 0x8d, 0x79, 0xf1, 0x93, 0x05, 0x4a, 0xff, 0x0d, 0x45,
+0x05, 0x46, 0xca, 0x86, 0x4e, 0x87, 0xef, 0x00, 0x9e, 0x95, 0x11, 0xa0, 0x01, 0x4a, 0x52, 0x85,
+0xa0, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x40, 0x9b, 0x8b, 0xc8, 0x15, 0xe4, 0xae, 0x89, 0x2a, 0x89,
+0x0d, 0x45, 0x21, 0x37, 0x39, 0xc9, 0x31, 0x4a, 0x85, 0x44, 0x13, 0x04, 0x40, 0x0e, 0x64, 0x91,
+0xef, 0xc0, 0x7a, 0xe3, 0xaa, 0x8a, 0xa4, 0x91, 0x0d, 0x45, 0x35, 0x37, 0x0b, 0x16, 0x05, 0x01,
+0x33, 0x05, 0x49, 0x01, 0xb3, 0x85, 0x49, 0x41, 0x93, 0x06, 0x80, 0x0d, 0x56, 0x86, 0xef, 0x30,
+0xc7, 0x80, 0x22, 0x8a, 0x13, 0xb5, 0x24, 0x03, 0x85, 0x04, 0x13, 0x04, 0x8a, 0x0d, 0xb3, 0xb5,
+0x89, 0x00, 0xe4, 0x9d, 0x6d, 0x8d, 0x61, 0xf5, 0x93, 0x05, 0x4a, 0xff, 0x1d, 0x45, 0x05, 0x46,
+0xca, 0x86, 0x4e, 0x87, 0xef, 0x00, 0xbe, 0x8e, 0x11, 0xa0, 0x01, 0x4a, 0x52, 0x85, 0x20, 0x9b,
+0x00, 0x00, 0xc0, 0x9b, 0x0b, 0xc9, 0x15, 0xd4, 0xae, 0x89, 0x2a, 0x89, 0x19, 0x45, 0x71, 0x3d,
+0x21, 0xcd, 0x31, 0x4a, 0x05, 0x44, 0x13, 0x0b, 0x40, 0x0d, 0xa0, 0x90, 0x26, 0x85, 0xef, 0xd0,
+0x9b, 0xa5, 0xaa, 0x8a, 0x19, 0x45, 0xa6, 0x85, 0x7d, 0x3d, 0x0b, 0x16, 0x05, 0x01, 0x33, 0x05,
+0x49, 0x01, 0xb3, 0x85, 0x49, 0x41, 0x93, 0x06, 0x80, 0x0c, 0x56, 0x86, 0xef, 0x20, 0xf7, 0xf9,
+0x5a, 0x8a, 0x13, 0x35, 0x44, 0x02, 0x05, 0x04, 0x13, 0x0b, 0x8a, 0x0c, 0xb3, 0xb5, 0x69, 0x01,
+0xe4, 0x9d, 0x6d, 0x8d, 0x79, 0xf1, 0x93, 0x05, 0x4a, 0xff, 0x39, 0x45, 0x05, 0x46, 0xca, 0x86,
+0x4e, 0x87, 0xef, 0x00, 0xde, 0x87, 0x11, 0xa0, 0x01, 0x4a, 0x52, 0x85, 0xa0, 0x9b, 0x00, 0x00,
+0x00, 0x00, 0xc0, 0x9b, 0x0b, 0xca, 0x15, 0xbc, 0xae, 0x89, 0x2a, 0x89, 0x05, 0x45, 0x05, 0x44,
+0x2d, 0x35, 0x29, 0xcd, 0x31, 0x4a, 0x13, 0x0b, 0xc0, 0x0b, 0xa0, 0x90, 0x26, 0x85, 0xef, 0xf0,
+0x0b, 0xdb, 0xaa, 0x8a, 0x05, 0x45, 0xa6, 0x85, 0xb9, 0x35, 0x0b, 0x17, 0x05, 0x01, 0x23, 0x96,
+0x8a, 0x0a, 0x33, 0x05, 0x49, 0x01, 0xb3, 0x85, 0x49, 0x41, 0x93, 0x06, 0x00, 0x0b, 0x56, 0x86,
+0xef, 0x20, 0xb7, 0xf2, 0x5a, 0x8a, 0x13, 0x35, 0x84, 0x01, 0x05, 0x04, 0x13, 0x0b, 0x0a, 0x0b,
+0xb3, 0xb5, 0x69, 0x01, 0xe4, 0x9d, 0x6d, 0x8d, 0x69, 0xf1, 0x93, 0x05, 0x4a, 0xff, 0x55, 0x45,
+0x05, 0x46, 0xca, 0x86, 0x4e, 0x87, 0xef, 0x00, 0x9e, 0x80, 0x11, 0xa0, 0x01, 0x4a, 0x52, 0x85,
+0xa0, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x37, 0xc5, 0x04, 0x20, 0x13, 0x05, 0x85, 0xf6, 0x83, 0x25,
+0x05, 0x16, 0x07, 0x30, 0x85, 0x12, 0x37, 0xb5, 0x09, 0x00, 0x87, 0x30, 0x85, 0x5c, 0x37, 0xb5,
+0x09, 0x00, 0x07, 0x31, 0x05, 0x69, 0x33, 0x35, 0xb0, 0x00, 0xd3, 0x85, 0x00, 0xa2, 0x6d, 0x8d,
+0xd3, 0x05, 0x20, 0xa2, 0x6d, 0x8d, 0x82, 0x80, 0x00, 0x00, 0x37, 0xb5, 0x09, 0x00, 0x03, 0x45,
+0x25, 0x71, 0x3a, 0x36, 0x05, 0x04, 0x01, 0x0c, 0xf3, 0x82, 0x80, 0x00, 0x00, 0xc0, 0x98, 0xef,
+0x20, 0xec, 0xc2, 0x01, 0xe5, 0x05, 0x44, 0x5d, 0x3f, 0x11, 0xe1, 0x01, 0x44, 0x37, 0xb5, 0x09,
+0x00, 0x23, 0x09, 0x85, 0x70, 0xa0, 0x98, 0x00, 0x00, 0x40, 0x98, 0x37, 0xb5, 0x09, 0x00, 0x03,
+0x45, 0x25, 0x71, 0x0d, 0xc1, 0xef, 0xe0, 0x1e, 0xf9, 0x85, 0x45, 0xa3, 0x00, 0xb5, 0x00, 0xef,
+0x20, 0xae, 0x90, 0xaa, 0x85, 0x35, 0x45, 0x0b, 0x84, 0x05, 0x01, 0xef, 0xe0, 0xbe, 0xf7, 0x8d,
+0x45, 0x23, 0x11, 0xb5, 0x00, 0x05, 0x45, 0x20, 0x98, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x9d, 0x13,
+0x01, 0x01, 0xdd, 0x27, 0x3c, 0x81, 0x28, 0x36, 0x84, 0xb2, 0x89, 0x2e, 0x89, 0x28, 0x00, 0x93,
+0x05, 0x00, 0x29, 0x7d, 0x56, 0x93, 0x06, 0x00, 0x29, 0x13, 0x0a, 0x81, 0x00, 0xef, 0x30, 0xc7,
+0xc5, 0x28, 0x00, 0x93, 0x05, 0x40, 0x0a, 0xef, 0x50, 0x7e, 0xd5, 0x37, 0x15, 0x09, 0x00, 0x13,
+0x05, 0x05, 0x98, 0xab, 0x05, 0x84, 0x04, 0x33, 0x86, 0xa5, 0x00, 0x83, 0x0a, 0x06, 0x00, 0x13,
+0xa6, 0x1a, 0x00, 0x93, 0xb6, 0x19, 0x00, 0x01, 0x4b, 0x55, 0x8e, 0x51, 0xea, 0x2e, 0x95, 0x93,
+0x0b, 0x15, 0x00, 0x37, 0xb5, 0x09, 0x00, 0x07, 0x34, 0x85, 0x69, 0x05, 0x4c, 0x37, 0x15, 0x09,
+0x00, 0x93, 0x0c, 0x45, 0x9a, 0x81, 0x44, 0x33, 0x85, 0x9b, 0x00, 0x03, 0x44, 0x05, 0x00, 0x13,
+0x1d, 0x0c, 0x01, 0x13, 0x5d, 0x0d, 0x41, 0x0b, 0x5f, 0x04, 0x1b, 0x22, 0x85, 0xea, 0x85, 0xef,
+0x80, 0x6e, 0xdf, 0x0d, 0xc5, 0xab, 0x85, 0x8c, 0x04, 0x03, 0x94, 0x25, 0x00, 0x63, 0x40, 0x04,
+0x02, 0xab, 0x05, 0xaa, 0x04, 0x8c, 0x41, 0x8b, 0x85, 0x05, 0xff, 0xef, 0x70, 0x2e, 0xe7, 0x19,
+0xc5, 0x28, 0x69, 0x53, 0x00, 0x05, 0x42, 0x53, 0x05, 0x80, 0xa2, 0x19, 0xcd, 0x85, 0x04, 0x0b,
+0x9e, 0xe4, 0x04, 0x33, 0x25, 0x5d, 0x01, 0x93, 0x15, 0x0b, 0x01, 0xc1, 0x81, 0xb3, 0xb5, 0x35,
+0x01, 0x6d, 0x8d, 0x05, 0x0c, 0x45, 0xf1, 0x21, 0xa8, 0x33, 0x05, 0x84, 0x01, 0x93, 0x15, 0x0b,
+0x01, 0xc1, 0x81, 0x05, 0x0b, 0xab, 0x05, 0xb9, 0x02, 0x23, 0x90, 0xa5, 0x00, 0xd9, 0xbf, 0x13,
+0x15, 0x0b, 0x01, 0x41, 0x81, 0x07, 0x34, 0x81, 0x29, 0x13, 0x01, 0x01, 0x23, 0xbc, 0x9d, 0x00,
+0x00, 0x5c, 0x9e, 0x13, 0x01, 0x01, 0xdc, 0x27, 0x38, 0x81, 0x2a, 0x27, 0x34, 0x91, 0x2a, 0x27,
+0x30, 0x21, 0x2b, 0x2a, 0xc6, 0x63, 0x0d, 0x05, 0x14, 0x2e, 0x84, 0x01, 0x45, 0x93, 0x09, 0x01,
+0x01, 0xfd, 0x55, 0x13, 0x06, 0x00, 0x29, 0xb3, 0x86, 0xa9, 0x00, 0x11, 0x05, 0x8c, 0xc2, 0xe3,
+0x1c, 0xc5, 0xfe, 0x08, 0x08, 0x93, 0x05, 0x40, 0x0a, 0xef, 0x50, 0x5e, 0xc5, 0x13, 0x7a, 0xf4,
+0x0f, 0x63, 0x07, 0x0a, 0x12, 0x01, 0x45, 0x81, 0x4a, 0xb7, 0xb5, 0x09, 0x00, 0x07, 0xb4, 0x85,
+0x69, 0xb7, 0xb5, 0x09, 0x00, 0x87, 0xb4, 0x05, 0x6a, 0xb7, 0x15, 0x09, 0x00, 0x13, 0x8b, 0x45,
+0x9a, 0x53, 0x09, 0x00, 0xd2, 0xab, 0x05, 0xab, 0x04, 0x83, 0x9b, 0x05, 0x00, 0x0b, 0xae, 0x3b,
+0x01, 0x32, 0x46, 0x2b, 0x0c, 0xa6, 0x10, 0x93, 0x8c, 0x25, 0x00, 0x85, 0x44, 0x13, 0xf5, 0xfa,
+0x0f, 0xe4, 0x91, 0xef, 0x80, 0x2e, 0xd0, 0x2a, 0x84, 0x7d, 0x15, 0x28, 0x91, 0x8b, 0x53, 0x35,
+0xa3, 0x22, 0x85, 0xef, 0x70, 0xae, 0xd8, 0x83, 0x4d, 0x0c, 0x00, 0x0b, 0xd0, 0x3d, 0x24, 0x83,
+0x95, 0x0c, 0x00, 0x63, 0xcc, 0x05, 0x0a, 0x2a, 0x8d, 0x1d, 0xc1, 0x07, 0x25, 0x0d, 0x05, 0x53,
+0x00, 0x05, 0x42, 0x53, 0x05, 0x80, 0xa2, 0x55, 0xe1, 0x2b, 0x85, 0x89, 0x04, 0x08, 0x41, 0xa6,
+0x95, 0x2b, 0x06, 0xbc, 0x03, 0x23, 0x12, 0xb6, 0x00, 0x8b, 0x16, 0x05, 0xff, 0x15, 0xa8, 0x2b,
+0x85, 0x89, 0x04, 0x08, 0x41, 0x8b, 0x01, 0x25, 0xff, 0xa6, 0x95, 0x2b, 0x06, 0xbc, 0x03, 0x23,
+0x12, 0xb6, 0x00, 0x13, 0x34, 0x1d, 0x00, 0x33, 0x09, 0xbc, 0x01, 0x23, 0x0e, 0x09, 0x0c, 0xef,
+0x50, 0x3e, 0xc5, 0x93, 0x05, 0x15, 0x00, 0xab, 0x65, 0xa0, 0x20, 0x23, 0x0e, 0xb9, 0x0c, 0x0d,
+0xec, 0x07, 0x25, 0x0d, 0x05, 0x53, 0x00, 0x05, 0x42, 0x53, 0x15, 0x04, 0xa2, 0x53, 0x70, 0x90,
+0x12, 0xd3, 0x00, 0x29, 0x23, 0xab, 0x60, 0xa0, 0x3a, 0xd3, 0x95, 0x00, 0xc2, 0x2b, 0x06, 0xbc,
+0x03, 0x23, 0x16, 0xb6, 0x04, 0x53, 0x00, 0x29, 0x23, 0x11, 0xcd, 0x07, 0x25, 0x4d, 0x05, 0x53,
+0x00, 0x05, 0x42, 0x53, 0x70, 0x90, 0x12, 0x39, 0xa0, 0x2b, 0x05, 0xbc, 0x03, 0x23, 0x16, 0x05,
+0x04, 0x53, 0x00, 0x29, 0x23, 0x53, 0x15, 0x00, 0xc2, 0xab, 0x05, 0xbc, 0x03, 0x23, 0x9a, 0xa5,
+0x08, 0x03, 0x05, 0x0c, 0x00, 0x05, 0x05, 0x23, 0x00, 0xac, 0x00, 0x13, 0x85, 0x14, 0x00, 0xe8,
+0x90, 0xe3, 0xde, 0x9b, 0xf0, 0x85, 0x0a, 0x13, 0xf5, 0xfa, 0x0f, 0xe3, 0x6d, 0x45, 0xef, 0x07,
+0x39, 0x01, 0x2a, 0x87, 0x34, 0x81, 0x2a, 0x07, 0x34, 0x01, 0x2b, 0x13, 0x01, 0x01, 0x24, 0x3c,
+0x9e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x99, 0x2e, 0x89, 0xaa, 0x84, 0x93, 0x06, 0xc5, 0x10, 0x37,
+0xb5, 0x09, 0x00, 0x13, 0x06, 0x85, 0x6a, 0x93, 0x05, 0x00, 0x08, 0x4a, 0x85, 0xef, 0x00, 0x07,
+0xba, 0x63, 0x45, 0x05, 0x06, 0x13, 0x84, 0x04, 0x0d, 0x22, 0x85, 0xef, 0x60, 0x36, 0xb8, 0xaa,
+0x86, 0x93, 0x05, 0x00, 0x08, 0x4a, 0x85, 0x22, 0x86, 0xef, 0x70, 0x97, 0x9e, 0x39, 0xe5, 0x93,
+0x84, 0x04, 0x0f, 0x26, 0x85, 0xef, 0x60, 0x96, 0xb6, 0xaa, 0x86, 0x93, 0x05, 0x00, 0x08, 0x4a,
+0x85, 0x26, 0x86, 0xef, 0x70, 0xf7, 0x9c, 0x15, 0xe9, 0x26, 0x85, 0xef, 0x60, 0x36, 0xb5, 0x8b,
+0x13, 0x05, 0x01, 0x37, 0xb5, 0x09, 0x00, 0x13, 0x04, 0xf5, 0x6a, 0x29, 0xa0, 0x37, 0xb5, 0x09,
+0x00, 0x13, 0x04, 0x15, 0x6b, 0x22, 0x85, 0xef, 0x60, 0x76, 0xb3, 0xaa, 0x86, 0x93, 0x05, 0x00,
+0x08, 0x4a, 0x85, 0x22, 0x86, 0xef, 0x70, 0xd7, 0x99, 0x11, 0xc1, 0xa0, 0x99, 0x4a, 0x85, 0xef,
+0x60, 0xf6, 0xb1, 0xaa, 0x85, 0x13, 0x06, 0x00, 0x08, 0x4a, 0x85, 0xef, 0x60, 0x2e, 0x89, 0x4a,
+0x85, 0xef, 0x60, 0xd6, 0xb0, 0x13, 0x06, 0x00, 0x08, 0xaa, 0x85, 0x4a, 0x85, 0x80, 0x99, 0x6f,
+0x60, 0x6e, 0x90, 0x00, 0x00, 0x40, 0x9a, 0x32, 0x89, 0xae, 0x89, 0x01, 0x45, 0x01, 0x44, 0x93,
+0x85, 0xa5, 0x1b, 0x33, 0x86, 0xa5, 0x00, 0x03, 0x16, 0x06, 0x00, 0x63, 0x43, 0xc0, 0x00, 0x01,
+0x46, 0x30, 0x92, 0x09, 0x05, 0x32, 0x94, 0x0b, 0x1b, 0xf5, 0x0c, 0x93, 0x86, 0xc9, 0x10, 0x37,
+0xb5, 0x09, 0x00, 0x13, 0x06, 0x85, 0x6b, 0x93, 0x05, 0x00, 0x08, 0x4a, 0x85, 0xef, 0x00, 0x07,
+0xad, 0x63, 0x47, 0x05, 0x0a, 0x93, 0x84, 0x09, 0x0d, 0x26, 0x85, 0xef, 0x60, 0x36, 0xab, 0xaa,
+0x86, 0x93, 0x05, 0x00, 0x08, 0x4a, 0x85, 0x26, 0x86, 0xef, 0x70, 0x97, 0x91, 0x49, 0xe9, 0x93,
+0x84, 0x09, 0x03, 0x26, 0x85, 0xef, 0x60, 0x96, 0xa9, 0xaa, 0x86, 0x93, 0x05, 0x00, 0x08, 0x4a,
+0x85, 0x26, 0x86, 0xef, 0x70, 0xf7, 0x8f, 0x25, 0xed, 0x93, 0x84, 0x09, 0x10, 0x26, 0x85, 0xef,
+0x60, 0xf6, 0xa7, 0xaa, 0x86, 0x93, 0x05, 0x00, 0x08, 0x85, 0x27, 0x05, 0x04, 0x01, 0x0d, 0xf2,
+0x4a, 0x85, 0x26, 0x86, 0xef, 0x70, 0x57, 0x8e, 0x39, 0xed, 0x93, 0x06, 0x00, 0x08, 0x22, 0x85,
+0x81, 0x45, 0x4a, 0x86, 0xef, 0x50, 0xde, 0xf1, 0x4e, 0x85, 0xef, 0x60, 0xb6, 0xa5, 0xaa, 0x86,
+0x93, 0x05, 0x00, 0x08, 0x4a, 0x85, 0x4e, 0x86, 0xef, 0x70, 0x17, 0x8c, 0x0d, 0xed, 0x13, 0x84,
+0x09, 0x05, 0x22, 0x85, 0xef, 0x60, 0x16, 0xa4, 0xaa, 0x86, 0x93, 0x05, 0x00, 0x08, 0x4a, 0x85,
+0x22, 0x86, 0xef, 0x70, 0x77, 0x8a, 0x05, 0xe1, 0x37, 0xb5, 0x09, 0x00, 0x13, 0x04, 0xf5, 0x6b,
+0x22, 0x85, 0xef, 0x60, 0x36, 0xa2, 0xaa, 0x86, 0x93, 0x05, 0x00, 0x08, 0x4a, 0x85, 0x22, 0x86,
+0xef, 0x70, 0x97, 0x88, 0x11, 0xc1, 0x20, 0x9a, 0x4a, 0x85, 0xef, 0x60, 0xb6, 0xa0, 0xaa, 0x85,
+0x13, 0x06, 0x00, 0x08, 0x4a, 0x85, 0xef, 0x50, 0xfe, 0xf7, 0x4a, 0x85, 0xef, 0x60, 0x96, 0x9f,
+0x13, 0x06, 0x00, 0x08, 0xaa, 0x85, 0x4a, 0x85, 0x00, 0x9a, 0x6f, 0x50, 0x3e, 0xff, 0x00, 0x00,
+0x40, 0x98, 0xef, 0x10, 0xae, 0xec, 0xb7, 0xc5, 0x04, 0x20, 0x03, 0xa6, 0x85, 0x0c, 0x81, 0x45,
+0x01, 0xe6, 0x85, 0x45, 0x0b, 0x52, 0x05, 0x05, 0x2e, 0x85, 0x20, 0x98, 0xef, 0xb0, 0x5b, 0xb0,
+0x13, 0x25, 0x55, 0x00, 0x8d, 0x45, 0x33, 0x85, 0xa5, 0x40, 0x20, 0x98, 0x00, 0x00, 0x00, 0x00,
+0xc0, 0x99, 0x2a, 0x84, 0xf1, 0x37, 0xaa, 0x84, 0xef, 0xb0, 0x9b, 0xae, 0x2a, 0x89, 0x84, 0x92,
+0x37, 0xb5, 0x09, 0x00, 0x93, 0x04, 0xe5, 0x59, 0x91, 0x45, 0x22, 0x85, 0x26, 0x86, 0xef, 0x00,
+0x67, 0x9a, 0x63, 0x4a, 0x05, 0x00, 0x13, 0x05, 0x44, 0x00, 0xc1, 0x45, 0x26, 0x86, 0xca, 0x86,
+0x80, 0x99, 0x6f, 0x00, 0x27, 0x99, 0xa0, 0x99, 0xdc, 0x99, 0x7d, 0x71, 0x2e, 0x89, 0xaa, 0x84,
+0x08, 0x10, 0x93, 0x05, 0x00, 0x06, 0x93, 0x06, 0x00, 0x06, 0x01, 0x46, 0xef, 0x20, 0x57, 0xfc,
+0x28, 0x00, 0xd1, 0x45, 0xd1, 0x46, 0x01, 0x46, 0xef, 0x20, 0x97, 0xfb, 0x37, 0x05, 0x05, 0x20,
+0x13, 0x04, 0x85, 0xc3, 0x22, 0x85, 0xef, 0x60, 0x2e, 0xaf, 0x08, 0x10, 0xa2, 0x85, 0xef, 0x60,
+0x2e, 0xab, 0x28, 0x00, 0x71, 0x37, 0x37, 0xb5, 0x09, 0x00, 0x13, 0x06, 0x25, 0x6c, 0x26, 0x85,
+0xca, 0x85, 0xef, 0x70, 0xa7, 0xbc, 0x3d, 0xe9, 0x10, 0x10, 0x26, 0x85, 0xca, 0x85, 0xef, 0x70,
+0xe7, 0xbb, 0x2d, 0xe5, 0x10, 0x18, 0x26, 0x85, 0xca, 0x85, 0xef, 0x70, 0x27, 0xbb, 0x39, 0xed,
+0x90, 0x00, 0x26, 0x85, 0xca, 0x85, 0xef, 0x70, 0x67, 0xba, 0x29, 0xe9, 0x90, 0x08, 0x26, 0x85,
+0xca, 0x85, 0xef, 0x70, 0xa7, 0xb9, 0x39, 0xe1, 0x30, 0x00, 0x26, 0x85, 0xca, 0x85, 0xef, 0x70,
+0xe7, 0xb8, 0x0d, 0xed, 0x90, 0x10, 0x26, 0x85, 0xca, 0x85, 0xef, 0x70, 0x27, 0xb8, 0x1d, 0xe5,
+0x70, 0x00, 0x26, 0x85, 0xca, 0x85, 0xef, 0x70, 0x67, 0xb7, 0x0d, 0xe1, 0x26, 0x85, 0xef, 0x60,
+0x76, 0x8d, 0xaa, 0x85, 0x26, 0x85, 0x4a, 0x86, 0xef, 0x50, 0xde, 0xe4, 0x26, 0x85, 0xef, 0x60,
+0x76, 0x8c, 0xaa, 0x85, 0x26, 0x85, 0x4a, 0x86, 0xef, 0x50, 0x5e, 0xec, 0x41, 0x61, 0xbc, 0x99,
+0x7d, 0x71, 0x37, 0xc6, 0x04, 0x20, 0x07, 0x25, 0x86, 0x13, 0xc8, 0xe5, 0x13, 0x05, 0x05, 0x03,
+0x53, 0x00, 0x05, 0x42, 0x02, 0xa4, 0x22, 0x47, 0xb2, 0x47, 0xb7, 0xb5, 0x09, 0x00, 0x13, 0x86,
+0xb5, 0x6c, 0xc1, 0x45, 0x41, 0x61, 0x6f, 0x00, 0xe7, 0x89, 0x00, 0x00, 0x82, 0x80, 0x00, 0x00,
+0x37, 0x45, 0x05, 0x20, 0x23, 0x2a, 0x05, 0x8c, 0x23, 0x28, 0x05, 0x8c, 0x37, 0xb5, 0x09, 0x00,
+0x23, 0x26, 0x05, 0x70, 0x23, 0x24, 0x05, 0x70, 0x82, 0x80, 0x00, 0x00, 0x49, 0x1f, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x49, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x49, 0x1f, 0x00, 0x00, 0xc7, 0x31, 0x00, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51,
+0x47, 0x03, 0x08, 0x00, 0x87, 0x40, 0x04, 0x01, 0x04, 0x00, 0x73, 0x4c, 0x6b, 0x0b, 0x06, 0x00,
+0x87, 0x40, 0x08, 0x02, 0x03, 0x00, 0x88, 0x41, 0x64, 0x08, 0x06, 0x00, 0x88, 0x41, 0x32, 0x04,
+0x07, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x07, 0x00, 0x43, 0x44, 0x1a, 0x09, 0x06, 0x00, 0x63, 0x65,
+0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x47, 0x03, 0x08, 0x00, 0xfd, 0x78, 0xc9, 0x01, 0x05, 0x00,
+0x73, 0x4c, 0x6b, 0x0b, 0x06, 0x00, 0x47, 0x6e, 0xcd, 0x03, 0x05, 0x00, 0x88, 0x41, 0x64, 0x08,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x07, 0x00, 0x43, 0x44,
+0x1a, 0x09, 0x06, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x47, 0x03, 0x08, 0x00,
+0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x1c, 0x0d, 0x06, 0x00, 0xaa, 0x79, 0x28, 0x01,
+0x05, 0x00, 0xde, 0x7a, 0xbf, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x44,
+0x8d, 0x04, 0x07, 0x00, 0x43, 0x44, 0x1a, 0x09, 0x06, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00,
+0xe9, 0x51, 0x47, 0x03, 0x08, 0x00, 0xd3, 0x64, 0xed, 0x09, 0x02, 0x00, 0x43, 0x44, 0x35, 0x12,
+0x05, 0x00, 0x87, 0x40, 0x08, 0x02, 0x03, 0x00, 0xde, 0x7a, 0x7f, 0x1d, 0x06, 0x00, 0x88, 0x41,
+0x32, 0x04, 0x07, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x07, 0x00, 0x43, 0x44, 0x1a, 0x09, 0x06, 0x00,
+0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x47, 0x03, 0x08, 0x00, 0xfd, 0x78, 0xc9, 0x01,
+0x05, 0x00, 0x43, 0x44, 0x35, 0x12, 0x05, 0x00, 0x47, 0x6e, 0xcd, 0x03, 0x05, 0x00, 0x88, 0x41,
+0x64, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x07, 0x00,
+0x43, 0x44, 0x1a, 0x09, 0x06, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x47, 0x03,
+0x08, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x1c, 0x0d, 0x06, 0x00, 0xaa, 0x79,
+0x28, 0x01, 0x05, 0x00, 0xde, 0x7a, 0xbf, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x43, 0x44, 0x8d, 0x04, 0x07, 0x00, 0x43, 0x44, 0x1a, 0x09, 0x06, 0x00, 0x63, 0x65, 0xce, 0x00,
+0x05, 0x00, 0xe9, 0x51, 0x1c, 0x0d, 0x06, 0x00, 0x87, 0x40, 0x04, 0x01, 0x04, 0x00, 0x73, 0x4c,
+0x6b, 0x0b, 0x06, 0x00, 0x87, 0x40, 0x08, 0x02, 0x03, 0x00, 0x88, 0x41, 0x64, 0x08, 0x06, 0x00,
+0x88, 0x41, 0x32, 0x04, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x1c, 0x0d, 0x06, 0x00, 0xfd, 0x78,
+0xc9, 0x01, 0x05, 0x00, 0x73, 0x4c, 0x6b, 0x0b, 0x06, 0x00, 0x47, 0x6e, 0xcd, 0x03, 0x05, 0x00,
+0x88, 0x41, 0x64, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51,
+0x1c, 0x0d, 0x06, 0x00, 0x63, 0x65, 0xce, 0x00, 0x05, 0x00, 0xe9, 0x51, 0x1c, 0x0d, 0x06, 0x00,
+0xaa, 0x79, 0x28, 0x01, 0x05, 0x00, 0xde, 0x7a, 0xbf, 0x0e, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x93, 0x71, 0x05, 0x04, 0x01, 0x0e, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x57, 0x61, 0x00, 0x0e, 0x00, 0x53, 0x55, 0x23, 0x01, 0x12,
+0x00, 0xcd, 0x4f, 0x29, 0x00, 0x10, 0x00, 0x43, 0x44, 0xea, 0x02, 0x14, 0x00, 0x60, 0x52, 0xae,
+0x00, 0x11, 0x00, 0x43, 0x44, 0xea, 0x02, 0x14, 0x00, 0x43, 0x44, 0x2f, 0x02, 0x15, 0x00, 0x43,
+0x44, 0x47, 0x02, 0x14, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x14, 0x00, 0x21, 0x57, 0x61, 0x00, 0x0e,
+0x00, 0x53, 0x55, 0x23, 0x01, 0x12, 0x00, 0xcd, 0x4f, 0x29, 0x00, 0x10, 0x00, 0x43, 0x44, 0xea,
+0x02, 0x14, 0x00, 0x60, 0x52, 0xae, 0x00, 0x11, 0x00, 0x43, 0x44, 0xea, 0x02, 0x14, 0x00, 0x43,
+0x44, 0x2f, 0x02, 0x15, 0x00, 0x43, 0x44, 0x47, 0x02, 0x14, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x14,
+0x00, 0x21, 0x57, 0x61, 0x00, 0x0e, 0x00, 0x53, 0x55, 0x23, 0x01, 0x12, 0x00, 0x25, 0x66, 0x2a,
+0x00, 0x11, 0x00, 0x43, 0x44, 0x76, 0x05, 0x13, 0x00, 0x60, 0x52, 0xa3, 0x00, 0x11, 0x00, 0x43,
+0x44, 0xbb, 0x02, 0x14, 0x00, 0x43, 0x44, 0x2f, 0x02, 0x15, 0x00, 0x43, 0x44, 0x02, 0x06, 0x13,
+0x00, 0x43, 0x44, 0x35, 0x12, 0x13, 0x00, 0x0d, 0x5f, 0x3a, 0x00, 0x0f, 0x00, 0x43, 0x44, 0x5d,
+0x00, 0x13, 0x00, 0xcd, 0x4f, 0x7f, 0x00, 0x10, 0x00, 0x43, 0x44, 0x1a, 0x09, 0x14, 0x00, 0x60,
+0x52, 0x1f, 0x02, 0x11, 0x00, 0x43, 0x44, 0x1a, 0x09, 0x14, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x15,
+0x00, 0x43, 0x44, 0x47, 0x02, 0x14, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x14, 0x00, 0x0d, 0x5f, 0x3a,
+0x00, 0x0f, 0x00, 0x43, 0x44, 0x5d, 0x00, 0x13, 0x00, 0xcd, 0x4f, 0x7f, 0x00, 0x10, 0x00, 0x43,
+0x44, 0x1a, 0x09, 0x14, 0x00, 0x60, 0x52, 0x1f, 0x02, 0x11, 0x00, 0x43, 0x44, 0x1a, 0x09, 0x14,
+0x00, 0x43, 0x44, 0x8d, 0x04, 0x15, 0x00, 0x43, 0x44, 0x47, 0x02, 0x14, 0x00, 0x43, 0x44, 0x8d,
+0x04, 0x14, 0x00, 0x21, 0x57, 0x61, 0x00, 0x0e, 0x00, 0x53, 0x55, 0x23, 0x01, 0x12, 0x00, 0x25,
+0x66, 0xd1, 0x00, 0x11, 0x00, 0x43, 0x44, 0x35, 0x12, 0x13, 0x00, 0x60, 0x52, 0x1f, 0x02, 0x11,
+0x00, 0x43, 0x44, 0x1a, 0x09, 0x14, 0x00, 0x43, 0x44, 0x8d, 0x04, 0x15, 0x00, 0x43, 0x44, 0xe9,
+0x00, 0x14, 0x00, 0x43, 0x44, 0xd2, 0x01, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc4, 0x1d, 0x43, 0xd7, 0x41, 0x24,
+0x41, 0x63, 0x68, 0x69, 0x6c, 0x6c, 0x65, 0x73, 0x2c, 0x48, 0x37, 0x53, 0x31, 0x2c, 0x51, 0x33,
+0x35, 0x2c, 0x46, 0x31, 0x50, 0x32, 0x36, 0x2e, 0x30, 0x00, 0x24, 0x41, 0x63, 0x68, 0x69, 0x6c,
+0x6c, 0x65, 0x73, 0x2c, 0x48, 0x37, 0x53, 0x31, 0x2c, 0x51, 0x35, 0x30, 0x2c, 0x46, 0x31, 0x50,
+0x32, 0x36, 0x2e, 0x30, 0x00, 0x2c, 0x25, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x40, 0x8f, 0x40, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xe3, 0x3f, 0x9a,
+0x99, 0x99, 0x99, 0x99, 0x99, 0xd9, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xa0, 0x41, 0x0a, 0xd7, 0x23, 0x3d, 0x00,
+0x00, 0xa0, 0x40, 0x00, 0x00, 0x40, 0x40, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xeb, 0x3f, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x40, 0xe8, 0x6a, 0x2b, 0xf6, 0x97, 0xdd, 0xed, 0x3f, 0xc0,
+0xa8, 0xa4, 0x4e, 0x40, 0x13, 0xb1, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x40, 0x00,
+0x00, 0xf0, 0x41, 0x00, 0x00, 0xc8, 0x41, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0xc8, 0xc1, 0x9a,
+0x99, 0x99, 0xbe, 0x00, 0x00, 0xa0, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x9a,
+0x99, 0x99, 0x99, 0x99, 0x99, 0xb9, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x33,
+0x33, 0x33, 0x33, 0x33, 0x33, 0xd3, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x00,
+0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x50, 0xc3, 0x47, 0x00, 0x00, 0x00, 0x00, 0x87,
+0x44, 0xe7, 0x4a, 0x18, 0x57, 0xc6, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x55,
+0x94, 0xe7, 0x4a, 0x18, 0x57, 0xb6, 0x3f, 0xf8, 0xc1, 0x63, 0x1a, 0xdc, 0xa5, 0x4c, 0x40, 0x24,
+0x25, 0x73, 0x5a, 0x44, 0x41, 0x00, 0x2c, 0x2c, 0x2c, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x00, 0x24,
+0x25, 0x73, 0x47, 0x47, 0x41, 0x00, 0x2c, 0x2c, 0x00, 0x24, 0x50, 0x4e, 0x54, 0x48, 0x30, 0x30,
+0x31, 0x00, 0x2c, 0x25, 0x2e, 0x32, 0x66, 0x00, 0x23, 0x00, 0x00, 0x00, 0x70, 0x05, 0x20, 0xd8,
+0x72, 0x05, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x1b, 0x01, 0x00, 0x04, 0x00, 0x00, 0x05, 0x00,
+0x51, 0x55, 0x49, 0x54, 0x20
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_fw_file_array.c b/code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_fw_file_array.c
new file mode 100644 (file)
index 0000000..38f9a48
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  gnss firmware dummy file arrays.
+ *
+ * History:
+ * 2023-11-01, Create file.
+ */
+#include "gnss_fw_file_array.h"
+#include "tiot_types.h"
+
+/* 仅用于SDK,无文件系统使用文件数组时,替换此目录下文件. */
+
+#define GNSS_FW_ATTR
+
+#define GNSS_CFG_BIN  "gnss_cfg.bin"
+GNSS_FW_ATTR const char g_gnss_cfg_file[] = {
+#include GNSS_CFG_BIN
+};
+
+const tiot_file g_gnss_fw_files[] = {
+    { "cfg", sizeof(g_gnss_cfg_file), g_gnss_cfg_file },
+};
+
+const tiot_file_path g_gnss_fw_file_path = {
+    g_gnss_fw_files, sizeof(g_gnss_fw_files) / sizeof(tiot_file)
+};
+
+const tiot_file_path *gnss_fw_file_path_get(void)
+{
+    return &g_gnss_fw_file_path;
+}
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_fw_file_array.h b/code/sdk/zhihui/gnss/driver/device/gnss/firmware/gnss_fw_file_array.h
new file mode 100644 (file)
index 0000000..36312d9
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  gnss firmware file arrays.
+ *
+ * History:
+ * 2023-11-01, Create file.
+ */
+
+#ifndef GNSS_FW_FILE_ARRAY_H
+#define GNSS_FW_FILE_ARRAY_H
+
+#include "tiot_fileops.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+const tiot_file_path *gnss_fw_file_path_get(void);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/gnss_device_info.c b/code/sdk/zhihui/gnss/driver/device/gnss/gnss_device_info.c
new file mode 100644 (file)
index 0000000..38578d9
--- /dev/null
@@ -0,0 +1,157 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: GNSS device info. \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-25, Create file. \n\r
+ */\r
+\r
+#include "gnss_device_info.h"\r
+#include "tiot_pm_default.h"\r
+#include "tiot_board_uart_port.h"\r
+#include "tiot_board_log.h"\r
+#include "tiot_controller.h"\r
+#include "tiot_board_pin_port.h"\r
+#include "tiot_cfg_handle_priv.h"\r
+#include "tiot_sys_msg_handle.h"\r
+#ifdef CONFIG_FILE_BY_ARRAY\r
+#include "gnss_fw_file_array.h"\r
+#endif\r
+\r
+#define GNSS_POWERON_WAIT_MS      1      /* Wait time before power on. */\r
+#define GNSS_BOOT_TIME_MS         200    /* Power on ==> Boot time. */\r
+#define GNSS_INIT_TIME_MS         600    /* Boot ==> Init time. */\r
+#define GNSS_WAKEUP_PULSE_MS      1      /* GPIO wake up pulse. */\r
+#define GNSS_WAKEUP_WAIT_MS       50     /* Wake up wait ms. */\r
+#define GNSS_BAUD_CHANGE_WAIT_US  11000  /* Baudrate change wait μs. */\r
+\r
+#ifdef CONFIG_GNSS_TCXO_FREQ_38P4M\r
+#define GNSS_WAKEUP_PIN_INIT_LEVEL  TIOT_PIN_LEVEL_LOW\r
+#else\r
+#define GNSS_WAKEUP_PIN_INIT_LEVEL  TIOT_PIN_LEVEL_HIGH\r
+#endif\r
+\r
+#ifdef CONFIG_GNSS_UART_WITH_FLOWCTRL\r
+#define GNSS_UART_ATTR_FLOW_CTRL    TIOT_UART_ATTR_FLOW_CTRL_ENABLE\r
+#else\r
+#define GNSS_UART_ATTR_FLOW_CTRL    TIOT_UART_ATTR_FLOW_CTRL_DISABLE\r
+#endif\r
+\r
+#define GNSS_DEFAULT_UART_CONFIG                        \\r
+{                                                       \\r
+    115200,                                             \\r
+    { .data_bits = TIOT_UART_ATTR_DATABIT_8,            \\r
+      .parity    = TIOT_UART_ATTR_PARITY_NONE,          \\r
+      .stop_bits = TIOT_UART_ATTR_STOPBIT_1,            \\r
+      .flow_ctrl = GNSS_UART_ATTR_FLOW_CTRL             \\r
+    }                                                   \\r
+}\r
+\r
+static inline int32_t gnss_pin_set_level_if_exist(uint32_t pin, uint32_t pin_level)\r
+{\r
+    if (pin != TIOT_PIN_NONE) {\r
+        return tiot_board_pin_set_level(pin, pin_level);\r
+    }\r
+    return 0;\r
+}\r
+\r
+static tiot_pm_retcode gnss_pm_power_on(tiot_pm *pm)\r
+{\r
+    uint32_t wakeup_device_pin = pm->pm_info[TIOT_PIN_HOST_WAKEUP_DEVICE];\r
+    /* GNSS板级连接唤醒管脚时,上拉或下拉 */\r
+    if (gnss_pin_set_level_if_exist(wakeup_device_pin, GNSS_WAKEUP_PIN_INIT_LEVEL) != 0) {\r
+        tiot_print_err("[TIoT][pm]set wkup pin level %d fail.\n", GNSS_WAKEUP_PIN_INIT_LEVEL);\r
+        return TIOT_PM_EVTRET_FAIL;\r
+    }\r
+    if (tiot_pm_default_power_on(pm) == TIOT_PM_EVTRET_FAIL) {\r
+        return TIOT_PM_EVTRET_FAIL;\r
+    }\r
+    if (gnss_pin_set_level_if_exist(wakeup_device_pin, TIOT_PIN_LEVEL_LOW) != 0) {\r
+        tiot_print_err("[TIoT][pm]set wkup pin level low fail.\n");\r
+        return TIOT_PM_EVTRET_FAIL;\r
+    }\r
+    return TIOT_PM_EVTRET_NEXT_STATE;\r
+}\r
+\r
+static const tiot_pm_event_entry g_gnss_pm_event_map[TIOT_PM_EVENT_MAX] = {\r
+    { TIOT_PM_TAG_POWERON, TIOT_PM_STATE_POWEROFF, tiot_pm_default_power_off },\r
+    /* 上电后等待init消息或业务消息才说明进入work状态 */\r
+    /* GNSS板级连接唤醒管脚时,上电特殊处理 */\r
+    { TIOT_PM_TAG_POWEROFF, TIOT_PM_STATE_INIT, gnss_pm_power_on },\r
+#ifdef CONFIG_GNSS_WAKEUP_TYPE_UART\r
+    /* 只有sleep态才需要唤醒 */\r
+    { TIOT_PM_TAG_CAN_WAKEUP, TIOT_PM_STATE_WAKING, tiot_pm_default_wakeup_device_by_uart },\r
+#else\r
+    /* 只有sleep态才需要唤醒 */\r
+    { TIOT_PM_TAG_CAN_WAKEUP, TIOT_PM_STATE_WAKING, tiot_pm_default_wakeup_device_by_gpio },\r
+#endif\r
+    /* 有device wakeup host管脚时,通过此管脚说明已唤醒,且需要下发disallow消息 */\r
+    { TIOT_PM_TAG_POWERON, TIOT_PM_STATE_WORK, tiot_pm_default_wakeup_ack_handle },\r
+    /* 接收到request sleep消息,下发allow sleep消息 */\r
+    { TIOT_PM_TAG_CAN_ALLOW_SLEEP, TIOT_PM_STATE_SLEEPING, tiot_pm_default_request_sleep_handle },\r
+    /* 接收到dev wkup host gpio拉低,需要释放唤醒锁 */\r
+    { TIOT_PM_TAG_CAN_SLEEP, TIOT_PM_STATE_SLEEP, tiot_pm_default_sleep_ack_handle },\r
+    /* 非S3状态,下发allow sleep并释放唤醒锁 */\r
+    { TIOT_PM_TAG_CAN_ALLOW_SLEEP, TIOT_PM_STATE_SLEEP, tiot_pm_default_request_sleep_ack_handle },\r
+    /* 上报init消息或业务消息说明唤醒成功 */\r
+    { TIOT_PM_TAG_CAN_WORK, TIOT_PM_STATE_WORK, NULL },\r
+    { TIOT_PM_TAG_POWERON, TIOT_PM_STATE_INVALID, tiot_pm_default_work_vote_up },\r
+    { TIOT_PM_TAG_POWERON, TIOT_PM_STATE_INVALID, tiot_pm_default_work_vote_down }\r
+};\r
+\r
+static void gnss_firmware_before_load(tiot_fw *fw)\r
+{\r
+    /* 加载前设置为固件加载默认波特率 */\r
+    tiot_uart_config gnss_firmware_load_config = GNSS_DEFAULT_UART_CONFIG;\r
+    tiot_controller *ctrl = tiot_container_of(fw, tiot_controller, firmware);\r
+    tiot_xfer_manager *xfer = &ctrl->transfer;\r
+    if (tiot_xfer_set_config(xfer, &gnss_firmware_load_config) != 0) {\r
+        tiot_print_dbg("[TIoT:fw]config before load fail.\r\n");\r
+    }\r
+    /* 加载前先清掉rx_buff */\r
+#ifdef CONFIG_XFER_DEFAULT_RX_BUFF\r
+    if (xfer->xmit_ops->rx_mode == TIOT_XMIT_RX_MODE_BUFFED) {\r
+        circ_buf_flush(&xfer->rx_buff);\r
+    }\r
+#endif\r
+}\r
+\r
+static void gnss_firmware_after_load(tiot_fw *fw)\r
+{\r
+    /* 加载过程中可能切换波特率,加载后设置为业务默认波特率 */\r
+    tiot_uart_config gnss_transfer_config = GNSS_DEFAULT_UART_CONFIG;\r
+    tiot_controller *ctrl = tiot_container_of(fw, tiot_controller, firmware);\r
+    tiot_xfer_manager *xfer = &ctrl->transfer;\r
+    if (tiot_xfer_set_config(xfer, &gnss_transfer_config) != 0) {\r
+        tiot_print_dbg("[TIoT:fw]config after load fail.\r\n");\r
+    }\r
+}\r
+\r
+static int gnss_rx_wait_func(const void *param)\r
+{\r
+    (void)param;\r
+    /* GNSS通过UART上报数据,不需要拉高管脚来通知读取 */\r
+    return 0;\r
+}\r
+\r
+static const tiot_device_info g_gnss_device_info = {\r
+    .pm_event_map = (tiot_pm_event_entry *)g_gnss_pm_event_map,\r
+    .pm_event_map_size = sizeof(g_gnss_pm_event_map) / sizeof(tiot_pm_event_entry),\r
+    .exec_cbs = { gnss_firmware_before_load, gnss_firmware_after_load, tiot_fw_ext_cmd_handle_priv, NULL },\r
+    .xfer_info = { TIOT_XMIT_TYPE_UART, gnss_rx_wait_func },\r
+    .pkt_sys_msg_handle = tiot_pkt_sys_msg_handle,\r
+    .timings = {\r
+        .power_on_wait_ms = GNSS_POWERON_WAIT_MS,\r
+        .boot_time_ms = GNSS_BOOT_TIME_MS,\r
+        .init_time_ms = GNSS_INIT_TIME_MS,\r
+        .wakeup_pulse_ms = GNSS_WAKEUP_PULSE_MS,\r
+        .wakeup_wait_ms = GNSS_WAKEUP_WAIT_MS,\r
+        .baud_change_wait_us = GNSS_BAUD_CHANGE_WAIT_US,\r
+    }\r
+};\r
+\r
+const tiot_device_info *gnss_device_get_info(void)\r
+{\r
+    return &g_gnss_device_info;\r
+}\r
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/gnss_device_info.h b/code/sdk/zhihui/gnss/driver/device/gnss/gnss_device_info.h
new file mode 100644 (file)
index 0000000..5356fbd
--- /dev/null
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: GNSS device info header. \n
+ *
+ * History: \n
+ * 2023-06-13, Create file. \n
+ */
+#ifndef GNSS_DEVICE_INFO_H
+#define GNSS_DEVICE_INFO_H
+
+#include "tiot_device_info.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_device_gnss_device_info  GNSS Device Info
+ * @ingroup  tiot_device_gnss
+ * @{
+ */
+
+/**
+ * @brief  GNSS device get info, same for all GNSS devices.
+ * @return GNSS device info.
+ */
+const tiot_device_info *gnss_device_get_info(void);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/gnss_service.c b/code/sdk/zhihui/gnss/driver/device/gnss/gnss_service.c
new file mode 100644 (file)
index 0000000..6a570e5
--- /dev/null
@@ -0,0 +1,434 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description:  \n\r
+ *\r
+ * History: \n\r
+ * 2023-03-31, Create file. \n\r
+ */\r
+#include "gnss_service.h"\r
+#include "gnss_device_info.h"\r
+#include "gnss_board_port.h"\r
+#include "tiot_board_log.h"\r
+#include "tiot_controller.h"\r
+#include "tiot_controller_helper.h"\r
+#include "tiot_packet.h"\r
+#include "tiot_sys_msg_types.h"\r
+#include "tiot_board_pin_port.h"\r
+#include "tiot_board_uart_port.h"\r
+#include "tiot_board_misc_port.h"\r
+#include "tiot_board.h"\r
+#include "tiot_service_interface.h"\r
+\r
+#ifndef CONFIG_BOARD_DYNAMIC_ALLOC\r
+/* 加载 & 数据收发复用buffer,不同时使用 */\r
+/* 数据收发需求 ~10K用于缓存数据. */\r
+/* 固件加载时 ~3K用于保存解析后命令, ~128字节用于加载回复接收. */\r
+#define GNSS_FW_LOAD_REUSE_BUFF_START 0U\r
+#define GNSS_FW_LOAD_RX_BUFF_START    GNSS_FW_LOAD_REUSE_BUFF_START\r
+#define GNSS_FW_LOAD_RX_BUFF_SIZE     128U\r
+\r
+#define GNSS_FW_LOAD_REUSE_BUFF_END   (GNSS_FW_LOAD_RX_BUFF_START + GNSS_FW_LOAD_RX_BUFF_SIZE)\r
+\r
+#define GNSS_COMMON_BUFF_MAX    ((CONFIG_GNSS_PACKET_BUFF_MAX > GNSS_FW_LOAD_REUSE_BUFF_END) ? \\r
+                                 CONFIG_GNSS_PACKET_BUFF_MAX : GNSS_FW_LOAD_REUSE_BUFF_END)\r
+#endif\r
+\r
+#define GNSS_PACKET_QUEUE_NODES    8\r
+\r
+typedef enum {\r
+    GNSS_RX_SUBSYS_0 = 0,\r
+    GNSS_RX_SUBSYS_MAX\r
+} gnss_rx_subsys_id;\r
+\r
+typedef enum {\r
+    GNSS_PLT_SWITCH_GUART_BPS = 0,\r
+    GNSS_PLT_SWITCH_DBGUART_BPS,\r
+    GNSS_PLT_SWITCH_UART_SELECT,\r
+    GNSS_PLT_SWITCH_HSO_OR_SDT,\r
+    GNSS_PLT_SWITCH_DBGUART_SKIP,\r
+    GNSS_PLT_CMD_MAXSIZE\r
+} gnss_plt_cmd;\r
+\r
+typedef struct {\r
+    uint32_t bps;\r
+    uint32_t cr_crg;\r
+} tiot_plt_guart_para;\r
+\r
+typedef struct {\r
+    uint8_t frame_start;\r
+    uint8_t func_type;\r
+    uint8_t prime_id;\r
+    uint8_t reserved;\r
+    uint16_t frame_len;\r
+    uint16_t sn;\r
+} tiot_plt_om_header;\r
+\r
+typedef struct {\r
+    uint16_t cmd;\r
+    uint16_t para_len;\r
+} tiot_plt_cmd_header;\r
+\r
+#pragma pack(push, 1)\r
+typedef struct {\r
+    tiot_plt_om_header om_header;\r
+    tiot_plt_cmd_header cmd_header;\r
+    tiot_plt_guart_para para;\r
+    uint8_t tail;\r
+} tiot_plt_guart_cmd;\r
+#pragma pack(pop)\r
+\r
+#define tiot_plat_guart_baud_cmd(bps, flow_ctrl)                                \\r
+{                                                                               \\r
+    .om_header = { 0x7e, 0x0c, 0x00, 0x00, 0x15, 0x00 },                        \\r
+    .cmd_header = { GNSS_PLT_SWITCH_GUART_BPS, sizeof(tiot_plt_guart_para) },   \\r
+    .para = { (bps),                                                            \\r
+              ((flow_ctrl) == TIOT_UART_ATTR_FLOW_CTRL_ENABLE) ? 0xC301 : 0x301 \\r
+    },                                                                          \\r
+    .tail = 0x7e                                                                \\r
+}\r
+\r
+static tiot_controller g_gnss_controllers[CONFIG_GNSS_DEV_NUM] = { 0 };\r
+static tiot_packet_context g_gnss_pkt_ctx[CONFIG_GNSS_DEV_NUM];\r
+static tiot_packet g_gnss_pkt_queue_nodes[CONFIG_GNSS_DEV_NUM][GNSS_PACKET_QUEUE_NODES];\r
+static tiot_packet_queue g_gnss_pkt_queues[CONFIG_GNSS_DEV_NUM][GNSS_RX_SUBSYS_MAX];\r
+\r
+#ifndef CONFIG_BOARD_DYNAMIC_ALLOC\r
+static uint8_t g_gnss_common_buff_mem[CONFIG_GNSS_DEV_NUM][GNSS_COMMON_BUFF_MAX];\r
+#endif\r
+\r
+static uint16_t gnss_packet_manager_match_func(uint32_t subsys_code)\r
+{\r
+    if ((subsys_code == GNSS_FIRST_MSG) || (subsys_code == GNSS_COMMON_MSG) ||\r
+        (subsys_code == GNSS_LAST_MSG) || (subsys_code == MSG_BUTT)) {\r
+        return GNSS_RX_SUBSYS_0;\r
+    }\r
+    return GNSS_RX_SUBSYS_MAX;\r
+}\r
+\r
+static void gnss_device_wakeup_host_cb(uint32_t pin)\r
+{\r
+    (void)tiot_board_pin_enable_int(pin, TIOT_PIN_INT_DISABLE);\r
+    tiot_controller *cur_ctrl = tiot_find_controller_by_pin(g_gnss_controllers, CONFIG_GNSS_DEV_NUM,\r
+                                                            pin, GNSS_PIN_DEVICE_WAKEUP_HOST);\r
+    if (cur_ctrl != NULL) {\r
+        tiot_pm_set_event(&cur_ctrl->pm, TIOT_PM_EVENT_WAKEUP_ACK);\r
+    }\r
+    (void)tiot_board_pin_enable_int(pin, TIOT_PIN_INT_ENABLE);\r
+}\r
+\r
+static int32_t gnss_change_uart_config(tiot_xfer_manager *xfer, tiot_uart_config *uart_cfg)\r
+{\r
+    tiot_plt_guart_cmd uart_cmd = tiot_plat_guart_baud_cmd(uart_cfg->baudrate, uart_cfg->attr.flow_ctrl);\r
+    tiot_xfer_tx_param param = { SUBSYS_OM };\r
+    int32_t ret = tiot_xfer_send(xfer, (const uint8_t *)&uart_cmd, sizeof(tiot_plt_guart_cmd), &param);\r
+    if (ret != sizeof(tiot_plt_guart_cmd)) {\r
+        tiot_print_err("[TIOT]set user baudrate cmd fail.\r\n");\r
+        return -1;\r
+    }\r
+    ret = tiot_xfer_set_config(xfer, uart_cfg);\r
+    if (ret != 0) {\r
+        tiot_print_err("[TIOT]set user baudrate fail.\r\n");\r
+        return -1;\r
+    }\r
+    return 0;\r
+}\r
+\r
+static inline int32_t gnss_send_host_need_wakeup(tiot_controller *ctrl)\r
+{\r
+    int32_t ret;\r
+    const uint8_t host_need_wakeup_cmd = SYS_PL_PM_SET_WAKEUP_HOST_VALID;\r
+    const tiot_xfer_tx_param param = { SUBSYS_SYS };\r
+    ret = tiot_xfer_send(&ctrl->transfer, &host_need_wakeup_cmd, sizeof(uint8_t), &param);\r
+    if (ret != sizeof(uint8_t)) {\r
+        tiot_print_err("[TIOT]set host need wakeup cmd fail.\r\n");\r
+        return -1;\r
+    }\r
+    return 0;\r
+}\r
+\r
+static int32_t gnss_send_change_buadrate(tiot_controller *ctrl, uint32_t new_buadrate)\r
+{\r
+    const tiot_device_timings *timings = &ctrl->dev_info->timings;\r
+    tiot_uart_config uart_config = { 0 };\r
+    (void)tiot_xfer_get_config(&ctrl->transfer, &uart_config);\r
+    /* 配置用户波特率 */\r
+    if (uart_config.baudrate == new_buadrate) {\r
+        return 0;\r
+    }\r
+    uart_config.baudrate = new_buadrate;\r
+    if (gnss_change_uart_config(&ctrl->transfer, &uart_config) != 0) {\r
+        tiot_print_err("[TIoT]send change buadrate fail\n");\r
+        return -1;\r
+    }\r
+    /* 切换波特率后等待波特率稳定,device或host? */\r
+    tiot_board_udelay(timings->baud_change_wait_us);\r
+    return 0;\r
+}\r
+\r
+static int32_t gnss_service_packet_init(tiot_controller *ctrl, uint8_t dev_id)\r
+{\r
+    int32_t ret;\r
+#ifndef CONFIG_BOARD_DYNAMIC_ALLOC\r
+    tiot_packet_buffer pkt_buff = { g_gnss_common_buff_mem[dev_id], CONFIG_GNSS_PACKET_BUFF_MAX, 0 };\r
+#endif\r
+    tiot_packet_context_param param = {\r
+        .flags = TIOT_PKT_FLAGS_SUPPORT_ASCII,\r
+        .rx_manager_info = { g_gnss_pkt_queues[dev_id], GNSS_RX_SUBSYS_MAX, gnss_packet_manager_match_func },\r
+        .buff = NULL\r
+    };\r
+#ifndef CONFIG_BOARD_DYNAMIC_ALLOC\r
+    param.buff = &pkt_buff;\r
+#endif\r
+    g_gnss_pkt_queues[dev_id][GNSS_RX_SUBSYS_0].queue_nodes = g_gnss_pkt_queue_nodes[dev_id];\r
+    g_gnss_pkt_queues[dev_id][GNSS_RX_SUBSYS_0].queue_size = GNSS_PACKET_QUEUE_NODES;\r
+    tiot_packet_context *pkt_ctx = &g_gnss_pkt_ctx[dev_id];\r
+    ret = tiot_packet_init(pkt_ctx, &ctrl->transfer, &param);\r
+    if (ret != 0) {\r
+        tiot_print_err("[TIOT]packet init fail.\r\n");\r
+    }\r
+    return ret;\r
+}\r
+\r
+static int32_t gnss_service_install_packet(tiot_controller *ctrl, uint8_t dev_id)\r
+{\r
+    tiot_xfer_packet_ops gnss_packet_ops = {\r
+        .read_out = tiot_packet_read_out,\r
+        .rx_data_store = tiot_packet_rx_data_store,\r
+        .tx_push = tiot_packet_tx_push,\r
+    };\r
+    const tiot_device_timings *timings = &ctrl->dev_info->timings;\r
+    /* 收发模块注册包格式 */\r
+    if (tiot_xfer_install_packet(&ctrl->transfer, (tiot_xfer_packet_ops *)&gnss_packet_ops,\r
+                                 (uintptr_t)&g_gnss_pkt_ctx[dev_id]) != 0) {\r
+        tiot_print_err("[TIOT]packet install fail.\r\n");\r
+        return -1;\r
+    }\r
+    /* 必须等待device UART初始化后才能接收消息, 待确认时间. */\r
+    osal_msleep(timings->init_time_ms);\r
+    tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_REPORT_WORK);\r
+    return 0;\r
+}\r
+\r
+static inline int32_t gnss_service_custom_msg_send(tiot_controller *ctrl, uint32_t dev_wkup_host_pin,\r
+                                                   uint32_t custom_buadrate)\r
+{\r
+    /* 通过管脚有无判断host是否需要唤醒 */\r
+    if (dev_wkup_host_pin != TIOT_PIN_NONE) {\r
+        if (gnss_send_host_need_wakeup(ctrl) != 0) {\r
+            return -1;\r
+        }\r
+    }\r
+    /* 切换波特率 */\r
+    if (gnss_send_change_buadrate(ctrl, custom_buadrate) != 0) {\r
+        return -1;\r
+    }\r
+    return 0;\r
+}\r
+\r
+static inline int32_t gnss_get_dev_id(tiot_controller *ctrl, uint8_t *dev_id)\r
+{\r
+    uint8_t i;\r
+    for (i = 0; i < CONFIG_GNSS_DEV_NUM; i++) {\r
+        if (ctrl == &g_gnss_controllers[i]) {\r
+            *dev_id = i;\r
+            return 0;\r
+        }\r
+    }\r
+    tiot_print_err("[TIoT]invalid device\n");\r
+    return -1;\r
+}\r
+\r
+static inline void gnss_set_open_param(tiot_xfer_open_param *xfer_open_param, tiot_service_open_param *param)\r
+{\r
+    if (param == NULL) {\r
+        return;\r
+    }\r
+    xfer_open_param->rx_cbk_param.buff = param->buff;\r
+    xfer_open_param->rx_cbk_param.buff_len = param->buff_len;\r
+    xfer_open_param->rx_cbk_param.rx_callback = param->rx_callback;\r
+}\r
+\r
+static inline int32_t gnss_firmware_load(tiot_fw *firmware)\r
+{\r
+    int ret = -1;\r
+#ifdef CONFIG_FILE_BY_ARRAY\r
+    ret = tiot_firmware_load(firmware, gnss_fw_file_path_get(), TIOT_FW_FILE_ARRAY_CFG_NAME);\r
+#else\r
+    ret = tiot_firmware_load(firmware, NULL, gnss_board_get_info()->cfg_path);\r
+#endif\r
+    if (ret != 0) {\r
+        tiot_print_err("[TIoT]Gnss firmware load fail.\n");\r
+    }\r
+    return ret;\r
+}\r
+\r
+static int32_t gnss_service_open(tiot_controller *ctrl, void *param)\r
+{\r
+    int ret = -1;\r
+    uint8_t dev_id;\r
+    uint32_t dev_wkup_host_pin;\r
+    tiot_xfer_open_param xfer_open_param = { 0 };\r
+    if (gnss_get_dev_id(ctrl, &dev_id) != 0) {\r
+        return -1;\r
+    }\r
+    gnss_set_open_param(&xfer_open_param, param);\r
+    /* 传输启动 */\r
+    if (tiot_xfer_open(&ctrl->transfer, &xfer_open_param) != 0) {\r
+        /* 通信接口打开失败 */\r
+        tiot_print_err("[TIoT]Transfer port open fail\n");\r
+        goto xfer_open_fail;\r
+    }\r
+    /* 上电 */\r
+    if (tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_POWERON) != 0) {\r
+        /* 上电失败 */\r
+        tiot_print_err("[TIoT]Power on fail\n");\r
+        goto power_on_fail;\r
+    }\r
+    /* 加载固件 */\r
+    ret = gnss_firmware_load(&ctrl->firmware);\r
+    if (ret != 0) {\r
+        goto fw_load_fail;\r
+    }\r
+    /* 使能中断 */\r
+    dev_wkup_host_pin = ctrl->pm.pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST];\r
+    tiot_pin_int_request(dev_wkup_host_pin, gnss_device_wakeup_host_cb);\r
+\r
+    ret = gnss_service_packet_init(ctrl, dev_id);\r
+    if (ret != 0) {\r
+        goto pkt_init_fail;\r
+    }\r
+    ret = gnss_service_install_packet(ctrl, dev_id);\r
+    if (ret != 0) {\r
+        goto pkt_install_fail;\r
+    }\r
+    ret = gnss_service_custom_msg_send(ctrl, dev_wkup_host_pin, CONFIG_GNSS_UART_BAUDRATE);\r
+    if (ret != 0) {\r
+        goto pkt_install_fail;\r
+    }\r
+    /* 打开OK */\r
+    tiot_print_suc("[TIoT]Controller open succ.\n");\r
+    return 0;\r
+\r
+pkt_install_fail:\r
+    tiot_packet_deinit(&g_gnss_pkt_ctx[dev_id]);\r
+pkt_init_fail:\r
+    tiot_pin_int_release(dev_wkup_host_pin);\r
+fw_load_fail:\r
+    (void)tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_POWEROFF);\r
+power_on_fail:\r
+    tiot_xfer_close(&ctrl->transfer);\r
+xfer_open_fail:\r
+    return ret;\r
+}\r
+\r
+static void gnss_service_close(tiot_controller *ctrl)\r
+{\r
+    uint8_t dev_id;\r
+    uint32_t dev_wkup_host_pin;\r
+    if (gnss_get_dev_id(ctrl, &dev_id) != 0) {\r
+        return;\r
+    }\r
+    dev_wkup_host_pin = ctrl->pm.pm_info[TIOT_PIN_DEVICE_WAKEUP_HOST];\r
+    (void)tiot_pm_set_event(&ctrl->pm, TIOT_PM_EVENT_POWEROFF);\r
+    tiot_pin_int_release(dev_wkup_host_pin);\r
+    tiot_xfer_close(&ctrl->transfer);\r
+    tiot_xfer_uninstall_packet(&ctrl->transfer);\r
+    tiot_packet_deinit(&g_gnss_pkt_ctx[dev_id]);\r
+}\r
+\r
+static int32_t gnss_service_write(tiot_controller *ctrl, const uint8_t *data,\r
+                                  uint32_t len, const tiot_xfer_tx_param *param)\r
+{\r
+    tiot_unused(param);\r
+    uint8_t dev_id;\r
+    if (gnss_get_dev_id(ctrl, &dev_id) != 0) {\r
+        return -1;\r
+    }\r
+    const tiot_xfer_tx_param tx_param = { SUBSYS_GNSS };\r
+    tiot_pm *pm = &ctrl->pm;\r
+    (void)tiot_pm_set_event(pm, TIOT_PM_EVENT_WORK_VOTE_UP);\r
+    /* 尝试唤醒device */\r
+    int32_t ret = tiot_pm_set_event(pm, TIOT_PM_EVENT_WAKEUP);\r
+    if (ret != 0) {\r
+        tiot_print_err("[TIoT]wake up error\n");\r
+        goto vote_down;\r
+    }\r
+    /* 等待成功唤醒device */\r
+    ret = tiot_pm_wait_state(&ctrl->pm, TIOT_PM_STATE_WORK, ctrl->dev_info->timings.wakeup_wait_ms);\r
+    if (ret <= 0) {\r
+        tiot_print_warning("[TIoT]wakeup device fail, pm state is 0x%x.\n", pm->state);\r
+    }\r
+    ret = tiot_xfer_send(&ctrl->transfer, data, len, &tx_param);\r
+vote_down:\r
+    (void)tiot_pm_set_event(pm, TIOT_PM_EVENT_WORK_VOTE_DOWN);\r
+    return ret;\r
+}\r
+\r
+static int32_t gnss_service_read(tiot_controller *ctrl, uint8_t *buff, uint32_t buff_len,\r
+                                 const tiot_xfer_rx_param *param)\r
+{\r
+    uint8_t dev_id;\r
+    if (gnss_get_dev_id(ctrl, &dev_id) != 0) {\r
+        return -1;\r
+    }\r
+    return tiot_xfer_recv(&ctrl->transfer, buff, buff_len, param);\r
+}\r
+\r
+int32_t gnss_service_init(void)\r
+{\r
+    uint8_t i;\r
+    int32_t ret;\r
+    tiot_board_info per_board_info;\r
+    tiot_controller_info ctrl_info;\r
+    for (i = 0; i < CONFIG_GNSS_DEV_NUM; i++) {\r
+        if (gnss_board_init(&i) != 0) {\r
+            tiot_print_err("[TIoT]board init fail\n");\r
+            return -1;\r
+        }\r
+    }\r
+    const gnss_board_info *board_info = gnss_board_get_info();\r
+    if (board_info == NULL) {\r
+        tiot_print_err("[TIoT]no board info.\n");\r
+        goto deinit;\r
+    }\r
+    for (i = 0; i < CONFIG_GNSS_DEV_NUM; i++) {\r
+        per_board_info.hw_info.xmit_id = board_info->hw_infos[i].xmit_id;\r
+        per_board_info.hw_info.pm_info = board_info->hw_infos[i].pm_info;\r
+        ctrl_info.board_info = &per_board_info;\r
+        ctrl_info.dev_info = gnss_device_get_info();\r
+        ctrl_info.dev_cus = 0;\r
+        ret = tiot_controller_init(&g_gnss_controllers[i], &ctrl_info);\r
+        if (ret != 0) {\r
+            tiot_print_err("[TIoT]controller init fail\n");\r
+            goto deinit;\r
+        }\r
+    }\r
+    for (i = 0; i < CONFIG_GNSS_DEV_NUM; i++) {\r
+        g_gnss_controllers[i].ops.open = gnss_service_open;\r
+        g_gnss_controllers[i].ops.close = gnss_service_close;\r
+        g_gnss_controllers[i].ops.write = gnss_service_write;\r
+        g_gnss_controllers[i].ops.read = gnss_service_read;\r
+        g_gnss_controllers[i].ops.pm_ctrl = NULL;\r
+    }\r
+    return 0;\r
+deinit:\r
+    gnss_service_deinit();\r
+    return -1;\r
+}\r
+\r
+void gnss_service_deinit(void)\r
+{\r
+    uint8_t i;\r
+    for (i = 0; i < CONFIG_GNSS_DEV_NUM; i++) {\r
+        tiot_controller_deinit(&g_gnss_controllers[i]);\r
+    }\r
+    for (i = 0; i < CONFIG_GNSS_DEV_NUM; i++) {\r
+        gnss_board_deinit(&i);\r
+    }\r
+}\r
+\r
+uintptr_t gnss_service_get_ctrl(uint8_t dev_id)\r
+{\r
+    return (uintptr_t)&g_gnss_controllers[dev_id];\r
+}\r
diff --git a/code/sdk/zhihui/gnss/driver/device/gnss/gnss_service.h b/code/sdk/zhihui/gnss/driver/device/gnss/gnss_service.h
new file mode 100644 (file)
index 0000000..3d37a81
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: GNSS service interface. \n
+ *
+ * History: \n
+ * 2023-06-13, Create file. \n
+ */
+#ifndef GNSS_SERVICE_H
+#define GNSS_SERVICE_H
+
+#include "tiot_types.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+/**
+ * @defgroup tiot_device_gnss_service_if  GNSS Service Interface
+ * @ingroup  tiot_device_gnss
+ * @{
+ */
+
+/**
+ * @brief  GNSS service init.
+ * @return zero if OK, -1 if failed.
+ */
+int32_t gnss_service_init(void);
+
+/**
+ * @brief  GNSS service deinit.
+ */
+void gnss_service_deinit(void);
+
+/**
+ * @brief  GNSS service get ctrl.
+ * @param  dev_id Device id.
+ * @return Tiot controller instace.
+ */
+uintptr_t gnss_service_get_ctrl(uint8_t dev_id);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/product_porting/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7149394
--- /dev/null
@@ -0,0 +1,12 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+add_subdirectory(porting)  # 替换成对应porting目录
+
+set(
+    tiot_product_header_list
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${tiot_product_header_list}" CACHE INTERNAL "tiot header list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/porting/CMakeLists.txt b/code/sdk/zhihui/gnss/driver/product_porting/porting/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b5e1185
--- /dev/null
@@ -0,0 +1,19 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+#===============================================================================
+set(
+    tiot_product_src_list
+    ${CMAKE_CURRENT_SOURCE_DIR}/gnss_board_port.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_board_uart_port.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_board_pin_port.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/tiot_board_misc_port.c
+)
+
+set(
+    tiot_product_header_list
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(TIOT_HEADER_LIST "${TIOT_HEADER_LIST}" "${tiot_product_header_list}" CACHE INTERNAL "tiot header list" FORCE)
+set(TIOT_SRC_LIST "${TIOT_SRC_LIST}" "${tiot_product_src_list}" CACHE INTERNAL "tiot src list" FORCE)
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/porting/gnss_board_port.c b/code/sdk/zhihui/gnss/driver/product_porting/porting/gnss_board_port.c
new file mode 100644 (file)
index 0000000..63927a7
--- /dev/null
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description:  \n
+ *
+ * History: \n
+ * 2023-06-13, Create file. \n
+ */
+
+#include "gnss_board_port.h"
+#include "tiot_board_pin_port.h"
+#include "gpio.h"
+#include "uart.h"
+#include "pinctrl.h"
+#include "soc_osal.h"
+
+/* 根据板级MCU与gnss两个芯片的硬件连接修改适配 */
+/* 1. MCU芯片连接到gnss芯片的UART bus编号, 如UART_BUS_0. */
+/* 2. MCU芯片连接到gnss芯片PWREN管脚号, 。必须. 
+U8  GPS_1V8 S_AGPIO_L28   High  默认一直拉高
+    GPS_BAT_ON S_AGPIO_L23  High 默认一直拉高
+    PWREN S_AGPIO_L30   High  只需要控制PWREN
+*/
+/* 3. MCU芯片连接到gnss芯片GPIO9(host唤醒gnss)管脚号,
+      U8 当下悬空。
+      可选,如果板级未连接此管脚,必须设为TIOT_PIN_NONE宏.
+       */
+/* 4. MCU芯片连接到gnss芯片GPIO7(gnss唤醒host)管脚号,
+      U8 S_AGPIO_L31。
+      可选,如果板级未连接此管脚,必须设为TIOT_PIN_NONE宏.
+       */
+static const gnss_board_hw_info g_gnss_board_hw_info = { UART_BUS_0, { S_AGPIO_L30, TIOT_PIN_NONE, TIOT_PIN_NONE } };
+static const gnss_board_info g_gnss_board_info = {
+    .cfg_path = NULL,  /* 如果使用文件系统,此处填写固件cfg文件完整路径,
+                          例如 .cfg_path = "user/gnss_firmware/gnss_fw_cfg";
+                          否则, 填写NULL,并替换源码目录tiot_driver/device/gnss/firmware下的固件数组文件。 */
+    .hw_infos = (gnss_board_hw_info *)&g_gnss_board_hw_info
+};
+
+int32_t gnss_board_init(void *param)
+{
+    tiot_unused(param);
+    const uint32_t *gnss_pins = g_gnss_board_hw_info.pm_info;
+    /* power en */
+    uint32_t power_ctrl_pin = gnss_pins[GNSS_PIN_POWER_CTRL];
+    (void)uapi_pin_set_mode((pin_t)power_ctrl_pin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+    (void)uapi_pin_set_pull((pin_t)power_ctrl_pin, PIN_PULL_DOWN);
+    (void)uapi_gpio_set_val((pin_t)power_ctrl_pin, GPIO_LEVEL_LOW);
+    (void)uapi_gpio_set_dir((pin_t)power_ctrl_pin, GPIO_DIRECTION_OUTPUT);
+    (void)uapi_pin_set_ds((pin_t)power_ctrl_pin, (pin_drive_strength_t)(PIN_DS_MAX - 1));
+
+    /* host wakeup dev */
+    uint32_t host_wakeup_device_pin = gnss_pins[GNSS_PIN_HOST_WAKEUP_DEVICE];
+    if (host_wakeup_device_pin != TIOT_PIN_NONE) {
+        (void)uapi_pin_set_mode((pin_t)host_wakeup_device_pin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+        (void)uapi_pin_set_ds((pin_t)host_wakeup_device_pin, (pin_drive_strength_t)(PIN_DS_MAX - 1));
+        (void)uapi_pin_set_pull((pin_t)host_wakeup_device_pin, PIN_PULL_DOWN);
+        (void)uapi_gpio_set_val((pin_t)host_wakeup_device_pin, GPIO_LEVEL_LOW);
+        (void)uapi_gpio_set_dir((pin_t)host_wakeup_device_pin, GPIO_DIRECTION_OUTPUT);
+    }
+
+    /* device wakeup host */
+    uint32_t device_wakeup_host_pin = gnss_pins[GNSS_PIN_DEVICE_WAKEUP_HOST];
+    if (device_wakeup_host_pin != TIOT_PIN_NONE) {
+        (void)uapi_pin_set_mode((pin_t)device_wakeup_host_pin, (pin_mode_t)HAL_PIO_FUNC_GPIO);
+        (void)uapi_pin_set_pull((pin_t)device_wakeup_host_pin, PIN_PULL_DOWN);
+        (void)uapi_gpio_set_val((pin_t)device_wakeup_host_pin, GPIO_LEVEL_LOW);
+        (void)uapi_gpio_set_dir((pin_t)device_wakeup_host_pin, GPIO_DIRECTION_INPUT);
+    }
+    /* UART1 pinmux已经在板级完成初始化, 或在UART open时进行初始化。 */
+    return 0;
+}
+
+void gnss_board_deinit(void *param)
+{
+    tiot_unused(param);
+    const uint32_t *gnss_pins = g_gnss_board_hw_info.pm_info;
+    /* 确保PWREN管脚下拉 */
+    (void)uapi_gpio_set_val((pin_t)gnss_pins[GNSS_PIN_POWER_CTRL], GPIO_LEVEL_LOW);
+}
+
+const gnss_board_info *gnss_board_get_info(void)
+{
+    return &g_gnss_board_info;
+}
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_log_port.h b/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_log_port.h
new file mode 100644 (file)
index 0000000..8a87996
--- /dev/null
@@ -0,0 +1,46 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board log port. \n\r
+ *\r
+ * History: \n\r
+ * 2023-05-06, Create file. \n\r
+ */\r
+#ifndef BOARD_LOG_PORT_H\r
+#define BOARD_LOG_PORT_H\r
+\r
+#include <stdio.h>\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C" {\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+/**\r
+ * @defgroup tiot_board_port_log LOG port\r
+ * @ingroup  tiot_board_port\r
+ * @{\r
+ */\r
+\r
+/* 通过printf直接打印,不需要日志时需要注释掉define后半部分. */\r
+#define BOARD_PRINT_FUNCTION_NAME           printf("%s\r\n", __func__)\r
+#define board_print_dbg(s, args...)         printf(s, ##args)\r
+#define board_print_info(s, args...)        printf(s, ##args)\r
+#define board_print_info(s, args...)        printf(s, ##args)\r
+#define board_print_suc(s, args...)         printf(s, ##args)\r
+#define board_print_warning(s, args...)     printf(s, ##args)\r
+#define board_print_err(s, args...)         printf(s, ##args)\r
+#define board_print_alter(s, args...)       printf(s, ##args)\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+#endif /* __cplusplus */\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_misc_port.c b/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_misc_port.c
new file mode 100644 (file)
index 0000000..a7a6e43
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
+ *
+ * Description: Board Misc port. \n
+ *
+ * History: \n
+ * 2023-12-04, Create file. \n
+ */
+#include "tiot_board_misc_port.h"
+#include "soc_osal.h"
+#include "pm_veto.h"
+
+#define TIOT_WAKEUP_LOCK_ID  PM_ID_SYS
+
+int32_t tiot_board_wake_lock_init(tiot_board_wakelock *lock)
+{
+    tiot_unused(lock);
+    return 0;
+}
+
+void tiot_board_wake_lock(tiot_board_wakelock *lock)
+{
+    tiot_unused(lock);
+#if ENABLE_LOW_POWER == YES
+    (void)uapi_pm_add_sleep_veto(TIOT_WAKEUP_LOCK_ID);
+#endif
+}
+
+void tiot_board_wake_unlock(tiot_board_wakelock *lock)
+{
+    tiot_unused(lock);
+#if ENABLE_LOW_POWER == YES
+    (void)uapi_pm_remove_sleep_veto(TIOT_WAKEUP_LOCK_ID);
+#endif
+}
+
+void tiot_board_wake_lock_destroy(tiot_board_wakelock *lock)
+{
+    tiot_unused(lock);
+}
+
+void tiot_board_udelay(uint32_t us)
+{
+    osal_udelay(us);
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_pin_port.c b/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_pin_port.c
new file mode 100644 (file)
index 0000000..aebb1c2
--- /dev/null
@@ -0,0 +1,112 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board PIN port. \n\r
+ *\r
+ * History: \n\r
+ * 2023-04-20, Create file. \n\r
+ */\r
+#include "tiot_board_pin_port.h"\r
+#include "gpio.h"\r
+\r
+#define uapi_err2ret(errcode)      (((errcode) == ERRCODE_SUCC) ? 0 : -1)\r
+\r
+/* TIoT驱动使用中断管脚个数,需要按实际板级情况适配修改。 */\r
+#define TIOT_INT_PIN_NUMBER    1\r
+typedef struct {\r
+    uint32_t pin;\r
+    tiot_pin_int_callback callback;\r
+} tiot_int_pin_map;\r
+/* TIoT驱动使用中断管脚配置,需要按实际使用的中断管脚适配修改。 */\r
+static tiot_int_pin_map g_tiot_int_pin_map[TIOT_INT_PIN_NUMBER] = {\r
+    /* 例如使用XXX唤醒MCU管脚,对应GPIO ID为S_AGPIO_R0. */\r
+    { S_AGPIO_R0, NULL }\r
+};\r
+\r
+/**\r
+ * @brief  Board set pin level interface.\r
+ * @param  [in] pin   Pin id.\r
+ * @param  [in] level Pin level, see @ref tiot_pin_level.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_set_level(uint32_t pin, uint8_t level)\r
+{\r
+    errcode_t errcode;\r
+    gpio_level_t gpio_level = (level == TIOT_PIN_LEVEL_LOW) ? GPIO_LEVEL_LOW : GPIO_LEVEL_HIGH;\r
+    errcode = uapi_gpio_set_val((pin_t)pin, gpio_level);\r
+    return uapi_err2ret(errcode);\r
+}\r
+\r
+/**\r
+ * @brief  Board get current pin level interface.\r
+ * @param  [in]  pin   Pin id.\r
+ * @param  [out] level Current pin level, see @ref tiot_pin_level.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_get_level(uint32_t pin, uint8_t *level)\r
+{\r
+    gpio_level_t gpio_level = uapi_gpio_get_val((pin_t)pin);\r
+    *level = (gpio_level == GPIO_LEVEL_LOW) ? TIOT_PIN_LEVEL_LOW : TIOT_PIN_LEVEL_HIGH;\r
+    return 0;\r
+}\r
+\r
+/**\r
+ * @brief  Board pin interrupt enable interface.\r
+ * @param  [in] pin         Pin id.\r
+ * @param  [in] int_enable  Interrupt enable or disable, see @ref tiot_pin_int_enable.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_enable_int(uint32_t pin, uint8_t int_enable)\r
+{\r
+    errcode_t errcode;\r
+    if (int_enable == TIOT_PIN_INT_ENABLE) {\r
+        errcode = uapi_gpio_enable_interrupt((pin_t)pin);\r
+    } else {\r
+        errcode = uapi_gpio_disable_interrupt((pin_t)pin);\r
+    }\r
+    return uapi_err2ret(errcode);\r
+}\r
+\r
+\r
+static void tiot_board_gpio_callback(pin_t pin, uintptr_t param)\r
+{\r
+    (void)param;\r
+    uapi_gpio_clear_interrupt(pin);\r
+    for (uint8_t index = 0; index < TIOT_INT_PIN_NUMBER; index++) {\r
+        if ((pin == g_tiot_int_pin_map[index].pin) && (g_tiot_int_pin_map[index].callback != NULL)) {\r
+            g_tiot_int_pin_map[index].callback(pin);\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * @brief  Board pin interrupt callback register interface.\r
+ * @note   Porting should ensure this callback is called when enters pin irq if interrupt enabled.\r
+ * @param  [in] pin     Pin id.\r
+ * @param  [in] int_cb  Registed interrupt callback, see @ref tiot_pin_int_callback.\r
+ * @return zero if OK;\r
+ *         non-zero if FAIL.\r
+ */\r
+int32_t tiot_board_pin_register_int_callback(uint32_t pin, tiot_pin_int_callback int_cb)\r
+{\r
+    errcode_t errcode;\r
+    if (int_cb != NULL) {\r
+        errcode = uapi_gpio_register_isr_func((pin_t)pin, GPIO_INTERRUPT_RISING_EDGE, tiot_board_gpio_callback);\r
+    } else {\r
+        errcode = uapi_gpio_unregister_isr_func((pin_t)pin);\r
+    }\r
+    if (errcode != ERRCODE_SUCC) {\r
+        return -1;\r
+    }\r
+    for (uint8_t index = 0; index < TIOT_INT_PIN_NUMBER; index++) {\r
+        if (pin == g_tiot_int_pin_map[index].pin) {\r
+            g_tiot_int_pin_map[index].callback = int_cb;\r
+            break;\r
+        }\r
+    }\r
+    return 0;\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_uart_port.c b/code/sdk/zhihui/gnss/driver/product_porting/porting/tiot_board_uart_port.c
new file mode 100644 (file)
index 0000000..36dd877
--- /dev/null
@@ -0,0 +1,193 @@
+/**\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.\r
+ *\r
+ * Description: Board UART port\n\r
+ *\r
+ * History: \n\r
+ * 2023-03-25, Create file. \n\r
+ */\r
+#include "tiot_board_uart_port.h"\r
+#include "tiot_board_log.h"\r
+\r
+#include "uart.h"\r
+#include "uart_porting.h"\r
+#include "pinctrl.h"\r
+#include "pinctrl_porting.h"\r
+\r
+#define TIOT_UAPI_RW_TIMEOUT    0xFFFFFFFF\r
+#define UART_RX_BUFFER_SIZE     56\r
+\r
+#define TIOT_UAPI_UART_RX_MAX   1024\r
+\r
+/* TIoT驱动使用MCU UART个数. */\r
+enum tiot_uart_port {\r
+    TIOT_UART_PORT0,\r
+    TIOT_UART_NUM,\r
+    TIOT_UART_NONE = TIOT_UART_NUM\r
+};\r
+\r
+enum tiot_uart_pin_type {\r
+    UART_PIN_TYPE_TX,\r
+    UART_PIN_TYPE_RX,\r
+    UART_PIN_TYPE_CTS,\r
+    UART_PIN_TYPE_RTS,\r
+    UART_PIN_TYPE_NUM\r
+};\r
+\r
+typedef struct {\r
+    tiot_xmit *xmit;\r
+    uint8_t flow_ctrl_bk;\r
+    uint8_t rx_buff[UART_RX_BUFFER_SIZE];\r
+    const uart_pin_config_t pin_config_orig;\r
+    uart_pin_config_t pin_config;\r
+    hal_pio_func_t pinmux[UART_PIN_TYPE_NUM];\r
+    uart_rx_callback_t rx_callback;\r
+} tiot_board_uart_port;\r
+\r
+static tiot_xmit_callbacks g_tiot_xmit_cbs;\r
+\r
+/* MCU UART管脚接收回调,按TIoT驱动使用UART个数适配增加 */\r
+static void tiot_board_rx_callback0(const void *buff, uint16_t length, bool error);\r
+/* TIoT驱动使用的UART初始信息,需要按实际板级情况适配。 */\r
+static tiot_board_uart_port g_tiot_board_uart_port[TIOT_UART_NUM] = {\r
+    /* TIOT_UART_PORT0. */\r
+    {\r
+        .flow_ctrl_bk = TIOT_UART_ATTR_FLOW_CTRL_ENABLE,   /* MCU UART默认是否开启流控。 */\r
+        .rx_buff = { 0 },\r
+        .pin_config_orig = { S_MGPIO19, S_MGPIO20, S_MGPIO21, S_MGPIO22 },   /* MCU UART管脚,按实际板级情况适配。 */\r
+        /* MCU UART管脚pinmux,按实际板级情况适配。 */\r
+        .pinmux = {\r
+            HAL_PIO_FUNC_UART1, HAL_PIO_FUNC_UART1,\r
+            HAL_PIO_FUNC_UART1, HAL_PIO_FUNC_UART1\r
+        },\r
+        .rx_callback = tiot_board_rx_callback0             /* MCU UART管脚接收回调,按TIoT驱动使用UART个数适配增加。 */\r
+    }\r
+    /* TIOT_UART_PORTx... */\r
+};\r
+\r
+/* MCU UART bus号与TIoT驱动使用的UART 对应关系,需要按实际情况适配。 */\r
+static inline enum tiot_uart_port tiot_board_uart_bus_convert_port(uart_bus_t bus)\r
+{\r
+    /* 例如 UART_BUS_0 对应 TIoT驱动使用的第一个UART。 */\r
+    if (bus == UART_BUS_0) {\r
+        return TIOT_UART_PORT0;\r
+    }\r
+    return TIOT_UART_NONE;\r
+}\r
+\r
+static inline void tiot_board_rx_callback_common(tiot_board_uart_port *port, const void *buff, uint16_t length)\r
+{\r
+    g_tiot_xmit_cbs.rx_notify(port->xmit, (uint8_t *)buff, length);\r
+}\r
+\r
+/* MCU UART管脚接收回调,按TIoT驱动使用UART个数适配增加 */\r
+static void tiot_board_rx_callback0(const void *buff, uint16_t length, bool error)\r
+{\r
+    if (error == false) {\r
+        tiot_board_rx_callback_common(&g_tiot_board_uart_port[TIOT_UART_PORT0], buff, length);\r
+    } else {\r
+        tiot_print_err("[TIoT]uart port0 receive error.\r\n");\r
+    }\r
+}\r
+\r
+static void tiot_board_uart_txrx_pinmux_init(tiot_board_uart_port *port)\r
+{\r
+    /* 防止板级未初始化. */\r
+    uapi_pin_set_mode(port->pin_config.tx_pin, (pin_mode_t)port->pinmux[UART_PIN_TYPE_TX]);\r
+    uapi_pin_set_mode(port->pin_config.rx_pin, (pin_mode_t)port->pinmux[UART_PIN_TYPE_RX]);\r
+}\r
+\r
+static void tiot_board_uart_switch_flowctrl(tiot_board_uart_port *port)\r
+{\r
+    /* 板级uart初始化不会初始化ctsrts pinmux... */\r
+    if (port->flow_ctrl_bk == TIOT_UART_ATTR_FLOW_CTRL_ENABLE) {\r
+        port->pin_config.cts_pin = port->pin_config_orig.cts_pin;\r
+        port->pin_config.rts_pin = port->pin_config_orig.rts_pin;\r
+        uapi_pin_set_mode(port->pin_config.cts_pin, (pin_mode_t)port->pinmux[UART_PIN_TYPE_CTS]);\r
+        uapi_pin_set_mode(port->pin_config.rts_pin, (pin_mode_t)port->pinmux[UART_PIN_TYPE_RTS]);\r
+    } else {\r
+        port->pin_config.cts_pin = PIN_NONE;\r
+        port->pin_config.rts_pin = PIN_NONE;\r
+    }\r
+}\r
+\r
+static int32_t tiot_board_uart_reopen(uart_bus_t bus, tiot_board_uart_port *port, const uart_attr_t *attr)\r
+{\r
+    uart_buffer_config_t buff_cfg = { (uint8_t *)port->rx_buff, UART_RX_BUFFER_SIZE };\r
+    (void)uapi_uart_deinit(bus);\r
+    tiot_board_uart_txrx_pinmux_init(port);\r
+    tiot_board_uart_switch_flowctrl(port);\r
+    errcode_t ret = uapi_uart_init(bus, &(port->pin_config), attr, NULL, &buff_cfg);\r
+    if (ret != ERRCODE_SUCC) {\r
+        return -1;\r
+    }\r
+    uapi_uart_register_rx_callback(bus, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE,\r
+                                   TIOT_UAPI_UART_RX_MAX, port->rx_callback);\r
+    return 0;\r
+}\r
+\r
+int32_t tiot_board_uart_open(tiot_xmit *xmit, tiot_xmit_callbacks *cbs)\r
+{\r
+    enum tiot_uart_port port_type = tiot_board_uart_bus_convert_port((uart_bus_t)xmit->id);\r
+    if (port_type == TIOT_UART_NONE) {\r
+        return -1;\r
+    }\r
+    tiot_board_uart_port *port = &g_tiot_board_uart_port[port_type];\r
+    const uart_attr_t init_attr = { 115200, UART_DATA_BIT_8, UART_STOP_BIT_1, UART_PARITY_NONE,\r
+                                    ((port->flow_ctrl_bk == TIOT_UART_ATTR_FLOW_CTRL_ENABLE) ?\r
+                                    UART_FLOW_CTRL_RTS_CTS : UART_FLOW_CTRL_NONE) };\r
+    port->pin_config.tx_pin = port->pin_config_orig.tx_pin;\r
+    port->pin_config.rx_pin = port->pin_config_orig.rx_pin;\r
+    if (tiot_board_uart_reopen((uart_bus_t)xmit->id, port, &init_attr) != 0) {\r
+        return -1;\r
+    }\r
+    g_tiot_xmit_cbs = *cbs;\r
+    port->xmit = xmit;\r
+    xmit->handle = port;\r
+    return 0;\r
+}\r
+\r
+void tiot_board_uart_close(tiot_xmit *xmit)\r
+{\r
+    uapi_uart_unregister_rx_callback(xmit->id);\r
+    (void)uapi_uart_deinit(xmit->id);\r
+}\r
+\r
+int32_t tiot_board_uart_write(tiot_xmit *xmit, const uint8_t *buff, uint32_t len)\r
+{\r
+    return uapi_uart_write(xmit->id, buff, len, TIOT_UAPI_RW_TIMEOUT);\r
+}\r
+\r
+int32_t tiot_board_uart_read(tiot_xmit *xmit, uint8_t *buff, uint32_t len)\r
+{\r
+    return uapi_uart_read(xmit->id, buff, len, TIOT_UAPI_RW_TIMEOUT);\r
+}\r
+\r
+int32_t tiot_board_uart_set_config(tiot_xmit *xmit, tiot_uart_config *config)\r
+{\r
+    errcode_t ret;\r
+    tiot_board_uart_port *port = xmit->handle;\r
+    if ((config == NULL) || (config->attr.data_bits >= TIOT_UART_ATTR_DATABIT_BUTT) ||\r
+        (config->attr.stop_bits >= TIOT_UART_ATTR_STOPBIT_BUTT) ||\r
+        (config->attr.parity >= TIOT_UART_ATTR_PARITY_BUTT)) {\r
+        return -1;\r
+    }\r
+    if (port == NULL) {\r
+        return -1;\r
+    }\r
+    /* 确保当前无数据正在FIFO内传输,才能修改配置. */\r
+    while (uapi_uart_has_pending_transmissions(xmit->id) == true) {;}\r
+\r
+    const uart_attr_t attr = { config->baudrate, UART_DATA_BIT_8, UART_STOP_BIT_1, UART_PARITY_NONE,\r
+                               ((config->attr.flow_ctrl == TIOT_UART_ATTR_FLOW_CTRL_ENABLE) ?\r
+                               UART_FLOW_CTRL_RTS_CTS : UART_FLOW_CTRL_NONE) };\r
+    /* 调整流控需要重新init. */\r
+    if (config->attr.flow_ctrl != port->flow_ctrl_bk) {\r
+        port->flow_ctrl_bk = config->attr.flow_ctrl;\r
+        if (tiot_board_uart_reopen((uart_bus_t)xmit->id, port, &attr) != 0) {\r
+            return -1;\r
+        }\r
+    }\r
+    ret = uapi_uart_set_attr(xmit->id, &attr);\r
+    return (ret == ERRCODE_SUCC) ? 0 : -1;\r
+}\r
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/readme.txt b/code/sdk/zhihui/gnss/driver/product_porting/readme.txt
new file mode 100644 (file)
index 0000000..53939af
--- /dev/null
@@ -0,0 +1,2 @@
+TCXO时钟26M + 硬件流控连接
+TCXO时钟26M + 硬件流控悬空 + 无文件系统及动态内存
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/tiot_autoconfig.h b/code/sdk/zhihui/gnss/driver/product_porting/tiot_autoconfig.h
new file mode 100644 (file)
index 0000000..fc27814
--- /dev/null
@@ -0,0 +1,27 @@
+/* Config 0/2 Common */
+#define CONFIG_DEV_GNSS 1
+#define CONFIG_GNSS_DEV_NUM 1
+#define CONFIG_GNSS_WAKEUP_TYPE_UART 1
+#define CONFIG_GNSS_TCXO_FREQ_26M 1
+#define CONFIG_GNSS_UART_BAUDRATE 115200
+#define CONFIG_FILE_BY_ARRAY 1
+#define CONFIG_FIRMWARE_CFG_HANDLE_PRIV 1
+#define CONFIG_FIRMWARE_FILE_READ_BUF_LEN 1029
+#define CONFIG_PM_WAKEUP_BY_UART 1
+#define CONFIG_PM_MANAGE_LOWPOWER 1
+#define CONFIG_XMIT_WITH_UART 1
+#define CONFIG_UART_RX_MODE_BUFFED 1
+#define CONFIG_XFER_PACKET_TIOT 1
+#define CONFIG_XFER_DEFAULT_RX_BUFF 1
+#define CONFIG_XFER_RX_BUFF_SIZE 512
+
+
+/**Config2   OSAL 已有, 安全应用已经实现, 动态申请内存*/
+#define CONFIG_OSAL_DEFINED 1
+#define CONFIG_LIBBOUNDSCHECK_IMPLEMENTED 1
+#define CONFIG_BOARD_DYNAMIC_ALLOC 1
+
+/* Config0 */
+#if (CONFIG_BOARD_DYNAMIC_ALLOC != 1)
+#define CONFIG_GNSS_PACKET_BUFF_MAX 10000
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/driver/product_porting/tiot_defconfig b/code/sdk/zhihui/gnss/driver/product_porting/tiot_defconfig
new file mode 100644 (file)
index 0000000..a84e7ea
--- /dev/null
@@ -0,0 +1,101 @@
+# Generated by HiCFBB Kconfig Tool.
+# Note: !!!This file can not be modify manually!!!
+
+#
+# Devices
+#
+
+#
+# Config the devices.
+#
+CONFIG_DEV_GNSS=y
+CONFIG_GNSS_DEV_NUM=1
+CONFIG_GNSS_WAKEUP_TYPE_UART=y
+# CONFIG_GNSS_WAKEUP_TYPE_GPIO is not set
+CONFIG_GNSS_TCXO_FREQ_26M=y
+# CONFIG_GNSS_TCXO_FREQ_38P4M is not set
+CONFIG_GNSS_UART_BAUDRATE=115200
+# CONFIG_GNSS_UART_WITH_FLOWCTRL is not set
+CONFIG_GNSS_PACKET_BUFF_MAX=10000
+# CONFIG_DEV_W33 is not set
+# CONFIG_DEV_CA01 is not set
+# end of Devices
+
+#
+# Common
+#
+
+#
+# Config common modules.
+#
+
+#
+# Misc
+#
+CONFIG_FILE_BY_ARRAY=y
+CONFIG_OSAL_DEFINED=y
+CONFIG_LIBBOUNDSCHECK_IMPLEMENTED=y
+CONFIG_BOARD_DYNAMIC_ALLOC=y
+# end of Misc
+
+#
+# Firmware Load
+#
+
+#
+# Firmware load module.
+#
+CONFIG_FIRMWARE_CFG_HANDLE_PRIV=y
+# CONFIG_FIRMWARE_CFG_HANDLE_XCI is not set
+CONFIG_FIRMWARE_FILE_READ_BUF_LEN=1029
+# end of Firmware Load
+
+#
+# Power Management
+#
+
+#
+# Power management module.
+#
+CONFIG_PM_WAKEUP_BY_UART=y
+CONFIG_PM_MANAGE_LOWPOWER=y
+# end of Power Management
+
+#
+# Transfer
+#
+
+#
+# Transfer module.
+#
+
+#
+# Transmit Type Support
+#
+
+#
+# Transmit type support.
+#
+CONFIG_XMIT_WITH_UART=y
+# CONFIG_XMIT_WITH_SPI is not set
+# CONFIG_XMIT_WITH_I2C is not set
+CONFIG_UART_RX_MODE_BUFFED=y
+# CONFIG_UART_RX_MODE_BLOCK is not set
+# end of Transmit Type Support
+
+#
+# Packet Handle Support
+#
+
+#
+# Pakcet handle support.
+#
+CONFIG_XFER_PACKET_TIOT=y
+# CONFIG_XFER_PACKET_NCI is not set
+# end of Packet Handle Support
+
+CONFIG_XFER_DEFAULT_RX_BUFF=y
+CONFIG_XFER_RX_BUFF_SIZE=512
+# CONFIG_XFER_TX_SUPPORT_TASK is not set
+# end of Transfer
+# end of Common
diff --git a/code/sdk/zhihui/gnss/sample/agnss_sample/CMakeLists.txt b/code/sdk/zhihui/gnss/sample/agnss_sample/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5b80af7
--- /dev/null
@@ -0,0 +1,41 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "agnss_sample")
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/agnss_sample.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/agnss_encode.c
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PUBLIC_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+CONFIG_AGNSS_SAMPLE
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-implicit-function-declaration
+)
+
+set(WHOLE_LINK
+true
+)
+
+set(BUILD_AS_OBJ
+false
+)
+
+set(MAIN_COMPONENT
+false
+)
+build_component()
diff --git a/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_encode.c b/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_encode.c
new file mode 100644 (file)
index 0000000..9309437
--- /dev/null
@@ -0,0 +1,252 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ * Description: agnss encode\r
+ * Author:\r
+ * Create:\r
+ */\r
+#include "agnss_encode.h"\r
+#include <stdio.h>\r
+#include <dirent.h>\r
+#include <string.h>\r
+#include "securec.h"\r
+#include "gnss_datatypes.h"\r
+#include "tiot_service_interface.h"\r
+\r
+#define GNSS_ENCODE_BUFF_MAX_LEN 9300\r
+#define FILE_PATH_LEN            1024\r
+#define INJECT_SLEEP_MS_TIME     500\r
+#define REPORT_MAX_BYTES         10000\r
+#define LISTEN_TIME_THR          1000\r
+#define AGNSS_FILE_MAX_SIZE      1024000\r
+#define AGNSS_DATA_PATH          "/user/xgnss/AGNSS.dat" // 可自行配置路径\r
+\r
+// 监听消息\r
+static uint8_t g_ackBuff[REPORT_MAX_BYTES] = { 0 };\r
+\r
+/* 计算命令内容校准和 */\r
+static uint16_t CalcChecksum(uint8_t *buff, uint16_t len)\r
+{\r
+    uint16_t checksum = 0;\r
+    uint16_t i = 0;\r
+    while (i++ < len) {\r
+        checksum += *buff;\r
+        buff++;\r
+    }\r
+    return checksum;\r
+}\r
+\r
+/* AGNSS计算内容校准和, 校验和模256,与芯片侧的命令校验和计算不可混用 */\r
+uint8_t CalcAgnssCheckSum(uint8_t *data, uint16_t len)\r
+{\r
+    uint8_t sum = 0;\r
+    for (uint16_t i = 0; i < len; i++) {\r
+        sum += data[i];\r
+    }\r
+    return sum;\r
+}\r
+\r
+int32_t AgnssInjectUtcTime(tiot_handle handle, GnssUtcTime *utcTime)\r
+{\r
+    uint8_t *buff = (uint8_t *)malloc(GNSS_ENCODE_BUFF_MAX_LEN);\r
+    if (buff == NULL) {\r
+        printf("\nerror: malloc failed in AgnssInjectUtcTime\n");\r
+        return 0;\r
+    }\r
+    memset_s(buff, GNSS_ENCODE_BUFF_MAX_LEN, 0, GNSS_ENCODE_BUFF_MAX_LEN);\r
+\r
+    GnssMsg *hdr = (GnssMsg *)buff;\r
+    hdr->cmd = CMD_XGNSS_INJECT_UTC_TIME;\r
+    hdr->sequence = 0;\r
+    errno_t copyRet = memcpy_s(hdr->data, (GNSS_ENCODE_BUFF_MAX_LEN - sizeof(GnssMsg)), utcTime, sizeof(GnssUtcTime));\r
+    if (copyRet != EOK) {\r
+        printf("\nmemcpy UtcTime failed! Errno is %d\n", copyRet);\r
+        free(buff);\r
+        return 0;\r
+    }\r
+    hdr->dataLength = sizeof(GnssUtcTime);\r
+    hdr->checkSum = CalcChecksum(hdr->data, hdr->dataLength);\r
+    int32_t ret = tiot_service_write(handle, buff, (sizeof(GnssMsg) + hdr->dataLength));\r
+    if (ret < 0) {\r
+        printf("\nerror: AgnssInjectUtcTime error: %d\n", ret);\r
+        free(buff);\r
+        return 0;\r
+    }\r
+\r
+    free(buff);\r
+    return 1;\r
+}\r
+\r
+static uint16_t FillGnssMessageData(uint8_t *inBuff, uint32_t inLen, uint8_t *outBuff, uint32_t outLen)\r
+{\r
+    errno_t ret = memcpy_s(outBuff, outLen, inBuff, inLen);\r
+    if (ret != EOK) {\r
+        printf("memcpy XgnssData failed! Errno is %d", ret);\r
+        return 0;\r
+    }\r
+\r
+    return inLen;\r
+}\r
+\r
+static int32_t EncodeGnssMsg(uint8_t *inBuff, uint32_t inLen, uint8_t *outBuff, uint32_t outLen)\r
+{\r
+    uint16_t len = FillGnssMessageData(inBuff, inLen, outBuff, outLen);\r
+    if (len > 0) {\r
+        return 1;\r
+    }\r
+    return 0;\r
+}\r
+\r
+static void ListenAck(tiot_handle handle)\r
+{\r
+    int32_t i = 0;\r
+    for (;;) {\r
+        // 监听\r
+        int32_t ret = tiot_service_read(handle, g_ackBuff, REPORT_MAX_BYTES, LISTEN_TIME_THR);\r
+        if (ret > 0) {\r
+            uint16_t *type = (uint16_t *)g_ackBuff;\r
+            // 二进制消息类型\r
+            if (type[0] == 0) {\r
+                g_ackBuff[ret] = '\0';\r
+                printf("%s\n", (char *)&g_ackBuff[MSG_CONTENT_IDX]);\r
+            }\r
+            i++;\r
+        }\r
+        if (i >= 1) {\r
+            printf("\ncnt enough\n");\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+static int32_t EncodeAndInjectCmd(tiot_handle handle, GnssCmdType cmdType, uint8_t* inBuff, uint32_t inLen)\r
+{\r
+    // 获取GNSS业务消息头\r
+    int32_t len = 0;\r
+    uint8_t *buff = (uint8_t *)malloc(GNSS_ENCODE_BUFF_MAX_LEN);\r
+    if (buff == NULL) {\r
+        printf("\nerror: malloc failed in EncodeAndInjectCmd\n");\r
+        return 0;\r
+    }\r
+    memset_s(buff, GNSS_ENCODE_BUFF_MAX_LEN, 0, GNSS_ENCODE_BUFF_MAX_LEN);\r
+\r
+    GnssMsg *gnssHdr = (GnssMsg *)buff;\r
+    len += sizeof(GnssMsg);\r
+\r
+    gnssHdr->sequence = 0;\r
+\r
+    int32_t retLen = EncodeGnssMsg(inBuff, inLen, buff + len, (GNSS_ENCODE_BUFF_MAX_LEN - len));\r
+    if (retLen != 1) {\r
+        printf("\nerror: Encode Cmd failed: %d\n", cmdType);\r
+        free(buff);\r
+        return retLen;\r
+    }\r
+    gnssHdr->cmd = cmdType;\r
+    gnssHdr->dataLength = inLen;\r
+    gnssHdr->checkSum = CalcChecksum(gnssHdr->data, gnssHdr->dataLength);\r
+    int32_t ret = tiot_service_write(handle, buff, (sizeof(GnssMsg) + gnssHdr->dataLength));\r
+    if (ret < 0) {\r
+        printf("\nerror: Inject Cmd failed: %d\n", cmdType);\r
+        free(buff);\r
+        return 0;\r
+    }\r
+    ListenAck(handle);\r
+    printf("\nInject Cmd SUCCESS: %x\n", cmdType);\r
+    free(buff);\r
+    return 1;\r
+}\r
+\r
+void ProcAndInjectAgnssCmd(tiot_handle handle, uint16_t dataType, uint8_t *data, uint16_t dataLen)\r
+{\r
+    /* 1.根据AGNSS dataType类型,转换为芯片侧消息类型 */\r
+    const struct {\r
+        AgnssDataType agnssDataType;    // AGNSS type类型,\r
+        GnssCmdType innerType;            // 芯片侧消息类型\r
+    } table[] = {\r
+        {AGNSS_GPS_INJECT_EPH, CMD_AGNSS_INJECT_NAV},\r
+        {AGNSS_GPS_INJECT_UTC, CMD_AGNSS_INJECT_UTC},\r
+        {AGNSS_GPS_INJECT_ION, CMD_AGNSS_INJECT_IONO},\r
+        {AGNSS_GPS_INJECT_RTI, CMD_AGNSS_INJECT_RTI},\r
+        {AGNSS_GLO_INJECT_EPH, CMD_AGNSS_INJECT_GANSS_NAV},\r
+        {AGNSS_GLO_INJECT_RTI, CMD_AGNSS_INJECT_GANSS_RTI},\r
+        {AGNSS_GLO_INJECT_AUX, CMD_AGNSS_INJECT_GANSS_AUXI},\r
+        {AGNSS_BDS_INJECT_EPH, CMD_AGNSS_INJECT_GANSS_NAV},\r
+        {AGNSS_BDS_INJECT_ION, CMD_AGNSS_INJECT_GANSS_ADDL_IONO},\r
+        {AGNSS_BDS_INJECT_RTI, CMD_AGNSS_INJECT_GANSS_RTI},\r
+        {AGNSS_GAL_INJECT_EPH, CMD_AGNSS_INJECT_GANSS_NAV},\r
+        {AGNSS_GAL_INJECT_RTI, CMD_AGNSS_INJECT_GANSS_RTI}\r
+    };\r
+    uint16_t cmdType = 0;\r
+    // 2.遍历对应关系表\r
+    for (int i = 0; i < sizeof(table) / sizeof(table[0]); i++) {\r
+        if (dataType == table[i].agnssDataType) {\r
+            cmdType = (uint16_t)table[i].innerType;\r
+            // 3.找到对应芯片侧消息类型,并下发消息\r
+            EncodeAndInjectCmd(handle, cmdType, data, dataLen);\r
+            break;\r
+        }\r
+    }\r
+    osal_msleep(INJECT_SLEEP_MS_TIME);\r
+}\r
+\r
+void AgnssInjectAllContent(tiot_handle handle, uint8_t *buff, int32_t len)\r
+{\r
+    int32_t remainLen = len;\r
+    // tlv\r
+    while ((uint32_t)remainLen >= sizeof(AgnssDataHeader) + sizeof(AgnssDataTail)) {\r
+        AgnssDataHeader *header = (AgnssDataHeader *)buff;\r
+        uint16_t dataLen = header->len;\r
+        if ((uint32_t)remainLen < sizeof(AgnssDataHeader) + sizeof(AgnssDataTail) + dataLen) {\r
+            printf("AgnssInjectAllContent: remainLen %d and dataLen %d not match\n", remainLen, dataLen);\r
+            return;\r
+        }\r
+        uint8_t localCheckSum = CalcAgnssCheckSum((uint8_t *)header, (header->data - (uint8_t *)header) + dataLen);\r
+        uint8_t checkSum = ((AgnssDataTail *)(header->data + dataLen))->checkSum;\r
+        if (localCheckSum != checkSum) {\r
+            printf("AgnssInjectAllContent: local CheckSum %d and CheckSum %d not match\n", localCheckSum, checkSum);\r
+            return;\r
+        }\r
+        ProcAndInjectAgnssCmd(handle, header->dataType, header->data, dataLen);\r
+        buff += sizeof(AgnssDataHeader) + sizeof(AgnssDataTail) + dataLen;\r
+        remainLen -= sizeof(AgnssDataHeader) + sizeof(AgnssDataTail) + dataLen;\r
+    }\r
+}\r
+\r
+void ProcAgnssFileContent(tiot_handle handle)\r
+{\r
+    char fileName[] = AGNSS_DATA_PATH;\r
+    FILE *fp = fopen(fileName, "rb");\r
+    if (fp == NULL) {\r
+        printf("\nerror: open file failed: %s\n", fileName);\r
+        return;\r
+    }\r
+    fseek(fp, 0, SEEK_END);\r
+    int32_t len = ftell(fp);\r
+    fseek(fp, 0, SEEK_SET);\r
+    if (len < 0 || len > AGNSS_FILE_MAX_SIZE) {\r
+        fclose(fp);\r
+        printf("\nerror: get file len failed: %s\n", fileName);\r
+        return;\r
+    }\r
+    uint8_t *buff = (uint8_t *)malloc(len);\r
+    if (buff == NULL) {\r
+        fclose(fp);\r
+        printf("\nerror: malloc file len failed: %s\n", fileName);\r
+        return;\r
+    }\r
+    int32_t dataSize = fread(buff, len, 1, fp);\r
+    if (dataSize < 0) {\r
+        fclose(fp);\r
+        printf("\nerror: read file failed: %s\n", fileName);\r
+        free(buff);\r
+        return;\r
+    }\r
+    fclose(fp);\r
+    AgnssInjectAllContent(handle, buff, len);\r
+    free(buff);\r
+}\r
+\r
+void AgnssInject(tiot_handle handle)\r
+{\r
+    // 处理AGNSS文件,向芯片注入Agnss辅助数据\r
+    ProcAgnssFileContent(handle);\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_encode.h b/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_encode.h
new file mode 100644 (file)
index 0000000..bbef153
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ * Description: agnss encode\r
+ * Author:\r
+ * Create:\r
+ */\r
+#ifndef AGNSS_ENCODE_H\r
+#define AGNSS_ENCODE_H\r
+\r
+#include "gnss_datatypes.h"\r
+#include "tiot_service_interface.h"\r
+\r
+int32_t AgnssInjectUtcTime(tiot_handle handle, GnssUtcTime *utcTime);\r
+void AgnssInject(tiot_handle handle);\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_sample.c b/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_sample.c
new file mode 100644 (file)
index 0000000..537608d
--- /dev/null
@@ -0,0 +1,193 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ * Description: agnss sample\r
+ * Author:\r
+ * Create:\r
+ */\r
+#include "agnss_sample.h"\r
+#include <stdio.h>\r
+#include "securec.h"\r
+#include "tiot_service_interface.h"\r
+#include "pm_definition.h"\r
+#include "gnss_datatypes.h"\r
+#include "agnss_encode.h"\r
+\r
+#define AGNSS_FIXMODEALL_NMEADEF_SAMPLE            0\r
+\r
+#ifndef ARRAY_SIZE\r
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\r
+#endif\r
+\r
+#define MSG_TYPE_BINRY              0\r
+#define MSG_TYPE_ASCII              1\r
+#define LISTEN_DATA_MAX_LINES       1000\r
+#define REPORT_MAX_BYTES            10000\r
+\r
+static FILE* g_gnssLogFp = NULL;\r
+static uint8_t g_gnssServiceBuff[REPORT_MAX_BYTES] = { 0 };\r
+\r
+typedef int32_t (*GnssCfgFunc)(tiot_handle handle);\r
+\r
+typedef struct {\r
+    uint16_t    sampleId;\r
+    GnssCfgFunc cfgHandle;\r
+} GnssSamplesCfgTable;\r
+\r
+static int32_t QryVersion(tiot_handle handle)\r
+{\r
+    const uint8_t qryVersion[] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};\r
+    // 查询版本号\r
+    int32_t ret = tiot_service_write(handle, qryVersion, sizeof(qryVersion));\r
+    if (ret < 0) {\r
+        printf("error: QryVersion error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    return 1;\r
+}\r
+\r
+// 注入AGNSS,使用默认配置启动\r
+int32_t InjectAgnss(tiot_handle handle)\r
+{\r
+    const uint8_t cfgLogLevelInfo[] = {0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x10, 0x01, 0x00, 0x03};\r
+\r
+    // 配置log级别:info级别。\r
+    int32_t ret = tiot_service_write(handle, cfgLogLevelInfo, sizeof(cfgLogLevelInfo));\r
+    if (ret < 0) {\r
+        printf("error: cfgLogLevelInfo error: %d\n", ret);\r
+        return 0;\r
+    }\r
+\r
+    // 注入UTC时间, 注入Agnss辅助数据前必须先注入参考时间\r
+    GnssUtcTime utcTime = {2024, 3, 22, 10, 0, 0, 0, 1}; // 需要用当前的UTC时间替换\r
+    ret = AgnssInjectUtcTime(handle, &utcTime);\r
+    if (ret == 0) {\r
+        printf("error: AgnssInjectUtcTime failed!\n");\r
+        return 0;\r
+    }\r
+    printf("AgnssInjectUtcTime success!\n");\r
+\r
+    // AGNSS注入\r
+    // 注意,默认AGNSS文件存放在/user/xgnss/目录中,如修改目录,请全局搜索替换\r
+    AgnssInject(handle);\r
+\r
+    return 1;\r
+}\r
+\r
+static const GnssSamplesCfgTable g_gnssSamplesCfg[] = {\r
+    {AGNSS_FIXMODEALL_NMEADEF_SAMPLE, InjectAgnss},\r
+};\r
+\r
+static int32_t StartGnss(tiot_handle handle)\r
+{\r
+    const uint8_t startCmd[] = {0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,\r
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00};\r
+    // 启动GNSS\r
+    int32_t ret = tiot_service_write(handle, startCmd, sizeof(startCmd));\r
+    if (ret < 0) {\r
+        printf("error: start gnss error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    printf("start gnss\n");\r
+    return 1;\r
+}\r
+\r
+static int32_t StopGnss(tiot_handle handle)\r
+{\r
+    const uint8_t stopCmd[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
+    // 停止GNSS\r
+    int32_t ret = tiot_service_write(handle, stopCmd, sizeof(stopCmd));\r
+    if (ret < 0) {\r
+        printf("error: stop gnss error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    printf("stop gnss\n");\r
+    return 1;\r
+}\r
+\r
+static void ListenGnssData(tiot_handle handle)\r
+{\r
+    int32_t i = 0;\r
+    // 写日志\r
+    for (;;) {  // 写日志条件\r
+        // 监听\r
+        int32_t ret = tiot_service_read(handle, g_gnssServiceBuff, REPORT_MAX_BYTES, 1000);\r
+        if (ret > 0) {\r
+            uint16_t *type = (uint16_t *)g_gnssServiceBuff;\r
+            if (type[0] == MSG_TYPE_ASCII) {\r
+                g_gnssServiceBuff[ret] = '\0';\r
+                printf("%s\n", (char *)&g_gnssServiceBuff[MSG_CONTENT_IDX]);\r
+                fprintf(g_gnssLogFp, "%s\n", (char *)&g_gnssServiceBuff[MSG_CONTENT_IDX]);\r
+            }\r
+            i++;\r
+        }\r
+        if (i >= LISTEN_DATA_MAX_LINES) {\r
+            printf("cnt enough\n");\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+void AgnssExecuteSamples(void)\r
+{\r
+    uapi_pm_add_sleep_veto(PM_ID_SYS);\r
+    printf("enter gnss samples\n");\r
+    // Step1: init\r
+    int32_t ret = tiot_service_init();\r
+    if (ret != 0) {\r
+        printf("tiot service init fail\n");\r
+    }\r
+\r
+    // 打开日志文件\r
+    g_gnssLogFp = fopen("/user/gnss.log", "w");\r
+    if (g_gnssLogFp == NULL) {\r
+        printf("error: open log file error\n");\r
+        return;\r
+    }\r
+    printf("before open tiot service\n");\r
+\r
+    // Step2: power on gnss\r
+    tiot_handle handle = tiot_service_open("gn71", NULL);\r
+    if (handle == 0) {\r
+        printf("open tiot service fail\n");\r
+        return;\r
+    }\r
+    printf("open tiot service success\n");\r
+\r
+    int32_t cfgRet;\r
+    // ---- loop ----------\r
+    for (uint16_t i = 0; i < ARRAY_SIZE(g_gnssSamplesCfg); i++) {\r
+        cfgRet = 0;\r
+        if (g_gnssSamplesCfg[i].sampleId == i) {\r
+            // Step3: config gnss\r
+            if (g_gnssSamplesCfg[i].cfgHandle != NULL) {\r
+                cfgRet = g_gnssSamplesCfg[i].cfgHandle(handle);\r
+            }\r
+            if (cfgRet == 0) {\r
+                continue;\r
+            }\r
+            printf("cfg sample id:%u\n", g_gnssSamplesCfg[i].sampleId);\r
+            QryVersion(handle);\r
+\r
+            // Step4: start gnss\r
+            if (StartGnss(handle) == 0) {\r
+                continue;\r
+            }\r
+            // Step5: listening gnss data\r
+            ListenGnssData(handle);\r
+            // Step6: stop gnss\r
+            if (StopGnss(handle) == 0) {\r
+                continue;\r
+            }\r
+        }\r
+    }\r
+    // ---------------------\r
+    // Step7: power off gnss\r
+    tiot_service_close(handle);\r
+    // 关日志文件\r
+    fclose(g_gnssLogFp);\r
+    g_gnssLogFp = NULL;\r
+    // Step8: deinit\r
+    tiot_service_deinit();\r
+    uapi_pm_remove_sleep_veto(PM_ID_SYS);\r
+    printf("finish gnss samples\n");\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_sample.h b/code/sdk/zhihui/gnss/sample/agnss_sample/agnss_sample.h
new file mode 100644 (file)
index 0000000..8c8823b
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ * Description: agnss sample\r
+ * Author:\r
+ * Create:\r
+ */\r
+#ifndef AGNSS_SAMPLE_H\r
+#define AGNSS_SAMPLE_H\r
+\r
+void AgnssExecuteSamples(void);\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/sample/agnss_sample/gnss_datatypes.h b/code/sdk/zhihui/gnss/sample/agnss_sample/gnss_datatypes.h
new file mode 100644 (file)
index 0000000..97607f9
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.\r
+ * Description: gnss datatypes\r
+ * Author:\r
+ * Create:\r
+ */\r
+#ifndef GNSS_DATATYPES_H\r
+#define GNSS_DATATYPES_H\r
+\r
+#include <stdint.h>\r
+\r
+#define MSG_CONTENT_IDX             2\r
+\r
+// 消息类型\r
+typedef enum {\r
+    CMD_AGNSS_INJECT_REF_LOC = 0x0302,         // 位置预测注入\r
+    CMD_AGNSS_INJECT_NAV = 0x0303,             // 星历数据注入\r
+    CMD_AGNSS_INJECT_IONO = 0x0304,            // 电离层参数注入\r
+    CMD_AGNSS_INJECT_UTC = 0x0305,             // UTC时间注入\r
+    CMD_AGNSS_INJECT_RTI = 0x0306,             // 完好性信息注入\r
+    CMD_AGNSS_INJECT_GANSS_ADDL_IONO = 0x0308, // 非GPS电离层参数注入\r
+    CMD_AGNSS_INJECT_GANSS_NAV = 0x0309,       // 非GPS星历数据注入\r
+    CMD_AGNSS_INJECT_GANSS_RTI = 0x030A,       // 非GPS完好性信息注入\r
+    CMD_AGNSS_INJECT_GANSS_AUXI = 0x030C,      // 频点对应关系注入,GLONASS\r
+    CMD_XGNSS_INJECT_UTC_TIME = 0x0404,        // 最开始注入的UTC时间\r
+    CMD_BUTT,\r
+} GnssCmdType;\r
+\r
+typedef enum {\r
+    AGNSS_GPS_INJECT_EPH = 0x0002,\r
+    AGNSS_GPS_INJECT_UTC = 0x0003,\r
+    AGNSS_GPS_INJECT_ION = 0x0004,\r
+    AGNSS_GPS_INJECT_RTI = 0x0005,\r
+    AGNSS_GLO_INJECT_EPH = 0x0022,\r
+    AGNSS_GLO_INJECT_RTI = 0x0025,\r
+    AGNSS_GLO_INJECT_AUX = 0x0026,\r
+    AGNSS_BDS_INJECT_EPH = 0x0042,\r
+    AGNSS_BDS_INJECT_ION = 0x0044,\r
+    AGNSS_BDS_INJECT_RTI = 0x0045,\r
+    AGNSS_GAL_INJECT_EPH = 0x0062,\r
+    AGNSS_GAL_INJECT_RTI = 0x0065\r
+} AgnssDataType;\r
+\r
+#pragma pack(1)\r
+typedef struct {\r
+    uint16_t  cmd;          // 消息类型\r
+    uint16_t  checkSum;     // 校验和,只计算实际数据部分,不包含头\r
+    uint16_t  sequence;     // 序列号,host下发\r
+    uint16_t  dataLength;   // 数据长度,实际数据的长度,不包含头\r
+    uint8_t   data[0];\r
+} GnssMsg;\r
+\r
+typedef struct {\r
+    uint16_t year;          // YYYY\r
+    uint8_t  month;         // MM, 1~12\r
+    uint8_t  day;           // DD, 1~31\r
+    uint8_t  hour;          // hh, 0~23\r
+    uint8_t  minute;        // mm, 0~59\r
+    uint8_t  second;        // ss, 0~59\r
+    uint16_t ms;            // ms, 0~999\r
+    uint8_t  valid;         // 0: invalid, 1: valid\r
+} GnssUtcTime;\r
+\r
+typedef struct {\r
+    uint16_t dataType;\r
+    uint16_t len;\r
+    uint8_t data[0];\r
+} AgnssDataHeader;\r
+\r
+typedef struct {\r
+    uint8_t checkSum;\r
+} AgnssDataTail;\r
+\r
+#pragma pack()\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/sample/gnss_sample/CMakeLists.txt b/code/sdk/zhihui/gnss/sample/gnss_sample/CMakeLists.txt
new file mode 100644 (file)
index 0000000..780a541
--- /dev/null
@@ -0,0 +1,41 @@
+#===============================================================================
+# @brief    cmake make file
+# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2024-2024. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "gnss_sample")
+
+set(SOURCES
+    ${CMAKE_CURRENT_SOURCE_DIR}/gnss_sample.c
+)
+
+set(PRIVATE_HEADER
+    ${TIOT_HEADER_LIST}
+)
+
+set(PUBLIC_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+CONFIG_GNSS_SAMPLE
+)
+
+set(COMPONENT_CCFLAGS
+    -Wno-implicit-function-declaration
+)
+
+set(WHOLE_LINK
+true
+)
+
+set(BUILD_AS_OBJ
+false
+)
+
+set(MAIN_COMPONENT
+false
+)
+build_component()
diff --git a/code/sdk/zhihui/gnss/sample/gnss_sample/gnss_sample.c b/code/sdk/zhihui/gnss/sample/gnss_sample/gnss_sample.c
new file mode 100644 (file)
index 0000000..18e1d8a
--- /dev/null
@@ -0,0 +1,228 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved.\r
+ * Description: gnss sample\r
+ * Author:\r
+ * Create:\r
+ */\r
+#include "gnss_sample.h"\r
+#include <stdio.h>\r
+#include "securec.h"\r
+#include "tiot_service_interface.h"\r
+#include "pm_definition.h"\r
+\r
+#define COLDSTART_FIXMODEGPS_NMEAALL_SAMPLE        0\r
+#define AUTOSTART_FIXMODEALL_NMEADEF_SAMPLE        1\r
+\r
+#ifndef ARRAY_SIZE\r
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\r
+#endif\r
+#define MSG_CONTENT_IDX             2\r
+#define MSG_TYPE_BINRY              0\r
+#define MSG_TYPE_ASCII              1\r
+#define LISTEN_DATA_MAX_LINES       1000\r
+#define REPORT_MAX_BYTES            10000\r
+#define LISTEN_TIME_THR             1000\r
+\r
+static FILE* g_gnssLogFp = NULL;\r
+static uint8_t g_gnssServiceBuff[REPORT_MAX_BYTES] = { 0 };\r
+\r
+typedef int32_t (*GnssCfgFunc)(tiot_handle handle);\r
+\r
+typedef struct {\r
+    uint16_t    sampleId;\r
+    GnssCfgFunc cfgHandle;\r
+} GnssSamplesCfgTable;\r
+\r
+int32_t CfgColdStartFixModeGpsNmeaAll(tiot_handle handle)\r
+{\r
+    const uint8_t cfgColdStartCmd[] = {0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01};\r
+    const uint8_t cfgFixModeGpsCmd[] = {0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,\r
+        0x00, 0x00, 0x00};\r
+    const uint8_t cfgNmeaAllCmd[] = {0x03, 0x00, 0x04, 0x01, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x02, 0x00, 0xff,\r
+        0x00};\r
+    // 配置启动模式:冷启动模式。\r
+    int32_t ret = tiot_service_write(handle, cfgColdStartCmd, sizeof(cfgColdStartCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: cfgColdStartCmd error: %d\n", ret);\r
+        return 0;\r
+    }\r
+\r
+    // 配置使能的GNSS星座:GPS。\r
+    ret = tiot_service_write(handle, cfgFixModeGpsCmd, sizeof(cfgFixModeGpsCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: cfgFixModeGpsCmd error: %d\n", ret);\r
+        return 0;\r
+    }\r
+\r
+    // 配置上报NMEA类型:PNT/ZDA/VTG/RMC/GSV/GSA/GLL/GGA。\r
+    ret = tiot_service_write(handle, cfgNmeaAllCmd, sizeof(cfgNmeaAllCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: cfgNmeaAllCmd error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    return 1;\r
+}\r
+\r
+// 如果有历史信息,自动模式启动会切换到热启动模式,如果无历史信息,则自动模式启动仍然为冷启动\r
+int32_t CfgAutoStartFixModeAllNmeaDefault(tiot_handle handle)\r
+{\r
+    const uint8_t cfgFixModeAllCmd[] = {0x03, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x1f,\r
+        0x00, 0x00, 0x00};\r
+    const uint8_t cfgAutoStartCmd[] = {0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00};\r
+    const uint8_t cfgNmeaDefaultCmd[] = {0x03, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x03, 0x00, 0x02, 0x00, 0x11,\r
+        0x00};\r
+\r
+    // 配置启动模式:自动模式。\r
+    int32_t ret = tiot_service_write(handle, cfgAutoStartCmd, sizeof(cfgAutoStartCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: cfgAutoStartCmd error: %d\n", ret);\r
+        return 0;\r
+    }\r
+\r
+    // 配置使能的GNSS星座:QZSS/GAL/BDS/GLO/GPS。\r
+    ret = tiot_service_write(handle, cfgFixModeAllCmd, sizeof(cfgFixModeAllCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: cfgFixModeAllCmd error: %d\n", ret);\r
+        return 0;\r
+    }\r
+\r
+    // 配置上报NMEA类型:RMC/GGA。\r
+    ret = tiot_service_write(handle, cfgNmeaDefaultCmd, sizeof(cfgNmeaDefaultCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: cfgNmeaDefaultCmd error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    return 1;\r
+}\r
+\r
+static int32_t QryVersion(tiot_handle handle)\r
+{\r
+    const uint8_t qryVersion[] = {0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00};\r
+    // 查询版本号\r
+    int32_t ret = tiot_service_write(handle, qryVersion, sizeof(qryVersion));\r
+    if (ret < 0) {\r
+        printf("\nerror: QryVersion error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    return 1;\r
+}\r
+\r
+static const GnssSamplesCfgTable g_gnssSamplesCfg[] = {\r
+    {COLDSTART_FIXMODEGPS_NMEAALL_SAMPLE,        CfgColdStartFixModeGpsNmeaAll},\r
+    {AUTOSTART_FIXMODEALL_NMEADEF_SAMPLE,        CfgAutoStartFixModeAllNmeaDefault}\r
+};\r
+\r
+static int32_t StartGnss(tiot_handle handle)\r
+{\r
+    const uint8_t startCmd[] = {0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,\r
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00};\r
+    // 启动GNSS\r
+    int32_t ret = tiot_service_write(handle, startCmd, sizeof(startCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: start gnss error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    printf("\nstart gnss\n");\r
+    return 1;\r
+}\r
+\r
+static int32_t StopGnss(tiot_handle handle)\r
+{\r
+    const uint8_t stopCmd[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\r
+    // 停止GNSS\r
+    int32_t ret = tiot_service_write(handle, stopCmd, sizeof(stopCmd));\r
+    if (ret < 0) {\r
+        printf("\nerror: stop gnss error: %d\n", ret);\r
+        return 0;\r
+    }\r
+    printf("\nstop gnss\n");\r
+    return 1;\r
+}\r
+\r
+static void ListenGnssData(tiot_handle handle)\r
+{\r
+    int32_t i = 0;\r
+    // 写日志\r
+    for (;;) {  // 写日志条件\r
+        // 监听\r
+        int32_t ret = tiot_service_read(handle, g_gnssServiceBuff, REPORT_MAX_BYTES, LISTEN_TIME_THR);\r
+        if (ret > 0) {\r
+            uint16_t *type = (uint16_t *)g_gnssServiceBuff;\r
+            if (type[0] == MSG_TYPE_ASCII) {\r
+                g_gnssServiceBuff[ret] = '\0';\r
+                printf("%s\n", (char *)&g_gnssServiceBuff[MSG_CONTENT_IDX]);\r
+                fprintf(g_gnssLogFp, "%s\n", (char *)&g_gnssServiceBuff[MSG_CONTENT_IDX]);\r
+            }\r
+            i++;\r
+        }\r
+        if (i >= LISTEN_DATA_MAX_LINES) {\r
+            printf("\ncnt enough\n");\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+void GnssExecuteSamples(void)\r
+{\r
+    uapi_pm_add_sleep_veto(PM_ID_SYS);\r
+    printf("\nenter gnss samples\n");\r
+    // Step1: init\r
+    int32_t ret = tiot_service_init();\r
+    if (ret != 0) {\r
+        printf("\ntiot service init fail\n");\r
+    }\r
+\r
+    // 打开日志文件\r
+    g_gnssLogFp = fopen("/user/gnss.log", "w");\r
+    if (g_gnssLogFp == NULL) {\r
+        printf("\nerror: open log file error\n");\r
+        return;\r
+    }\r
+    printf("\nbefore open tiot service\n");\r
+\r
+    // Step2: power on gnss\r
+    tiot_handle handle = tiot_service_open("gn71", NULL);\r
+    if (handle == 0) {\r
+        printf("\nopen tiot service fail\n");\r
+        return;\r
+    }\r
+    printf("\nopen tiot service success\n");\r
+\r
+    int32_t cfgRet;\r
+    // ---- loop ----------\r
+    for (uint16_t i = 0; i < ARRAY_SIZE(g_gnssSamplesCfg); i++) {\r
+        cfgRet = 0;\r
+        if (g_gnssSamplesCfg[i].sampleId == i) {\r
+            // Step3: config gnss\r
+            if (g_gnssSamplesCfg[i].cfgHandle != NULL) {\r
+                cfgRet = g_gnssSamplesCfg[i].cfgHandle(handle);\r
+            }\r
+            if (cfgRet == 0) {\r
+                continue;\r
+            }\r
+            printf("\ncfg sample id:%u\n", g_gnssSamplesCfg[i].sampleId);\r
+            QryVersion(handle);\r
+\r
+            // Step4: start gnss\r
+            if (StartGnss(handle) == 0) {\r
+                continue;\r
+            }\r
+            // Step5: listening gnss data\r
+            ListenGnssData(handle);\r
+            // Step6: stop gnss\r
+            if (StopGnss(handle) == 0) {\r
+                continue;\r
+            }\r
+        }\r
+    }\r
+    // ---------------------\r
+    // Step7: power off gnss\r
+    tiot_service_close(handle);\r
+    // 关日志文件\r
+    fclose(g_gnssLogFp);\r
+    g_gnssLogFp = NULL;\r
+    // Step8: deinit\r
+    tiot_service_deinit();\r
+    uapi_pm_remove_sleep_veto(PM_ID_SYS);\r
+    printf("\nfinish gnss samples\n");\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/gnss/sample/gnss_sample/gnss_sample.h b/code/sdk/zhihui/gnss/sample/gnss_sample/gnss_sample.h
new file mode 100644 (file)
index 0000000..9d3d275
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+ * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2024. All rights reserved.\r
+ * Description: gnss sample\r
+ * Author:\r
+ * Create:\r
+ */\r
+#ifndef GNSS_SAMPLE_H\r
+#define GNSS_SAMPLE_H\r
+\r
+void GnssExecuteSamples(void);\r
+\r
+#endif
\ No newline at end of file
similarity index 91%
rename from code/sdk/zhihui/gnss/uart_gnss.c
rename to code/sdk/zhihui/gnss/src/uart_gnss.c
index f6ad3ac..64f288e 100644 (file)
 #include "custom_utils.h"
 #include "uart_gnss.h"
 #include "gnss_ctl.h"
-errcode_t gnss_get_next_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
-errcode_t gnss_get_current_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
-errcode_t gnss_get_nmea_cfg_cmd(uint8_t** cmdbuf,int *cmdlen);
-errcode_t gnss_get_stop_cmd(uint8_t** cmdbuf,int *cmdlen);
-errcode_t gnss_get_start_cmd(uint8_t** cmdbuf,int *cmdlen);
+// errcode_t gnss_get_next_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
+// errcode_t gnss_get_current_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
+// errcode_t gnss_get_nmea_cfg_cmd(uint8_t** cmdbuf,int *cmdlen);
+// errcode_t gnss_get_stop_cmd(uint8_t** cmdbuf,int *cmdlen);
+// errcode_t gnss_get_start_cmd(uint8_t** cmdbuf,int *cmdlen);
 static unsigned long g_gnss_cmd_queue= 0xFFFFFFFF;
 #define MAX_BUFFER_SIZE (256)
 typedef struct {
@@ -155,11 +155,13 @@ static void uart_event_task(void const *arg)
                 uint32_t wlen=0;
                 uint8_t *buf=NULL;
                 uint16_t len=0;
-                if (gnss_get_current_cmd(last_cfg_cmd_index,&buf,&len)==0)
+                // if (gnss_get_current_cmd(last_cfg_cmd_index,&buf,&len)==0)
                 {
                     WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"write next cmd[%d] size=%d! %s \r\n",last_cfg_cmd_index,len);
                     wlen=gnss_write_cmd(buf,len);
-                }else{
+                }
+                // else
+                {
                     WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"no next cmd, stopped! \r\n");
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表结束写入
                 }
@@ -177,7 +179,7 @@ static void uart_event_task(void const *arg)
                     WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"last_cfg_cmd_index %d \r\n",last_cfg_cmd_index);
                     if (last_cfg_cmd_index == 0xFF) //第一次写
                     {
-                        if (gnss_get_current_cmd(0,&buf,&len)==0)
+                        // if (gnss_get_current_cmd(0,&buf,&len)==0)
                         {
                             WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"last_cfg_cmd_index %d \r\n",last_cfg_cmd_index);
                             last_cfg_cmd_index = 0;
@@ -185,15 +187,16 @@ static void uart_event_task(void const *arg)
                     } 
                 break;
                 case GNSS_CMD_NMEA_CFG:
-                    gnss_get_nmea_cfg_cmd(&buf,&len);
+                    // gnss_get_nmea_cfg_cmd(&buf,&len);
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表cfg结束写入,开始检测其他指令
                 break;
                 case GNSS_CMD_START:
-                    gnss_get_start_cmd(&buf,&len);
+                    // gnss_get_start_cmd(&buf,&len);
+                    GnssExecuteSamples();
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表cfg结束写入,开始检测其他指令
                 break;
                 case GNSS_CMD_STOP:
-                    gnss_get_stop_cmd(&buf,&len);
+                    // gnss_get_stop_cmd(&buf,&len);
                     last_cfg_cmd_index = 0xFF; //last_cfg_cmd_index=0xFF 代表cfg结束写入,开始检测其他指令
                 break;
                 default:
@@ -203,7 +206,7 @@ static void uart_event_task(void const *arg)
             }
             if (buf!=NULL)
             {
-                wlen=gnss_write_cmd(buf,len);
+                // wlen=gnss_write_cmd(buf,len);
                 WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"GNSS_CMD_WRITEDATA cmdtype %d, written len %d\r\n",mail.cmd_type,wlen);
             }else{
                 WEARABLE_LOGW(WEARABLE_LOG_MODULE_MAIN_SERVICE,"GNSS_CMD_WRITEDATA cmdtype %d failed \r\n",mail.cmd_type);