From 807c9e444b571a585bb1bcf21abf0e625e59ca10 Mon Sep 17 00:00:00 2001 From: Lizongdi <1210855344@qq.com> Date: Thu, 18 Jun 2026 09:18:37 +0800 Subject: [PATCH] =?UTF-8?q?=E8=80=81=E9=A1=B9=E7=9B=AE=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E4=B8=93=E5=B1=9E=E6=96=87=E4=BB=B6=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 4 +- .../Spoolold/CMakeLists.txt | 0 {project => project_old}/Spoolold/Spoolold.c | 0 {project => project_old}/Spoolold/dmk.c | 0 .../Spoolold/flash_operation.c | 0 .../Spoolold/include/dmk.h | 0 .../Spoolold/include/flash_operation.h | 0 .../Spoolold/include/modbus.h | 0 {project => project_old}/Spoolold/modbus.c | 0 .../paint_robot_old/BASE/Inc/BSP/BHBF_ROBOT.h | 123 ++ .../paint_robot_old/BASE/Inc/BSP/DLTuc.h | 248 +++ .../BASE/Inc/BSP/DLTucConfig.h | 74 + .../BASE/Inc/BSP/bsp_DLT_Log.h | 16 + .../paint_robot_old/BASE/Inc/BSP/bsp_EEPROM.h | 73 + .../BASE/Inc/BSP/bsp_Error_Detect.h | 25 + .../paint_robot_old/BASE/Inc/BSP/bsp_FDCAN.h | 84 + .../paint_robot_old/BASE/Inc/BSP/bsp_GPIO.h | 18 + .../BASE/Inc/BSP/bsp_MB_host.h | 50 + .../paint_robot_old/BASE/Inc/BSP/bsp_TIMER.h | 17 + .../paint_robot_old/BASE/Inc/BSP/bsp_UART.h | 128 ++ .../paint_robot_old/BASE/Inc/BSP/bsp_UDP.h | 23 + .../BASE/Inc/BSP/bsp_UpperComputer_Handler.h | 27 + .../BASE/Inc/BSP/bsp_client_setting.h | 13 + .../BASE/Inc/BSP/bsp_com_helper.h | 82 + .../BASE/Inc/BSP/bsp_cpu_flash.h | 66 + .../BASE/Inc/BSP/bsp_decode_command.h | 39 + .../BASE/Inc/BSP/bsp_include.h | 57 + .../paint_robot_old/BASE/Inc/BSP/bsp_mqtt.h | 36 + .../BASE/Inc/BSP/bsp_mqtt_pub.h | 26 + .../BASE/Inc/BSP/bsp_pb_decode_encode.h | 51 + .../BASE/Inc/BSP/bsp_qspi_w25q128.h | 107 + .../BASE/Inc/BSP/bsp_tempature.h | 19 + project_old/paint_robot_old/BASE/Inc/BSP/pb.h | 917 +++++++++ .../paint_robot_old/BASE/Inc/BSP/pb_common.h | 49 + .../paint_robot_old/BASE/Inc/BSP/pb_decode.h | 193 ++ .../paint_robot_old/BASE/Inc/BSP/pb_encode.h | 185 ++ .../paint_robot_old/BASE/Inc/BSP/readme.h | 38 + .../paint_robot_old/BASE/Inc/BSP/tcp_server.h | 49 + .../BASE/Inc/MSP/msp_Force_Sensor.h | 13 + .../BASE/Inc/MSP/msp_JTBATTERY.h | 15 + .../BASE/Inc/MSP/msp_LeiSai_ISV2_CAN.h | 42 + .../paint_robot_old/BASE/Inc/MSP/msp_MK32_1.h | 18 + .../paint_robot_old/BASE/Inc/MSP/msp_PID.h | 19 + .../paint_robot_old/BASE/Inc/MSP/msp_TL720D.h | 24 + .../BASE/Inc/MSP/msp_WH_LTE_7S0.h | 21 + .../BASE/Protobuf/PSource/bsp_CV.pb.c | 20 + .../BASE/Protobuf/PSource/bsp_CV.pb.h | 125 ++ .../BASE/Protobuf/PSource/bsp_Cmd.pb.c | 12 + .../BASE/Protobuf/PSource/bsp_Cmd.pb.h | 80 + .../BASE/Protobuf/PSource/bsp_Error.pb.c | 13 + .../BASE/Protobuf/PSource/bsp_Error.pb.h | 72 + .../BASE/Protobuf/PSource/bsp_GV.pb.c | 12 + .../BASE/Protobuf/PSource/bsp_GV.pb.h | 108 ++ .../BASE/Protobuf/PSource/bsp_IAP.pb.c | 12 + .../BASE/Protobuf/PSource/bsp_IAP.pb.h | 58 + .../BASE/Protobuf/PSource/bsp_IO.pb.c | 12 + .../BASE/Protobuf/PSource/bsp_IO.pb.h | 81 + .../BASE/Protobuf/PSource/bsp_IV.pb.c | 12 + .../BASE/Protobuf/PSource/bsp_IV.pb.h | 75 + .../BASE/Protobuf/PSource/bsp_PID.pb.c | 20 + .../BASE/Protobuf/PSource/bsp_PID.pb.h | 57 + .../BASE/Protobuf/PSource/bsp_PV.pb.c | 20 + .../BASE/Protobuf/PSource/bsp_PV.pb.h | 64 + .../BASE/Protobuf/PSource/bsp_ReCmd.pb.c | 12 + .../BASE/Protobuf/PSource/bsp_ReCmd.pb.h | 80 + .../PSource/msp_LS_MotorParameters.pb.c | 20 + .../PSource/msp_LS_MotorParameters.pb.h | 84 + .../BASE/Protobuf/PSource/msp_MK32.pb.c | 12 + .../BASE/Protobuf/PSource/msp_MK32.pb.h | 99 + .../BASE/Protobuf/PSource/msp_Motor.pb.c | 12 + .../BASE/Protobuf/PSource/msp_Motor.pb.h | 91 + .../BASE/Protobuf/PSource/msp_TL720D.pb.c | 12 + .../BASE/Protobuf/PSource/msp_TL720D.pb.h | 72 + .../BASE/Protobuf/Proto/bsp_CV.proto | 42 + .../BASE/Protobuf/Proto/bsp_Cmd.options | 2 + .../BASE/Protobuf/Proto/bsp_Cmd.proto | 24 + .../BASE/Protobuf/Proto/bsp_Error.proto | 25 + .../BASE/Protobuf/Proto/bsp_GV.options | 2 + .../BASE/Protobuf/Proto/bsp_GV.proto | 29 + .../BASE/Protobuf/Proto/bsp_IAP.options | 2 + .../BASE/Protobuf/Proto/bsp_IAP.proto | 11 + .../BASE/Protobuf/Proto/bsp_IO.proto | 19 + .../BASE/Protobuf/Proto/bsp_IV.proto | 18 + .../BASE/Protobuf/Proto/bsp_PID.proto | 9 + .../BASE/Protobuf/Proto/bsp_PV.proto | 15 + .../BASE/Protobuf/Proto/bsp_ReCmd.options | 2 + .../BASE/Protobuf/Proto/bsp_ReCmd.proto | 24 + .../Proto/msp_LS_MotorParameters.proto | 19 + .../BASE/Protobuf/Proto/msp_MK32.proto | 22 + .../BASE/Protobuf/Proto/msp_Motor.proto | 23 + .../BASE/Protobuf/Proto/msp_TL720D.proto | 20 + .../paint_robot_old/BASE/Src/BSP/BHBF_ROBOT.c | 127 ++ .../paint_robot_old/BASE/Src/BSP/DLT/DLTuc.c | 636 ++++++ .../BASE/Src/BSP/bsp_DLT_Log.c | 126 ++ .../paint_robot_old/BASE/Src/BSP/bsp_EEPROM.c | 570 ++++++ .../BASE/Src/BSP/bsp_Error_Detect.c | 31 + .../paint_robot_old/BASE/Src/BSP/bsp_FDCAN.c | 334 ++++ .../paint_robot_old/BASE/Src/BSP/bsp_GPIO.c | 104 + .../BASE/Src/BSP/bsp_INTERCALL.c | 41 + .../BASE/Src/BSP/bsp_MB_host.c | 372 ++++ .../paint_robot_old/BASE/Src/BSP/bsp_TIMER.c | 70 + .../paint_robot_old/BASE/Src/BSP/bsp_UART.c | 636 ++++++ .../paint_robot_old/BASE/Src/BSP/bsp_UDP.c | 438 +++++ .../BASE/Src/BSP/bsp_UpperComputer_Handler.c | 114 ++ .../BASE/Src/BSP/bsp_client_setting.c | 128 ++ .../BASE/Src/BSP/bsp_com_helper.c | 191 ++ .../BASE/Src/BSP/bsp_cpu_flash.c | 499 +++++ .../BASE/Src/BSP/bsp_decode_command.c | 473 +++++ .../BASE/Src/BSP/bsp_qspi_w25q128.c | 488 +++++ .../BASE/Src/BSP/bsp_tempature.c | 81 + .../paint_robot_old/BASE/Src/BSP/pb_common.c | 388 ++++ .../paint_robot_old/BASE/Src/BSP/pb_decode.c | 1727 +++++++++++++++++ .../paint_robot_old/BASE/Src/BSP/pb_encode.c | 1000 ++++++++++ .../paint_robot_old/BASE/Src/BSP/tcp_server.c | 251 +++ .../BASE/Src/MSP/msp_LeiSai_ISV2_CAN.c | 390 ++++ .../paint_robot_old/BASE/Src/MSP/msp_MK32_1.c | 118 ++ .../paint_robot_old/BASE/Src/MSP/msp_PID.c | 96 + .../paint_robot_old/BASE/Src/MSP/msp_TL720D.c | 114 ++ .../BASE/Src/MSP/msp_WH_LTE_7S0.c | 98 + .../paint_robot_old/CMakeLists.txt | 0 .../FSM/Inc/change_line_control.h | 56 + .../paint_robot_old/FSM/Inc/fsm_state.h | 44 + .../FSM/Inc/fsm_state_control.h | 24 + project_old/paint_robot_old/FSM/Inc/motors.h | 15 + .../FSM/Inc/motors_power_action.h | 31 + .../FSM/Inc/paint_gun_action.h | 22 + .../FSM/Inc/robot_move_actions.h | 69 + .../FSM/Src/change_line_control.c | 404 ++++ .../paint_robot_old/FSM/Src/fsm_state.c | 51 + .../FSM/Src/fsm_state_control.c | 465 +++++ project_old/paint_robot_old/FSM/Src/motors.c | 152 ++ .../FSM/Src/motors_power_action.c | 35 + .../FSM/Src/paint_gun_action.c | 46 + .../FSM/Src/robot_move_actions.c | 312 +++ project_old/paint_robot_old/include/bsp_fsm.h | 13 + project_old/paint_robot_old/include/com.pb.h | 57 + project_old/paint_robot_old/include/motors.h | 22 + project_old/paint_robot_old/paint_robot_old.c | 0 project_old/paint_robot_old/paint_robot_old.h | 20 + 139 files changed, 16121 insertions(+), 2 deletions(-) rename {project => project_old}/Spoolold/CMakeLists.txt (100%) rename {project => project_old}/Spoolold/Spoolold.c (100%) rename {project => project_old}/Spoolold/dmk.c (100%) rename {project => project_old}/Spoolold/flash_operation.c (100%) rename {project => project_old}/Spoolold/include/dmk.h (100%) rename {project => project_old}/Spoolold/include/flash_operation.h (100%) rename {project => project_old}/Spoolold/include/modbus.h (100%) rename {project => project_old}/Spoolold/modbus.c (100%) create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/BHBF_ROBOT.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/DLTuc.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/DLTucConfig.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_DLT_Log.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_EEPROM.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_Error_Detect.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_FDCAN.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_GPIO.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_MB_host.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_TIMER.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_UART.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_UDP.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_UpperComputer_Handler.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_client_setting.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_com_helper.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_cpu_flash.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_decode_command.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_include.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt_pub.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_pb_decode_encode.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_qspi_w25q128.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/bsp_tempature.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/pb.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/pb_common.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/pb_decode.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/pb_encode.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/readme.h create mode 100644 project_old/paint_robot_old/BASE/Inc/BSP/tcp_server.h create mode 100644 project_old/paint_robot_old/BASE/Inc/MSP/msp_Force_Sensor.h create mode 100644 project_old/paint_robot_old/BASE/Inc/MSP/msp_JTBATTERY.h create mode 100644 project_old/paint_robot_old/BASE/Inc/MSP/msp_LeiSai_ISV2_CAN.h create mode 100644 project_old/paint_robot_old/BASE/Inc/MSP/msp_MK32_1.h create mode 100644 project_old/paint_robot_old/BASE/Inc/MSP/msp_PID.h create mode 100644 project_old/paint_robot_old/BASE/Inc/MSP/msp_TL720D.h create mode 100644 project_old/paint_robot_old/BASE/Inc/MSP/msp_WH_LTE_7S0.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.c create mode 100644 project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.h create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_CV.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.options create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Error.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.options create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.options create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IO.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IV.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PID.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PV.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.options create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/msp_LS_MotorParameters.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/msp_MK32.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/msp_Motor.proto create mode 100644 project_old/paint_robot_old/BASE/Protobuf/Proto/msp_TL720D.proto create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/BHBF_ROBOT.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/DLT/DLTuc.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_DLT_Log.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_EEPROM.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_Error_Detect.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_FDCAN.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_GPIO.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_INTERCALL.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_MB_host.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_TIMER.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_UART.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_UDP.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_UpperComputer_Handler.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_client_setting.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_com_helper.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_cpu_flash.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_decode_command.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_qspi_w25q128.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/bsp_tempature.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/pb_common.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/pb_decode.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/pb_encode.c create mode 100644 project_old/paint_robot_old/BASE/Src/BSP/tcp_server.c create mode 100644 project_old/paint_robot_old/BASE/Src/MSP/msp_LeiSai_ISV2_CAN.c create mode 100644 project_old/paint_robot_old/BASE/Src/MSP/msp_MK32_1.c create mode 100644 project_old/paint_robot_old/BASE/Src/MSP/msp_PID.c create mode 100644 project_old/paint_robot_old/BASE/Src/MSP/msp_TL720D.c create mode 100644 project_old/paint_robot_old/BASE/Src/MSP/msp_WH_LTE_7S0.c rename {project => project_old}/paint_robot_old/CMakeLists.txt (100%) create mode 100644 project_old/paint_robot_old/FSM/Inc/change_line_control.h create mode 100644 project_old/paint_robot_old/FSM/Inc/fsm_state.h create mode 100644 project_old/paint_robot_old/FSM/Inc/fsm_state_control.h create mode 100644 project_old/paint_robot_old/FSM/Inc/motors.h create mode 100644 project_old/paint_robot_old/FSM/Inc/motors_power_action.h create mode 100644 project_old/paint_robot_old/FSM/Inc/paint_gun_action.h create mode 100644 project_old/paint_robot_old/FSM/Inc/robot_move_actions.h create mode 100644 project_old/paint_robot_old/FSM/Src/change_line_control.c create mode 100644 project_old/paint_robot_old/FSM/Src/fsm_state.c create mode 100644 project_old/paint_robot_old/FSM/Src/fsm_state_control.c create mode 100644 project_old/paint_robot_old/FSM/Src/motors.c create mode 100644 project_old/paint_robot_old/FSM/Src/motors_power_action.c create mode 100644 project_old/paint_robot_old/FSM/Src/paint_gun_action.c create mode 100644 project_old/paint_robot_old/FSM/Src/robot_move_actions.c create mode 100644 project_old/paint_robot_old/include/bsp_fsm.h create mode 100644 project_old/paint_robot_old/include/com.pb.h create mode 100644 project_old/paint_robot_old/include/motors.h create mode 100644 project_old/paint_robot_old/paint_robot_old.c create mode 100644 project_old/paint_robot_old/paint_robot_old.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b87e7a1..13b18ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -120,8 +120,8 @@ add_module(bspMCU bspMCU OFF OFF) add_module(RBcore project/RBcore OFF OFF) add_module(optional optional OFF OFF) add_module(Spoolend project/Spoolend OFF OFF) -add_module(Spoolold project/Spoolold OFF OFF) -add_module(paint_robot_old project/paint_robot_old OFF OFF) +add_module(Spoolold project_old/Spoolold OFF OFF) +add_module(paint_robot_old project_old/paint_robot_old OFF OFF) if(A_BUILD_MAIN) add_subdirectory(main) diff --git a/project/Spoolold/CMakeLists.txt b/project_old/Spoolold/CMakeLists.txt similarity index 100% rename from project/Spoolold/CMakeLists.txt rename to project_old/Spoolold/CMakeLists.txt diff --git a/project/Spoolold/Spoolold.c b/project_old/Spoolold/Spoolold.c similarity index 100% rename from project/Spoolold/Spoolold.c rename to project_old/Spoolold/Spoolold.c diff --git a/project/Spoolold/dmk.c b/project_old/Spoolold/dmk.c similarity index 100% rename from project/Spoolold/dmk.c rename to project_old/Spoolold/dmk.c diff --git a/project/Spoolold/flash_operation.c b/project_old/Spoolold/flash_operation.c similarity index 100% rename from project/Spoolold/flash_operation.c rename to project_old/Spoolold/flash_operation.c diff --git a/project/Spoolold/include/dmk.h b/project_old/Spoolold/include/dmk.h similarity index 100% rename from project/Spoolold/include/dmk.h rename to project_old/Spoolold/include/dmk.h diff --git a/project/Spoolold/include/flash_operation.h b/project_old/Spoolold/include/flash_operation.h similarity index 100% rename from project/Spoolold/include/flash_operation.h rename to project_old/Spoolold/include/flash_operation.h diff --git a/project/Spoolold/include/modbus.h b/project_old/Spoolold/include/modbus.h similarity index 100% rename from project/Spoolold/include/modbus.h rename to project_old/Spoolold/include/modbus.h diff --git a/project/Spoolold/modbus.c b/project_old/Spoolold/modbus.c similarity index 100% rename from project/Spoolold/modbus.c rename to project_old/Spoolold/modbus.c diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/BHBF_ROBOT.h b/project_old/paint_robot_old/BASE/Inc/BSP/BHBF_ROBOT.h new file mode 100644 index 0000000..3f1a5e9 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/BHBF_ROBOT.h @@ -0,0 +1,123 @@ +/* + * BHBF_ROBOT.h + * + * Created on: Oct 26, 2023 + * Author: shiya + */ + +#ifndef INC_BHBF_ROBOT_H_ +#define INC_BHBF_ROBOT_H_ + +#include +#include +#include +#include +#include +#include + + + +#include "BHBF_ROBOT.h" +#include "bsp_PV.pb.h" +#include "bsp_IV.pb.h" + +#include "BSP/pb.h" +#include "BSP/pb_decode.h" +#include "BSP/pb_encode.h" +#include "BSP/bsp_EEPROM.h" +#include "BSP/bsp_pb_decode_encode.h" +#include "bsp_MB_host.h" +#include "BSP/bsp_include.h" +#include "BSP/bsp_UART.h" +#include "BSP/DLTuc.h" +#include "BSP/bsp_DLT_Log.h" +#include "BSP/bsp_UDP.h" +#include "BSP/tcp_server.h" +#include "BSP/bsp_cpu_flash.h" +#include "BSP/bsp_qspi_w25q128.h" +#include "BSP/bsp_UpperComputer_Handler.h" +#include "BSP/bsp_Error_Detect.h" +#include "BSP/bsp_MB_host.h" + +#include "MSP/msp_JTBATTERY.h" +#include "MSP/msp_LeiSai_ISV2_CAN.h" +#include "MSP/msp_Force_Sensor.h" +#include "MSP/msp_TL720D.h" +#include "MSP/msp_MK32_1.h" +#include "MSP/msp_Force_Sensor.h" +#include "MSP/msp_WH_LTE_7S0.h" + + +#include "paint_gun_action.h" +#include "fsm_state_control.h" +#include "change_line_control.h" +#include "fsm_state.h" +#include "robot_move_actions.h" + +//#include "robot_state.h" +//FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 896K +//#define VECT_TAB_OFFSET 0x00020000U + + + + +#define DLTViewer 1 + + +extern bool CompareTimer_Delay(int32_t Delay); + +extern GV_struct_define GV; +extern IV_struct_define IV; +extern CV_struct_define CV; +extern PV_struct_define decoded_PV; +extern PV_struct_define decoded_PV_variable; +extern PV_struct_define _decoded_PV_temp; +typedef struct sys_timer_handler +{ + int start_timer; + int sys_current_timer_count; + int sys_timer_flag; + +}Sys_timer_handler; + +extern Sys_timer_handler timer_handler_1; +extern Sys_timer_handler timer_handler_2; +extern Sys_timer_handler timer_handler_3; +extern Sys_timer_handler timer_handler_4; + +//first start Timer, then WaitTimer +extern bool CompareTimer(int32_t DelayMiliSeconds,Sys_timer_handler * timer_handler); +extern void SystemTimer_Intialize(); +extern void GF_Timer_Count(); +extern void GF_Robot_Init(void); +extern void GF_Robot_MainLoop(void); +extern void GF_WatchDog_Loop(void); +extern int32_t speed_M_min_toE01_M_min(int32_t speedm_min); + + extern void SET_BIT_1(int32_t* num,int32_t k); + extern void SET_BIT_0(int32_t* num,int32_t k); + extern int32_t Get_BIT(int32_t* num,int32_t k); + +//A &= ~(1 << bit) + + + +extern int32_t* SystemErrorCode; +extern ErrorData* SystemErrorData; + +#define IV_Run_Mode_Maunal 0 +#define IV_Run_Mode_Automation 1 +#define IV_Run_Mode_EmergencyStop 2 +#define IV_Run_Mode_Vertical_LaneChange 3 +#define IV_Run_Mode_Horizontal_LaneChange 4 +#define IV_Run_Mode_Forward 5 +#define IV_Run_Mode_BackWard 6 +#define IV_Run_Mode_TurnLeft 7 +#define IV_Run_Mode_TurnRight 8 +#define IV_Run_Mode_HALT 9 + + + +extern int32_t SystemTimeMiliCount; //2ms加一 + +#endif /* INC_BHBF_ROBOT_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/DLTuc.h b/project_old/paint_robot_old/BASE/Inc/BSP/DLTuc.h new file mode 100644 index 0000000..d3453e7 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/DLTuc.h @@ -0,0 +1,248 @@ +/** + * @file DLTuc.h + * @author teodor + * @date 1 Jul 2022 + * @brief This file is a part of DLTuc library + * + * In this header, you can find types, Api functions, which are provided by DLTuc library + * Usefull macros, for convience usage of DLTuc library in logging purposes + * + * Requirments: + * Around ~2kB of RAM + * Check Configuration file and defines: + * DLT_TRANSMIT_RING_BUFFER_SIZE, DLT_TRANSMIT_MAX_SINGLE_MESSAGE_SIZE + * + */ + +#ifndef INC_DLT_LOGS_MCU_H_ +#define INC_DLT_LOGS_MCU_H_ + +/* + * ******************************************************************************************* + * Includes + * ******************************************************************************************* + * */ + +#include "stdint.h" +#include +#include + +#include "DLTucConfig.h" + +/* + * ******************************************************************************************* + * Exported defines + * ******************************************************************************************* + * */ + +/*@brief + * + * - convert the To strings to uint32_t + */ +#define DLT_LOG_ECUID_VALUE ((uint32_t)((((uint32_t) ((uint8_t)DLT_LOG_ECUID[0])) << 24UL) | \ + (((uint32_t) ((uint8_t)DLT_LOG_ECUID[1])) << 16UL) | \ + (((uint32_t) ((uint8_t)DLT_LOG_ECUID[2])) << 8UL) | \ + ((uint32_t)((uint8_t)DLT_LOG_ECUID[3])))) + + +#define DLT_LOG_APPID_VALUE ((uint32_t)((((uint32_t) ((uint8_t)DLT_LOG_APPID[0])) << 24UL) | \ + (((uint32_t) ((uint8_t)DLT_LOG_APPID[1])) << 16UL) | \ + (((uint32_t) ((uint8_t)DLT_LOG_APPID[2])) << 8UL) | \ + ((uint32_t)((uint8_t)DLT_LOG_APPID[3])))) + + +#define DLT_LOG_CONTEX_VALUE ((uint32_t)((((uint32_t) ((uint8_t)DLT_LOG_CONTEX[0])) << 24UL) | \ + (((uint32_t) ((uint8_t)DLT_LOG_CONTEX[1])) << 16UL) | \ + (((uint32_t) ((uint8_t)DLT_LOG_CONTEX[2])) << 8UL) | \ + ((uint32_t)((uint8_t)DLT_LOG_CONTEX[3])))) + + + + +/* + * Definitions of DLT services. + */ +#define DLT_SERVICE_ID_SET_LOG_LEVEL 0x01 /**< Service ID: Set log level */ +#define DLT_SERVICE_ID_SETRACE_STATUS 0x02 /**< Service ID: Set trace status */ +#define DLT_SERVICE_ID_GET_LOG_INFO 0x03 /**< Service ID: Get log info */ +#define DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL 0x04 /**< Service ID: Get dafault log level */ +#define DLT_SERVICE_ID_STORE_CONFIG 0x05 /**< Service ID: Store configuration */ +#define DLT_SERVICE_ID_RESETO_FACTORY_DEFAULT 0x06 /**< Service ID: Reset to factory defaults */ +#define DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS 0x07 /**< Service ID: Set communication interface status */ +#define DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH 0x08 /**< Service ID: Set communication interface maximum bandwidth */ +#define DLT_SERVICE_ID_SET_VERBOSE_MODE 0x09 /**< Service ID: Set verbose mode */ +#define DLT_SERVICE_ID_SET_MESSAGE_FILTERING 0x0A /**< Service ID: Set message filtering */ +#define DLT_SERVICE_ID_SETIMING_PACKETS 0x0B /**< Service ID: Set timing packets */ +#define DLT_SERVICE_ID_GET_LOCALIME 0x0C /**< Service ID: Get local time */ +#define DLT_SERVICE_ID_USE_ECU_ID 0x0D /**< Service ID: Use ECU id */ +#define DLT_SERVICE_ID_USE_SESSION_ID 0x0E /**< Service ID: Use session id */ +#define DLT_SERVICE_ID_USEIMESTAMP 0x0F /**< Service ID: Use timestamp */ +#define DLT_SERVICE_ID_USE_EXTENDED_HEADER 0x10 /**< Service ID: Use extended header */ +#define DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL 0x11 /**< Service ID: Set default log level */ +#define DLT_SERVICE_ID_SET_DEFAULTRACE_STATUS 0x12 /**< Service ID: Set default trace status */ +#define DLT_SERVICE_ID_GET_SOFTWARE_VERSION 0x13 /**< Service ID: Get software version */ +#define DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW 0x14 /**< Service ID: Message buffer overflow */ +#define DLT_SERVICE_ID_CALLSW_CINJECTION 0xFFF /**< Service ID: Message Injection (minimal ID) */ + +/* + * ******************************************************************************************* + * Exported types + * ******************************************************************************************* + * */ + +/**! + * \brief DltLogLevel_t + * \details Typdef used to identify the DLT log level + * */ +typedef enum +{ + DL_FATAL =1, + DL_ERROR =2, + DL_WARN =3, + DL_INFO =4, + DL_DEBUG =5, + DL_VERBOSE =6, +}DltLogLevel_t; + + + + + +/* + * ******************************************************************************************* + * Exported function - API + * ******************************************************************************************* + * */ + +/*! + ************************************************************************************************ + * \brief DLTuc_RawDataReceiveDone + * \details OPTIONAL - Use only if you need handle data receive, like Injection messages + * Call the function to inform DLTuc that Raw data packet has been received + ************************************************************************************************/ +void DLTuc_RawDataReceiveDone(uint16_t Size); + +/*! + ************************************************************************************************ + * \brief DLTuc_RegisterReceiveSerialDataFunction + * \details OPTIONAL - Use only if you need handle data receive, like Injection messages. + * - Register callback function which will be used by DLTuc to start data receive process. + * The Callback function is basicly called only after registration and if data packet has been received, + * to start again receive data packet + * \param in LLSerialRecDataFunctionC ... + ************************************************************************************************/ +void DLTuc_RegisterReceiveSerialDataFunction(void LLSerialRecDataFunctionC(uint8_t *DltLogData, uint16_t Size)); + +/*! + ************************************************************************************************ + * \brief DLTuc_RegisterInjectionDataReceivedCb + * \details OPTIONAL - Use only if you need handle data receive, like Injection messages + * Register injection data received call back + * Use the function if you want register call back function to handle the Injection messages in your application + * \param in InjectionDataRcvd ... + ************************************************************************************************/ +void DLTuc_RegisterInjectionDataReceivedCb + (void InjectionDataRcvd(uint32_t AppId, uint32_t ConId,uint32_t ServId,uint8_t *Data, uint16_t Size)); + +/*! + ************************************************************************************************ + * \brief DLTuc_RegisterTransmitSerialDataFunction + * \details This simple stack/library must be initialized by "DLTuc_RegisterTransmitSerialDataFunction" + * As a parameter must be passed function which will transmit serial data + * \param in LLSerialTrDataFunctionC transmit function pointer + ************************************************************************************************/ +void DLTuc_RegisterTransmitSerialDataFunction(void LLSerialTrDataFunctionC(uint8_t *DltLogData, uint8_t Size)); + +/*! + ************************************************************************************************ + * \brief DLTuc_RegisterGetTimeStampMsCallback + * \details function to update time stamp in library +* \param in GetSysTime - pointer to function which allow to read system time in msec + *************************************************************************************************/ +void DLTuc_RegisterGetTimeStampMsCallback(uint32_t GetSysTime(void)); + + +/*! + ************************************************************************************************ + * \brief DLTuc_MessageTransmitDone + * \details IMPORTANT!!!!! + * Call this function when the transsmision is end + * For example in "DMA transmission end callback" to inform the lib that the message is transmitted + ************************************************************************************************ + * */ +void DLTuc_MessageTransmitDone(void); + +/*! + ************************************************************************************************ + * \brief DLTuc_LogOutVarArgs + * \details default function to create DLT Log + * \param DltLogLevel_t Level - of Dlt log + * \param in AppId - size of the "DltLogData" (return value) + * \param in ContextId - pointer to the message stored in RingBuffer (return value) + * \param in Payload String to send as dlt log + * \param in ... parameters same as in printf function + *************************************************************************************************/ +void DLTuc_LogOutVarArgs(DltLogLevel_t Level, uint32_t AppId, uint32_t ContextId, uint8_t *Payload, ...); + + +/* + * ******************************************************************************************* + * Additional macros to facilitate the use of the library + * ******************************************************************************************* + * */ + +#ifdef LOGS_ENABLE + +/**! + * \brief LOGL(level, str, ...) + * \details Transmit DltLog using function DLTuc_LogOutVarArgs but user don't have to add + * log_level, DLT_LOG_APPID_VALUE and DLT_LOG_CONTEX_VALUE + * + * */ +#define LOG(str, ...)\ + if(DL_INFO <= DLT_LOG_ENABLE_LEVEL){\ + DLTuc_LogOutVarArgs(DL_INFO, DLT_LOG_APPID_VALUE, DLT_LOG_CONTEX_VALUE,(uint8_t *) str, ##__VA_ARGS__);\ + } + +/**! + * \brief LOGL(level, str, ...) + * \details Transmit DltLog using function DLTuc_LogOutVarArgs but user don't have to add DLT_LOG_APPID_VALUE and DLT_LOG_CONTEX_VALUE + * + * */ +#define LOGL(log_level, str, ...)\ + if(log_level <= DLT_LOG_ENABLE_LEVEL){\ + DLTuc_LogOutVarArgs(log_level, DLT_LOG_APPID_VALUE, DLT_LOG_CONTEX_VALUE,(uint8_t *) str, ##__VA_ARGS__);\ + } + +/**! + * @brief LOGF(log_level, str, ...) + * \details Transmit DltLog using function DLTuc_LogOutVarArgs but user don't have to add DLT_LOG_APPID_VALUE and DLT_LOG_CONTEX_VALUE + * Additionally add the name of the calling function + * + * + * */ +#define LOGF(log_level, str, ...)\ + if(log_level <= DLT_LOG_ENABLE_LEVEL){\ + DLTuc_LogOutVarArgs(log_level, DLT_LOG_APPID_VALUE, DLT_LOG_CONTEX_VALUE,(uint8_t *) "FUN:%s LOG: "str, __FUNCTION__,##__VA_ARGS__);\ + } + +/**! + * \brief LOGFF(log_level, str, ...) + * \details Transmit DltLog using function DLTuc_LogOutVarArgs but user don't have to add DLT_LOG_APPID_VALUE and DLT_LOG_CONTEX_VALUE + * Additionally add the name of the calling function and file name + * + * + * */ +#define LOGFF(log_level, str, ...)\ + if(log_level <= DLT_LOG_ENABLE_LEVEL){\ + DLTuc_LogOutVarArgs(log_level, DLT_LOG_APPID_VALUE, DLT_LOG_CONTEX_VALUE,(uint8_t *)"FILE:%s LINE: %d FUN:%s LOG: "str,__FILE__,__LINE__,__FUNCTION__,##__VA_ARGS__);\ + } + +#else +LOG(str, ...) +LOGL(log_level, str, ...) +LOGF(log_level, str, ...) +LOGFF(log_level, str, ...) +#endif + +#endif /* INC_DLT_LOGS_MCU_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/DLTucConfig.h b/project_old/paint_robot_old/BASE/Inc/BSP/DLTucConfig.h new file mode 100644 index 0000000..25df93b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/DLTucConfig.h @@ -0,0 +1,74 @@ +/** + * @file DLTuc.c + * @author teodor + * @date 1 Jul 2022 + * @brief This file is a part of DLTuc library + * + * In this header file is placed DLTuc configuration template + * + */ + +#if 1 /*Set it to "1" to enable content*/ + +#ifndef __DLT_CONFIG__ + +/*Comment this line to turn off all logs..*/ +#define LOGS_ENABLE + +/*Pass here the entry critical entry function for your RTOS or + Interrupt block functions if you want use the library from diffrent context*/ +#define DLTuc_OS_CRITICAL_START() +#define DLTuc_OS_CRITICAL_END() + + +/*Default minimum log level to transmit the log*/ +//#ifndef DLT_LOG_ENABLE_LEVEL +////#define DLT_LOG_ENABLE_LEVEL DL_VERBOSE +// #define DLT_LOG_ENABLE_LEVEL 0 +//#endif + +extern char DLT_LOG_ENABLE_LEVEL; + + +/**! +* \brief DLT_LOG_CONTEX +* \details to define the minimum level log which will printed using the debug macros +* +*/ +#ifndef DLT_LOG_CONTEX +#define DLT_LOG_CONTEX "DFLT" +#endif + +/**! +* \brief DLT_LOG_APPID +* \details to define the minimum level log which will printed using the debug macros +* +*/ +#ifndef DLT_LOG_APPID +#define DLT_LOG_APPID "0000" +#endif + +/**! +* \brief DLT_LOG_ECUID +* \details you can define here you ECUID .. +* +*/ +#define DLT_LOG_ECUID "uCID" /*Electronic Controller Unit ID*/ + +#define DLT_ECU_SW_VER 0001 + +/* +*@brief DLT_TRANSMIT_MAX_SINGLE_MESSAGE_SIZE & DLT_TRANSMIT_RING_BUFFER_SIZE +* these values define the size of the circular buffer and the maximum size of a single DLT message +* Size of out Circular DLT messages buffer is equal: DLT_TRANSMIT_MAX_SINGLE_MESSAGE_SIZE*DLT_TRANSMIT_RING_BUFFER_SIZE +*/ +#define DLT_TRANSMIT_MAX_SINGLE_MESSAGE_SIZE 255 +#define DLT_TRANSMIT_RING_BUFFER_SIZE 15 + + +#define DLT_REC_SINGLE_MESSAGE_MAX_SIZE 255 +#define DLT_RECEIVE_RING_BUFFER_SIZE 2 + +#endif //__DLT_CONFIG__ + +#endif //Content enable diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_DLT_Log.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_DLT_Log.h new file mode 100644 index 0000000..52aaabf --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_DLT_Log.h @@ -0,0 +1,16 @@ +/* + * bsp_DLT_Log.h + * + * Created on: Aug 8, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_DLT_LOG_H_ +#define INC_BSP_BSP_DLT_LOG_H_ + +#include "BHBF_ROBOT.h" + + +extern void dLT_Log_intialize(struct UARTHandler *Handler); +extern void dLT_Log_intialize_udp_tcp(); +#endif /* INC_BSP_BSP_DLT_LOG_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_EEPROM.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_EEPROM.h new file mode 100644 index 0000000..7da52ce --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_EEPROM.h @@ -0,0 +1,73 @@ +/* + * bsp_EEPROM.h + * + * Created on: Oct 26, 2023 + * Author: shiya + */ + +#ifndef INC_BSP_EEPROM_H_ +#define INC_BSP_EEPROM_H_ + + + + +#include "bsp_include.h" +#include "bsp_CV.pb.h" +#include "bsp_IAP.pb.h" + + +#define EEPROM_WP_Pin GPIO_PIN_11 +#define EEPROM_WP_GPIO_Port GPIOE +#define EEPROM_SCL_Pin GPIO_PIN_12 +#define EEPROM_SCL_GPIO_Port GPIOE +#define EEPROM_SDA_Pin GPIO_PIN_13 +#define EEPROM_SDA_GPIO_Port GPIOE + +#define AT24C512 +#ifdef AT24C512 +#define EE_MODEL_NAME "AT24C512" +#define EE_DEV_ADDR 0xA0 /* 设备地址 */ +#define EE_PAGE_SIZE 128 /* 页面大小(字节) */ +#define EE_SIZE (512*128) /* 总容量(字节) */ // not used in this progrm +#define EE_ADDR_BYTES 2 /* 地址字节个数 */ +#endif + +#define I2C_WR 0 /* 写控制bit */ +#define I2C_RD 1 /* 读控制bit */ + +////////////////////////////////////////////////////////////////// +//there are 12M eeprom in total, and the code download Address is App_Download_EEPROM_Addr +//512 Pages x 128 Bytes = 65536 Bytes = 512 kbits + + +#define GF_BSP_EEPROM_CV_struct_define_Start_Address 0 +#define IAP_struct_define_Start_Address 512 + +extern uint16_t App_Download_EEPROM_Addr; + +//返回值::1-正常;0-错误 +uint8_t GF_BSP_EEPROM_Init(void); + +uint8_t GF_BSP_EEPROM_CheckOK(void); +uint8_t GF_BSP_EEPROM_ReadBytes(uint8_t *_pReadBuf, uint16_t _usAddress, + uint16_t _usSize); +uint8_t GF_BSP_EEPROM_WriteBytes(uint8_t *_pWriteBuf, uint16_t _usAddress, + uint16_t _usSize); + + + + +CV_struct_define GF_BSP_EEPROM_Get_CV(void); +uint8_t GF_BSP_EEPROM_Set_CV(CV_struct_define cv); + +IAP_struct_define GF_BSP_EEPROM_Get_IAP(void); +uint8_t GF_BSP_EEPROM_Set_IAP(IAP_struct_define iap); + + + +PV_struct_define GF_BSP_EEPROM_Get_PV(void); + +uint8_t GF_BSP_EEPROM_Set_PV(PV_struct_define pv); + + +#endif /* INC_BSP_EEPROM_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_Error_Detect.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_Error_Detect.h new file mode 100644 index 0000000..12b92d5 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_Error_Detect.h @@ -0,0 +1,25 @@ +/* + * bsp_Error_Detect.h + * + * Created on: Oct 23, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_ERROR_DETECT_H_ +#define INC_BSP_BSP_ERROR_DETECT_H_ + + +/* Includes ------------------------------------------------------------------*/ +#include "BHBF_ROBOT.h" +#include "bsp_com_helper.h" +#include "BSP/bsp_include.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +extern HardWareController *HardWareErrorController; +/* Exported functions ------------------------------------------------------- */ +extern char Error_Detect_Enable; +extern void Error_Detect_Intialzie(uint16_t DispacherPeriod); + + +#endif /* INC_BSP_BSP_ERROR_DETECT_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_FDCAN.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_FDCAN.h new file mode 100644 index 0000000..7796c5b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_FDCAN.h @@ -0,0 +1,84 @@ +/* + * bsp_FDCAN.h + * + * Created on: Oct 26, 2023 + * Author: shiya + */ + +#ifndef INC_BSP_FDCAN_H_ +#define INC_BSP_FDCAN_H_ +#include "bsp_Error.pb.h" +#include "bsp_com_helper.h" +uint8_t GF_BSP_FDCAN_Init(void); + +void GF_BSP_FDCAN_Senddata(uint8_t FDCAN_CH, uint32_t FrameID, + uint8_t DataLength, uint8_t *Txdata); + +extern uint8_t CAN_Buf[8]; + +extern uint8_t CAN_Buf[8]; +extern uint8_t CAN_Buf_2[8]; +typedef struct _CANSendHandler +{ + uint32_t CAN_ID; + uint32_t SendListTimePeriod; + uint8_t SendLength; + uint8_t Tx_Buf[8]; + void (*CAN_Decode)(uint32_t, uint8_t*, uint32_t); + struct _CANSendHandler *pNext; +} CANSendHandler; + +typedef struct _FDCANHandler +{ + + FDCAN_HandleTypeDef *canfd; //CAN to use + struct _DispacherController *dispacherController; + + + uint8_t timeSpan; + + uint8_t SendListExists; + uint32_t SendList_Period; //时间ms + uint32_t SendList_time_Count; + + CANSendHandler *pCurrentCANSendHadler; // + void (*AddCANSendList)(struct _FDCANHandler*, uint32_t, uint8_t, uint8_t*,uint32_t,//这里是修改等待时间 + void (*CAN_Decode)(uint32_t, uint8_t*, uint32_t)); +//void CANHandlerAddTxList(FDCANHandler *handler, uint32_t CAN_ID,uint8_t SendLength, uint8_t *Tx_Buf,uint32_t sendListTimePeriod,void (*CAN_Decode)(uint32_t, uint8_t*, uint32_t)) //参数其实就是一组can数据 在FDHandler添加东西 + void (*CAN_Decode)(uint32_t, uint8_t*, uint32_t); // decode can frame, received from other devices + + void (*CAN_Send)(struct _FDCANHandler*, uint32_t, uint8_t, uint8_t*); + void (*CAN_Send_Data)(struct _FDCANHandler*); + //(uint8_t FDCAN_CH, uint32_t FrameID,uint8_t DataLength, uint8_t *Txdata) + uint8_t Rx_Buf[128]; //接收缓冲 + uint8_t Tx_Buf[128]; //发送缓冲 + uint32_t ReceivedLength;//接收长度 + uint32_t SendLength; //发送长度 + uint32_t ReceivedFrameID; //接收帧ID + uint32_t SendFrameID; //发送帧ID + +} FDCANHandler; + +extern FDCANHandler FD_CAN_1_Handler; +extern FDCANHandler FD_CAN_2_Handler; +void GF_BSP_CAN_Timer(); +void CAN_Send_t(struct _FDCANHandler *fd, uint32_t FrameID, uint8_t DataLength, + uint8_t *Txdata); +void CAN_Send_Data_t(struct _FDCANHandler *fd); + +void GF_CAN_Send_List_Send(FDCANHandler *handler); +void CANHandlerAddTxList(FDCANHandler *handler, uint32_t CAN_ID, + uint8_t SendLength, uint8_t *Tx_Buf,uint32_t sendListTimePeriod, + void (*CAN_Decode)(uint32_t, uint8_t*, uint32_t)); +void GF_BSP_CANHandler_Init(int can1_sendListPeriod, int can1_DispacherPeriod, + int can2_sendListPeriod, int can2_DispacherPeriod); +void GF_BSP_CANHandler_Init_CAN(FDCANHandler *handler, + FDCAN_HandleTypeDef *canfd, int sendListPeriod, int DispacherPeriod); + +void DecodeMotorCAN(uint32_t canID, uint8_t *buffer, uint32_t length); + +extern FDCANHandler FD_CAN_1_Handler; +extern FDCANHandler FD_CAN_2_Handler; +extern int32_t CAN_ID; +extern int32_t CAN_ID_2; +#endif /* INC_BSP_FDCAN_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_GPIO.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_GPIO.h new file mode 100644 index 0000000..dfc4c76 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_GPIO.h @@ -0,0 +1,18 @@ +/* + * bsp_GPIO.h + * + * Created on: Oct 26, 2023 + * Author: shiya + */ + +#ifndef INC_BSP_GPIO_H_ +#define INC_BSP_GPIO_H_ + +#include "bsp_include.h" + +uint8_t GF_BSP_GPIO_Init(void); +void GF_BSP_GPIO_SetIO(uint8_t IO_Index,uint8_t Level); +uint8_t GF_BSP_GPIO_ReadIO(uint8_t IO_Index); +uint8_t GF_BSP_GPIO_ToggleIO(uint8_t IO_Index); + +#endif /* INC_BSP_GPIO_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_MB_host.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_MB_host.h new file mode 100644 index 0000000..9503578 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_MB_host.h @@ -0,0 +1,50 @@ +#ifndef __BSP_MB_HOST_H__ +#define __BSP_MB_HOST_H__ + +/* 包含头文件 ----------------------------------------------------------------*/ + +/* 类型定义 ------------------------------------------------------------------*/ + +/* 宏定义 --------------------------------------------------------------------*/ +#define MB_SLAVEADDR 0x0001 //从机地址 +#define MB_REG_ADDR 0 //寄存器地址(离散、线圈) +#define HoldingReg 0 //保持寄存器 +#define InputRegReg 0x0020 //输入寄存器 +#include "bsp_include.h" +#include "BSP/bsp_UART.h" + +/* 扩展变量 ------------------------------------------------------------------*/ + typedef struct +{ + + uint16_t DATA_01H; + uint16_t DATA_02H; + uint16_t DATA_03H; + + uint16_t DATA_04H; + uint16_t DATA_05H; + uint16_t DATA_06H; + uint8_t DATA_10H[64]; + +}MB_REG_DATA; + +//; +extern uint8_t MB_rx_flag; +extern uint16_t Read_Reg_Num; + +/* 函数声明 ------------------------------------------------------------------*/ +uint16_t MB_CRC16(uint8_t *pushMsg, uint16_t usDataLen); +void MB_ReadCoil(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _num); +void MB_WriteCoil(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _sta); +void MB_ReadInput(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _num); +void MB_ReadHoldingReg(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _num); +void MB_ReadInputReg(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _num); +void MB_WriteHoldingReg(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _data); +//void MB_WriteNumHoldingReg(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _num,uint8_t *_databuf) +void MB_WriteNumHoldingReg(uint8_t* Tx_Buf,uint8_t* TxCount_t,uint8_t _addr, uint16_t _reg, uint16_t _num,uint8_t *_databuf); +void MB_WriteNumCoil(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _num, uint8_t *_databuf); + +#endif /* __BSP_MB_HOST_H__ */ + +/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_TIMER.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_TIMER.h new file mode 100644 index 0000000..9f1b96f --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_TIMER.h @@ -0,0 +1,17 @@ +/* + * bsp_TIMER.h + * + * Created on: Oct 26, 2023 + * Author: shiya + */ + +#ifndef INC_BSP_TIMER_H_ +#define INC_BSP_TIMER_H_ + +#include "bsp_include.h" + +uint8_t GF_BSP_TIMER_Init(void); +void GF_BSP_TIMER_DelayUS(uint32_t n); + + +#endif /* INC_BSP_TIMER_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UART.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UART.h new file mode 100644 index 0000000..e7bdb38 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UART.h @@ -0,0 +1,128 @@ + + +#ifndef INC_BSP_UART_H_ +#define INC_BSP_UART_H_ + +#include "BSP/bsp_include.h" +#include "main.h" +#include "bsp_Error.pb.h" +#define UART_Transmit_MAX_NUM 1024 +#define UART_Receive_MAX_NUM 100 + +extern struct UARTHandler RS_485_1_UART_Handler; +extern struct UARTHandler RS_485_2_UART_Handler; +extern struct UARTHandler RS_485_3_UART_Handler; +extern struct UARTHandler RS_485_4_UART_Handler; +extern struct UARTHandler InterCall_DEBUG_UART_Handler; +extern struct UARTHandler E28_SBUS_UART_Handler; +extern struct UARTHandler LTE_7S0_Serial_UART_Handler; + + + +#if defined (hlpuart1Exit) + extern struct UARTHandler LPUART1_UART_Handler; + +#endif + +uint8_t GF_BSP_UART_Init(void); + +void GF_BSP_UARTHandlers_Intialize( + int32_t RS485_1_WaitTime, + int32_t RS485_2_WaitTime, + int32_t RS485_3_WaitTime, + int32_t RS485_4_WaitTime, + int32_t LTE_7S0_Serial_WaitTime, + int32_t InterCall_DEBUG_WaitTime, + int32_t E28_SBUS_WaitTime, + int32_t LPUART1_UART_WaitTime, + int32_t RS485_1_Dispacher_Time, + int32_t RS485_2_Dispacher_Time, + int32_t RS485_3_Dispacher_Time, + int32_t RS485_4_Dispacher_Time, + int32_t LTE_7S0_Serial_Dispacher_Time, + int32_t InterCall_DEBUG_Dispacher_Time, + int32_t E28_SBUS_Dispacher_Time, + int32_t LPUART1_UART_Dispacher_Time +); + +//串行发送完成后才能发送第二帧数据,没有做缓冲,如未发送完成,第二次发送无效,丢弃发送数据 +void GF_BSP_UART_Transmit(const uint8_t RS485_Index,const uint8_t *pData, uint16_t Size); + + + + +typedef struct UARTSendHandler +{ + uint16_t SendLength; + uint16_t SendListTimePeriod; + uint8_t Tx_Buf[502]; + void (*UART_Decode)(uint8_t*, uint16_t); // 发送缓存 + struct UARTSendHandler* pNext; +}UARTSendHandler; + + +struct UARTHandler +{ + char startCountFlag; //indicate that to start counting + char send_finished;//indicate decode finished or not + char decode_finished;//indicate decode finished or not + uint8_t tmp_Rx_Buf[2]; // temporary data to store received data + + uint32_t Wait_time; // the time to wait + //uint32_t Send_time; + //uint32_t count; + uint32_t Wait_Time_Count; + uint32_t SendList_time_Count; + + uint32_t SendList_Period; + uint8_t SendListExists; + + UART_HandleTypeDef* uart; //UART to use + unsigned char timeSpan; // timer elapsed time + uint8_t Rx_Buf[2048]; // 接收缓存,最大256字节 + uint8_t Tx_Buf[2048]; //发送缓存 157,864 + uint16_t TxCount; + + uint16_t RxCount; + + + //(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size) + void (*UART_Tx)(struct UARTHandler*); //void UART_Tx(uint8_t *Tx_Buf,uint16_t TxCount); + void (*UART_Rx)(struct UARTHandler*); + void (*UART_Decode)(uint8_t*, uint16_t); //Decode Rx_Buf + UARTSendHandler *pCurrentUARTSendHadler; // + void (*AddSendList)(struct UARTHandler*, uint8_t*, uint16_t,uint32_t,//这里是修改等待时间 + void (*UART_Decode)(uint8_t*, uint16_t)); + + + + struct _DispacherController *dispacherController; + +// //got a dispacher alone +// Dispatcher *pHead;// = NULL; //环形链表中的数据头指针 +// Dispatcher *pTail;// = NULL; //环形链表中的数据尾指针 +// uint16_t DispacherNumber;// = 0; +// +// uint16_t DispacherCallPeriod; //= 100; //2ms 一次, +// +// uint16_t Dispacher_Counter;// = 0; +// uint16_t Dispacher_Enable;// = 0; +// void(*Add_Dispatcher_List)(struct UARTHandler *uartHandler,void (*dispache)(void));//UART的调度程序 +// void(*Dispatcher_Run)(struct UARTHandler *uartHandler);//UART的调度程序 + + + + +}; + +void UARTHandlerTx(struct UARTHandler *uartHandler); +void UARTHandlerRX(struct UARTHandler *uartHandler); +//void IntializeUARTHandler(struct UARTHandler *uartHandler, UART_HandleTypeDef uart,int32_t WaitTime,unsigned char timeSpan); +void Counting(struct UARTHandler *uartHandler); + + +void IntializeUARTHandler(struct UARTHandler *uartHandler, + UART_HandleTypeDef *uart, int32_t WaitTime, unsigned char timeSpan,int32_t Dispacher_Time); +void GF_BSP_UART_Timer(); + +#endif /* INC_BSP_UART_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UDP.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UDP.h new file mode 100644 index 0000000..0d6b4b7 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UDP.h @@ -0,0 +1,23 @@ +/* + * bsp_UDP.h + * + * Created on: Aug 13, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_UDP_H_ +#define INC_BSP_BSP_UDP_H_ + +void udp_client_init(void); + + +void udp_dlt_send_back(char *pData,uint16_t Size); +void udp_cmd_send_back(char *pData, uint16_t Size); + +typedef void (*DLT_DecodeFuncPtr)(uint8_t*, uint16_t); +void udp_send_by_pcb(struct udp_pcb * upcb,char *pData, uint16_t Size); +// 再用该类型声明变量 +extern DLT_DecodeFuncPtr UDP_DLT_ReceivedCallback; +extern int8_t is_udp_GV_update_loop_enalbed; + +#endif /* INC_BSP_BSP_UDP_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UpperComputer_Handler.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UpperComputer_Handler.h new file mode 100644 index 0000000..198b159 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_UpperComputer_Handler.h @@ -0,0 +1,27 @@ +/* + * bsp_desulfurizer_handler.h + * + * Created on: Jul 29, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_UPPERCOMPUTER_HANDLER_H_ +#define INC_BSP_BSP_UPPERCOMPUTER_HANDLER_H_ +#include +#include +#include "bsp_MB_host.h" +#include "stdio.h" +#include "BSP/bsp_UART.h" +#include "usart.h" +#include "gpio.h" + + +extern struct UARTHandler *desulfurizer_message_UART_Handler; +void upper_Computer_UART_Handler_intialize(struct UARTHandler *Handler); + +void decode_command_from_computer(uint8_t *buffer, uint16_t length); + + +void send_data_to_upper_computer(double Angle, double WireLength, + double Thickness, char IsFittingPoint,char isMqtt,struct UARTHandler *send_UART_Handler); +#endif /* INC_BSP_BSP_UPPERCOMPUTER_HANDLER_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_client_setting.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_client_setting.h new file mode 100644 index 0000000..1b13112 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_client_setting.h @@ -0,0 +1,13 @@ +/* + * bsp_pv_setting.h + * + * Created on: Jan 8, 2025 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_CLIENT_SETTING_H_ +#define INC_BSP_BSP_CLIENT_SETTING_H_ +#include "BHBF_ROBOT.h" + +void client_setting_intialize(struct UARTHandler *Handler); +#endif /* INC_BSP_BSP_CLIENT_SETTING_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_com_helper.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_com_helper.h new file mode 100644 index 0000000..a0b0d80 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_com_helper.h @@ -0,0 +1,82 @@ +/* + * bsp_com_helper.h + * + * Created on: Oct 9, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_COM_HELPER_H_ +#define INC_BSP_BSP_COM_HELPER_H_ +#include "bsp_include.h" + + +typedef struct _Dispatcher +{ + //uint8_t IsDeleted; + void (*dispache)(void); + + //struct _Dispatcher* pBefore; + struct _Dispatcher* pNext; +}Dispatcher; + + +//通讯链表节点结构体 +typedef struct _ComHardWare +{ + //void (*dispache)(void); + char Name[50]; + char IsOnline; + uint32_t BitFlag; + struct _ComHardWare* pNext; +}ComHardWare; + + + + + +typedef struct _DispacherController +{ + Dispatcher *pHead; // = NULL; //环形链表中的数据头指针 + Dispatcher *pTail; // = NULL; //环形链表中的数据尾指针 + uint16_t DispacherNumber; // = 0; + uint16_t DispacherCallTime; // + uint16_t Dispacher_Counter; // = 0; + uint16_t Dispacher_Enable; // = 0 disable 1 enable + void (*Add_Dispatcher_List)(struct _DispacherController* , + void (*dispacher)(void)); //UART的调度程序 + void (*Dispatcher_Run)(struct _DispacherController* ); //UART的调度程序 + +}DispacherController; + +typedef struct _HardWareController +{ + struct _ComHardWare *pComHWHead; + struct _ComHardWare *pComHWTail; + uint16_t HardWare_Check_Counter; + uint16_t DispacherCallTime; //= 100; //2ms 一次, + void (*Add_PCOMHardWare)(struct _HardWareController *, char* , char ,uint32_t); + void (*PCOMHardWare_Check)(struct _HardWareController *); + int (*Set_PCOMHardWare)(struct _HardWareController *, char* , char ); + + +} HardWareController; + + + + + void Dispatch_t(DispacherController *uartHandler); + +void Dispatcher_List_Add_t(DispacherController *uartHandler,void (*dispache)(void)); +// void Dispatcher_List_Add_t(DispacherController *uartHandler, +// void (*dispache)(void),void (*Decode)(uint8_t*, uint16_t)); +// void ComHardWare_List_Add_t(HardWareController *uartHandler, char *name,char value); + + void PCOMHardWare_Check_t(HardWareController *uartHandler); + +int Set_PCOMHardWare_t(HardWareController *uartHandler, char *name, char value); + +void ComHardWare_List_Add_t(HardWareController *uartHandler, char *name, + char value,uint32_t bitFlag); + + +#endif /* INC_BSP_BSP_COM_HELPER_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_cpu_flash.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_cpu_flash.h new file mode 100644 index 0000000..898c10b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_cpu_flash.h @@ -0,0 +1,66 @@ +/* + * bsp_cpu_flash.h + * + * Created on: Aug 28, 2024 + * Author: akeguo + */ + +#ifndef SRC_BSP_BSP_CPU_FLASH_H_ +#define SRC_BSP_BSP_CPU_FLASH_H_ + +#include "main.h" + +#include +#include "quadspi.h" + +#define ENABLE_INT() __set_PRIMASK(0) /* 使能全局中断 */ +#define DISABLE_INT() __set_PRIMASK(1) /* 禁止全局中断 */ + + +#define CPU_FLASH_BASE_ADDR (uint32_t)(FLASH_BASE) /* 0x08000000 */ +#define CPU_FLASH_END_ADDR (uint32_t)(0x081FFFFF) + +#define CPU_FLASH_SIZE (2 * 1024 * 1024) /* FLASH总容量 */ +#define CPU_FLASH_SECTOR_SIZE (128 * 1024) /* 扇区大小,字节 */ + +/* Base address of the Flash sectors Bank 1 */ +#define ADDR_FLASH_SECTOR_0_BANK1 ((uint32_t)0x08000000) /* Base @ of Sector 0, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_1_BANK1 ((uint32_t)0x08020000) /* Base @ of Sector 1, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_2_BANK1 ((uint32_t)0x08040000) /* Base @ of Sector 2, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_3_BANK1 ((uint32_t)0x08060000) /* Base @ of Sector 3, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_4_BANK1 ((uint32_t)0x08080000) /* Base @ of Sector 4, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_5_BANK1 ((uint32_t)0x080A0000) /* Base @ of Sector 5, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_6_BANK1 ((uint32_t)0x080C0000) /* Base @ of Sector 6, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_7_BANK1 ((uint32_t)0x080E0000) /* Base @ of Sector 7, 128 Kbytes */ + +/* Base address of the Flash sectors Bank 2 */ +#define ADDR_FLASH_SECTOR_0_BANK2 ((uint32_t)0x08100000) /* Base @ of Sector 0, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_1_BANK2 ((uint32_t)0x08120000) /* Base @ of Sector 1, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_2_BANK2 ((uint32_t)0x08140000) /* Base @ of Sector 2, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_3_BANK2 ((uint32_t)0x08160000) /* Base @ of Sector 3, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_4_BANK2 ((uint32_t)0x08180000) /* Base @ of Sector 4, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_5_BANK2 ((uint32_t)0x081A0000) /* Base @ of Sector 5, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_6_BANK2 ((uint32_t)0x081C0000) /* Base @ of Sector 6, 128 Kbytes */ +#define ADDR_FLASH_SECTOR_7_BANK2 ((uint32_t)0x081E0000) /* Base @ of Sector 7, 128 Kbytes */ + +#define FLASH_IS_EQU 0 /* Flash内容和待写入的数据相等,不需要擦除和写操作 */ +#define FLASH_REQ_WRITE 1 /* Flash不需要擦除,直接写 */ +#define FLASH_REQ_ERASE 2 /* Flash需要先擦除,再写 */ +#define FLASH_PARAM_ERR 3 /* 函数参数错误 */ + + +#define App_Start_Addr 0x08000000 +#define App_Run_Addr 0x08020000 +#define App_Download_Addr 0x08080000 // ADDR_FLASH_SECTOR_4_BANK1 + + + +uint8_t bsp_ReadCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize); +uint8_t bsp_WriteCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize); +uint8_t bsp_CmpCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpBuf, uint32_t _ulSize); +void JumpToApp(void); +void Copy_Peripheral_Download_Flash_to_App_Start(uint32_t totalBytes); +uint8_t bsp_EraseCpuFlash(uint32_t _ulFlashAddr); +void Erase_App_Download_Flash_Addr(); +void Copy_Download_Flash_to_Start(); +#endif /* SRC_BSP_BSP_CPU_FLASH_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_decode_command.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_decode_command.h new file mode 100644 index 0000000..494370a --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_decode_command.h @@ -0,0 +1,39 @@ +/* + * bsp_decode_command.h + * + * Created on: Sep 24, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_DECODE_COMMAND_H_ +#define INC_BSP_BSP_DECODE_COMMAND_H_ +#include "main.h" +#include "msp_WH_LTE_7S0.h" + +#include "pb_decode.h" +#include "pb_encode.h" +#include "bsp_include.h" +#include "pb.h" + +#include "bsp_Cmd.pb.h" +#include +#include +#include + +#include "BHBF_ROBOT.h" +#include "bsp_cpu_flash.h" +#include +#include +#include "bsp_ReCmd.pb.h" +#include "bsp_IV.pb.h" + +void send_received_data_to_upper_computer(uint8_t *buffer, uint16_t length); +void decode_command_and_feedback(uint8_t *buffer, uint16_t length, char sendWay, + struct UARTHandler *send_Handler); + +extern void WrapInCmdAndSend(ReCmd send_Cmd, uint8_t *buf, int8_t sendWay,struct UARTHandler *send_Handler); + + +extern void WrapInCmdAndSendMessage(ReCmd send_Cmd,int8_t functionNum,int8_t isSuccess, uint8_t *buf, int8_t sendWay, + struct UARTHandler *send_Handler); +#endif /* INC_BSP_BSP_DECODE_COMMAND_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_include.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_include.h new file mode 100644 index 0000000..a8d831f --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_include.h @@ -0,0 +1,57 @@ +/* + * bsp_include.h + * + * Created on: Oct 26, 2023 + * Author: shiya + */ + +#ifndef INC_BSP_INCLUDE_H_ +#define INC_BSP_INCLUDE_H_ + +#include "main.h" +#include "dma.h" +#include "fdcan.h" +#include "i2c.h" +#include "tim.h" +#include "usart.h" +#include "gpio.h" + +#include "bsp_EEPROM.h" +#include "bsp_GPIO.h" +#include "bsp_FDCAN.h" + +#include "bsp_TIMER.h" +#include "bsp_PV.pb.h" + +#include "bsp_GV.pb.h" +#include "bsp_CV.pb.h" +#include "pb.h" +#include "pb_decode.h" +#include "pb_common.h" +#include "DLTuc.h" +//一个中断回调函数支持多少个回调函数链接 +#define DF_BSP_InterCall_Num 20 + +//一共支持多少种中断函数 +#define DF_BSP_InterCall_Type_Num 11 + +enum DF_BSP_InterCall_Type +{ + DF_BSP_InterCall_FDCAN1_RxFifo0Callback = 0, + DF_BSP_InterCall_FDCAN2_RxFifo0Callback, + DF_BSP_InterCall_RS485_1_RxCpltCallback, + DF_BSP_InterCall_RS485_2_RxCpltCallback, + DF_BSP_InterCall_RS485_3_RxCpltCallback, + DF_BSP_InterCall_RS485_4_RxCpltCallback, + DF_BSP_InterCall_DEBUG_RxCpltCallback, + DF_BSP_InterCall_E22_Serial_RxCpltCallback, + DF_BSP_InterCall_E28_SBUS_RxFifo0Callback, + DF_BSP_InterCall_TIM1_100ms_PeriodElapsedCallback, + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback +}; + +uint8_t GF_BSP_Interrupt_Add_CallBack(enum DF_BSP_InterCall_Type _type, + void (*_fn)(void)); +void GF_BSP_Interrupt_Run_CallBack(enum DF_BSP_InterCall_Type _type); + +#endif /* INC_BSP_INCLUDE_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt.h new file mode 100644 index 0000000..f7bb15d --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt.h @@ -0,0 +1,36 @@ + +#ifndef __BSP_MQTT_H +#define __BSP_MQTT_H + +/*----------------------------------------------------------- + * Includes files + *----------------------------------------------------------*/ + +/*----------------------------------------------------------- + * Exported constants + *----------------------------------------------------------*/ + + +/*----------------------------------------------------------- + * Exported macro + *----------------------------------------------------------*/ + +/*----------------------------------------------------------- + * Exported function + *----------------------------------------------------------*/ +/*! +* @brief 封装 MQTT 初始化接口 +* 执行条件:无 +* +* @retval: 无 +*/ +void bsp_mqtt_init(void); +void bsp_mqtt_test(void); + + +extern void bsp_mqtt_pub_send(char topic[],char buf[],size_t len); + + +#include "bsp_pb_decode_encode.h" + +#endif /* __BSP_WOLFSSL_H */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt_pub.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt_pub.h new file mode 100644 index 0000000..3764cb0 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_mqtt_pub.h @@ -0,0 +1,26 @@ +/* + * bsp_mqtt_pub.h + * + * Created on: Jul 9, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_MQTT_PUB_H_ +#define INC_BSP_BSP_MQTT_PUB_H_ + +#include "bsp_pb_decode_encode.h" +#include "pb_decode.h" +#include "pb_encode.h" +#include "bsp_CV.pb.h" +#include "bsp_pb_decode_encode.h" +#include "BSP/bsp_EEPROM.h" + + + + + +extern void log_info(char logger[], char message[]); +extern void log_debug(char logger[], char message[]); +extern void log_err(char logger[], char message[]); + +#endif /* INC_BSP_BSP_MQTT_PUB_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_pb_decode_encode.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_pb_decode_encode.h new file mode 100644 index 0000000..8480dbe --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_pb_decode_encode.h @@ -0,0 +1,51 @@ +/* + * bsp_pb_decode_encode.h + * + * Created on: Jul 5, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_PB_DECODE_ENCODE_H_ +#define INC_BSP_BSP_PB_DECODE_ENCODE_H_ + +#include +#include +#include +#include + +#include "pb_decode.h" +#include "pb_encode.h" +#include "pb.h" +#include "bsp_CV.pb.h" +#include "bsp_GV.pb.h" +#include "msp_MK32.pb.h" +#include "msp_Motor.pb.h" +#include "bsp_PV.pb.h" +#include "bsp_CV.pb.h" +#include "bsp_CV.pb.h" +#include "pb_common.h" + +#include "bsp_IAP.pb.h" +IAP_struct_define pb_decode_IAP(uint8_t *buf, size_t length); + +typedef struct pb_buffer_arg +{ + /* Buffer to be written, or reference to read buffer */ + void const *buf; + /* Length of buf */ + size_t buf_len; +} pb_buffer_arg; + + + bool pb_encode_string_cb(pb_ostream_t *stream, const pb_field_t *field, void *const *arg); + bool pb_decode_string_cb(pb_istream_t *stream, const pb_field_t *field, void **arg); + + +extern CV_struct_define pb_decode_CV(char *buf, size_t length); +extern void Test_CV(); + +//extern void pb_encode_TraceMessage(char buf[], size_t buf_len,size_t* len,TraceLevel traceLevel, char logger[], char message[] ); +void pb_encode_TraceMessage(char buf[],size_t buf_len, size_t* len, + char traceLevel[], char logger[], char message[] ); + +#endif /* INC_BSP_BSP_PB_DECODE_ENCODE_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_qspi_w25q128.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_qspi_w25q128.h new file mode 100644 index 0000000..61791e4 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_qspi_w25q128.h @@ -0,0 +1,107 @@ +/* + * bsp_quadspi_W25Q128.h + * + * Created on: Apr 21, 2021 + * Author: Administrator + * + * 该bsp用于华邦的w25q128JV,跟华邦的w25q128JV不一样 + * 坑爹的 + */ + +#ifndef BSP_QSPI_W25Q128_H_ +#define BSP_QSPI_W25Q128_H_ + + +#include "quadspi.h" +#include "stdio.h" + +/* 宏定义 --------------------------------------------------------------------*/ +#define FLASH_BEGIN_ADDRESS 0x00000 + +#define CODE_DOWNLOAD_FLASH_BEGIN_ADDRESS 0x00000 +#define CODE_FLASH_STORAGE_SIZE 1024*1024 // 留下1M的空间存储数据 + +#define W25Q128FV_FLASH_SIZE 0x1000000 /* 128 MBits => 16MBytes */ +#define W25Q128FV_BLOCK_SIZE 0x10000 /* 256 Blocks of 64KBytes */ +#define W25Q128FV_HALF_BLOCK_SIZE 0x8000 /* 128 Blocks of 32KBytes */ +#define W25Q128FV_SECTOR_SIZE 0x1000 /* 4096 sectors of 4kBytes */ +#define W25Q128FV_PAGE_SIZE 0x100 /* 65536 pages of 256 bytes */ + +#define W25Q128FV_DUMMY_CYCLES_READ 4 +#define W25Q128FV_DUMMY_CYCLES_READ_QUAD 10 + +#define W25Q128FV_BULK_ERASE_MAX_TIME 250000//ms +#define W25Q128FV_SECTOR_ERASE_MAX_TIME 3000 +#define W25Q128FV_SUBSECTOR_ERASE_MAX_TIME 800 + +#define W25Q128FV_FLASH_ID 0XEF4018 +/* W25Q128FV 指令 */ +/* 复位操作 */ +#define RESET_ENABLE_CMD 0x66 +#define RESET_MEMORY_CMD 0x99 + +#define ENTER_QPI_MODE_CMD 0x38 +#define EXIT_QPI_MODE_CMD 0xFF + +/* 读取ID指令 */ +#define READ_ID_CMD 0x90 +#define DUAL_READ_ID_CMD 0x92 +#define QUAD_READ_ID_CMD 0x94 +#define READ_JEDEC_ID_CMD 0x9F + +/* 读操作指令 */ +#define READ_CMD 0x03 +#define FAST_READ_CMD 0x0B +#define DUAL_OUT_FAST_READ_CMD 0x3B +#define DUAL_INOUT_FAST_READ_CMD 0xBB +#define QUAD_OUT_FAST_READ_CMD 0x6B +#define QUAD_INOUT_FAST_READ_CMD 0xEB + +/* 写使能操作指令 */ +#define WRITE_ENABLE_CMD 0x06 +#define WRITE_DISABLE_CMD 0x04 + +/* 读写状态寄存器操作指令 */ +#define READ_STATUS_REG1_CMD 0x05 +#define READ_STATUS_REG2_CMD 0x35 +#define READ_STATUS_REG3_CMD 0x15 + +#define WRITE_STATUS_REG1_CMD 0x01 +#define WRITE_STATUS_REG2_CMD 0x31 +#define WRITE_STATUS_REG3_CMD 0x11 + +/* 编程指令 */ +#define PAGE_PROG_CMD 0x02 +#define QUAD_INPUT_PAGE_PROG_CMD 0x32 + +/* 擦除Flash指令 */ +#define SECTOR_ERASE_CMD 0x20 +#define BLOCK_32KB_ERASE_CMD 0x52 +#define BLOCK_64KB_ERASE_CMD 0xD8 +#define CHIP_ERASE_CMD 0xC7 + +#define PROG_ERASE_RESUME_CMD 0x7A +#define PROG_ERASE_SUSPEND_CMD 0x75 + +/* 状态寄存器标志位 */ +#define W25Q128FV_FSR_BUSY ((uint8_t)0x01) /* busy */ +#define W25Q128FV_FSR_WREN ((uint8_t)0x02) /* write enable */ +#define W25Q128FV_FSR_QE ((uint8_t)0x02) /* quad enable */ + +/* Flash 状态码*/ +#define FLASH_OK ((uint8_t)0x00) +#define FLASH_ERROR ((uint8_t)0x01) +#define FLASH_BUSY ((uint8_t)0x02) +#define FLASH_NOT_SUPPORTED ((uint8_t)0x04) +#define FLASH_SUSPENDED ((uint8_t)0x08) + + + +uint32_t QSPI_W25Qx_ReadID(void); +void QSPI_W25Qx_Reset_Memory(); +void QSPI_W25Qx_EraseSector(uint32_t _SectorAddr); +uint8_t QSPI_W25Qx_Write_Buffer(uint8_t *_pBuf,uint32_t _write_Addr,uint16_t _write_Size); +void QSPI_W25Qx_Read_Buffer(uint8_t *_pBuf,uint32_t _read_Addr,uint32_t _read_Size); +void QSPI_W25Qx_EraseDownLoadFlash(); +void user_Assert(char *file,uint32_t line); +#endif /* BSP_QSPI_W25Q128_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/bsp_tempature.h b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_tempature.h new file mode 100644 index 0000000..a93fdb0 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/bsp_tempature.h @@ -0,0 +1,19 @@ +/* + * bsp_adc.h + * + * Created on: Feb 21, 2025 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_TEMPATURE_H_ +#define INC_BSP_BSP_TEMPATURE_H_ + + +#include "main.h" +#include "DLTuc.h" + +int32_t read_temperature(); +void ADC_Intialize(); + +extern int32_t * tempature; +#endif /* INC_BSP_BSP_TEMPATURE_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/pb.h b/project_old/paint_robot_old/BASE/Inc/BSP/pb.h new file mode 100644 index 0000000..ef3d83e --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/pb.h @@ -0,0 +1,917 @@ +/* Common parts of the nanopb library. Most of these are quite low-level + * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. + */ + +#ifndef PB_H_INCLUDED +#define PB_H_INCLUDED + +/***************************************************************** + * Nanopb compilation time options. You can change these here by * + * uncommenting the lines, or on the compiler command line. * + *****************************************************************/ + +/* Enable support for dynamically allocated fields */ +/* #define PB_ENABLE_MALLOC 1 */ + +/* Define this if your CPU / compiler combination does not support + * unaligned memory access to packed structures. Note that packed + * structures are only used when requested in .proto options. */ +/* #define PB_NO_PACKED_STRUCTS 1 */ + +/* Increase the number of required fields that are tracked. + * A compiler warning will tell if you need this. */ +/* #define PB_MAX_REQUIRED_FIELDS 256 */ + +/* Add support for tag numbers > 65536 and fields larger than 65536 bytes. */ +/* #define PB_FIELD_32BIT 1 */ + +/* Disable support for error messages in order to save some code space. */ +/* #define PB_NO_ERRMSG 1 */ + +/* Disable support for custom streams (support only memory buffers). */ +/* #define PB_BUFFER_ONLY 1 */ + +/* Disable support for 64-bit datatypes, for compilers without int64_t + or to save some code space. */ +/* #define PB_WITHOUT_64BIT 1 */ + +/* Don't encode scalar arrays as packed. This is only to be used when + * the decoder on the receiving side cannot process packed scalar arrays. + * Such example is older protobuf.js. */ +/* #define PB_ENCODE_ARRAYS_UNPACKED 1 */ + +/* Enable conversion of doubles to floats for platforms that do not + * support 64-bit doubles. Most commonly AVR. */ +/* #define PB_CONVERT_DOUBLE_FLOAT 1 */ + +/* Check whether incoming strings are valid UTF-8 sequences. Slows down + * the string processing slightly and slightly increases code size. */ +/* #define PB_VALIDATE_UTF8 1 */ + +/* This can be defined if the platform is little-endian and has 8-bit bytes. + * Normally it is automatically detected based on __BYTE_ORDER__ macro. */ +/* #define PB_LITTLE_ENDIAN_8BIT 1 */ + +/* Configure static assert mechanism. Instead of changing these, set your + * compiler to C11 standard mode if possible. */ +/* #define PB_C99_STATIC_ASSERT 1 */ +/* #define PB_NO_STATIC_ASSERT 1 */ + +/****************************************************************** + * You usually don't need to change anything below this line. * + * Feel free to look around and use the defined macros, though. * + ******************************************************************/ + + +/* Version of the nanopb library. Just in case you want to check it in + * your own program. */ +#define NANOPB_VERSION "nanopb-0.4.8-dev" + +/* Include all the system headers needed by nanopb. You will need the + * definitions of the following: + * - strlen, memcpy, memset functions + * - [u]int_least8_t, uint_fast8_t, [u]int_least16_t, [u]int32_t, [u]int64_t + * - size_t + * - bool + * + * If you don't have the standard header files, you can instead provide + * a custom header that defines or includes all this. In that case, + * define PB_SYSTEM_HEADER to the path of this file. + */ +#ifdef PB_SYSTEM_HEADER +#include PB_SYSTEM_HEADER +#else +#include +#include +#include +#include +#include + +#ifdef PB_ENABLE_MALLOC +#include +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macro for defining packed structures (compiler dependent). + * This just reduces memory requirements, but is not required. + */ +#if defined(PB_NO_PACKED_STRUCTS) + /* Disable struct packing */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#elif defined(__GNUC__) || defined(__clang__) + /* For GCC and clang */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed __attribute__((packed)) +#elif defined(__ICCARM__) || defined(__CC_ARM) + /* For IAR ARM and Keil MDK-ARM compilers */ +# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +# define pb_packed +#elif defined(_MSC_VER) && (_MSC_VER >= 1500) + /* For Microsoft Visual C++ */ +# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +# define PB_PACKED_STRUCT_END __pragma(pack(pop)) +# define pb_packed +#else + /* Unknown compiler */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#endif + +/* Detect endianness */ +#ifndef PB_LITTLE_ENDIAN_8BIT +#if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ + defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ + defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)) \ + && CHAR_BIT == 8 +#define PB_LITTLE_ENDIAN_8BIT 1 +#endif +#endif + +/* Handly macro for suppressing unreferenced-parameter compiler warnings. */ +#ifndef PB_UNUSED +#define PB_UNUSED(x) (void)(x) +#endif + +/* Harvard-architecture processors may need special attributes for storing + * field information in program memory. */ +#ifndef PB_PROGMEM +#ifdef __AVR__ +#include +#define PB_PROGMEM PROGMEM +#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) +#else +#define PB_PROGMEM +#define PB_PROGMEM_READU32(x) (x) +#endif +#endif + +/* Compile-time assertion, used for checking compatible compilation options. + * If this does not work properly on your compiler, use + * #define PB_NO_STATIC_ASSERT to disable it. + * + * But before doing that, check carefully the error message / place where it + * comes from to see if the error has a real cause. Unfortunately the error + * message is not always very clear to read, but you can see the reason better + * in the place where the PB_STATIC_ASSERT macro was called. + */ +#ifndef PB_NO_STATIC_ASSERT +# ifndef PB_STATIC_ASSERT +# if defined(__ICCARM__) + /* IAR has static_assert keyword but no _Static_assert */ +# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); +# elif defined(_MSC_VER) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112) + /* MSVC in C89 mode supports static_assert() keyword anyway */ +# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); +# elif defined(PB_C99_STATIC_ASSERT) + /* Classic negative-size-array static assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; +# define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +# define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER +# elif defined(__cplusplus) + /* C++11 standard static_assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); +# else + /* C11 standard _Static_assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG); +# endif +# endif +#else + /* Static asserts disabled by PB_NO_STATIC_ASSERT */ +# define PB_STATIC_ASSERT(COND,MSG) +#endif + +/* Test that PB_STATIC_ASSERT works + * If you get errors here, you may need to do one of these: + * - Enable C11 standard support in your compiler + * - Define PB_C99_STATIC_ASSERT to enable C99 standard support + * - Define PB_NO_STATIC_ASSERT to disable static asserts altogether + */ +PB_STATIC_ASSERT(1, STATIC_ASSERT_IS_NOT_WORKING) + +/* Number of required fields to keep track of. */ +#ifndef PB_MAX_REQUIRED_FIELDS +#define PB_MAX_REQUIRED_FIELDS 64 +#endif + +#if PB_MAX_REQUIRED_FIELDS < 64 +#error You should not lower PB_MAX_REQUIRED_FIELDS from the default value (64). +#endif + +#ifdef PB_WITHOUT_64BIT +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Cannot use doubles without 64-bit types */ +#undef PB_CONVERT_DOUBLE_FLOAT +#endif +#endif + +/* List of possible field types. These are used in the autogenerated code. + * Least-significant 4 bits tell the scalar type + * Most-significant 4 bits specify repeated/required/packed etc. + */ + +typedef uint_least8_t pb_type_t; + +/**** Field data types ****/ + +/* Numeric types */ +#define PB_LTYPE_BOOL 0x00U /* bool */ +#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ +#define PB_LTYPE_UVARINT 0x02U /* uint32, uint64 */ +#define PB_LTYPE_SVARINT 0x03U /* sint32, sint64 */ +#define PB_LTYPE_FIXED32 0x04U /* fixed32, sfixed32, float */ +#define PB_LTYPE_FIXED64 0x05U /* fixed64, sfixed64, double */ + +/* Marker for last packable field type. */ +#define PB_LTYPE_LAST_PACKABLE 0x05U + +/* Byte array with pre-allocated buffer. + * data_size is the length of the allocated PB_BYTES_ARRAY structure. */ +#define PB_LTYPE_BYTES 0x06U + +/* String with pre-allocated buffer. + * data_size is the maximum length. */ +#define PB_LTYPE_STRING 0x07U + +/* Submessage + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMESSAGE 0x08U + +/* Submessage with pre-decoding callback + * The pre-decoding callback is stored as pb_callback_t right before pSize. + * submsg_fields is pointer to field descriptions */ +#define PB_LTYPE_SUBMSG_W_CB 0x09U + +/* Extension pseudo-field + * The field contains a pointer to pb_extension_t */ +#define PB_LTYPE_EXTENSION 0x0AU + +/* Byte array with inline, pre-allocated byffer. + * data_size is the length of the inline, allocated buffer. + * This differs from PB_LTYPE_BYTES by defining the element as + * pb_byte_t[data_size] rather than pb_bytes_array_t. */ +#define PB_LTYPE_FIXED_LENGTH_BYTES 0x0BU + +/* Number of declared LTYPES */ +#define PB_LTYPES_COUNT 0x0CU +#define PB_LTYPE_MASK 0x0FU + +/**** Field repetition rules ****/ + +#define PB_HTYPE_REQUIRED 0x00U +#define PB_HTYPE_OPTIONAL 0x10U +#define PB_HTYPE_SINGULAR 0x10U +#define PB_HTYPE_REPEATED 0x20U +#define PB_HTYPE_FIXARRAY 0x20U +#define PB_HTYPE_ONEOF 0x30U +#define PB_HTYPE_MASK 0x30U + +/**** Field allocation types ****/ + +#define PB_ATYPE_STATIC 0x00U +#define PB_ATYPE_POINTER 0x80U +#define PB_ATYPE_CALLBACK 0x40U +#define PB_ATYPE_MASK 0xC0U + +#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) +#define PB_LTYPE_IS_SUBMSG(x) (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || \ + PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) + +/* Data type used for storing sizes of struct fields + * and array counts. + */ +#if defined(PB_FIELD_32BIT) + typedef uint32_t pb_size_t; + typedef int32_t pb_ssize_t; +#else + typedef uint_least16_t pb_size_t; + typedef int_least16_t pb_ssize_t; +#endif +#define PB_SIZE_MAX ((pb_size_t)-1) + +/* Data type for storing encoded data and other byte streams. + * This typedef exists to support platforms where uint8_t does not exist. + * You can regard it as equivalent on uint8_t on other platforms. + */ +typedef uint_least8_t pb_byte_t; + +/* Forward declaration of struct types */ +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_field_iter_s pb_field_iter_t; + +/* This structure is used in auto-generated constants + * to specify struct fields. + */ +typedef struct pb_msgdesc_s pb_msgdesc_t; +struct pb_msgdesc_s { + const uint32_t *field_info; + const pb_msgdesc_t * const * submsg_info; + const pb_byte_t *default_value; + + bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field); + + pb_size_t field_count; + pb_size_t required_field_count; + pb_size_t largest_tag; +}; + +/* Iterator for message descriptor */ +struct pb_field_iter_s { + const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */ + void *message; /* Pointer to start of the structure */ + + pb_size_t index; /* Index of the field */ + pb_size_t field_info_index; /* Index to descriptor->field_info array */ + pb_size_t required_field_index; /* Index that counts only the required fields */ + pb_size_t submessage_index; /* Index that counts only submessages */ + + pb_size_t tag; /* Tag of current field */ + pb_size_t data_size; /* sizeof() of a single item */ + pb_size_t array_size; /* Number of array entries */ + pb_type_t type; /* Type of current field */ + + void *pField; /* Pointer to current field in struct */ + void *pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ + void *pSize; /* Pointer to count/has field */ + + const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ +}; + +/* For compatibility with legacy code */ +typedef pb_field_iter_t pb_field_t; + +/* Make sure that the standard integer types are of the expected sizes. + * Otherwise fixed32/fixed64 fields can break. + * + * If you get errors here, it probably means that your stdint.h is not + * correct for your platform. + */ +#ifndef PB_WITHOUT_64BIT +PB_STATIC_ASSERT(sizeof(int64_t) == 2 * sizeof(int32_t), INT64_T_WRONG_SIZE) +PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) +#endif + +/* This structure is used for 'bytes' arrays. + * It has the number of bytes in the beginning, and after that an array. + * Note that actual structs used will have a different length of bytes array. + */ +#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } +#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) + +struct pb_bytes_array_s { + pb_size_t size; + pb_byte_t bytes[1]; +}; +typedef struct pb_bytes_array_s pb_bytes_array_t; + +/* This structure is used for giving the callback function. + * It is stored in the message structure and filled in by the method that + * calls pb_decode. + * + * The decoding callback will be given a limited-length stream + * If the wire type was string, the length is the length of the string. + * If the wire type was a varint/fixed32/fixed64, the length is the length + * of the actual value. + * The function may be called multiple times (especially for repeated types, + * but also otherwise if the message happens to contain the field multiple + * times.) + * + * The encoding callback will receive the actual output stream. + * It should write all the data in one call, including the field tag and + * wire type. It can write multiple fields. + * + * The callback can be null if you want to skip a field. + */ +typedef struct pb_callback_s pb_callback_t; +struct pb_callback_s { + /* Callback functions receive a pointer to the arg field. + * You can access the value of the field as *arg, and modify it if needed. + */ + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); + } funcs; + + /* Free arg for use by callback */ + void *arg; +}; + +extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); + +/* Wire types. Library user needs these only in encoder callbacks. */ +typedef enum { + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5, + PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ +} pb_wire_type_t; + +/* Structure for defining the handling of unknown/extension fields. + * Usually the pb_extension_type_t structure is automatically generated, + * while the pb_extension_t structure is created by the user. However, + * if you want to catch all unknown fields, you can also create a custom + * pb_extension_type_t with your own callback. + */ +typedef struct pb_extension_type_s pb_extension_type_t; +typedef struct pb_extension_s pb_extension_t; +struct pb_extension_type_s { + /* Called for each unknown field in the message. + * If you handle the field, read off all of its data and return true. + * If you do not handle the field, do not read anything and return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, + uint32_t tag, pb_wire_type_t wire_type); + + /* Called once after all regular fields have been encoded. + * If you have something to write, do so and return true. + * If you do not have anything to write, just return true. + * If you run into an error, return false. + * Set to NULL for default handler. + */ + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); + + /* Free field for use by the callback. */ + const void *arg; +}; + +struct pb_extension_s { + /* Type describing the extension field. Usually you'll initialize + * this to a pointer to the automatically generated structure. */ + const pb_extension_type_t *type; + + /* Destination for the decoded data. This must match the datatype + * of the extension field. */ + void *dest; + + /* Pointer to the next extension handler, or NULL. + * If this extension does not match a field, the next handler is + * automatically called. */ + pb_extension_t *next; + + /* The decoder sets this to true if the extension was found. + * Ignored for encoding. */ + bool found; +}; + +#define pb_extension_init_zero {NULL,NULL,NULL,false} + +/* Memory allocation functions to use. You can define pb_realloc and + * pb_free to custom functions if you want. */ +#ifdef PB_ENABLE_MALLOC +# ifndef pb_realloc +# define pb_realloc(ptr, size) realloc(ptr, size) +# endif +# ifndef pb_free +# define pb_free(ptr) free(ptr) +# endif +#endif + +/* This is used to inform about need to regenerate .pb.h/.pb.c files. */ +#define PB_PROTO_HEADER_VERSION 40 + +/* These macros are used to declare pb_field_t's in the constant array. */ +/* Size of a structure member, in bytes. */ +#define pb_membersize(st, m) (sizeof ((st*)0)->m) +/* Number of entries in an array. */ +#define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) +/* Delta from start of one member to the start of another member. */ +#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) + +/* Force expansion of macro value */ +#define PB_EXPAND(x) x + +/* Binding of a message field set into a specific structure */ +#define PB_BIND(msgname, structname, width) \ + const uint32_t structname ## _field_info[] PB_PROGMEM = \ + { \ + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \ + 0 \ + }; \ + const pb_msgdesc_t* const structname ## _submsg_info[] = \ + { \ + msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ + NULL \ + }; \ + const pb_msgdesc_t structname ## _msg = \ + { \ + structname ## _field_info, \ + structname ## _submsg_info, \ + msgname ## _DEFAULT, \ + msgname ## _CALLBACK, \ + 0 msgname ## _FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ + 0 msgname ## _FIELDLIST(PB_GEN_REQ_FIELD_COUNT, structname), \ + 0 msgname ## _FIELDLIST(PB_GEN_LARGEST_TAG, structname), \ + }; \ + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname) + +#define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 +#define PB_GEN_REQ_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) \ + + (PB_HTYPE_ ## htype == PB_HTYPE_REQUIRED) +#define PB_GEN_LARGEST_TAG(structname, atype, htype, ltype, fieldname, tag) \ + * 0 + tag + +/* X-macro for generating the entries in struct_field_info[] array. */ +#define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ + tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_FIELDINFO_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + +/* X-macro for generating asserts that entries fit in struct_field_info[] array. + * The structure of macros here must match the structure above in PB_GEN_FIELD_INFO_x(), + * but it is not easily reused because of how macro substitutions work. */ +#define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ + PB_FIELDINFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ + tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_FIELDINFO_ASSERT_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ASSERT_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DO_PB_HTYPE_REQUIRED(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_SINGULAR(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DO_PB_HTYPE_OPTIONAL(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_REPEATED(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_FIXARRAY(structname, fieldname) offsetof(structname, fieldname) + +#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SO ## htype(structname, fieldname) +#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SO_PTR ## htype(structname, fieldname) +#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SO_CB ## htype(structname, fieldname) +#define PB_SO_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname)) +#define PB_SO_PB_HTYPE_ONEOF2(structname, fullname, unionname) PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) +#define PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_ ## unionname) +#define PB_SO_PB_HTYPE_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_ ## fieldname) +#define PB_SO_PB_HTYPE_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname ## _count) +#define PB_SO_PB_HTYPE_FIXARRAY(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) +#define PB_SO_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_REPEATED(structname, fieldname) PB_SO_PB_HTYPE_REPEATED(structname, fieldname) +#define PB_SO_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) +#define PB_SO_CB_PB_HTYPE_OPTIONAL(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_REPEATED(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_FIXARRAY(structname, fieldname) 0 + +#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_AS ## htype(structname, fieldname) +#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) PB_AS_PTR ## htype(structname, fieldname) +#define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 +#define PB_AS_PB_HTYPE_REQUIRED(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_SINGULAR(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_OPTIONAL(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_ONEOF(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_REPEATED(structname, fieldname) pb_arraysize(structname, fieldname) +#define PB_AS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname) +#define PB_AS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_ONEOF(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_REPEATED(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname[0]) + +#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DS ## htype(structname, fieldname) +#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DS_PTR ## htype(structname, fieldname) +#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DS_CB ## htype(structname, fieldname) +#define PB_DS_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DS_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0]) +#define PB_DS_PTR_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0][0]) +#define PB_DS_CB_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DS_CB_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname) + +#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple) +#define PB_ONEOF_NAME_UNION(unionname,membername,fullname) unionname +#define PB_ONEOF_NAME_MEMBER(unionname,membername,fullname) membername +#define PB_ONEOF_NAME_FULL(unionname,membername,fullname) fullname + +#define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \ + PB_SUBMSG_INFO_ ## htype(_PB_LTYPE_ ## ltype, structname, fieldname) + +#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), PB_ONEOF_NAME(MEMBER, fieldname)) +#define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) +#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SI ## ltype(structname ## _ ## unionname ## _ ## membername ## _MSGTYPE) +#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SI_PB_LTYPE_BOOL(t) +#define PB_SI_PB_LTYPE_BYTES(t) +#define PB_SI_PB_LTYPE_DOUBLE(t) +#define PB_SI_PB_LTYPE_ENUM(t) +#define PB_SI_PB_LTYPE_UENUM(t) +#define PB_SI_PB_LTYPE_FIXED32(t) +#define PB_SI_PB_LTYPE_FIXED64(t) +#define PB_SI_PB_LTYPE_FLOAT(t) +#define PB_SI_PB_LTYPE_INT32(t) +#define PB_SI_PB_LTYPE_INT64(t) +#define PB_SI_PB_LTYPE_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SI_PB_LTYPE_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SI_PB_LTYPE_SFIXED32(t) +#define PB_SI_PB_LTYPE_SFIXED64(t) +#define PB_SI_PB_LTYPE_SINT32(t) +#define PB_SI_PB_LTYPE_SINT64(t) +#define PB_SI_PB_LTYPE_STRING(t) +#define PB_SI_PB_LTYPE_UINT32(t) +#define PB_SI_PB_LTYPE_UINT64(t) +#define PB_SI_PB_LTYPE_EXTENSION(t) +#define PB_SI_PB_LTYPE_FIXED_LENGTH_BYTES(t) +#define PB_SUBMSG_DESCRIPTOR(t) &(t ## _msg), + +/* The field descriptors use a variable width format, with width of either + * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always + * encode the descriptor size, 6 lowest bits of field tag number, and 8 bits + * of the field type. + * + * Descriptor size is encoded as 0 = 1 word, 1 = 2 words, 2 = 4 words, 3 = 8 words. + * + * Formats, listed starting with the least significant bit of the first word. + * 1 word: [2-bit len] [6-bit tag] [8-bit type] [8-bit data_offset] [4-bit size_offset] [4-bit data_size] + * + * 2 words: [2-bit len] [6-bit tag] [8-bit type] [12-bit array_size] [4-bit size_offset] + * [16-bit data_offset] [12-bit data_size] [4-bit tag>>6] + * + * 4 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit array_size] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * + * 8 words: [2-bit len] [6-bit tag] [8-bit type] [16-bit reserved] + * [8-bit size_offset] [24-bit tag>>6] + * [32-bit data_offset] + * [32-bit data_size] + * [32-bit array_size] + * [32-bit reserved] + * [32-bit reserved] + * [32-bit reserved] + */ + +#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ + (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) & 0xFF) << 16) | \ + (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)), + +#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ + (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \ + (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x3c0) << 22)), + +#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ + (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFFF) << 16)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), + +#define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ + (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), (array_size), 0, 0, 0, + +/* These assertions verify that the field information fits in the allocated space. + * The generator tries to automatically determine the correct width that can fit all + * data associated with a message. These asserts will fail only if there has been a + * problem in the automatic logic - this may be worth reporting as a bug. As a workaround, + * you can increase the descriptor width by defining PB_FIELDINFO_WIDTH or by setting + * descriptorsize option in .options file. + */ +#define PB_FITS(value,bits) ((uint32_t)(value) < ((uint32_t)1<2GB messages with nanopb anyway. + */ +#define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag) + +#define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ + PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,31), FIELDINFO_DOES_NOT_FIT_width8_field ## tag) +#endif + + +/* Automatic picking of FIELDINFO width: + * Uses width 1 when possible, otherwise resorts to width 2. + * This is used when PB_BIND() is called with "AUTO" as the argument. + * The generator will give explicit size argument when it knows that a message + * structure grows beyond 1-word format limits. + */ +#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FI_WIDTH ## atype(htype, ltype) +#define PB_FI_WIDTH_PB_ATYPE_STATIC(htype, ltype) PB_FI_WIDTH ## htype(ltype) +#define PB_FI_WIDTH_PB_ATYPE_POINTER(htype, ltype) PB_FI_WIDTH ## htype(ltype) +#define PB_FI_WIDTH_PB_ATYPE_CALLBACK(htype, ltype) 2 +#define PB_FI_WIDTH_PB_HTYPE_REQUIRED(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_SINGULAR(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_OPTIONAL(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_ONEOF(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_REPEATED(ltype) 2 +#define PB_FI_WIDTH_PB_HTYPE_FIXARRAY(ltype) 2 +#define PB_FI_WIDTH_PB_LTYPE_BOOL 1 +#define PB_FI_WIDTH_PB_LTYPE_BYTES 2 +#define PB_FI_WIDTH_PB_LTYPE_DOUBLE 1 +#define PB_FI_WIDTH_PB_LTYPE_ENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_UENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_FLOAT 1 +#define PB_FI_WIDTH_PB_LTYPE_INT32 1 +#define PB_FI_WIDTH_PB_LTYPE_INT64 1 +#define PB_FI_WIDTH_PB_LTYPE_MESSAGE 2 +#define PB_FI_WIDTH_PB_LTYPE_MSG_W_CB 2 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_STRING 2 +#define PB_FI_WIDTH_PB_LTYPE_UINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_UINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_EXTENSION 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED_LENGTH_BYTES 2 + +/* The mapping from protobuf types to LTYPEs is done using these macros. */ +#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL +#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB +#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION +#define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES + +/* These macros are used for giving out error messages. + * They are mostly a debugging aid; the main error information + * is the true/false return value from functions. + * Some code space can be saved by disabling the error + * messages if not used. + * + * PB_SET_ERROR() sets the error message if none has been set yet. + * msg must be a constant string literal. + * PB_GET_ERROR() always returns a pointer to a string. + * PB_RETURN_ERROR() sets the error and returns false from current + * function. + */ +#ifdef PB_NO_ERRMSG +#define PB_SET_ERROR(stream, msg) PB_UNUSED(stream) +#define PB_GET_ERROR(stream) "(errmsg disabled)" +#else +#define PB_SET_ERROR(stream, msg) (stream->errmsg = (stream)->errmsg ? (stream)->errmsg : (msg)) +#define PB_GET_ERROR(stream) ((stream)->errmsg ? (stream)->errmsg : "(none)") +#endif + +#define PB_RETURN_ERROR(stream, msg) return PB_SET_ERROR(stream, msg), false + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#ifdef __cplusplus +#if __cplusplus >= 201103L +#define PB_CONSTEXPR constexpr +#else // __cplusplus >= 201103L +#define PB_CONSTEXPR +#endif // __cplusplus >= 201103L + +#if __cplusplus >= 201703L +#define PB_INLINE_CONSTEXPR inline constexpr +#else // __cplusplus >= 201703L +#define PB_INLINE_CONSTEXPR PB_CONSTEXPR +#endif // __cplusplus >= 201703L + +extern "C++" +{ +namespace nanopb { +// Each type will be partially specialized by the generator. +template struct MessageDescriptor; +} // namespace nanopb +} +#endif /* __cplusplus */ + +#endif diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/pb_common.h b/project_old/paint_robot_old/BASE/Inc/BSP/pb_common.h new file mode 100644 index 0000000..58aa90f --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/pb_common.h @@ -0,0 +1,49 @@ +/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c. + * These functions are rarely needed by applications directly. + */ + +#ifndef PB_COMMON_H_INCLUDED +#define PB_COMMON_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initialize the field iterator structure to beginning. + * Returns false if the message type is empty. */ +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message); + +/* Get a field iterator for extension field. */ +bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension); + +/* Same as pb_field_iter_begin(), but for const message pointer. + * Note that the pointers in pb_field_iter_t will be non-const but shouldn't + * be written to when using these functions. */ +bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message); +bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension); + +/* Advance the iterator to the next field. + * Returns false when the iterator wraps back to the first field. */ +bool pb_field_iter_next(pb_field_iter_t *iter); + +/* Advance the iterator until it points at a field with the given tag. + * Returns false if no such field exists. */ +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag); + +/* Find a field with type PB_LTYPE_EXTENSION, or return false if not found. + * There can be only one extension range field per message. */ +bool pb_field_iter_find_extension(pb_field_iter_t *iter); + +#ifdef PB_VALIDATE_UTF8 +/* Validate UTF-8 text string */ +bool pb_validate_utf8(const char *s); +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif + diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/pb_decode.h b/project_old/paint_robot_old/BASE/Inc/BSP/pb_decode.h new file mode 100644 index 0000000..ae1d3cc --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/pb_decode.h @@ -0,0 +1,193 @@ +/* pb_decode.h: Functions to decode protocol buffers. Depends on pb_decode.c. + * The main function is pb_decode. You also need an input stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_DECODE_H_INCLUDED +#define PB_DECODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom input streams. You will need to provide + * a callback function to read the bytes from your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause decoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer), + * and rely on pb_read to verify that no-body reads past bytes_left. + * 3) Your callback may be used with substreams, in which case bytes_left + * is different than from the main stream. Don't use bytes_left to compute + * any pointers. + */ +struct pb_istream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + */ + int *callback; +#else + bool (*callback)(pb_istream_t *stream, pb_byte_t *buf, size_t count); +#endif + + void *state; /* Free field for use by callback implementation */ + size_t bytes_left; + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +#ifndef PB_NO_ERRMSG +#define PB_ISTREAM_EMPTY {0,0,0,0} +#else +#define PB_ISTREAM_EMPTY {0,0,0} +#endif + +/*************************** + * Main decoding functions * + ***************************/ + +/* Decode a single protocol buffers message from input stream into a C structure. + * Returns true on success, false on any failure. + * The actual struct pointed to by dest must match the description in fields. + * Callback fields of the destination structure must be initialized by caller. + * All other fields will be initialized by this function. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_istream_t stream; + * + * // ... read some data into buffer ... + * + * stream = pb_istream_from_buffer(buffer, count); + * pb_decode(&stream, MyMessage_fields, &msg); + */ +bool pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct); + +/* Extended version of pb_decode, with several options to control + * the decoding process: + * + * PB_DECODE_NOINIT: Do not initialize the fields to default values. + * This is slightly faster if you do not need the default + * values and instead initialize the structure to 0 using + * e.g. memset(). This can also be used for merging two + * messages, i.e. combine already existing data with new + * values. + * + * PB_DECODE_DELIMITED: Input message starts with the message size as varint. + * Corresponds to parseDelimitedFrom() in Google's + * protobuf API. + * + * PB_DECODE_NULLTERMINATED: Stop reading when field tag is read as 0. This allows + * reading null terminated messages. + * NOTE: Until nanopb-0.4.0, pb_decode() also allows + * null-termination. This behaviour is not supported in + * most other protobuf implementations, so PB_DECODE_DELIMITED + * is a better option for compatibility. + * + * Multiple flags can be combined with bitwise or (| operator) + */ +#define PB_DECODE_NOINIT 0x01U +#define PB_DECODE_DELIMITED 0x02U +#define PB_DECODE_NULLTERMINATED 0x04U +bool pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags); + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define pb_decode_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NOINIT) +#define pb_decode_delimited(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED) +#define pb_decode_delimited_noinit(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_DELIMITED | PB_DECODE_NOINIT) +#define pb_decode_nullterminated(s,f,d) pb_decode_ex(s,f,d, PB_DECODE_NULLTERMINATED) + +/* Release any allocated pointer fields. If you use dynamic allocation, you should + * call this for any successfully decoded message when you are done with it. If + * pb_decode() returns with an error, the message is already released. + */ +void pb_release(const pb_msgdesc_t *fields, void *dest_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an input stream for reading from a memory buffer. + * + * msglen should be the actual length of the message, not the full size of + * allocated buffer. + * + * Alternatively, you can use a custom stream that reads directly from e.g. + * a file or a network socket. + */ +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen); + +/* Function to read from a pb_istream_t. You can use this if you need to + * read some custom header data, or to read data in field callbacks. + */ +bool pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Decode the tag for the next field in the stream. Gives the wire type and + * field tag. At end of the message, returns false and sets eof to true. */ +bool pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof); + +/* Skip the field payload data, given the wire type. */ +bool pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type); + +/* Decode an integer in the varint format. This works for enum, int32, + * int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_varint(pb_istream_t *stream, uint64_t *dest); +#else +#define pb_decode_varint pb_decode_varint32 +#endif + +/* Decode an integer in the varint format. This works for enum, int32, + * and uint32 field types. */ +bool pb_decode_varint32(pb_istream_t *stream, uint32_t *dest); + +/* Decode a bool value in varint format. */ +bool pb_decode_bool(pb_istream_t *stream, bool *dest); + +/* Decode an integer in the zig-zagged svarint format. This works for sint32 + * and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest); +#else +bool pb_decode_svarint(pb_istream_t *stream, int32_t *dest); +#endif + +/* Decode a fixed32, sfixed32 or float value. You need to pass a pointer to + * a 4-byte wide C variable. */ +bool pb_decode_fixed32(pb_istream_t *stream, void *dest); + +#ifndef PB_WITHOUT_64BIT +/* Decode a fixed64, sfixed64 or double value. You need to pass a pointer to + * a 8-byte wide C variable. */ +bool pb_decode_fixed64(pb_istream_t *stream, void *dest); +#endif + +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Decode a double value into float variable. */ +bool pb_decode_double_as_float(pb_istream_t *stream, float *dest); +#endif + +/* Make a limited-length substream for reading a PB_WT_STRING field. */ +bool pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream); +bool pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/pb_encode.h b/project_old/paint_robot_old/BASE/Inc/BSP/pb_encode.h new file mode 100644 index 0000000..8913683 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/pb_encode.h @@ -0,0 +1,185 @@ +/* pb_encode.h: Functions to encode protocol buffers. Depends on pb_encode.c. + * The main function is pb_encode. You also need an output stream, and the + * field descriptions created by nanopb_generator.py. + */ + +#ifndef PB_ENCODE_H_INCLUDED +#define PB_ENCODE_H_INCLUDED + +#include "pb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for defining custom output streams. You will need to provide + * a callback function to write the bytes to your storage, which can be + * for example a file or a network socket. + * + * The callback must conform to these rules: + * + * 1) Return false on IO errors. This will cause encoding to abort. + * 2) You can use state to store your own data (e.g. buffer pointer). + * 3) pb_write will update bytes_written after your callback runs. + * 4) Substreams will modify max_size and bytes_written. Don't use them + * to calculate any pointers. + */ +struct pb_ostream_s +{ +#ifdef PB_BUFFER_ONLY + /* Callback pointer is not used in buffer-only configuration. + * Having an int pointer here allows binary compatibility but + * gives an error if someone tries to assign callback function. + * Also, NULL pointer marks a 'sizing stream' that does not + * write anything. + */ + const int *callback; +#else + bool (*callback)(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +#endif + void *state; /* Free field for use by callback implementation. */ + size_t max_size; /* Limit number of output bytes written (or use SIZE_MAX). */ + size_t bytes_written; /* Number of bytes written so far. */ + +#ifndef PB_NO_ERRMSG + const char *errmsg; +#endif +}; + +/*************************** + * Main encoding functions * + ***************************/ + +/* Encode a single protocol buffers message from C structure into a stream. + * Returns true on success, false on any failure. + * The actual struct pointed to by src_struct must match the description in fields. + * All required fields in the struct are assumed to have been filled in. + * + * Example usage: + * MyMessage msg = {}; + * uint8_t buffer[64]; + * pb_ostream_t stream; + * + * msg.field1 = 42; + * stream = pb_ostream_from_buffer(buffer, sizeof(buffer)); + * pb_encode(&stream, MyMessage_fields, &msg); + */ +bool pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); + +/* Extended version of pb_encode, with several options to control the + * encoding process: + * + * PB_ENCODE_DELIMITED: Prepend the length of message as a varint. + * Corresponds to writeDelimitedTo() in Google's + * protobuf API. + * + * PB_ENCODE_NULLTERMINATED: Append a null byte to the message for termination. + * NOTE: This behaviour is not supported in most other + * protobuf implementations, so PB_ENCODE_DELIMITED + * is a better option for compatibility. + */ +#define PB_ENCODE_DELIMITED 0x02U +#define PB_ENCODE_NULLTERMINATED 0x04U +bool pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags); + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define pb_encode_delimited(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_DELIMITED) +#define pb_encode_nullterminated(s,f,d) pb_encode_ex(s,f,d, PB_ENCODE_NULLTERMINATED) + +/* Encode the message to get the size of the encoded data, but do not store + * the data. */ +bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct); + +/************************************** + * Functions for manipulating streams * + **************************************/ + +/* Create an output stream for writing into a memory buffer. + * The number of bytes written can be found in stream.bytes_written after + * encoding the message. + * + * Alternatively, you can use a custom stream that writes directly to e.g. + * a file or a network socket. + */ +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize); + +/* Pseudo-stream for measuring the size of a message without actually storing + * the encoded data. + * + * Example usage: + * MyMessage msg = {}; + * pb_ostream_t stream = PB_OSTREAM_SIZING; + * pb_encode(&stream, MyMessage_fields, &msg); + * printf("Message size is %d\n", stream.bytes_written); + */ +#ifndef PB_NO_ERRMSG +#define PB_OSTREAM_SIZING {0,0,0,0,0} +#else +#define PB_OSTREAM_SIZING {0,0,0,0} +#endif + +/* Function to write into a pb_ostream_t stream. You can use this if you need + * to append or prepend some custom headers to the message. + */ +bool pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); + + +/************************************************ + * Helper functions for writing field callbacks * + ************************************************/ + +/* Encode field header based on type and field number defined in the field + * structure. Call this from the callback before writing out field contents. */ +bool pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_iter_t *field); + +/* Encode field header by manually specifying wire type. You need to use this + * if you want to write out packed arrays from a callback field. */ +bool pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number); + +/* Encode an integer in the varint format. + * This works for bool, enum, int32, int64, uint32 and uint64 field types. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_varint(pb_ostream_t *stream, uint64_t value); +#else +bool pb_encode_varint(pb_ostream_t *stream, uint32_t value); +#endif + +/* Encode an integer in the zig-zagged svarint format. + * This works for sint32 and sint64. */ +#ifndef PB_WITHOUT_64BIT +bool pb_encode_svarint(pb_ostream_t *stream, int64_t value); +#else +bool pb_encode_svarint(pb_ostream_t *stream, int32_t value); +#endif + +/* Encode a string or bytes type field. For strings, pass strlen(s) as size. */ +bool pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size); + +/* Encode a fixed32, sfixed32 or float value. + * You need to pass a pointer to a 4-byte wide C variable. */ +bool pb_encode_fixed32(pb_ostream_t *stream, const void *value); + +#ifndef PB_WITHOUT_64BIT +/* Encode a fixed64, sfixed64 or double value. + * You need to pass a pointer to a 8-byte wide C variable. */ +bool pb_encode_fixed64(pb_ostream_t *stream, const void *value); +#endif + +#ifdef PB_CONVERT_DOUBLE_FLOAT +/* Encode a float value so that it appears like a double in the encoded + * message. */ +bool pb_encode_float_as_double(pb_ostream_t *stream, float value); +#endif + +/* Encode a submessage field. + * You need to pass the pb_field_t array and pointer to struct, just like + * with pb_encode(). This internally encodes the submessage twice, first to + * calculate message size and then to actually write it out. + */ +bool pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/readme.h b/project_old/paint_robot_old/BASE/Inc/BSP/readme.h new file mode 100644 index 0000000..d7a8510 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/readme.h @@ -0,0 +1,38 @@ + + +/* + * readme.h + * + * Created on: 2023年10月31日 + * Author: shiya + * + * CAN_H7_Bootloader程序存放位置 + * FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K + * 要求APP的存放位置为: + * FLASH (rx) : ORIGIN = 0x08020000, LENGTH = 896K + * APP的中断向量表设置为: + * define VECT_TAB_OFFSET 0x00020000U + * + * Boot顺序(关联CAN总线2): + * Boot程序总线返回报文ID:0x1FF 类型:标准帧 + * 1. Boot启动,返回报文长度1的报文; + * 2. 延时100ms,期间等待报文0x110标准帧,首字节0x55,如果接收到 进入BootLoader程序 A; + * 3. 如果没有收到进入bootloader请求,返回报文长度3的报文,跳转到APP; + * + * A. 如果进入bootloader程序,返回报文长度2的报文,等待刷写; + * 刷写ID为0x222,逻辑参见“canbootloader.lua” + * B. 如果刷写过程存在失败,返回报文长度4的报文,可以重新尝试运行“canbootloader.lua”进行刷写; + * + * C. 刷写成功,返回报文长度3的报文,进入APP; + * PV 用户可修改数据 + * CV 管理员配置权限,CV中有PV + * GV 机器人数据 + * IV 机器人返回上位机的表征数据 + * + */ +#ifndef INC_BSP_README_H_ +#define INC_BSP_README_H_ + + + +#endif /* INC_BSP_README_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/BSP/tcp_server.h b/project_old/paint_robot_old/BASE/Inc/BSP/tcp_server.h new file mode 100644 index 0000000..8a7e4a4 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/BSP/tcp_server.h @@ -0,0 +1,49 @@ +/* + * bsp_TCPServer.h + * + * Created on: 2025年8月4日 + * Author: akeguo + */ + +#ifndef BASE_INC_BSP_TCP_SERVER_H_ +#define BASE_INC_BSP_TCP_SERVER_H_ + +//#ifndef TCP_SERVER_H +//#define TCP_SERVER_H + +#include "lwip/tcp.h" +#include + +// 最大客户端连接数 +#define MAX_CLIENTS 8 + +// 客户端连接结构 +typedef struct { + struct tcp_pcb *pcb; // LwIP PCB指针 + uint8_t active; // 连接是否活跃 +} client_conn_t; + +// 服务器初始化 +void tcp_server_init(uint16_t port); + +// 发送数据给所有客户端 +void tcp_send_to_all_clients(const char *data, uint16_t len); + +// 定时器回调声明 +void tcp_server_timer_callback(void); + +typedef struct SendDataNode +{ + uint8_t Tx_Buf[255]; /*发送数据*/ + uint8_t Tx_Count; /*学号*/ + struct SendDataNode * next; /*指向下一个节点的指针*/ +}SendDataNode; +extern void tcp_add_sendList(uint8_t *tx_Buf, uint8_t tx_count); + + + + +//#endif /* TCP_SERVER_H */ + + +#endif /* BASE_INC_BSP_TCP_SERVER_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/MSP/msp_Force_Sensor.h b/project_old/paint_robot_old/BASE/Inc/MSP/msp_Force_Sensor.h new file mode 100644 index 0000000..8548a94 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/MSP/msp_Force_Sensor.h @@ -0,0 +1,13 @@ +/* + * msp_Force_Sensor.h + * + * Created on: Oct 8, 2024 + * Author: akeguo + */ + +#ifndef INC_MSP_MSP_FORCE_SENSOR_H_ +#define INC_MSP_MSP_FORCE_SENSOR_H_ +#include "bsp_MB_host.h" +extern void force_sensor_intialize(struct UARTHandler *Handler); +extern int32_t* ForceValue; +#endif /* INC_MSP_MSP_FORCE_SENSOR_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/MSP/msp_JTBATTERY.h b/project_old/paint_robot_old/BASE/Inc/MSP/msp_JTBATTERY.h new file mode 100644 index 0000000..777a51b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/MSP/msp_JTBATTERY.h @@ -0,0 +1,15 @@ +/* + * msp_JTBATTERY.h + * + * Created on: Oct 26, 2023 + * Author: shiya + */ + +#ifndef INC_MSP_MSP_JTBATTERY_H_ +#define INC_MSP_MSP_JTBATTERY_H_ + +#include "BSP/bsp_include.h" + + + +#endif /* INC_MSP_MSP_JTBATTERY_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/MSP/msp_LeiSai_ISV2_CAN.h b/project_old/paint_robot_old/BASE/Inc/MSP/msp_LeiSai_ISV2_CAN.h new file mode 100644 index 0000000..9ff10a7 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/MSP/msp_LeiSai_ISV2_CAN.h @@ -0,0 +1,42 @@ +/* + * msp_LeiSai_ISV2_CAN.h + * + * Created on: Oct 22, 2024 + * Author: akeguo + */ + +#ifndef INC_MSP_MSP_LEISAI_ISV2_CAN_H_ +#define INC_MSP_MSP_LEISAI_ISV2_CAN_H_ + +#include "BHBF_ROBOT.h" +#include "bsp_FDCAN.h" +#include "msp_LS_MotorParameters.pb.h" + +extern LS_MotorParameters* LS_Motor[7]; +extern double wheel_diameter_m; //1m 260mm +extern double motor_pulses_rer_rotation; //1 pulse +extern double wheel_reduction_ratio; +extern double wheel_001m_per_min_to_plus_per_s_ratio; +extern double wheel_plus_per_s_to_m_per_min_ratio; + +void LS_Analytic_Fun(int32_t MotorID, uint8_t *buffer); +void LS_DO_Set(int32_t MotorID, int32_t Do, uint8_t state, FDCANHandler *Motor_Controller, int32_t WaitTime); +void LS_Request_Position(int32_t MotorID,FDCANHandler *Motor_Controller,int32_t WaitTime); +void LS_Request_Velocity(int32_t MotorID,FDCANHandler *Motor_Controller,int32_t WaitTime); +void LS_Request_Current(int32_t MotorID,FDCANHandler *Motor_Controller,int32_t WaitTime); +void LS_Request_Fault(int32_t MotorID,FDCANHandler *Motor_Controller,int32_t WaitTime); +void LS_Reset_All_Motors(FDCANHandler *Motor_Controller, int32_t WaitTime); +void LS_Activate_All_Motors(FDCANHandler *Motor_Controller, int32_t WaitTime); +void LS_SpeedModeSetup(int32_t MotorID,FDCANHandler *Motor_Controller,int32_t WaitTime,int32_t AccTime, int32_t DecTime, int32_t TargetSpeed); +void LS_SpeedMode_Set_TargetSpeed(int32_t MotorID,FDCANHandler *Motor_Controller,int32_t WaitTime,int32_t TargetSpeed); +void LS_PostionModeSetUp(int32_t MotorID, int32_t TargetPosition,int32_t TargetSpeed, int32_t AccTime, int32_t DecTime,FDCANHandler *Motor_Controller,int32_t WaitTime); +void LS_PostionMode_Set_Position(int32_t MotorID, int32_t TargetPosition,FDCANHandler *Motor_Controller,int32_t WaitTime); +void LS_Set_Current_Positon_Zero(uint8_t MotorID, FDCANHandler *Motor_Controller, int32_t WaitTime); +void LS_Set_WatchDogTime(int32_t MotorID, FDCANHandler *Motor_Controller, + int32_t WaitTime); + + + + + +#endif /* INC_MSP_MSP_LEISAI_ISV2_CAN_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/MSP/msp_MK32_1.h b/project_old/paint_robot_old/BASE/Inc/MSP/msp_MK32_1.h new file mode 100644 index 0000000..9c48328 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/MSP/msp_MK32_1.h @@ -0,0 +1,18 @@ +/* + * msp_MK32_1.h + * + * Created on: Oct 8, 2024 + * Author: akeguo + */ + +#ifndef INC_MSP_MSP_MK32_1_H_ +#define INC_MSP_MSP_MK32_1_H_ +#include "BSP/bsp_UART.h" +#include "msp_MK32.pb.h" +void Sbus_Data_Count(uint8_t *buf, int32_t *But_Value); +extern SP_MSP_MK32_Button *P_MK32; + +extern char ReceivedFromMK32; +void MK32_Sbus_UART_Handler_intialize(struct UARTHandler* Handler); +extern char Is_All_Button_Reset; +#endif /* INC_MSP_MSP_MK32_1_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/MSP/msp_PID.h b/project_old/paint_robot_old/BASE/Inc/MSP/msp_PID.h new file mode 100644 index 0000000..437958a --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/MSP/msp_PID.h @@ -0,0 +1,19 @@ +/* + * msp_PID.h + * + * Created on: 2024年1月22日 + * Author: Administrator + */ + +#ifndef INC_MSP_MSP_PID_H_ +#define INC_MSP_MSP_PID_H_ + +#include "BSP/bsp_include.h" + + + + +extern double Angle_Tune_PID(double CurrentAngle, double TargetAngle, double Position_KP, + double Position_KI, double Position_KD, double MaxValue); + +#endif /* INC_MSP_MSP_PID_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/MSP/msp_TL720D.h b/project_old/paint_robot_old/BASE/Inc/MSP/msp_TL720D.h new file mode 100644 index 0000000..8b380da --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/MSP/msp_TL720D.h @@ -0,0 +1,24 @@ +/* + * msp_TL720D.h + * + * Created on: Jul 19, 2024 + * Author: bihon + */ + +#ifndef INC_MSP_MSP_TL720D_H_ +#define INC_MSP_MSP_TL720D_H_ + +#include +#include +#include "bsp_MB_host.h" +#include "stdio.h" +#include "BSP/bsp_UART.h" +#include "usart.h" +#include "gpio.h" + +void TL720D_intialize(struct UARTHandler *Handler); + +extern MSP_TL720DParameters* SP_MSP_RF_TL720D_Parameters_In; +extern int32_t *RobotAngle;//机器人角度 + +#endif /* INC_MSP_MSP_TL720D_H_ */ diff --git a/project_old/paint_robot_old/BASE/Inc/MSP/msp_WH_LTE_7S0.h b/project_old/paint_robot_old/BASE/Inc/MSP/msp_WH_LTE_7S0.h new file mode 100644 index 0000000..3a1f1ed --- /dev/null +++ b/project_old/paint_robot_old/BASE/Inc/MSP/msp_WH_LTE_7S0.h @@ -0,0 +1,21 @@ +/* + * bsp_WH_LTE_7S0.h + * + * Created on: Sep 14, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_BSP_WH_LTE_7S0_H_ +#define INC_BSP_BSP_WH_LTE_7S0_H_ +#include "stdint.h" +extern struct UARTHandler *wh_LTE_7S0_Handler; +//void WH_LTE_7S0_intialize(struct UARTHandler *Handler); +void Send_WH_LTE_7S0_Data(uint8_t* data,int length); + +void WH_LTE_7S0_intialize(struct UARTHandler *Handler); +void decode_received_data_from_computer(uint8_t *buffer, uint16_t length); +void decode_command_from_wh_LTE_7S0(uint8_t *buffer, uint16_t length); +void UpdateGV(); + +extern char NeedToFeedBackToComputer; +#endif /* INC_BSP_BSP_WH_LTE_7S0_H_ */ diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.c new file mode 100644 index 0000000..525d599 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.c @@ -0,0 +1,20 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_CV.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(CV_struct_define, CV_struct_define, AUTO) + + + +#ifndef PB_CONVERT_DOUBLE_FLOAT +/* On some platforms (such as AVR), double is really float. + * To be able to encode/decode double on these platforms, you need. + * to define PB_CONVERT_DOUBLE_FLOAT in pb.h or compiler command line. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) +#endif + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.h new file mode 100644 index 0000000..d107c68 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_CV.pb.h @@ -0,0 +1,125 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_CV_PB_H_INCLUDED +#define PB_BSP_CV_PB_H_INCLUDED +#include "pb.h" +#include "bsp_PV.pb.h" +#include "bsp_PID.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _CV_struct_define { + int32_t Speed_m_per_min; /* MPMin = 1m/min 1米每分钟 m/min */ + int32_t LeftTurnSpeed; + int32_t RightTurnSpeed; + int32_t RobotLeftAngleValue; /* 水平左方向 单位0.01° */ + int32_t RobotRightAngleValue; /* 水平右方向角度值 单位0.01° */ + int32_t RobotUpAngleValue; /* 竖直方向角度值 单位0.01° */ + int32_t RobotDownAngleValue; /* 竖直向下角度值 单位0.01° */ + int32_t Robot_Permitted_Angler_Error_Value_E_2D; /* 作业时需用的最大角度偏差值 0.01°,超出将停止作业 */ + int32_t Robot_Angle_Start_BaseE_2D; /* 角度值 0.01° */ + int32_t Lane_Change_Speed_m_per_min; + int32_t Is_Automation_Authorized; + int32_t Is_Function_Authorized; + int32_t Joy_Sticker_Angle_Allowance; /* 例如在90度的±30° */ + int32_t Joy_Sticker_Value_Allowance; /* 例如 joysticker的值超过600 */ + int32_t Allowable_Error_For_Angle_Tracking; /* 纠偏角度跟踪的允许误差1 度 */ + int32_t Paint_Gun_Shutdown_Distance; /* 喷枪关闭距离,喷枪关闭后多上厘米停止运行 */ + int32_t Horizontal_ChangeLane_Compensation; /* 水平换道补偿距离 */ + int32_t Vertical_ChangeLane_Compensation; /* 竖直换道补偿距离 */ + int32_t pulse_Per_Circle; /* 每转多少脉冲 */ + int32_t wheel_Reduction_Ratio; /* 减速比 */ + double wheel_Diameter_m; /* 车轮直径 m */ + bool has_PID_high; + PID_Parameters PID_high; + bool has_PID_mid; + PID_Parameters PID_mid; + bool has_PID_low; + PID_Parameters PID_low; +} CV_struct_define; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define CV_struct_define_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, PID_Parameters_init_default, false, PID_Parameters_init_default, false, PID_Parameters_init_default} +#define CV_struct_define_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, PID_Parameters_init_zero, false, PID_Parameters_init_zero, false, PID_Parameters_init_zero} + +/* Field tags (for use in manual encoding/decoding) */ +#define CV_struct_define_Speed_m_per_min_tag 1 +#define CV_struct_define_LeftTurnSpeed_tag 2 +#define CV_struct_define_RightTurnSpeed_tag 3 +#define CV_struct_define_RobotLeftAngleValue_tag 4 +#define CV_struct_define_RobotRightAngleValue_tag 5 +#define CV_struct_define_RobotUpAngleValue_tag 6 +#define CV_struct_define_RobotDownAngleValue_tag 7 +#define CV_struct_define_Robot_Permitted_Angler_Error_Value_E_2D_tag 8 +#define CV_struct_define_Robot_Angle_Start_BaseE_2D_tag 9 +#define CV_struct_define_Lane_Change_Speed_m_per_min_tag 10 +#define CV_struct_define_Is_Automation_Authorized_tag 11 +#define CV_struct_define_Is_Function_Authorized_tag 12 +#define CV_struct_define_Joy_Sticker_Angle_Allowance_tag 13 +#define CV_struct_define_Joy_Sticker_Value_Allowance_tag 14 +#define CV_struct_define_Allowable_Error_For_Angle_Tracking_tag 15 +#define CV_struct_define_Paint_Gun_Shutdown_Distance_tag 16 +#define CV_struct_define_Horizontal_ChangeLane_Compensation_tag 17 +#define CV_struct_define_Vertical_ChangeLane_Compensation_tag 18 +#define CV_struct_define_pulse_Per_Circle_tag 19 +#define CV_struct_define_wheel_Reduction_Ratio_tag 20 +#define CV_struct_define_wheel_Diameter_m_tag 21 +#define CV_struct_define_PID_high_tag 22 +#define CV_struct_define_PID_mid_tag 23 +#define CV_struct_define_PID_low_tag 24 + +/* Struct field encoding specification for nanopb */ +#define CV_struct_define_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, Speed_m_per_min, 1) \ +X(a, STATIC, SINGULAR, INT32, LeftTurnSpeed, 2) \ +X(a, STATIC, SINGULAR, INT32, RightTurnSpeed, 3) \ +X(a, STATIC, SINGULAR, INT32, RobotLeftAngleValue, 4) \ +X(a, STATIC, SINGULAR, INT32, RobotRightAngleValue, 5) \ +X(a, STATIC, SINGULAR, INT32, RobotUpAngleValue, 6) \ +X(a, STATIC, SINGULAR, INT32, RobotDownAngleValue, 7) \ +X(a, STATIC, SINGULAR, INT32, Robot_Permitted_Angler_Error_Value_E_2D, 8) \ +X(a, STATIC, SINGULAR, INT32, Robot_Angle_Start_BaseE_2D, 9) \ +X(a, STATIC, SINGULAR, INT32, Lane_Change_Speed_m_per_min, 10) \ +X(a, STATIC, SINGULAR, INT32, Is_Automation_Authorized, 11) \ +X(a, STATIC, SINGULAR, INT32, Is_Function_Authorized, 12) \ +X(a, STATIC, SINGULAR, INT32, Joy_Sticker_Angle_Allowance, 13) \ +X(a, STATIC, SINGULAR, INT32, Joy_Sticker_Value_Allowance, 14) \ +X(a, STATIC, SINGULAR, INT32, Allowable_Error_For_Angle_Tracking, 15) \ +X(a, STATIC, SINGULAR, INT32, Paint_Gun_Shutdown_Distance, 16) \ +X(a, STATIC, SINGULAR, INT32, Horizontal_ChangeLane_Compensation, 17) \ +X(a, STATIC, SINGULAR, INT32, Vertical_ChangeLane_Compensation, 18) \ +X(a, STATIC, SINGULAR, INT32, pulse_Per_Circle, 19) \ +X(a, STATIC, SINGULAR, INT32, wheel_Reduction_Ratio, 20) \ +X(a, STATIC, SINGULAR, DOUBLE, wheel_Diameter_m, 21) \ +X(a, STATIC, OPTIONAL, MESSAGE, PID_high, 22) \ +X(a, STATIC, OPTIONAL, MESSAGE, PID_mid, 23) \ +X(a, STATIC, OPTIONAL, MESSAGE, PID_low, 24) +#define CV_struct_define_CALLBACK NULL +#define CV_struct_define_DEFAULT NULL +#define CV_struct_define_PID_high_MSGTYPE PID_Parameters +#define CV_struct_define_PID_mid_MSGTYPE PID_Parameters +#define CV_struct_define_PID_low_MSGTYPE PID_Parameters + +extern const pb_msgdesc_t CV_struct_define_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define CV_struct_define_fields &CV_struct_define_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_CV_PB_H_MAX_SIZE CV_struct_define_size +#define CV_struct_define_size 358 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.c new file mode 100644 index 0000000..4354a69 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_Cmd.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(Cmd, Cmd, 2) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.h new file mode 100644 index 0000000..602e930 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Cmd.pb.h @@ -0,0 +1,80 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_CMD_PB_H_INCLUDED +#define PB_BSP_CMD_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* this message is used for the computer to send command */ +typedef struct _Cmd { + int32_t CommadNum; + /* 定义 1 上位机获取默认CV值 +定义 2 下位机返回CV值 +定义 3 上位机设定CV值 +定义 4 上位机设定Trace等级值,无返回 +定义 5 下位机上传位置点数据 +定义 6 上位机设定编码器角度值为0 +定义 7 上位机获取拟合点 +定义 8 上位机获取位置点 +定义 9 上位机向下位机下发程序 此时,Parameter0 下发的程序起始位,Parameter0 是校验位 +Buff_Data_Length 是下发的字节数, */ + int32_t Parameter0; + int32_t Parameter1; + int32_t Parameter2; + int32_t Parameter3; + int32_t Parameter4; + int32_t Buff_Data_Length; + pb_byte_t Buff_Data[512]; +} Cmd; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define Cmd_init_default {0, 0, 0, 0, 0, 0, 0, {0}} +#define Cmd_init_zero {0, 0, 0, 0, 0, 0, 0, {0}} + +/* Field tags (for use in manual encoding/decoding) */ +#define Cmd_CommadNum_tag 1 +#define Cmd_Parameter0_tag 2 +#define Cmd_Parameter1_tag 3 +#define Cmd_Parameter2_tag 4 +#define Cmd_Parameter3_tag 5 +#define Cmd_Parameter4_tag 6 +#define Cmd_Buff_Data_Length_tag 7 +#define Cmd_Buff_Data_tag 8 + +/* Struct field encoding specification for nanopb */ +#define Cmd_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, CommadNum, 1) \ +X(a, STATIC, SINGULAR, INT32, Parameter0, 2) \ +X(a, STATIC, SINGULAR, INT32, Parameter1, 3) \ +X(a, STATIC, SINGULAR, INT32, Parameter2, 4) \ +X(a, STATIC, SINGULAR, INT32, Parameter3, 5) \ +X(a, STATIC, SINGULAR, INT32, Parameter4, 6) \ +X(a, STATIC, SINGULAR, INT32, Buff_Data_Length, 7) \ +X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, Buff_Data, 8) +#define Cmd_CALLBACK NULL +#define Cmd_DEFAULT NULL + +extern const pb_msgdesc_t Cmd_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define Cmd_fields &Cmd_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_CMD_PB_H_MAX_SIZE Cmd_size +#define Cmd_size 592 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.c new file mode 100644 index 0000000..ef29e11 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.c @@ -0,0 +1,13 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_Error.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(ErrorData, ErrorData, AUTO) + + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.h new file mode 100644 index 0000000..dc60e4d --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_Error.pb.h @@ -0,0 +1,72 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_ERROR_PB_H_INCLUDED +#define PB_BSP_ERROR_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +typedef enum _ComError { + ComError_MK32_SBus = 0, + ComError_TL720D = 1, + ComError_LS_LeftMotor = 2, + ComError_LS_RightMotor = 3, + ComError_Remote_Button_Reset_State = 4, + ComError_MK32_Serial = 5, + ComError_MK32_UDP = 6 +} ComError; + +/* Struct definitions */ +typedef struct _ErrorData { + int32_t Com_Error_Code; + int32_t Left_Motor_Error_Code; + int32_t Right_Motor_Error_Code; +} ErrorData; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper constants for enums */ +#define _ComError_MIN ComError_MK32_SBus +#define _ComError_MAX ComError_MK32_UDP +#define _ComError_ARRAYSIZE ((ComError)(ComError_MK32_UDP+1)) + + + +/* Initializer values for message structs */ +#define ErrorData_init_default {0, 0, 0} +#define ErrorData_init_zero {0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define ErrorData_Com_Error_Code_tag 1 +#define ErrorData_Left_Motor_Error_Code_tag 2 +#define ErrorData_Right_Motor_Error_Code_tag 3 + +/* Struct field encoding specification for nanopb */ +#define ErrorData_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, Com_Error_Code, 1) \ +X(a, STATIC, SINGULAR, INT32, Left_Motor_Error_Code, 2) \ +X(a, STATIC, SINGULAR, INT32, Right_Motor_Error_Code, 3) +#define ErrorData_CALLBACK NULL +#define ErrorData_DEFAULT NULL + +extern const pb_msgdesc_t ErrorData_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define ErrorData_fields &ErrorData_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_ERROR_PB_H_MAX_SIZE ErrorData_size +#define ErrorData_size 33 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.c new file mode 100644 index 0000000..bf47c58 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_GV.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(GV_struct_define, GV_struct_define, 2) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.h new file mode 100644 index 0000000..da0dd0e --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_GV.pb.h @@ -0,0 +1,108 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_GV_PB_H_INCLUDED +#define PB_BSP_GV_PB_H_INCLUDED +#include "pb.h" +#include "msp_MK32.pb.h" +#include "msp_Motor.pb.h" +#include "msp_LS_MotorParameters.pb.h" +#include "msp_TL720D.pb.h" +#include "bsp_Error.pb.h" +#include "bsp_PV.pb.h" +#include "bsp_IO.pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _GV_struct_define { + int32_t TempatureE_2C; /* E_2C=0.01 Celsius 0.01摄氏度 */ + int32_t Left_Compensation; /* E_2D =0.01 Degree 0.01度 */ + int32_t Right_Compensation; /* 0.01度 */ + int32_t Robot_Angle; /* 机器人角度 //0.01度 */ + int32_t Robot_Move_Speed; /* 0.1rpm */ + int32_t ForceValue; + int32_t LaneChangeDistance; + bool has_P_MK32; + SP_MSP_MK32_Button P_MK32; + bool has_LeftMotor; + LS_MotorParameters LeftMotor; /* 左电机 ID2 */ + bool has_RightMotor; + LS_MotorParameters RightMotor; /* 右电机 ID3 */ + bool has_TL720DParameters; + MSP_TL720DParameters TL720DParameters; + bool has_IO; + IO_Data IO; + bool has_SystemErrorData; + ErrorData SystemErrorData; + bool has_PV; + PV_struct_define PV; /* 用户配置数据 */ +} GV_struct_define; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define GV_struct_define_init_default {0, 0, 0, 0, 0, 0, 0, false, SP_MSP_MK32_Button_init_default, false, LS_MotorParameters_init_default, false, LS_MotorParameters_init_default, false, MSP_TL720DParameters_init_default, false, IO_Data_init_default, false, ErrorData_init_default, false, PV_struct_define_init_default} +#define GV_struct_define_init_zero {0, 0, 0, 0, 0, 0, 0, false, SP_MSP_MK32_Button_init_zero, false, LS_MotorParameters_init_zero, false, LS_MotorParameters_init_zero, false, MSP_TL720DParameters_init_zero, false, IO_Data_init_zero, false, ErrorData_init_zero, false, PV_struct_define_init_zero} + +/* Field tags (for use in manual encoding/decoding) */ +#define GV_struct_define_TempatureE_2C_tag 1 +#define GV_struct_define_Left_Compensation_tag 2 +#define GV_struct_define_Right_Compensation_tag 3 +#define GV_struct_define_Robot_Angle_tag 4 +#define GV_struct_define_Robot_Move_Speed_tag 5 +#define GV_struct_define_ForceValue_tag 6 +#define GV_struct_define_LaneChangeDistance_tag 7 +#define GV_struct_define_P_MK32_tag 9 +#define GV_struct_define_LeftMotor_tag 10 +#define GV_struct_define_RightMotor_tag 11 +#define GV_struct_define_TL720DParameters_tag 12 +#define GV_struct_define_IO_tag 13 +#define GV_struct_define_SystemErrorData_tag 14 +#define GV_struct_define_PV_tag 15 + +/* Struct field encoding specification for nanopb */ +#define GV_struct_define_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, TempatureE_2C, 1) \ +X(a, STATIC, SINGULAR, INT32, Left_Compensation, 2) \ +X(a, STATIC, SINGULAR, INT32, Right_Compensation, 3) \ +X(a, STATIC, SINGULAR, INT32, Robot_Angle, 4) \ +X(a, STATIC, SINGULAR, INT32, Robot_Move_Speed, 5) \ +X(a, STATIC, SINGULAR, INT32, ForceValue, 6) \ +X(a, STATIC, SINGULAR, INT32, LaneChangeDistance, 7) \ +X(a, STATIC, OPTIONAL, MESSAGE, P_MK32, 9) \ +X(a, STATIC, OPTIONAL, MESSAGE, LeftMotor, 10) \ +X(a, STATIC, OPTIONAL, MESSAGE, RightMotor, 11) \ +X(a, STATIC, OPTIONAL, MESSAGE, TL720DParameters, 12) \ +X(a, STATIC, OPTIONAL, MESSAGE, IO, 13) \ +X(a, STATIC, OPTIONAL, MESSAGE, SystemErrorData, 14) \ +X(a, STATIC, OPTIONAL, MESSAGE, PV, 15) +#define GV_struct_define_CALLBACK NULL +#define GV_struct_define_DEFAULT NULL +#define GV_struct_define_P_MK32_MSGTYPE SP_MSP_MK32_Button +#define GV_struct_define_LeftMotor_MSGTYPE LS_MotorParameters +#define GV_struct_define_RightMotor_MSGTYPE LS_MotorParameters +#define GV_struct_define_TL720DParameters_MSGTYPE MSP_TL720DParameters +#define GV_struct_define_IO_MSGTYPE IO_Data +#define GV_struct_define_SystemErrorData_MSGTYPE ErrorData +#define GV_struct_define_PV_MSGTYPE PV_struct_define + +extern const pb_msgdesc_t GV_struct_define_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define GV_struct_define_fields &GV_struct_define_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_GV_PB_H_MAX_SIZE GV_struct_define_size +#define GV_struct_define_size 906 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.c new file mode 100644 index 0000000..991e03b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_IAP.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(IAP_struct_define, IAP_struct_define, AUTO) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.h new file mode 100644 index 0000000..e166370 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IAP.pb.h @@ -0,0 +1,58 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_IAP_PB_H_INCLUDED +#define PB_BSP_IAP_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* IAP,即In Application Programming,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写。 */ +typedef struct _IAP_struct_define { + int32_t Total_Bytes; /* all the received data; */ + int32_t NextCodeVrsion; /* the New upgrade Version of the Project */ + int32_t UtcTime; /* Udgrade Time */ + int32_t UpgradeSucceeded; /* */ +} IAP_struct_define; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define IAP_struct_define_init_default {0, 0, 0, 0} +#define IAP_struct_define_init_zero {0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define IAP_struct_define_Total_Bytes_tag 1 +#define IAP_struct_define_NextCodeVrsion_tag 2 +#define IAP_struct_define_UtcTime_tag 3 +#define IAP_struct_define_UpgradeSucceeded_tag 4 + +/* Struct field encoding specification for nanopb */ +#define IAP_struct_define_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, Total_Bytes, 1) \ +X(a, STATIC, SINGULAR, INT32, NextCodeVrsion, 2) \ +X(a, STATIC, SINGULAR, INT32, UtcTime, 3) \ +X(a, STATIC, SINGULAR, INT32, UpgradeSucceeded, 4) +#define IAP_struct_define_CALLBACK NULL +#define IAP_struct_define_DEFAULT NULL + +extern const pb_msgdesc_t IAP_struct_define_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define IAP_struct_define_fields &IAP_struct_define_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_IAP_PB_H_MAX_SIZE IAP_struct_define_size +#define IAP_struct_define_size 44 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.c new file mode 100644 index 0000000..6e56a6c --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_IO.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(IO_Data, IO_Data, AUTO) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.h new file mode 100644 index 0000000..28ae8f8 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IO.pb.h @@ -0,0 +1,81 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_IO_PB_H_INCLUDED +#define PB_BSP_IO_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _IO_Data { + int32_t DO0; + int32_t DO1; + int32_t DO2; + int32_t DO3; + int32_t DO4; + int32_t DO5; + int32_t DI0; + int32_t DI1; + int32_t DI2; + int32_t DI3; + int32_t DI4; + int32_t DI5; +} IO_Data; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define IO_Data_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define IO_Data_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define IO_Data_DO0_tag 1 +#define IO_Data_DO1_tag 2 +#define IO_Data_DO2_tag 3 +#define IO_Data_DO3_tag 4 +#define IO_Data_DO4_tag 5 +#define IO_Data_DO5_tag 6 +#define IO_Data_DI0_tag 7 +#define IO_Data_DI1_tag 8 +#define IO_Data_DI2_tag 9 +#define IO_Data_DI3_tag 10 +#define IO_Data_DI4_tag 11 +#define IO_Data_DI5_tag 12 + +/* Struct field encoding specification for nanopb */ +#define IO_Data_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, DO0, 1) \ +X(a, STATIC, SINGULAR, INT32, DO1, 2) \ +X(a, STATIC, SINGULAR, INT32, DO2, 3) \ +X(a, STATIC, SINGULAR, INT32, DO3, 4) \ +X(a, STATIC, SINGULAR, INT32, DO4, 5) \ +X(a, STATIC, SINGULAR, INT32, DO5, 6) \ +X(a, STATIC, SINGULAR, INT32, DI0, 7) \ +X(a, STATIC, SINGULAR, INT32, DI1, 8) \ +X(a, STATIC, SINGULAR, INT32, DI2, 9) \ +X(a, STATIC, SINGULAR, INT32, DI3, 10) \ +X(a, STATIC, SINGULAR, INT32, DI4, 11) \ +X(a, STATIC, SINGULAR, INT32, DI5, 12) +#define IO_Data_CALLBACK NULL +#define IO_Data_DEFAULT NULL + +extern const pb_msgdesc_t IO_Data_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define IO_Data_fields &IO_Data_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_IO_PB_H_MAX_SIZE IO_Data_size +#define IO_Data_size 132 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.c new file mode 100644 index 0000000..3e5a269 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_IV.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(IV_struct_define, IV_struct_define, AUTO) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.h new file mode 100644 index 0000000..423ef50 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_IV.pb.h @@ -0,0 +1,75 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_IV_PB_H_INCLUDED +#define PB_BSP_IV_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _IV_struct_define { + int32_t CurrentAngle; /* 单位0.01° */ + int32_t RobotMoveSpeed; /* 单位m/min 目标速度 */ + int32_t SBUS_State; /* 0断开 1连接 */ + int32_t SystemError; /* 硬件通讯错误及按键未初始化错误 */ + int32_t Left_Motor_Err; /* 左轮电机报警 */ + int32_t Right_Motor_Err; /* 右轮电机报警 */ + int32_t IsWorking; /* 机器人正在执行运动指令 */ + int32_t CurrentSpeed; /* 当前速度 */ + int64_t TimeStamp; /* 当前时间戳 */ + int32_t IsRestart; /* 是否重启 */ +} IV_struct_define; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define IV_struct_define_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define IV_struct_define_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define IV_struct_define_CurrentAngle_tag 1 +#define IV_struct_define_RobotMoveSpeed_tag 2 +#define IV_struct_define_SBUS_State_tag 3 +#define IV_struct_define_SystemError_tag 4 +#define IV_struct_define_Left_Motor_Err_tag 5 +#define IV_struct_define_Right_Motor_Err_tag 6 +#define IV_struct_define_IsWorking_tag 7 +#define IV_struct_define_CurrentSpeed_tag 8 +#define IV_struct_define_TimeStamp_tag 9 +#define IV_struct_define_IsRestart_tag 10 + +/* Struct field encoding specification for nanopb */ +#define IV_struct_define_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, CurrentAngle, 1) \ +X(a, STATIC, SINGULAR, INT32, RobotMoveSpeed, 2) \ +X(a, STATIC, SINGULAR, INT32, SBUS_State, 3) \ +X(a, STATIC, SINGULAR, INT32, SystemError, 4) \ +X(a, STATIC, SINGULAR, INT32, Left_Motor_Err, 5) \ +X(a, STATIC, SINGULAR, INT32, Right_Motor_Err, 6) \ +X(a, STATIC, SINGULAR, INT32, IsWorking, 7) \ +X(a, STATIC, SINGULAR, INT32, CurrentSpeed, 8) \ +X(a, STATIC, SINGULAR, INT64, TimeStamp, 9) \ +X(a, STATIC, SINGULAR, INT32, IsRestart, 10) +#define IV_struct_define_CALLBACK NULL +#define IV_struct_define_DEFAULT NULL + +extern const pb_msgdesc_t IV_struct_define_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define IV_struct_define_fields &IV_struct_define_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_IV_PB_H_MAX_SIZE IV_struct_define_size +#define IV_struct_define_size 110 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.c new file mode 100644 index 0000000..0000d2f --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.c @@ -0,0 +1,20 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_PID.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(PID_Parameters, PID_Parameters, AUTO) + + + +#ifndef PB_CONVERT_DOUBLE_FLOAT +/* On some platforms (such as AVR), double is really float. + * To be able to encode/decode double on these platforms, you need. + * to define PB_CONVERT_DOUBLE_FLOAT in pb.h or compiler command line. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) +#endif + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.h new file mode 100644 index 0000000..339179b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PID.pb.h @@ -0,0 +1,57 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_PID_PB_H_INCLUDED +#define PB_BSP_PID_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _PID_Parameters { + int32_t PID_Angle; /* 调整 单位0.01° 配置时需要*100 */ + double Kp; /* PID参数 */ + double Ki; + double Kd; +} PID_Parameters; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define PID_Parameters_init_default {0, 0, 0, 0} +#define PID_Parameters_init_zero {0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define PID_Parameters_PID_Angle_tag 1 +#define PID_Parameters_Kp_tag 2 +#define PID_Parameters_Ki_tag 3 +#define PID_Parameters_Kd_tag 4 + +/* Struct field encoding specification for nanopb */ +#define PID_Parameters_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, PID_Angle, 1) \ +X(a, STATIC, SINGULAR, DOUBLE, Kp, 2) \ +X(a, STATIC, SINGULAR, DOUBLE, Ki, 3) \ +X(a, STATIC, SINGULAR, DOUBLE, Kd, 4) +#define PID_Parameters_CALLBACK NULL +#define PID_Parameters_DEFAULT NULL + +extern const pb_msgdesc_t PID_Parameters_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define PID_Parameters_fields &PID_Parameters_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_PID_PB_H_MAX_SIZE PID_Parameters_size +#define PID_Parameters_size 38 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.c new file mode 100644 index 0000000..671a5c9 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.c @@ -0,0 +1,20 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_PV.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(PV_struct_define, PV_struct_define, AUTO) + + + +#ifndef PB_CONVERT_DOUBLE_FLOAT +/* On some platforms (such as AVR), double is really float. + * To be able to encode/decode double on these platforms, you need. + * to define PB_CONVERT_DOUBLE_FLOAT in pb.h or compiler command line. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) +#endif + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.h new file mode 100644 index 0000000..ab46cca --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_PV.pb.h @@ -0,0 +1,64 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_PV_PB_H_INCLUDED +#define PB_BSP_PV_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _PV_struct_define { + /* 喷漆项目 */ + int32_t RunMode; /* 1 手动无校准作业 2 手动竖直向左作业 3 手动竖直向右作业 */ + int32_t RobotSpeed; /* 0-30m/min */ + int32_t LaneChangeDistance; /* 1-100cm */ + double Vertical_Calibration; /* 1° */ + int32_t IV_IsRestart_Notified; /* 是否接收到IV restart flag */ + int64_t TimeStamp; /* */ +} PV_struct_define; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define PV_struct_define_init_default {0, 0, 0, 0, 0, 0} +#define PV_struct_define_init_zero {0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define PV_struct_define_RunMode_tag 1 +#define PV_struct_define_RobotSpeed_tag 2 +#define PV_struct_define_LaneChangeDistance_tag 3 +#define PV_struct_define_Vertical_Calibration_tag 4 +#define PV_struct_define_IV_IsRestart_Notified_tag 5 +#define PV_struct_define_TimeStamp_tag 6 + +/* Struct field encoding specification for nanopb */ +#define PV_struct_define_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, RunMode, 1) \ +X(a, STATIC, SINGULAR, INT32, RobotSpeed, 2) \ +X(a, STATIC, SINGULAR, INT32, LaneChangeDistance, 3) \ +X(a, STATIC, SINGULAR, DOUBLE, Vertical_Calibration, 4) \ +X(a, STATIC, SINGULAR, INT32, IV_IsRestart_Notified, 5) \ +X(a, STATIC, SINGULAR, INT64, TimeStamp, 6) +#define PV_struct_define_CALLBACK NULL +#define PV_struct_define_DEFAULT NULL + +extern const pb_msgdesc_t PV_struct_define_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define PV_struct_define_fields &PV_struct_define_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_PV_PB_H_MAX_SIZE PV_struct_define_size +#define PV_struct_define_size 64 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.c new file mode 100644 index 0000000..073320b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "bsp_ReCmd.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(ReCmd, ReCmd, 2) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.h new file mode 100644 index 0000000..724cf70 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/bsp_ReCmd.pb.h @@ -0,0 +1,80 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_BSP_RECMD_PB_H_INCLUDED +#define PB_BSP_RECMD_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +/* this message is used for the reply the command */ +typedef struct _ReCmd { + int32_t CommadNum; + /* 定义 1 上位机获取默认CV值 +定义 2 下位机返回CV值 +定义 3 上位机设定CV值 +定义 4 上位机设定Trace等级值,无返回 +定义 5 下位机上传位置点数据 +定义 6 上位机设定编码器角度值为0 +定义 7 上位机获取拟合点 +定义 8 上位机获取位置点 +定义 9 上位机向下位机下发程序 此时,Parameter0 下发的程序起始位,Parameter0 是校验位 +Buff_Data_Length 是下发的字节数, */ + int32_t Parameter0; + int32_t Parameter1; + int32_t Parameter2; + int32_t Parameter3; + int32_t Parameter4; + int32_t Buff_Data_Length; + pb_byte_t Buff_Data[512]; +} ReCmd; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define ReCmd_init_default {0, 0, 0, 0, 0, 0, 0, {0}} +#define ReCmd_init_zero {0, 0, 0, 0, 0, 0, 0, {0}} + +/* Field tags (for use in manual encoding/decoding) */ +#define ReCmd_CommadNum_tag 1 +#define ReCmd_Parameter0_tag 2 +#define ReCmd_Parameter1_tag 3 +#define ReCmd_Parameter2_tag 4 +#define ReCmd_Parameter3_tag 5 +#define ReCmd_Parameter4_tag 6 +#define ReCmd_Buff_Data_Length_tag 7 +#define ReCmd_Buff_Data_tag 8 + +/* Struct field encoding specification for nanopb */ +#define ReCmd_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, CommadNum, 1) \ +X(a, STATIC, SINGULAR, INT32, Parameter0, 2) \ +X(a, STATIC, SINGULAR, INT32, Parameter1, 3) \ +X(a, STATIC, SINGULAR, INT32, Parameter2, 4) \ +X(a, STATIC, SINGULAR, INT32, Parameter3, 5) \ +X(a, STATIC, SINGULAR, INT32, Parameter4, 6) \ +X(a, STATIC, SINGULAR, INT32, Buff_Data_Length, 7) \ +X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, Buff_Data, 8) +#define ReCmd_CALLBACK NULL +#define ReCmd_DEFAULT NULL + +extern const pb_msgdesc_t ReCmd_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define ReCmd_fields &ReCmd_msg + +/* Maximum encoded size of messages (where known) */ +#define BSP_RECMD_PB_H_MAX_SIZE ReCmd_size +#define ReCmd_size 592 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.c new file mode 100644 index 0000000..42ca3bb --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.c @@ -0,0 +1,20 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "msp_LS_MotorParameters.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(LS_MotorParameters, LS_MotorParameters, AUTO) + + + +#ifndef PB_CONVERT_DOUBLE_FLOAT +/* On some platforms (such as AVR), double is really float. + * To be able to encode/decode double on these platforms, you need. + * to define PB_CONVERT_DOUBLE_FLOAT in pb.h or compiler command line. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) +#endif + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.h new file mode 100644 index 0000000..948c0d3 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_LS_MotorParameters.pb.h @@ -0,0 +1,84 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_MSP_LS_MOTORPARAMETERS_PB_H_INCLUDED +#define PB_MSP_LS_MOTORPARAMETERS_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _LS_MotorParameters { + int32_t MotorID; + int32_t Real_Current; + int32_t Target_Current; /* 0.1rpm */ + int32_t Real_Velcity; /* 0.1rpm */ + int32_t Target_Velcity; /* 0.1rpm */ + int32_t Target_Position; /* 0.1rpm */ + int32_t Real_Position; + int32_t Motor_Fault; + int32_t Number_Of_Rounds; + int32_t Start_Measuring_Position; + int32_t Last_Real_Position; + double Real_Disatnce; + int32_t Start_Measuring; /* 开始测距 */ +} LS_MotorParameters; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define LS_MotorParameters_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define LS_MotorParameters_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define LS_MotorParameters_MotorID_tag 1 +#define LS_MotorParameters_Real_Current_tag 2 +#define LS_MotorParameters_Target_Current_tag 3 +#define LS_MotorParameters_Real_Velcity_tag 4 +#define LS_MotorParameters_Target_Velcity_tag 5 +#define LS_MotorParameters_Target_Position_tag 6 +#define LS_MotorParameters_Real_Position_tag 7 +#define LS_MotorParameters_Motor_Fault_tag 8 +#define LS_MotorParameters_Number_Of_Rounds_tag 9 +#define LS_MotorParameters_Start_Measuring_Position_tag 10 +#define LS_MotorParameters_Last_Real_Position_tag 11 +#define LS_MotorParameters_Real_Disatnce_tag 12 +#define LS_MotorParameters_Start_Measuring_tag 13 + +/* Struct field encoding specification for nanopb */ +#define LS_MotorParameters_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, MotorID, 1) \ +X(a, STATIC, SINGULAR, INT32, Real_Current, 2) \ +X(a, STATIC, SINGULAR, INT32, Target_Current, 3) \ +X(a, STATIC, SINGULAR, INT32, Real_Velcity, 4) \ +X(a, STATIC, SINGULAR, INT32, Target_Velcity, 5) \ +X(a, STATIC, SINGULAR, INT32, Target_Position, 6) \ +X(a, STATIC, SINGULAR, INT32, Real_Position, 7) \ +X(a, STATIC, SINGULAR, INT32, Motor_Fault, 8) \ +X(a, STATIC, SINGULAR, INT32, Number_Of_Rounds, 9) \ +X(a, STATIC, SINGULAR, INT32, Start_Measuring_Position, 10) \ +X(a, STATIC, SINGULAR, INT32, Last_Real_Position, 11) \ +X(a, STATIC, SINGULAR, DOUBLE, Real_Disatnce, 12) \ +X(a, STATIC, SINGULAR, INT32, Start_Measuring, 13) +#define LS_MotorParameters_CALLBACK NULL +#define LS_MotorParameters_DEFAULT NULL + +extern const pb_msgdesc_t LS_MotorParameters_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define LS_MotorParameters_fields &LS_MotorParameters_msg + +/* Maximum encoded size of messages (where known) */ +#define LS_MotorParameters_size 141 +#define MSP_LS_MOTORPARAMETERS_PB_H_MAX_SIZE LS_MotorParameters_size + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.c new file mode 100644 index 0000000..4c16c0b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "msp_MK32.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(SP_MSP_MK32_Button, SP_MSP_MK32_Button, AUTO) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.h new file mode 100644 index 0000000..d707cb7 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_MK32.pb.h @@ -0,0 +1,99 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_MSP_MK32_PB_H_INCLUDED +#define PB_MSP_MK32_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _SP_MSP_MK32_Button { + int32_t RxIndex; + int32_t CH0_RY_H; /* 上1000,下-1000 */ + int32_t CH1_RY_V; /* 上1000,下-1000 */ + int32_t CH2_LY_V; /* 上1000,下-1000 */ + int32_t CH3_LY_H; /* 上1000,下-1000 */ + int32_t CH4_SA; /* 上-1000,下1000 */ + int32_t CH5_SB; /* 上-1000,下1000 */ + int32_t CH6_SC; /* 上-1000,下1000 */ + int32_t CH7_SD; /* 上-1000,下1000 */ + int32_t CH8_SE; /* 上-1000,下1000 */ + int32_t CH9_SF; /* 上-1000,下1000 */ + int32_t CH10_LD1; + int32_t CH11_RD1; + int32_t CH12_S1; + int32_t CH13_S2; + int32_t CH14_LT; + int32_t CH15_RT; + int32_t IsOnline; +} SP_MSP_MK32_Button; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define SP_MSP_MK32_Button_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define SP_MSP_MK32_Button_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define SP_MSP_MK32_Button_RxIndex_tag 1 +#define SP_MSP_MK32_Button_CH0_RY_H_tag 2 +#define SP_MSP_MK32_Button_CH1_RY_V_tag 3 +#define SP_MSP_MK32_Button_CH2_LY_V_tag 4 +#define SP_MSP_MK32_Button_CH3_LY_H_tag 5 +#define SP_MSP_MK32_Button_CH4_SA_tag 6 +#define SP_MSP_MK32_Button_CH5_SB_tag 7 +#define SP_MSP_MK32_Button_CH6_SC_tag 8 +#define SP_MSP_MK32_Button_CH7_SD_tag 9 +#define SP_MSP_MK32_Button_CH8_SE_tag 10 +#define SP_MSP_MK32_Button_CH9_SF_tag 11 +#define SP_MSP_MK32_Button_CH10_LD1_tag 12 +#define SP_MSP_MK32_Button_CH11_RD1_tag 13 +#define SP_MSP_MK32_Button_CH12_S1_tag 14 +#define SP_MSP_MK32_Button_CH13_S2_tag 15 +#define SP_MSP_MK32_Button_CH14_LT_tag 16 +#define SP_MSP_MK32_Button_CH15_RT_tag 17 +#define SP_MSP_MK32_Button_IsOnline_tag 18 + +/* Struct field encoding specification for nanopb */ +#define SP_MSP_MK32_Button_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, RxIndex, 1) \ +X(a, STATIC, SINGULAR, INT32, CH0_RY_H, 2) \ +X(a, STATIC, SINGULAR, INT32, CH1_RY_V, 3) \ +X(a, STATIC, SINGULAR, INT32, CH2_LY_V, 4) \ +X(a, STATIC, SINGULAR, INT32, CH3_LY_H, 5) \ +X(a, STATIC, SINGULAR, INT32, CH4_SA, 6) \ +X(a, STATIC, SINGULAR, INT32, CH5_SB, 7) \ +X(a, STATIC, SINGULAR, INT32, CH6_SC, 8) \ +X(a, STATIC, SINGULAR, INT32, CH7_SD, 9) \ +X(a, STATIC, SINGULAR, INT32, CH8_SE, 10) \ +X(a, STATIC, SINGULAR, INT32, CH9_SF, 11) \ +X(a, STATIC, SINGULAR, INT32, CH10_LD1, 12) \ +X(a, STATIC, SINGULAR, INT32, CH11_RD1, 13) \ +X(a, STATIC, SINGULAR, INT32, CH12_S1, 14) \ +X(a, STATIC, SINGULAR, INT32, CH13_S2, 15) \ +X(a, STATIC, SINGULAR, INT32, CH14_LT, 16) \ +X(a, STATIC, SINGULAR, INT32, CH15_RT, 17) \ +X(a, STATIC, SINGULAR, INT32, IsOnline, 18) +#define SP_MSP_MK32_Button_CALLBACK NULL +#define SP_MSP_MK32_Button_DEFAULT NULL + +extern const pb_msgdesc_t SP_MSP_MK32_Button_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define SP_MSP_MK32_Button_fields &SP_MSP_MK32_Button_msg + +/* Maximum encoded size of messages (where known) */ +#define MSP_MK32_PB_H_MAX_SIZE SP_MSP_MK32_Button_size +#define SP_MSP_MK32_Button_size 201 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.c new file mode 100644 index 0000000..b1c1176 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "msp_Motor.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(MotorParameters, MotorParameters, AUTO) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.h new file mode 100644 index 0000000..44fcab2 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_Motor.pb.h @@ -0,0 +1,91 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_MSP_MOTOR_PB_H_INCLUDED +#define PB_MSP_MOTOR_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _MotorParameters { + int32_t MotorID; + int32_t RxIndex; + int32_t Run_Mode; + int32_t Current; + int32_t Target_Current; + int32_t Velcity; + int32_t Target_Velcity; + int32_t Position; + int32_t Target_Position; + int32_t ERROR_Flag; + int32_t Temperature_Motor; + int32_t Temperature_PCB; + int32_t AccTime; + int32_t DecTime; + int32_t EncoderOffset; /* 53 83 设置位置偏移 int32_t "设置偏移值和目标位置 +(目标位置=编码器位置 - 偏移值)" */ +} MotorParameters; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define MotorParameters_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} +#define MotorParameters_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define MotorParameters_MotorID_tag 1 +#define MotorParameters_RxIndex_tag 2 +#define MotorParameters_Run_Mode_tag 3 +#define MotorParameters_Current_tag 4 +#define MotorParameters_Target_Current_tag 5 +#define MotorParameters_Velcity_tag 6 +#define MotorParameters_Target_Velcity_tag 7 +#define MotorParameters_Position_tag 8 +#define MotorParameters_Target_Position_tag 9 +#define MotorParameters_ERROR_Flag_tag 10 +#define MotorParameters_Temperature_Motor_tag 11 +#define MotorParameters_Temperature_PCB_tag 12 +#define MotorParameters_AccTime_tag 13 +#define MotorParameters_DecTime_tag 14 +#define MotorParameters_EncoderOffset_tag 15 + +/* Struct field encoding specification for nanopb */ +#define MotorParameters_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, MotorID, 1) \ +X(a, STATIC, SINGULAR, INT32, RxIndex, 2) \ +X(a, STATIC, SINGULAR, INT32, Run_Mode, 3) \ +X(a, STATIC, SINGULAR, INT32, Current, 4) \ +X(a, STATIC, SINGULAR, INT32, Target_Current, 5) \ +X(a, STATIC, SINGULAR, INT32, Velcity, 6) \ +X(a, STATIC, SINGULAR, INT32, Target_Velcity, 7) \ +X(a, STATIC, SINGULAR, INT32, Position, 8) \ +X(a, STATIC, SINGULAR, INT32, Target_Position, 9) \ +X(a, STATIC, SINGULAR, INT32, ERROR_Flag, 10) \ +X(a, STATIC, SINGULAR, INT32, Temperature_Motor, 11) \ +X(a, STATIC, SINGULAR, INT32, Temperature_PCB, 12) \ +X(a, STATIC, SINGULAR, INT32, AccTime, 13) \ +X(a, STATIC, SINGULAR, INT32, DecTime, 14) \ +X(a, STATIC, SINGULAR, INT32, EncoderOffset, 15) +#define MotorParameters_CALLBACK NULL +#define MotorParameters_DEFAULT NULL + +extern const pb_msgdesc_t MotorParameters_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define MotorParameters_fields &MotorParameters_msg + +/* Maximum encoded size of messages (where known) */ +#define MSP_MOTOR_PB_H_MAX_SIZE MotorParameters_size +#define MotorParameters_size 165 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.c b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.c new file mode 100644 index 0000000..4681edd --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.c @@ -0,0 +1,12 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.8 */ + +#include "msp_TL720D.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(MSP_TL720DParameters, MSP_TL720DParameters, AUTO) + + + diff --git a/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.h b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.h new file mode 100644 index 0000000..6020cd6 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/PSource/msp_TL720D.pb.h @@ -0,0 +1,72 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_MSP_TL720D_PB_H_INCLUDED +#define PB_MSP_TL720D_PB_H_INCLUDED +#include "pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _MSP_TL720DParameters { + int32_t RF_Angle_Roll; /* 横滚角 */ + int32_t RF_Angle_Pitch; /* 俯仰角 */ + int32_t RF_Angle_Yaw; /* 航向角 */ + int32_t RF_Acc_X; /* X轴加速度 */ + int32_t RF_Acc_Y; /* Y轴加速度 */ + int32_t RF_Acc_Z; /* Z轴加速度 */ + int32_t RF_Gro_X; /* X轴陀螺 */ + int32_t RF_Gro_Y; /* Y轴陀螺 */ + int32_t RF_Gro_Z; /* Z轴陀螺 */ +} MSP_TL720DParameters; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define MSP_TL720DParameters_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0} +#define MSP_TL720DParameters_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define MSP_TL720DParameters_RF_Angle_Roll_tag 1 +#define MSP_TL720DParameters_RF_Angle_Pitch_tag 2 +#define MSP_TL720DParameters_RF_Angle_Yaw_tag 3 +#define MSP_TL720DParameters_RF_Acc_X_tag 4 +#define MSP_TL720DParameters_RF_Acc_Y_tag 5 +#define MSP_TL720DParameters_RF_Acc_Z_tag 6 +#define MSP_TL720DParameters_RF_Gro_X_tag 7 +#define MSP_TL720DParameters_RF_Gro_Y_tag 8 +#define MSP_TL720DParameters_RF_Gro_Z_tag 9 + +/* Struct field encoding specification for nanopb */ +#define MSP_TL720DParameters_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, RF_Angle_Roll, 1) \ +X(a, STATIC, SINGULAR, INT32, RF_Angle_Pitch, 2) \ +X(a, STATIC, SINGULAR, INT32, RF_Angle_Yaw, 3) \ +X(a, STATIC, SINGULAR, INT32, RF_Acc_X, 4) \ +X(a, STATIC, SINGULAR, INT32, RF_Acc_Y, 5) \ +X(a, STATIC, SINGULAR, INT32, RF_Acc_Z, 6) \ +X(a, STATIC, SINGULAR, INT32, RF_Gro_X, 7) \ +X(a, STATIC, SINGULAR, INT32, RF_Gro_Y, 8) \ +X(a, STATIC, SINGULAR, INT32, RF_Gro_Z, 9) +#define MSP_TL720DParameters_CALLBACK NULL +#define MSP_TL720DParameters_DEFAULT NULL + +extern const pb_msgdesc_t MSP_TL720DParameters_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define MSP_TL720DParameters_fields &MSP_TL720DParameters_msg + +/* Maximum encoded size of messages (where known) */ +#define MSP_TL720DParameters_size 99 +#define MSP_TL720D_PB_H_MAX_SIZE MSP_TL720DParameters_size + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_CV.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_CV.proto new file mode 100644 index 0000000..b950f9f --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_CV.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +//import "nanopb.proto"; + +import "bsp_PV.proto"; +import "bsp_PID.proto"; +message CV_struct_define{ + + //喷漆项目 + + int32 Speed_m_per_min = 1; // MPMin = 1m/min 1米每分钟 m/min + + int32 LeftTurnSpeed = 2; + int32 RightTurnSpeed = 3; + + + + int32 RobotLeftAngleValue=4;// 水平左方向 单位0.01° + int32 RobotRightAngleValue=5;// 水平右方向角度值 单位0.01° + int32 RobotUpAngleValue=6;// 竖直方向角度值 单位0.01° + int32 RobotDownAngleValue=7;// 竖直向下角度值 单位0.01° + + int32 Robot_Permitted_Angler_Error_Value_E_2D = 8;// 作业时需用的最大角度偏差值 0.01°,超出将停止作业 + int32 Robot_Angle_Start_BaseE_2D = 9;//角度值 0.01° + int32 Lane_Change_Speed_m_per_min = 10; + int32 Is_Automation_Authorized = 11; + int32 Is_Function_Authorized = 12; + int32 Joy_Sticker_Angle_Allowance = 13;// 例如在90度的±30° + int32 Joy_Sticker_Value_Allowance = 14;//例如 joysticker的值超过600 + int32 Allowable_Error_For_Angle_Tracking = 15;//纠偏角度跟踪的允许误差1 度 + int32 Paint_Gun_Shutdown_Distance = 16;//喷枪关闭距离,喷枪关闭后多上厘米停止运行 + int32 Horizontal_ChangeLane_Compensation=17; //水平换道补偿距离 + int32 Vertical_ChangeLane_Compensation=18; //竖直换道补偿距离 + int32 pulse_Per_Circle=19; //每转多少脉冲 + int32 wheel_Reduction_Ratio=20; //减速比 + double wheel_Diameter_m=21; //车轮直径 m + PID_Parameters PID_high=22; + PID_Parameters PID_mid=23; + PID_Parameters PID_low=24; + + + } + diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.options b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.options new file mode 100644 index 0000000..771dbaf --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.options @@ -0,0 +1,2 @@ +# lock.options +Cmd.Buff_Data max_size:512 fixed_length:true \ No newline at end of file diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.proto new file mode 100644 index 0000000..d7a4f13 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Cmd.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +//this message is used for the computer to send command +message Cmd{ + int32 CommadNum = 1; + //定义 1 上位机获取默认CV值 + //定义 2 下位机返回CV值 + //定义 3 上位机设定CV值 + //定义 4 上位机设定Trace等级值,无返回 + //定义 5 下位机上传位置点数据 + //定义 6 上位机设定编码器角度值为0 + //定义 7 上位机获取拟合点 + //定义 8 上位机获取位置点 + //定义 9 上位机向下位机下发程序 此时,Parameter0 下发的程序起始位,Parameter0 是校验位 + //Buff_Data_Length 是下发的字节数, + int32 Parameter0 = 2; + int32 Parameter1 = 3; + int32 Parameter2 = 4; + int32 Parameter3 = 5; + int32 Parameter4 = 6; + int32 Buff_Data_Length = 7; + bytes Buff_Data=8; + +}; + diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Error.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Error.proto new file mode 100644 index 0000000..951f75a --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_Error.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +option java_multiple_files = false; +option java_package = "com.example.paintapp.models"; + +message ErrorData +{ + int32 Com_Error_Code=1; + int32 Left_Motor_Error_Code=2; + int32 Right_Motor_Error_Code=3; + +} + +enum ComError //枚举消息类型 Error Bit Define + { + MK32_SBus = 0; + TL720D = 1; + LS_LeftMotor = 2; + LS_RightMotor = 3; + Remote_Button_Reset_State = 4; + MK32_Serial=5; + MK32_UDP=6; + } + +//protoc --nanopb_out=. *.proto diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.options b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.options new file mode 100644 index 0000000..b2dc56d --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.options @@ -0,0 +1,2 @@ +# lock.options +GV_struct_define.Motor_P max_size:50 fixed_length:true diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.proto new file mode 100644 index 0000000..ad19e79 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_GV.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; +import "msp_MK32.proto"; +import "msp_Motor.proto"; +import "msp_LS_MotorParameters.proto"; +import "msp_TL720D.proto"; +import "bsp_Error.proto"; +import "bsp_PV.proto"; +import "bsp_IO.proto"; + +message GV_struct_define +{ + int32 TempatureE_2C= 1; // E_2C=0.01 Celsius 0.01摄氏度 + int32 Left_Compensation= 2; // E_2D =0.01 Degree 0.01度 + int32 Right_Compensation= 3; //0.01度 + int32 Robot_Angle=4; //机器人角度 //0.01度 + int32 Robot_Move_Speed= 5; // 0.1rpm + int32 ForceValue= 6; + int32 LaneChangeDistance= 7; + SP_MSP_MK32_Button P_MK32=9; + LS_MotorParameters LeftMotor=10;//左电机 ID2 + LS_MotorParameters RightMotor=11;// 右电机 ID3 + MSP_TL720DParameters TL720DParameters= 12; + IO_Data IO=13; + ErrorData SystemErrorData=14; + PV_struct_define PV =15;//用户配置数据 + +}; + +//protoc --nanopb_out=. *.proto diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.options b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.options new file mode 100644 index 0000000..21bd11a --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.options @@ -0,0 +1,2 @@ +# lock.options +# IAP_struct_define.Buff_Data max_size:64 fixed_length:true \ No newline at end of file diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.proto new file mode 100644 index 0000000..3f4ca5e --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IAP.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +//IAP,即In Application Programming,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写。 +message IAP_struct_define +{ + int32 Total_Bytes = 1;// all the received data; + int32 NextCodeVrsion = 2;//the New upgrade Version of the Project + int32 UtcTime=3;//Udgrade Time + int32 UpgradeSucceeded=4;// + +}; + diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IO.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IO.proto new file mode 100644 index 0000000..9266692 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IO.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +message IO_Data +{ + int32 DO0=1; + int32 DO1=2; + int32 DO2=3; + int32 DO3=4; + int32 DO4=5; + int32 DO5=6; + int32 DI0=7; + int32 DI1=8; + int32 DI2=9; + int32 DI3=10; + int32 DI4=11; + int32 DI5=12; +}; + +//protoc --nanopb_out=. *.proto diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IV.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IV.proto new file mode 100644 index 0000000..449f519 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_IV.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +option java_multiple_files = false; +option java_package = "com.example.paintapp.models"; + +message IV_struct_define +{ + int32 CurrentAngle= 1; //单位0.01° + int32 RobotMoveSpeed= 2; //单位m/min 目标速度 + int32 SBUS_State=3; //0断开 1连接 + int32 SystemError=4; //硬件通讯错误及按键未初始化错误 + int32 Left_Motor_Err=5;//左轮电机报警 + int32 Right_Motor_Err=6;//右轮电机报警 + int32 IsWorking=7;//机器人正在执行运动指令 + int32 CurrentSpeed=8;//当前速度 + int64 TimeStamp=9;//当前时间戳 + int32 IsRestart=10;//是否重启 +}; diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PID.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PID.proto new file mode 100644 index 0000000..94d715a --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PID.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; + +message PID_Parameters { + int32 PID_Angle=1; //调整 单位0.01° 配置时需要*100 + double Kp=2; //PID参数 + double Ki=3; + double Kd=4; + + } \ No newline at end of file diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PV.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PV.proto new file mode 100644 index 0000000..f96f75e --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_PV.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +option java_multiple_files = false; +option java_package = "com.example.paintapp.models"; +message PV_struct_define{ + + // 喷漆项目 + int32 RunMode = 1; //1 手动无校准作业 2 手动竖直向左作业 3 手动竖直向右作业 + int32 RobotSpeed=2;//0-30m/min + int32 LaneChangeDistance= 3;//1-100cm + double Vertical_Calibration=4;// 1° + int32 IV_IsRestart_Notified=5;// 是否接收到IV restart flag + int64 TimeStamp=6;// + + +}; diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.options b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.options new file mode 100644 index 0000000..4890dc5 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.options @@ -0,0 +1,2 @@ +# lock.options +ReCmd.Buff_Data max_size:512 fixed_length:true \ No newline at end of file diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.proto new file mode 100644 index 0000000..13ed44d --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/bsp_ReCmd.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +//this message is used for the reply the command +message ReCmd{ + int32 CommadNum = 1; + //定义 1 上位机获取默认CV值 + //定义 2 下位机返回CV值 + //定义 3 上位机设定CV值 + //定义 4 上位机设定Trace等级值,无返回 + //定义 5 下位机上传位置点数据 + //定义 6 上位机设定编码器角度值为0 + //定义 7 上位机获取拟合点 + //定义 8 上位机获取位置点 + //定义 9 上位机向下位机下发程序 此时,Parameter0 下发的程序起始位,Parameter0 是校验位 + //Buff_Data_Length 是下发的字节数, + int32 Parameter0 = 2; + int32 Parameter1 = 3; + int32 Parameter2 = 4; + int32 Parameter3 = 5; + int32 Parameter4 = 6; + int32 Buff_Data_Length = 7; + bytes Buff_Data=8; + +}; + diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_LS_MotorParameters.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_LS_MotorParameters.proto new file mode 100644 index 0000000..458aace --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_LS_MotorParameters.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +message LS_MotorParameters { + int32 MotorID=1; + int32 Real_Current=2; + int32 Target_Current=3; // 0.1rpm + int32 Real_Velcity=4; // 0.1rpm + int32 Target_Velcity=5; // 0.1rpm + int32 Target_Position=6; // 0.1rpm + int32 Real_Position=7; + int32 Motor_Fault=8; + int32 Number_Of_Rounds=9; + int32 Start_Measuring_Position=10; + int32 Last_Real_Position=11; + double Real_Disatnce=12; + int32 Start_Measuring=13;//开始测距 + + } + diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_MK32.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_MK32.proto new file mode 100644 index 0000000..f7380f1 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_MK32.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +message SP_MSP_MK32_Button { + int32 RxIndex= 1; + int32 CH0_RY_H= 2;//上1000,下-1000 + int32 CH1_RY_V= 3; //上1000,下-1000 + int32 CH2_LY_V= 4;//上1000,下-1000 + int32 CH3_LY_H= 5;//上1000,下-1000 + int32 CH4_SA= 6;//上-1000,下1000 + int32 CH5_SB= 7;//上-1000,下1000 + int32 CH6_SC= 8;//上-1000,下1000 + int32 CH7_SD= 9;//上-1000,下1000 + int32 CH8_SE= 10;//上-1000,下1000 + int32 CH9_SF= 11;//上-1000,下1000 + int32 CH10_LD1= 12; + int32 CH11_RD1= 13; + int32 CH12_S1= 14; + int32 CH13_S2= 15; + int32 CH14_LT= 16; + int32 CH15_RT= 17; + int32 IsOnline= 18; + } diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_Motor.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_Motor.proto new file mode 100644 index 0000000..129d5b4 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_Motor.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; + +message MotorParameters{ + int32 MotorID=1; + int32 RxIndex=2; + int32 Run_Mode=3; + int32 Current=4; + int32 Target_Current=5; + int32 Velcity=6; + int32 Target_Velcity=7; + int32 Position=8; + int32 Target_Position=9; + int32 ERROR_Flag=10; + int32 Temperature_Motor=11; + int32 Temperature_PCB=12; + int32 AccTime=13; + int32 DecTime=14; + int32 EncoderOffset=15; + //53 83 设置位置偏移 int32_t "设置偏移值和目标位置 + //(目标位置=编码器位置 - 偏移值)" + +}; + diff --git a/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_TL720D.proto b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_TL720D.proto new file mode 100644 index 0000000..ad58377 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Protobuf/Proto/msp_TL720D.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +//import "nanopb.proto"; + +message MSP_TL720DParameters{ + + int32 RF_Angle_Roll=1; /*横滚角*/ + int32 RF_Angle_Pitch=2; /*俯仰角*/ + int32 RF_Angle_Yaw=3; /*航向角*/ + + int32 RF_Acc_X=4; /*X轴加速度*/ + int32 RF_Acc_Y=5; /*Y轴加速度*/ + int32 RF_Acc_Z=6; /*Z轴加速度*/ + + int32 RF_Gro_X=7; /*X轴陀螺*/ + int32 RF_Gro_Y=8; /*Y轴陀螺*/ + int32 RF_Gro_Z=9; /*Z轴陀螺*/ + + +}; + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/BHBF_ROBOT.c b/project_old/paint_robot_old/BASE/Src/BSP/BHBF_ROBOT.c new file mode 100644 index 0000000..e28c982 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/BHBF_ROBOT.c @@ -0,0 +1,127 @@ +/* + * BHBF_ROBOT.c + * + * Created on: Oct 26, 2023 + * Author: shiya + */ +#include "fsm.h" +#include "BHBF_ROBOT.h" +#include + + +#include "bsp_FDCAN.h" + + + + + + +int32_t* SystemTimeMiliSeconds; //似乎未用 +int32_t SystemTimeMiliCount; //2ms加一 + +int32_t* SystemErrorCode; +ErrorData* SystemErrorData; + + + + + +//Declare a CV and initialize CV +CV_struct_define CV = +{ 0 }; + + + + +//Declare a GV and initialize CV +GV_struct_define GV = +{ 0 }; + +PV_struct_define decoded_PV_variable = { 0 }; +PV_struct_define decoded_PV = { 0 }; +PV_struct_define _decoded_PV_temp = { 0 }; + +IV_struct_define IV ={ 0 }; + + + +void SET_BIT_1(int32_t* num,int32_t k) +{ + *num=((*num) | (1 << (k))); +} +void SET_BIT_0(int32_t* num,int32_t k) +{ + *num=((*num) & ~(1 << (k))); +} +int32_t Get_BIT(int32_t* num,int32_t k) +{ + return (*num >> (k)) & 1; +} + + + +void SystemTimer_Intialize() +{ + SystemTimeMiliCount=0; + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, GF_Timer_Count); +} + +void GF_Timer_Count() +{ + SystemTimeMiliCount++; +} + + +Sys_timer_handler timer_handler_1; +Sys_timer_handler timer_handler_2; +Sys_timer_handler timer_handler_3; +Sys_timer_handler timer_handler_4; + + + +int sys_timer_1_flag_count[4]; + + + + +bool CompareTimer(int32_t DelayMiliSeconds,Sys_timer_handler * timer_handler) +{ + if(timer_handler->start_timer==1) + { + timer_handler->sys_current_timer_count=DelayMiliSeconds/2+SystemTimeMiliCount; + timer_handler->start_timer=0; + } + if(timer_handler->sys_current_timer_count<=SystemTimeMiliCount) + { + return true; + }else + { + return false; + } + +} +bool CompareTimer_Delay(int32_t Delay) +{ + + + int32_t tickstart = SystemTimeMiliCount; + int32_t wait = Delay; + + /* Add a freq to guarantee minimum wait */ + if (wait < HAL_MAX_DELAY) + { + int32_t wait = Delay; + while ((SystemTimeMiliCount - tickstart) < wait/2) + { + } + } + +} +/*m/min--->0.1m/min 其实就是×10*/ +int32_t speed_M_min_toE01_M_min(int32_t speedm_min) +{ + return speedm_min*10; +} + + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/DLT/DLTuc.c b/project_old/paint_robot_old/BASE/Src/BSP/DLT/DLTuc.c new file mode 100644 index 0000000..b226900 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/DLT/DLTuc.c @@ -0,0 +1,636 @@ +/** + * @file DLTuc.c + * @author Teodor Rosolowski + * @date 1 Jul 2022 + * @brief This file is a part of DLTuc library + * + * In this source file you will find entire implementation of the DLTuc lib. + * + * Requirments: + * Around ~2kB of RAM + * Check Configuration file and defines: + * DLT_TRANSMIT_RING_BUFFER_SIZE, DLT_TRANSMIT_MAX_SINGLE_MESSAGE_SIZE + * + */ + +/* + * ******************************************************************************************* + * Includes + * ******************************************************************************************* + * */ +#include "DLTuc.h" + +#include "stdio.h" +#include "stdint.h" + +#include "stdbool.h" +#include +#include + +/* + * ******************************************************************************************* + * Local defines + * ******************************************************************************************* + * */ + +/**! +* \brief DLT_ACT_HEADER_SIZE - actual DLT header size +* \details Standard Header + Extended + TypeInfo +* Don't modify it if you aren't sure what are you doing!!! +*/ +#define DLT_ACT_HEADER_SIZE 32 + +/**! +* \brief DLT_MINIMUM_LOG_DROP_PERIOD +* \details minimum period between two drop info log +*/ +#define DLT_MINIMUM_LOG_DROP_PERIOD 200 + +/* + * ******************************************************************************************* + * Local types + * ******************************************************************************************* + * */ + +/* Prototypes to improve readability.. */ +/*typedefs for future use..*/ +// typedef +// { +// uint32_t HeaderStart; +// BaseHeaderConfig_t BaseHeaderConfig; +// uint8_t MessageCounter; +// uint16_t MessageLength; +// uint32_t EcuId; +// uint32_t TimeStamp; +// }DLT_BaseHeader_t; + +// typedef +// { +// DLT_DebugLevel_t DebugLevel; +// uint8_t NumberOfArguments; +// uint32_t AppId; +// uint32_t ContexID; +// TypeInfo_t TypeInfo; +// uint16_t Argument1; +// }DLT_ExtendedHeader_t; + + +//char DLT_LOG_ENABLE_LEVEL= 7; +char DLT_LOG_ENABLE_LEVEL= 0; +/**! + * \brief RB_Status + * \details --- + * */ +typedef enum +{ + RB_OK = 0, + RB_ERROR = 1 +} RB_Status; + +/**! + * \brief DltRingBufferTransmit_t + * \details --- + * */ +typedef struct DltRingBufferTransmit_Tag +{ + uint16_t Head; // Pointer to write + uint16_t Tail; // Pointer to read + bool readyToTransmit[DLT_TRANSMIT_RING_BUFFER_SIZE]; + uint8_t dataSize[DLT_TRANSMIT_RING_BUFFER_SIZE]; // Array to keep message size +} DltRingBufferTransmit_t; + +/**! + * \brief BluRingBufferReceive_t + * \details --- + * */ +typedef struct BluRingBufferReceive_Tag +{ + + uint16_t Head; // Pointer to write + uint16_t Tail; // Pointer to read + uint8_t MessageSize[DLT_RECEIVE_RING_BUFFER_SIZE]; // Array to keep message size + bool ReadyToRead[DLT_RECEIVE_RING_BUFFER_SIZE]; +} BluRingBufferReceive_t; + +/** + * ******************************************************************************************* + * Static variables + * ******************************************************************************************* + * */ + +/**! + * \brief ExtSerialTrDataFunctionCb + * \details --- + * */ +static void (*ExtSerialTrDataFunctionCb)(uint8_t *DltLogData, uint8_t Size); + +static void (*ExtSerialRecDataFunctionCb)(uint8_t *RecDataBuff, uint16_t Size); + +static void (*ExtInfoInjectionDataRcvdCb)(uint32_t AppId, uint32_t ConId,uint32_t ServId,uint8_t *Data, uint16_t Size); + +static uint32_t (*GetSystemTimeMs)(void); + +/**! + * \brief LogDroppedFlag + * \details --- + * */ +static bool LogDroppedFlag =false; + +static uint32_t PrevLogDropSendTime = 0u; + +static uint8_t DltLogDroppedInfo[] = "LOG DROPPED!!!"; + +static uint8_t DltLogDroppedInfoBuffer[60] = {0}; /* TODO: Remove magic number..*/ + +static uint8_t DLtLogDroppedSize = 0; + +static uint8_t ActDltMessageCounter =0; + +static DltRingBufferTransmit_t DltTrsmtRingBuffer = {.readyToTransmit[0]=true}; + +static uint8_t DltTrsmtMessagesTab[DLT_TRANSMIT_RING_BUFFER_SIZE][DLT_TRANSMIT_MAX_SINGLE_MESSAGE_SIZE]; + +static BluRingBufferReceive_t BleMainReceiveRingBuffer; + +static uint8_t BluMainReceiveMessagesTab[DLT_RECEIVE_RING_BUFFER_SIZE][DLT_REC_SINGLE_MESSAGE_MAX_SIZE]; + +static volatile uint8_t TransmitReadyStateFlag = true; /*TmpFromDma for example*/ + +/* + ********************************************************************************************* + * Prototypes of static functions + ******************************************************************************************** + */ + +/*! + ************************************************************************************************ + * \brief PrepareDltHeader + * \details A very lazy implementation of DLT Header - but it works fine + * Please refer to: https://www.autosar.org/fileadmin/user_upload/standards/foundation/1-0/AUTOSAR_PRS_DiagnosticLogAndTraceProtocol.pdf + ************************************************************************************************/ +static void PrepareDltHeader(uint8_t Level, uint32_t AppId, uint32_t ContextId, uint16_t size,uint8_t *headerAddrStart); + +/*! + ************************************************************************************************ + * \brief DLT_RB_TransmitRead Function to read data from ring buffer + * \details -- + * \param RingBuffer_t *Buf - pointer to Ring Buffer structure + * \param out MessageSize - size of the "DltLogData" (return value) + * \param out MessagePointer - pointer to the message stored in RingBuffer (return value) + * \return RB_OK if something read succesfully, otherwise RB_ERROR + * */ +static RB_Status DLT_RB_TransmitRead(DltRingBufferTransmit_t *Buf, uint8_t *MessageSize, uint8_t **MessagePointer); + +/*! + ************************************************************************************************ + * \brief DLT_RB_GetNextWriteIndex + * \details -- + * \param in RingBuffer_t *Buf - pointer to Ring Buffer structure + * \param out writeIndex - next index where DLT data should be stored, can be used only if fun return "RB_OK" + * \return RB_OK if index available, otherwise RB_ERROR + ************************************************************************************************/ +static RB_Status DLT_RB_GetNextWriteIndex(DltRingBufferTransmit_t *Buf,uint16_t *writeIndex); + +/*! + ************************************************************************************************ + * \brief DLT_RB_Receive_GetNextMessageAddress + * \details Function used to work with DMA - direct write to ring buffer by DMA + * \param in Buf - + * \param in WriteAddress - + ************************************************************************************************/ +static RB_Status DLT_RB_Receive_GetNextMessageAddress(BluRingBufferReceive_t *Buf, uint8_t **WriteAddress); + +/*! + ************************************************************************************************ + * \brief DLT_RB_Receive_Read Function to read data from ring buffer + * \details -- + * \param RingBuffer_t *Buf - pointer to Ring Buffer structure + * \param out MessageSize - size of the "BleLogData" (return value) + * \param out MessagePointer - pointer to the message stored in RingBuffer (return value) + * + * */ +static RB_Status DLT_RB_Receive_Read(BluRingBufferReceive_t *Buf, uint8_t *MessageSize, uint8_t **MessagePointer); + +/* + ********************************************************************************************* + * Static functions implementation + ******************************************************************************************** + */ + +static RB_Status DLT_RB_Receive_GetNextMessageAddress(BluRingBufferReceive_t *Buf, uint8_t **WriteAddress) +{ + /* TODO: The implementation isn't optimal...*/ + static uint8_t DefaultBlindBuffer[DLT_REC_SINGLE_MESSAGE_MAX_SIZE]; + + /*Mark previous message as ready to read*/ + Buf->ReadyToRead[Buf->Head] = true; + + // Compute new Head pointer value of a ring buffer + uint16_t HeadTmp = (Buf->Head + 1) % DLT_RECEIVE_RING_BUFFER_SIZE; + + // Check if there is one free space ahead the Head buffer + if(HeadTmp == Buf->Tail) + { + /*Even if buffer is full data must be received somewhere to don't crush application/ dma*/ + *WriteAddress = DefaultBlindBuffer; + // There is no space in the buffer - return an error + return RB_ERROR; + } + + Buf->ReadyToRead[HeadTmp] = false; + Buf->MessageSize[HeadTmp] = DLT_RECEIVE_RING_BUFFER_SIZE; + Buf->Head = HeadTmp; + + *WriteAddress = &BluMainReceiveMessagesTab[HeadTmp][0]; + + // Everything is ok - return OK status + return RB_OK; +} + +static RB_Status DLT_RB_Receive_Read(BluRingBufferReceive_t *Buf, uint8_t *MessageSize, uint8_t **MessagePointer) +{ + if(Buf->ReadyToRead[Buf->Tail] == false) + { + /*Any message in ring buffer isn't ready to read*/ + return RB_ERROR; + } + /*Mark again as not ready to read*/ + Buf->ReadyToRead[Buf->Tail] = false; + + // Check if Tail hit Head + if(Buf->Head == Buf->Tail) + { + // If yes - there is nothing to read + return RB_ERROR; + } + + // Write current value from buffer to pointer from argument + *MessageSize = Buf->MessageSize[Buf->Tail]; + *MessagePointer = &BluMainReceiveMessagesTab[Buf->Tail][0]; + + // Calculate new Tail pointer + Buf->Tail = (Buf->Tail + 1) % DLT_RECEIVE_RING_BUFFER_SIZE; + + // Everything is ok - return OK status + return RB_OK; +} + +static RB_Status DLT_RB_TransmitRead(DltRingBufferTransmit_t *Buf, uint8_t *MessageSize, uint8_t **MessagePointer) +{ + // Check if Tail hit Head + if(Buf->Head == Buf->Tail) + { + // If yes - there is nothing to read + return RB_ERROR; + } + else if(true == Buf->readyToTransmit[Buf->Tail]) + { + // Write current value from buffer to pointer from argument + *MessageSize = Buf->dataSize[Buf->Tail]; + *MessagePointer = &DltTrsmtMessagesTab[Buf->Tail][0]; + + // Calculate new Tail pointer + Buf->Tail = (Buf->Tail + 1) % DLT_TRANSMIT_RING_BUFFER_SIZE; + // Everything is ok - return OK status + return RB_OK; + } + else + { + /* Message still not ready to transmit */ + return RB_ERROR; + } + +} + +static RB_Status DLT_RB_GetNextWriteIndex(DltRingBufferTransmit_t *Buf,uint16_t *writeIndex) +{ +DLTuc_OS_CRITICAL_START(); + // Calculate new Head pointer value + uint8_t HeadTmp = (Buf->Head + 1) % DLT_TRANSMIT_RING_BUFFER_SIZE; + + // Check if there is one free space ahead the Head buffer + if(HeadTmp == Buf->Tail) + { + DLTuc_OS_CRITICAL_END(); + // There is no space in the buffer - return an error + return RB_ERROR; + } + Buf->Head = HeadTmp; + Buf->readyToTransmit[Buf->Head] = false; + *writeIndex = Buf->Head; + DLTuc_OS_CRITICAL_END(); + + return RB_OK; +} + +static void PrepareDltHeader(uint8_t Level, uint32_t AppId, uint32_t ContextId, uint16_t size,uint8_t *headerAddrStart) +{ + uint32_t ActualTime = 0; + + if(GetSystemTimeMs != NULL) + { + ActualTime = GetSystemTimeMs() * 10U; + /*Multiply by 10 to get value in MS also in DLTViewer + *Reson: Resolution in DLT Viewer is equal: 10^-4 + */ + } + + if(size > ((UINT8_MAX -1) - DLT_ACT_HEADER_SIZE) ) + { + /*Error to handle, or please develop this function to handle input size > UINT8_MAX */ + // while(1) + // { + // /*For development phase: lock the app*/ + // } + size = size - DLT_ACT_HEADER_SIZE -1; + } + + + /*START HEADER*/ + headerAddrStart[0] = 0x44; /*'D'*/ + headerAddrStart[1] = 0x4c; /*'L'*/ + headerAddrStart[2] = 0x53; /*'S'*/ + headerAddrStart[3] = 0x01; /*'0x01'*/ + + + headerAddrStart[4] = 0x35; /*'Dlt base header config + * Use extended header - true + * MSBF - false + * With ECU ID - true + * With Seesion ID - false + * With time stamp - true + * version number -random + '*/ + + headerAddrStart[5] = ActDltMessageCounter++; /*'Message counter value '*/ + + /*TODO: - it must be fixed!!!! - Length*/ + headerAddrStart[6] = 0x00; /*Message length general*/ +// headerAddrStart[7] = 0x37; /*'Message length general '*/ + headerAddrStart[7]=28+size; /*General size */ + + + uint32_t TempEcuId = DLT_LOG_ECUID_VALUE; + /*ECU ID*/ + headerAddrStart[8]= ((uint8_t*)&TempEcuId)[3]; + headerAddrStart[9]= ((uint8_t*)&TempEcuId)[2]; + headerAddrStart[10]= ((uint8_t*)&TempEcuId)[1]; + headerAddrStart[11]= ((uint8_t*)&TempEcuId)[0]; + + /*Time stamp*/ + headerAddrStart[12]= ((uint8_t*)&ActualTime)[3]; + headerAddrStart[13]= ((uint8_t*)&ActualTime)[2]; + headerAddrStart[14]= ((uint8_t*)&ActualTime)[1]; + headerAddrStart[15]= ((uint8_t*)&ActualTime)[0]; + + /*Extended header --verbose | type serial*/ +// headerAddrStart[16]= 0x41; /**/ + headerAddrStart[16]= (Level << 4) | 1; + + /*Number of arguments*/ + headerAddrStart[17]= 0x01; /**/ + + /*App id */ + headerAddrStart[18]= ((uint8_t*)&AppId)[3]; + headerAddrStart[19]= ((uint8_t*)&AppId)[2]; + headerAddrStart[20]= ((uint8_t*)&AppId)[1]; + headerAddrStart[21]= ((uint8_t*)&AppId)[0]; + + /*Contex ID (4 bytes*/ + headerAddrStart[22]= ((uint8_t*)&ContextId)[3]; + headerAddrStart[23]= ((uint8_t*)&ContextId)[2]; + headerAddrStart[24]= ((uint8_t*)&ContextId)[1]; + headerAddrStart[25]= ((uint8_t*)&ContextId)[0]; + + /*Type info*/ + headerAddrStart[26]= 0x01; /**/ + headerAddrStart[27]= 0x82; /**/ + headerAddrStart[28]= 0x00; /**/ + headerAddrStart[29]= 0x00; /**/ + + /*Argument 1*/ + headerAddrStart[30]= size; + /* Size of the load in simplified form, please verify in documentation of DLT protcool documentation */ + headerAddrStart[31]= 0x00; /**/ +} + +/* + **************************************************************************************************** + * Exported functions implementation. + * Descriptions are added in header file + ***************************************************************************************************** + */ + +void DLTuc_RawDataReceiveDone(uint16_t Size) +{ + static uint8_t *MessageReceiveBufferAddress = NULL; + uint8_t *MessageToRead_p = NULL; + uint8_t MessageToReadSize= 0U; + + DLT_RB_Receive_GetNextMessageAddress(&BleMainReceiveRingBuffer,&MessageReceiveBufferAddress); + if(ExtSerialRecDataFunctionCb != NULL){ + ExtSerialRecDataFunctionCb(MessageReceiveBufferAddress,DLT_REC_SINGLE_MESSAGE_MAX_SIZE); + } + + /* + * The receive buffer isn't handled fully correctly, it require deeper investigation. + * However, it is possible to receive the Injection messages, and base commands if are transmitted with breakes.. + * Received DTL messages are divided by the "IDLE" irq for now.., not by the size and etc... + */ + if(DLT_RB_Receive_Read(&BleMainReceiveRingBuffer, &MessageToReadSize,&MessageToRead_p) == RB_OK) + { + if(MessageToRead_p[4] == 53) /**/ + { + /*Use Extended, with EcuId, with Timestamp, end at[15] + then Extended data as follow: + [16] ==22-? - non verbose, type: control, MSTP: fatal + [17] numOfArgs == 1 - TODO: Only 1 argument is for nowsupported!!! + [18-21] - AppId + [22-25] - ContexId + [26-29] - ServiceId + [30-33] - Size*/ + + uint32_t AppId = MessageToRead_p[21] << 24 |MessageToRead_p[20] << 16 | MessageToRead_p[19] << 8 | MessageToRead_p[18] << 0; + uint32_t RecContexId = MessageToRead_p[25] << 24 |MessageToRead_p[24] << 16 | MessageToRead_p[23] << 8 | MessageToRead_p[22] << 0; + uint32_t RecServiceId = MessageToRead_p[29] << 24 |MessageToRead_p[28] << 16 | MessageToRead_p[27] << 8 | MessageToRead_p[26] << 0; + + if(RecServiceId >= DLT_SERVICE_ID_CALLSW_CINJECTION) + { + if(NULL != ExtInfoInjectionDataRcvdCb) + { + /*MSB LSB, wtf..?, it is somehow mixed? */ + uint32_t DltDatSize = MessageToRead_p[33] << 24 | MessageToRead_p[32] << 16 | MessageToRead_p[31] << 8 | MessageToRead_p[30] << 0; + + ExtInfoInjectionDataRcvdCb(AppId,RecContexId,RecServiceId,&MessageToRead_p[34],(uint16_t)DltDatSize); + } + } + else if(RecServiceId == DLT_SERVICE_ID_SET_LOG_LEVEL) + { + uint32_t NewLogLevel = MessageToRead_p[30]; + LOG("Set new log level request: %d How you triggered it?? , not supported", NewLogLevel); + /* It is handled correctly by DLT Viewer?? */ + } + else if(RecServiceId == DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL) + { + uint32_t NewLogLevel = MessageToRead_p[30]; + LOG("Set default log level request: %d", NewLogLevel); + + LOG("Not supported yet, I'm too lazy :)"); + } + else if(DLT_SERVICE_ID_GET_SOFTWARE_VERSION == RecServiceId) + { + LOG("ECU_SW_VERSION: %d", DLT_ECU_SW_VER); + /*TODO: The lib should send here answer of control message... */ + } + else if(DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL == RecServiceId) + { + LOG("Default log level: %d", DLT_LOG_ENABLE_LEVEL); + } + } + } +} + +void DLTuc_RegisterInjectionDataReceivedCb( + void InjectionDataRcvd(uint32_t AppId, uint32_t ConId,uint32_t ServId,uint8_t *Data, uint16_t Size)) +{ + ExtInfoInjectionDataRcvdCb = InjectionDataRcvd; +} + +void DLTuc_RegisterReceiveSerialDataFunction(void LLSerialRecDataFunctionC(uint8_t *DltLogData, uint16_t Size)) +{ + ExtSerialRecDataFunctionCb = LLSerialRecDataFunctionC; + + if(ExtSerialRecDataFunctionCb != NULL) + { + ExtSerialRecDataFunctionCb(&BluMainReceiveMessagesTab[0][0],DLT_REC_SINGLE_MESSAGE_MAX_SIZE); + } +} + +void DLTuc_RegisterTransmitSerialDataFunction(void LLSerialTrDataFunctionC(uint8_t *DltLogData, uint8_t Size)) +{ + ExtSerialTrDataFunctionCb = LLSerialTrDataFunctionC; + + /*Preapre LOG DROP Info Log*/ + /* 0x444C5443 - In Ascii code it is: DLTC. It is more convience to put magic numbers here :) */ + PrepareDltHeader(DL_ERROR,0x444C5443, 0x444C5443,sizeof(DltLogDroppedInfo),DltLogDroppedInfoBuffer); + for(int i=0; i DLT_MINIMUM_LOG_DROP_PERIOD) ) + { + /* If DLTuc will always send the DROP Message info, + * then will not read any message from RB..*/ + PrevLogDropSendTime = ActualSysTime; + LogDroppedFlag = false; + + if(ExtSerialTrDataFunctionCb != NULL) + { + ExtSerialTrDataFunctionCb(DltLogDroppedInfoBuffer, DLtLogDroppedSize); + } + return; + } + + DLTuc_OS_CRITICAL_START(); + if(DLT_RB_TransmitRead(&DltTrsmtRingBuffer,&TmpMessageSize,&TmpMessagePointer) == RB_OK) + { + if(ExtSerialTrDataFunctionCb != NULL) + { + DLTuc_OS_CRITICAL_END(); + ExtSerialTrDataFunctionCb(TmpMessagePointer, TmpMessageSize); + } + } + else + { + TransmitReadyStateFlag = true; + } + DLTuc_OS_CRITICAL_END(); +} + +void DLTuc_LogOutVarArgs(DltLogLevel_t Level, uint32_t AppId, uint32_t ContextId, uint8_t *Payload, ...) +{ + uint16_t Size; /* */ + uint8_t TmpMessageSize=0U; /* */ + uint8_t *TmpMessagePointer = NULL; /* */ + uint16_t writeIndex = 0U; /* */ + + if(DLT_RB_GetNextWriteIndex(&DltTrsmtRingBuffer,&writeIndex) != RB_OK) + { + DLTuc_OS_CRITICAL_START(); + LogDroppedFlag = true; + DLTuc_OS_CRITICAL_END(); + } + else + { + /* Put the DLT message data directly in ring buffer*/ + va_list ap; /* */ + va_start(ap, Payload); + Size = vsprintf((char *)&(DltTrsmtMessagesTab[writeIndex][DLT_ACT_HEADER_SIZE]), (char *)Payload,ap); + va_end(ap); + + Size += DLT_ACT_HEADER_SIZE; + /*Add additional zeros on the end of message - thanks to that it work stable */ + Size++; + DltTrsmtMessagesTab[writeIndex][Size] = 0U; + Size++; + DltTrsmtMessagesTab[writeIndex][Size] = 0U; + + PrepareDltHeader(Level,AppId,ContextId,Size,&(DltTrsmtMessagesTab[writeIndex][0])); + + Size = Size + DLT_ACT_HEADER_SIZE; + DltTrsmtRingBuffer.dataSize[writeIndex] = Size; + + DLTuc_OS_CRITICAL_START(); + DltTrsmtRingBuffer.readyToTransmit[writeIndex] = true; + DLTuc_OS_CRITICAL_END(); + } + + DLTuc_OS_CRITICAL_START(); + if(TransmitReadyStateFlag == true) + { + if(DLT_RB_TransmitRead(&DltTrsmtRingBuffer,&TmpMessageSize,&TmpMessagePointer) == RB_OK) + { + if(TmpMessageSize != 0U) + { + TransmitReadyStateFlag = false; + DLTuc_OS_CRITICAL_END(); + /*Log transmission must be started in this contex...*/ + /***********************************************/ + /* It may be a bug in implementation - it must be investigated.. */ + /* It's important to be aware of this fact!!*/ + /***********************************************/ + if(ExtSerialTrDataFunctionCb != NULL) + { + ExtSerialTrDataFunctionCb(TmpMessagePointer, TmpMessageSize); + } + else + { + // while(1); /*Please Register the callback...*/ + } + } + } + } + DLTuc_OS_CRITICAL_END(); +} + +void DLTuc_RegisterGetTimeStampMsCallback(uint32_t GetSysTime(void)) +{ + GetSystemTimeMs = GetSysTime; +} + + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_DLT_Log.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_DLT_Log.c new file mode 100644 index 0000000..714c4c0 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_DLT_Log.c @@ -0,0 +1,126 @@ +/* + * bsp_DLT_Log.c + * + * Created on: Aug 8, 2024 + * Author: akeguo + */ + +#include "bsp_DLT_Log.h" +#include +uint32_t GetSysTime(void); +void DltInjectDataRcvd(uint32_t AppId, uint32_t ConId, uint32_t ServId, + uint8_t *Data, uint16_t Size); +void DLT_LowLevelReceiveDmaToIdle(uint8_t *rxBuf, uint16_t size); +void DLT_DataReceiveEndCallback(uint8_t *rxBuf, uint16_t Size); +void DLT_DataTransmit(uint8_t *DltLogData, uint8_t Size); + +struct UARTHandler *dLT_Log_UART_Handler; + +typedef enum _send_out_port +{ + udp = 0, serialport = 1, tcp = 3, + +} send_out_port; + +char send_out_is_udp_or_serial_port = 0; + +void dLT_Log_intialize(struct UARTHandler *Handler) +{ + + dLT_Log_UART_Handler = Handler; + dLT_Log_UART_Handler->Wait_time = 40; + Handler->dispacherController->Dispacher_Enable = 1; + //log_info("angle_encoder_intialize"); + dLT_Log_UART_Handler->UART_Decode = DLT_DataReceiveEndCallback; + + /*Register Low Level Transmit/Receive functions for DLTuc Library*/ + DLTuc_RegisterTransmitSerialDataFunction(DLT_DataTransmit); + DLTuc_RegisterReceiveSerialDataFunction(DLT_LowLevelReceiveDmaToIdle); + + DLTuc_RegisterGetTimeStampMsCallback(GetSysTime); /*Register GetSysTime function*/ + /*The function "GetSysTime" must return the time in ms*/ + + DLTuc_RegisterInjectionDataReceivedCb(DltInjectDataRcvd); + send_out_is_udp_or_serial_port = serialport; +} +//dlt log 日志配置 默认为udp发送 +void dLT_Log_intialize_udp_tcp() +{ + + //DLT_DataReceiveEndCallback; + /*Register Low Level Transmit/Receive functions for DLTuc Library*/ + DLTuc_RegisterTransmitSerialDataFunction(DLT_DataTransmit); + DLTuc_RegisterReceiveSerialDataFunction(DLT_LowLevelReceiveDmaToIdle); + + DLTuc_RegisterGetTimeStampMsCallback(GetSysTime); /*Register GetSysTime function*/ + /*The function "GetSysTime" must return the time in ms*/ + + DLTuc_RegisterInjectionDataReceivedCb(DltInjectDataRcvd); + //send_out_is_udp_or_serial_port = udp; + send_out_is_udp_or_serial_port = tcp; + + UDP_DLT_ReceivedCallback = DLT_DataReceiveEndCallback; //将udp中的函数指针,指向解析 +} + +/*This CallBack was registered in main function using function: DLTuc_RegisterTransmitSerialDataFunction*/ +void DLT_DataTransmit(uint8_t *DltLogData, uint8_t Size) +{ + + if (send_out_is_udp_or_serial_port == udp) + { + udp_dlt_send_back(DltLogData, Size); + } + else if (send_out_is_udp_or_serial_port == serialport) + { + dLT_Log_UART_Handler->AddSendList(dLT_Log_UART_Handler, DltLogData, + Size, 100, NULL); + } + else if (send_out_is_udp_or_serial_port == tcp) + { + tcp_send_to_all_clients(DltLogData, Size);// + //tcp_add_sendList(DltLogData,Size); + } + + DLTuc_MessageTransmitDone(); + +} +/*CallBacks used by ucDltLibrary section end..*/ + +void DLT_DataReceiveEndCallback(uint8_t *rxBuf, uint16_t Size) +{ + if (Size == 3) + { + if (rxBuf[2]) + { + DLT_LOG_ENABLE_LEVEL = 7; + } + else + { + DLT_LOG_ENABLE_LEVEL = 0; + } + } + DLTuc_RawDataReceiveDone(Size); + /* + *In case of STM32 HAL lib, you have to subsitute this function using: + *void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) + */ +} +//HAL_UARTEx_RxEventCallback +void DLT_LowLevelReceiveDmaToIdle(uint8_t *rxBuf, uint16_t Size) +{ + + memcpy(rxBuf, dLT_Log_UART_Handler->Rx_Buf, Size); + +} + +void DltInjectDataRcvd(uint32_t AppId, uint32_t ConId, uint32_t ServId, + uint8_t *Data, uint16_t Size) +{ + LOG("RecInjectionData: %s, ServId: %d Size: %d", Data, ServId, Size) + +} + +uint32_t GetSysTime(void) +{ + return HAL_GetTick(); +} diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_EEPROM.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_EEPROM.c new file mode 100644 index 0000000..2d1c6f1 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_EEPROM.c @@ -0,0 +1,570 @@ +/* + * bsp_EEPROM.c + * + * Created on: Oct 26, 2023 + * Author: shiya + */ +#include "BSP/bsp_EEPROM.h" + +void bsp_InitI2C(void); +void i2c_Start(void); +void i2c_Stop(void); +void i2c_SendByte(uint8_t _ucByte); +uint8_t i2c_ReadByte(void); +uint8_t i2c_WaitAck(void); +void i2c_Ack(void); +void i2c_NAck(void); +uint8_t i2c_CheckDevice(uint8_t _Address); + +uint16_t App_Download_EEPROM_Addr= 1024; +/* 定义读写SCL和SDA的宏 */ +#define I2C_SCL_GPIO EEPROM_SCL_GPIO_Port +#define I2C_SDA_GPIO EEPROM_SDA_GPIO_Port +#define I2C_SCL_PIN EEPROM_SCL_Pin +#define I2C_SDA_PIN EEPROM_SDA_Pin + +#define I2C_SCL_1() I2C_SCL_GPIO->BSRR = I2C_SCL_PIN /* SCL = 1 */ +#define I2C_SCL_0() I2C_SCL_GPIO->BSRR = ((uint32_t)I2C_SCL_PIN << 16U) /* SCL = 0 */ + +#define I2C_SDA_1() I2C_SDA_GPIO->BSRR = I2C_SDA_PIN /* SDA = 1 */ +#define I2C_SDA_0() I2C_SDA_GPIO->BSRR = ((uint32_t)I2C_SDA_PIN << 16U) /* SDA = 0 */ + + +#define I2C_SDA_READ() ((I2C_SDA_GPIO->IDR & I2C_SDA_PIN) != 0) /* 读SDA口线状态 */ +#define I2C_SCL_READ() ((I2C_SCL_GPIO->IDR & I2C_SCL_PIN) != 0) /* 读SCL口线状态 */ + + + +uint8_t GF_BSP_EEPROM_Init(void) +{ + bsp_InitI2C(); + return(GF_BSP_EEPROM_CheckOK()); +} + +/* +********************************************************************************************************* +* 函 数 名: bsp_InitI2C +* 功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void bsp_InitI2C(void) +{ + GPIO_InitTypeDef gpio_init; + + + gpio_init.Mode = GPIO_MODE_OUTPUT_OD; /* 设置开漏输出 */ + gpio_init.Pull = GPIO_NOPULL; /* 上下拉电阻不使能 */ + gpio_init.Speed = GPIO_SPEED_FREQ_LOW; // GPIO_SPEED_FREQ_HIGH; /* GPIO速度等级 */ + + gpio_init.Pin = I2C_SCL_PIN; + HAL_GPIO_Init(I2C_SCL_GPIO, &gpio_init); + + gpio_init.Pin = I2C_SDA_PIN; + HAL_GPIO_Init(I2C_SDA_GPIO, &gpio_init); + + /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */ + i2c_Stop(); +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_Delay +* 功能说明: I2C总线位延迟,最快400KHz +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +static void i2c_Delay(void) +{ + GF_BSP_TIMER_DelayUS(2); +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_Start +* 功能说明: CPU发起I2C总线启动信号 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void i2c_Start(void) +{ + /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */ + I2C_SDA_1(); + I2C_SCL_1(); + i2c_Delay(); + I2C_SDA_0(); + i2c_Delay(); + + I2C_SCL_0(); + i2c_Delay(); +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_Start +* 功能说明: CPU发起I2C总线停止信号 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void i2c_Stop(void) +{ + /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */ + I2C_SDA_0(); + i2c_Delay(); + I2C_SCL_1(); + i2c_Delay(); + I2C_SDA_1(); + i2c_Delay(); +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_SendByte +* 功能说明: CPU向I2C总线设备发送8bit数据 +* 形 参: _ucByte : 等待发送的字节 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void i2c_SendByte(uint8_t _ucByte) +{ + uint8_t i; + + /* 先发送字节的高位bit7 */ + for (i = 0; i < 8; i++) + { + if (_ucByte & 0x80) + { + I2C_SDA_1(); + } + else + { + I2C_SDA_0(); + } + i2c_Delay(); + I2C_SCL_1(); + i2c_Delay(); + I2C_SCL_0(); + I2C_SCL_0(); /* 2019-03-14 针对GT811电容触摸,添加一行,相当于延迟几十ns */ + if (i == 7) + { + I2C_SDA_1(); // 释放总线 + } + _ucByte <<= 1; /* 左移一个bit */ + } +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_ReadByte +* 功能说明: CPU从I2C总线设备读取8bit数据 +* 形 参: 无 +* 返 回 值: 读到的数据 +********************************************************************************************************* +*/ +uint8_t i2c_ReadByte(void) +{ + uint8_t i; + uint8_t value; + + /* 读到第1个bit为数据的bit7 */ + value = 0; + for (i = 0; i < 8; i++) + { + value <<= 1; + I2C_SCL_1(); + i2c_Delay(); + if (I2C_SDA_READ()) + { + value++; + } + I2C_SCL_0(); + i2c_Delay(); + } + return value; +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_WaitAck +* 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号 +* 形 参: 无 +* 返 回 值: 返回0表示正确应答,1表示无器件响应 +********************************************************************************************************* +*/ +uint8_t i2c_WaitAck(void) +{ + uint8_t re; + + I2C_SDA_1(); /* CPU释放SDA总线 */ + i2c_Delay(); + I2C_SCL_1(); /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */ + i2c_Delay(); + if (I2C_SDA_READ()) /* CPU读取SDA口线状态 */ + { + re = 1; + } + else + { + re = 0; + } + I2C_SCL_0(); + i2c_Delay(); + return re; +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_Ack +* 功能说明: CPU产生一个ACK信号 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void i2c_Ack(void) +{ + I2C_SDA_0(); /* CPU驱动SDA = 0 */ + i2c_Delay(); + I2C_SCL_1(); /* CPU产生1个时钟 */ + i2c_Delay(); + I2C_SCL_0(); + i2c_Delay(); + I2C_SDA_1(); /* CPU释放SDA总线 */ + + i2c_Delay(); +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_NAck +* 功能说明: CPU产生1个NACK信号 +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void i2c_NAck(void) +{ + I2C_SDA_1(); /* CPU驱动SDA = 1 */ + i2c_Delay(); + I2C_SCL_1(); /* CPU产生1个时钟 */ + i2c_Delay(); + I2C_SCL_0(); + i2c_Delay(); +} + +/* +********************************************************************************************************* +* 函 数 名: i2c_CheckDevice +* 功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在 +* 形 参: _Address:设备的I2C总线地址 +* 返 回 值: 返回值 0 表示正确, 返回1表示未探测到 +********************************************************************************************************* +*/ +uint8_t i2c_CheckDevice(uint8_t _Address) +{ + uint8_t ucAck; + + if (I2C_SDA_READ() && I2C_SCL_READ()) + { + i2c_Start(); /* 发送启动信号 */ + + /* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */ + i2c_SendByte(_Address | I2C_WR); + ucAck = i2c_WaitAck(); /* 检测设备的ACK应答 */ + + i2c_Stop(); /* 发送停止信号 */ + + return ucAck; + } + return 1; /* I2C总线异常 */ +} + +/* +********************************************************************************************************* +* 函 数 名: ee_CheckOk +* 功能说明: 判断串行EERPOM是否正常 +* 形 参: 无 +* 返 回 值: 1 表示正常, 0 表示不正常 +********************************************************************************************************* +*/ +uint8_t GF_BSP_EEPROM_CheckOK(void) +{ + if (i2c_CheckDevice(EE_DEV_ADDR) == 0) + { + return 1; + } + else + { + /* 失败后,切记发送I2C总线停止信号 */ + i2c_Stop(); + return 0; + } +} + + +/* +********************************************************************************************************* +* 函 数 名: GF_BSP_EEPROM_ReadBytes +* 功能说明: 从串行EEPROM指定地址处开始读取若干数据 +* 形 参: _usAddress : 起始地址 +* _usSize : 数据长度,单位为字节 +* _pReadBuf : 存放读到的数据的缓冲区指针 +* 返 回 值: 0 表示失败,1表示成功 +********************************************************************************************************* +*/ +uint8_t GF_BSP_EEPROM_ReadBytes(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize) +{ + uint16_t i; + + /* 采用串行EEPROM随即读取指令序列,连续读取若干字节 */ + + /* 第1步:发起I2C总线启动信号 */ + i2c_Start(); + + /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */ + i2c_SendByte(EE_DEV_ADDR | I2C_WR); /* 此处是写指令 */ + + /* 第3步:发送ACK */ + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + + /* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04以上,那么此处需要连发多个地址 */ + if (EE_ADDR_BYTES == 1) + { + i2c_SendByte((uint8_t)_usAddress); + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + } + else + { + i2c_SendByte(_usAddress >> 8); + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + + i2c_SendByte(_usAddress&0xff); + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + } + + /* 第6步:重新启动I2C总线。下面开始读取数据 */ + i2c_Start(); + + /* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */ + i2c_SendByte(EE_DEV_ADDR | I2C_RD); /* 此处是读指令 */ + + /* 第8步:发送ACK */ + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + + /* 第9步:循环读取数据 */ + for (i = 0; i < _usSize; i++) + { + _pReadBuf[i] = i2c_ReadByte(); /* 读1个字节 */ + + /* 每读完1个字节后,需要发送Ack, 最后一个字节不需要Ack,发Nack */ + if (i != _usSize - 1) + { + i2c_Ack(); /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */ + } + else + { + i2c_NAck(); /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */ + } + } + /* 发送I2C总线停止信号 */ + i2c_Stop(); + return 1; /* 执行成功 */ + +cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */ + /* 发送I2C总线停止信号 */ + i2c_Stop(); + return 0; +} + +/* +********************************************************************************************************* +* 函 数 名: GF_BSP_EEPROM_WriteBytes +* 功能说明: 向串行EEPROM指定地址写入若干数据,采用页写操作提高写入效率 +* 形 参: _usAddress : 起始地址 +* _usSize : 数据长度,单位为字节 +* _pWriteBuf : 存放读到的数据的缓冲区指针 +* 返 回 值: 0 表示失败,1表示成功 +********************************************************************************************************* +*/ +uint8_t GF_BSP_EEPROM_WriteBytes(uint8_t *_pWriteBuf, uint16_t _usAddress, uint16_t _usSize) +{ + uint16_t i,m; + uint16_t usAddr; + + /* + 写串行EEPROM不像读操作可以连续读取很多字节,每次写操作只能在同一个page。 + 对于24xx02,page size = 8 + 简单的处理方法为:按字节写操作模式,每写1个字节,都发送地址 + 为了提高连续写的效率: 本函数采用page wirte操作。 + */ + + usAddr = _usAddress; + for (i = 0; i < _usSize; i++) + { + /* 当发送第1个字节或是页面首地址时,需要重新发起启动信号和地址 */ + if ((i == 0) || (usAddr & (EE_PAGE_SIZE - 1)) == 0) + { + /* 第0步:发停止信号,启动内部写操作 */ + i2c_Stop(); + + /* 通过检查器件应答的方式,判断内部写操作是否完成, 一般小于 10ms + CLK频率为200KHz时,查询次数为30次左右 + */ + for (m = 0; m < 1000; m++) + { + /* 第1步:发起I2C总线启动信号 */ + i2c_Start(); + + /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */ + i2c_SendByte(EE_DEV_ADDR | I2C_WR); /* 此处是写指令 */ + + /* 第3步:发送一个时钟,判断器件是否正确应答 */ + if (i2c_WaitAck() == 0) + { + break; + } + } + if (m == 1000) + { + goto cmd_fail; /* EEPROM器件写超时 */ + } + + /* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04以上,那么此处需要连发多个地址 */ + if (EE_ADDR_BYTES == 1) + { + i2c_SendByte((uint8_t)usAddr); + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + } + else + { + i2c_SendByte(usAddr >> 8); + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + + i2c_SendByte(usAddr&0xff); + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + } + } + + /* 第6步:开始写入数据 */ + i2c_SendByte(_pWriteBuf[i]); + + /* 第7步:发送ACK */ + if (i2c_WaitAck() != 0) + { + goto cmd_fail; /* EEPROM器件无应答 */ + } + + usAddr++; /* 地址增1 */ + } + + /* 命令执行成功,发送I2C总线停止信号 */ + i2c_Stop(); + + /* 通过检查器件应答的方式,判断内部写操作是否完成, 一般小于 10ms + CLK频率为200KHz时,查询次数为30次左右 + */ + for (m = 0; m < 1000; m++) + { + /* 第1步:发起I2C总线启动信号 */ + i2c_Start(); + + /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */ + #if EE_ADDR_A8 == 1 + i2c_SendByte(EE_DEV_ADDR | I2C_WR | ((_usAddress >> 7) & 0x0E)); /* 此处是写指令 */ + #else + i2c_SendByte(EE_DEV_ADDR | I2C_WR); /* 此处是写指令 */ + #endif + + /* 第3步:发送一个时钟,判断器件是否正确应答 */ + if (i2c_WaitAck() == 0) + { + break; + } + } + if (m == 1000) + { + goto cmd_fail; /* EEPROM器件写超时 */ + } + + /* 命令执行成功,发送I2C总线停止信号 */ + i2c_Stop(); + return 1; + +cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */ + /* 发送I2C总线停止信号 */ + i2c_Stop(); + return 0; +} + +CV_struct_define GF_BSP_EEPROM_Get_CV(void) +{ + CV_struct_define cv= {0}; + //char buffer[sizeof(CV_struct_define)]; + GF_BSP_EEPROM_ReadBytes(&cv, GF_BSP_EEPROM_CV_struct_define_Start_Address, sizeof(CV_struct_define)); + return cv; + +} + +uint8_t GF_BSP_EEPROM_Set_CV(CV_struct_define cv) +{ + return GF_BSP_EEPROM_WriteBytes((uint8_t*)&cv,GF_BSP_EEPROM_CV_struct_define_Start_Address,sizeof(CV_struct_define)); +} + + +IAP_struct_define GF_BSP_EEPROM_Get_IAP(void) +{ + IAP_struct_define iap= {0}; + + GF_BSP_EEPROM_ReadBytes(&iap, IAP_struct_define_Start_Address, sizeof(IAP_struct_define)); + return iap; + +} + +uint8_t GF_BSP_EEPROM_Set_IAP(IAP_struct_define iap) +{ + return GF_BSP_EEPROM_WriteBytes((uint8_t*)&iap,IAP_struct_define_Start_Address,sizeof(IAP_struct_define)); +} + + +//PV_struct_define GF_BSP_EEPROM_Get_PV(void) +//{ +// CV_struct_define cv=GF_BSP_EEPROM_Get_CV(); +// +// return cv.PV; +// +//} + +//uint8_t GF_BSP_EEPROM_Set_PV(PV_struct_define pv) +//{ +// CV_struct_define cv=GF_BSP_EEPROM_Get_CV(); +// cv.PV=pv; +// return GF_BSP_EEPROM_Set_CV(cv); +//} + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_Error_Detect.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_Error_Detect.c new file mode 100644 index 0000000..2431cd5 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_Error_Detect.c @@ -0,0 +1,31 @@ +/* + * bsp_Error_Detect.c + * + * Created on: Oct 23, 2024 + * Author: akeguo + */ +#include "bsp_Error_Detect.h" +void ErrorDetect(); +char Error_Detect_Enable=1; +HardWareController *HardWareErrorController; +void Error_Detect_Intialzie(uint16_t DispacherPeriod) +{ + HardWareErrorController = (HardWareController*) malloc( + sizeof(HardWareController)); + HardWareErrorController->pComHWHead = NULL; + HardWareErrorController->pComHWTail = NULL; + HardWareErrorController->Add_PCOMHardWare = ComHardWare_List_Add_t; + HardWareErrorController->Set_PCOMHardWare = Set_PCOMHardWare_t; + HardWareErrorController->PCOMHardWare_Check = PCOMHardWare_Check_t; + HardWareErrorController->DispacherCallTime = DispacherPeriod;//check the communicaton every 50ms + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, ErrorDetect); +} + +void ErrorDetect() +{ + if (Error_Detect_Enable == 1) + { + HardWareErrorController->PCOMHardWare_Check(HardWareErrorController); + } +} diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_FDCAN.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_FDCAN.c new file mode 100644 index 0000000..5e3843e --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_FDCAN.c @@ -0,0 +1,334 @@ +/* + * bsp_FDCAN.c + * + * Created on: Oct 26, 2023 + * Author: shiya + */ +#include "bsp_FDCAN.h" +#include "main.h" +#include +#include "bsp_Error.pb.h" +//#include "MSP/msp_TI5MOTOR.h" + +FDCANHandler FD_CAN_1_Handler; +FDCANHandler FD_CAN_2_Handler; + +FDCAN_RxHeaderTypeDef CAN_RX_HDR; + +uint8_t CAN_Buf[8]; +uint8_t CAN_Buf_2[8]; + +int32_t CAN_ID; +int32_t CAN_ID_2; + +uint8_t GF_BSP_FDCAN_Init(void) //can初始化 +{ + if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, + 0) != HAL_OK) + { + Error_Handler(); + } + + if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_BUS_OFF, 0) != HAL_OK) + { + Error_Handler(); + } + + HAL_FDCAN_Start(&hfdcan1); + + if (HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, + 0) != HAL_OK) + { + Error_Handler(); + } + + if (HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_BUS_OFF, 0) != HAL_OK) + { + Error_Handler(); + } + + HAL_FDCAN_Start(&hfdcan2); + + return 1; +} + +void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, + uint32_t ErrorStatusITs) +{ + if (hfdcan->Instance == FDCAN1) + { + MX_FDCAN1_Init(); + } + if (hfdcan->Instance == FDCAN2) + { + MX_FDCAN2_Init(); + } +} + +void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)//can接收 +{ + if (hfdcan->Instance == FDCAN1) + { + if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &CAN_RX_HDR, CAN_Buf)//把数据存CAN_Buf里 + == HAL_OK) + { + CAN_ID = FD_CAN_1_Handler.ReceivedFrameID = + (uint32_t) CAN_RX_HDR.Identifier; //ID + + #if NewCANSendVersion + FD_CAN_1_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength;//接收长度 + #else + FD_CAN_1_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength>>16; + #endif + + if (FD_CAN_1_Handler.CAN_Decode != NULL ) + { + FD_CAN_1_Handler.CAN_Decode(FD_CAN_1_Handler.ReceivedFrameID, + CAN_Buf, FD_CAN_1_Handler.ReceivedLength); + } + GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_FDCAN1_RxFifo0Callback); + } + + } else if (hfdcan->Instance == FDCAN2) + { + if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &CAN_RX_HDR, + CAN_Buf_2) == HAL_OK) ////把数据存CAN_Buf2里 + { + CAN_ID_2 = FD_CAN_2_Handler.ReceivedFrameID = + (uint32_t) CAN_RX_HDR.Identifier; + +#if NewCANSendVersion + FD_CAN_2_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength; +#else + FD_CAN_2_Handler.ReceivedLength = (uint32_t) CAN_RX_HDR.DataLength>>16; +#endif + + if (FD_CAN_2_Handler.CAN_Decode != NULL) + { + FD_CAN_2_Handler.CAN_Decode(FD_CAN_2_Handler.ReceivedFrameID, + CAN_Buf_2, FD_CAN_2_Handler.ReceivedLength); + } + GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_FDCAN2_RxFifo0Callback); + } + + } +} + +FDCAN_TxHeaderTypeDef TXHeader1; +FDCAN_TxHeaderTypeDef TXHeader2; + +void GF_BSP_CANHandler_Init(int can1_sendListPeriod, int can1_DispacherPeriod, + int can2_sendListPeriod, int can2_DispacherPeriod) +{ + + + GF_BSP_CANHandler_Init_CAN(&FD_CAN_1_Handler, &hfdcan1, can1_sendListPeriod, + can1_DispacherPeriod); + GF_BSP_CANHandler_Init_CAN(&FD_CAN_2_Handler, &hfdcan2, can2_sendListPeriod, + can2_DispacherPeriod); + + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, GF_BSP_CAN_Timer);//2ms一次 +} +/******************CAN初始化************************/ +void GF_BSP_CANHandler_Init_CAN(FDCANHandler *handler, + FDCAN_HandleTypeDef *canfd, int sendListPeriod, int DispacherPeriod) +{ + handler->canfd = canfd; //FD_CAN_1_Handler的的canfd与 FDCAN_HandleTypeDef hfdcan1;绑定 + handler->dispacherController = (DispacherController*) malloc( + sizeof(DispacherController)); + + + handler->dispacherController->pHead = NULL; + handler->dispacherController->pTail = NULL; + handler->dispacherController->Dispacher_Enable = 1; + handler->dispacherController->DispacherCallTime = DispacherPeriod ; // call the function every 50 ms + handler->dispacherController->Dispacher_Counter = 0; + handler->dispacherController->DispacherNumber = 0; + handler->dispacherController->Add_Dispatcher_List = Dispatcher_List_Add_t; + handler->dispacherController->Dispatcher_Run = Dispatch_t; + + handler->timeSpan = 2; + handler->SendList_time_Count = 0; + handler->AddCANSendList = CANHandlerAddTxList; + handler->SendList_Period = sendListPeriod; + + handler->CAN_Send = CAN_Send_t; + handler->CAN_Send_Data = CAN_Send_Data_t; + +} + +DispacherController *can_dispacherController; +HardWareController *can_HardWareController; +//2ms +void GF_BSP_CAN_Timer() +{ + can_dispacherController = FD_CAN_1_Handler.dispacherController; + + if (FD_CAN_1_Handler.pCurrentCANSendHadler != NULL) + { + GF_CAN_Send_List_Send(&FD_CAN_1_Handler); + + } else + { + can_dispacherController = FD_CAN_1_Handler.dispacherController; + can_dispacherController->Dispatcher_Run(can_dispacherController); + } + if (FD_CAN_2_Handler.pCurrentCANSendHadler != NULL) + { + GF_CAN_Send_List_Send(&FD_CAN_2_Handler); + } else + { + + can_dispacherController = FD_CAN_2_Handler.dispacherController; + can_dispacherController->Dispatcher_Run(can_dispacherController); + + } + +} + //发送函数 在上面定时器调用 2ms一次 +void GF_CAN_Send_List_Send(FDCANHandler *handler) +{ + + handler->SendList_time_Count++; + //timeSpan-->2 SendList_Period-->2 + if (handler->timeSpan * handler->SendList_time_Count + >= handler->SendList_Period) + { + handler->SendList_time_Count = 0; + handler->SendListExists = 1; + if (handler->pCurrentCANSendHadler != NULL) + { + //拷贝数据到相关的代码中,然后发送 + + handler->SendFrameID=handler->pCurrentCANSendHadler->CAN_ID; + + memcpy(handler->Tx_Buf, handler->pCurrentCANSendHadler->Tx_Buf, + handler->pCurrentCANSendHadler->SendLength); + handler->SendList_Period=handler->pCurrentCANSendHadler->SendListTimePeriod;//发送周期 + handler->SendLength = handler->pCurrentCANSendHadler->SendLength; + handler->CAN_Send_Data(handler); /***********发送*****************/ + + if (handler->pCurrentCANSendHadler->pNext != NULL) + { + CANSendHandler *temp = handler->pCurrentCANSendHadler->pNext; + free(handler->pCurrentCANSendHadler); //清除内存 + handler->pCurrentCANSendHadler = temp; + } else + { + free(handler->pCurrentCANSendHadler); //清除内存 + handler->pCurrentCANSendHadler = NULL; + } + + } else + { + handler->SendListExists = 0; + + } + + } + +} + +// +//handler->CAN_Send_Data = CAN_Send_Data_t; +void CAN_Send_Data_t(struct _FDCANHandler *fd) +{ + CAN_Send_t(fd, fd->SendFrameID, fd->SendLength, fd->Tx_Buf); +} +/* + * | + * | + * V + * */ +void CAN_Send_t(struct _FDCANHandler *fd, uint32_t FrameID, uint8_t DataLength, + uint8_t *Txdata) +{ + + //Function_code = Txdata[0]; + + if (DataLength > 8) + { + return; + } + if (fd->canfd == &hfdcan1) + { + TXHeader1.BitRateSwitch = FDCAN_BRS_OFF; + + #if NewCANSendVersion + TXHeader1.DataLength = (uint32_t) DataLength ; + #else + TXHeader1.DataLength = (uint32_t) DataLength << 16; //数据长度大于8的话会有错误 + #endif + + + TXHeader1.FDFormat = FDCAN_CLASSIC_CAN; + TXHeader1.IdType = FDCAN_STANDARD_ID; + TXHeader1.Identifier = FrameID; + TXHeader1.TxFrameType = FDCAN_DATA_FRAME; + HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TXHeader1, Txdata); + } else if (fd->canfd == &hfdcan2) + { + TXHeader2.BitRateSwitch = FDCAN_BRS_OFF; + + #if NewCANSendVersion + TXHeader2.DataLength = (uint32_t) DataLength ; + #else + TXHeader2.DataLength = (uint32_t) DataLength << 16; //数据长度大于8的话会有错误 + #endif + //TXHeader2.DataLength = (uint32_t) DataLength << 16; //数据长度大于8的话会有错误 + TXHeader2.FDFormat = FDCAN_CLASSIC_CAN; + TXHeader2.IdType = FDCAN_STANDARD_ID; + TXHeader2.Identifier = FrameID; + TXHeader2.TxFrameType = FDCAN_DATA_FRAME; + HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TXHeader2, Txdata); + } +} + + + +//handler->AddCANSendList = CANHandlerAddTxList;该函数由AddCANSendList调用 + +//把多个 CAN 消息按顺序添加到发送队列。系统按照设定的时间周期或者优先级依次发送队列中的消息。 +/* + * Motor_Controller->AddCANSendList(Motor_Controller, 0x600 + MotorID, 8, + Motor_Controller->Tx_Buf, WaitTime, NULL); + * */ +void CANHandlerAddTxList(FDCANHandler *handler, uint32_t CAN_ID, + uint8_t SendLength, uint8_t *Tx_Buf,uint32_t sendListTimePeriod, + void (*CAN_Decode)(uint32_t, uint8_t*, uint32_t)) //参数其实就是一组can数据 在FDHandler添加东西 +{ + + CANSendHandler *pTmp = NULL; //临时指针 链表中的节点 + + //临时指针2用于逐个申请内存 + pTmp = (CANSendHandler*) malloc(sizeof(CANSendHandler));//节点申请内存 + memcpy(pTmp->Tx_Buf, Tx_Buf, SendLength);//把参数2的内容复制到节点上 + pTmp->pNext = NULL; //下一个节点暂时为空 + pTmp->CAN_ID=CAN_ID; //设置节点ID + pTmp->SendLength = SendLength; + //pTmp->CAN_Decode = CAN_Decode; + pTmp->SendListTimePeriod=sendListTimePeriod;//节点的发送周期 + + +//if NULL, call intialize one + if (handler->pCurrentCANSendHadler == NULL) + { + handler->pCurrentCANSendHadler = pTmp; //空链表 + } else + { + char i = 0; + //插到尾部 + CANSendHandler *phead = NULL; + phead = handler->pCurrentCANSendHadler; + while (phead->pNext != NULL) + { + i++; + phead = phead->pNext; + } + phead->pNext = pTmp; + + } + +} + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_GPIO.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_GPIO.c new file mode 100644 index 0000000..8a77775 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_GPIO.c @@ -0,0 +1,104 @@ +/* + * bsp_GPIO.c + * + * Created on: Oct 26, 2023 + * Author: shiya + */ +#include "BSP/bsp_GPIO.h" + +uint8_t GF_BSP_GPIO_Init() +{ + + return 1; +} + +/* IO配置 + * IO_Index : 0-5 + * Level : 0:PIN_RESET; 1:PIN_SET; + * */ +void GF_BSP_GPIO_SetIO(uint8_t IO_Index,uint8_t Level) +{ + GPIO_PinState PinState; + if(Level == 0) + PinState=GPIO_PIN_RESET; + else + PinState=GPIO_PIN_SET; + + switch(IO_Index) + { + case 0: + HAL_GPIO_WritePin(OUT_0_GPIO_Port, OUT_0_Pin, PinState); + break; + case 1: + HAL_GPIO_WritePin(OUT_1_GPIO_Port, OUT_1_Pin, PinState);//pc3 + break; + case 2: + HAL_GPIO_WritePin(OUT_2_GPIO_Port, OUT_2_Pin, PinState); + break; + case 3: + HAL_GPIO_WritePin(OUT_3_GPIO_Port, OUT_3_Pin, PinState); + break; + case 4: + HAL_GPIO_WritePin(OUT_4_GPIO_Port, OUT_4_Pin, PinState); + break; + case 5: + HAL_GPIO_WritePin(OUT_5_GPIO_Port, OUT_5_Pin, PinState); + break; + } +} + +uint8_t GF_BSP_GPIO_ToggleIO(uint8_t IO_Index) +{ + + switch(IO_Index) + { + case 0: + HAL_GPIO_TogglePin(OUT_0_GPIO_Port, OUT_0_Pin); + break; + case 1: + HAL_GPIO_TogglePin(OUT_1_GPIO_Port, OUT_1_Pin); + break; + case 2: + HAL_GPIO_TogglePin(OUT_2_GPIO_Port, OUT_2_Pin); + break; + case 3: + HAL_GPIO_TogglePin(OUT_3_GPIO_Port, OUT_3_Pin); + break; + case 4: + HAL_GPIO_TogglePin(OUT_4_GPIO_Port, OUT_4_Pin); + break; + case 5: + HAL_GPIO_TogglePin(OUT_5_GPIO_Port, OUT_5_Pin); + break; + } + + +} + + +uint8_t GF_BSP_GPIO_ReadIO(uint8_t IO_Index) +{ + GPIO_PinState PinState; + switch(IO_Index) + { + case 0: + PinState = HAL_GPIO_ReadPin(IN_0_GPIO_Port, IN_0_Pin); + break; + case 1: + PinState = HAL_GPIO_ReadPin(IN_1_GPIO_Port, IN_1_Pin); + break; + case 2: + PinState = HAL_GPIO_ReadPin(IN_2_GPIO_Port, IN_2_Pin); + break; + case 3: + PinState = HAL_GPIO_ReadPin(IN_3_GPIO_Port, IN_3_Pin); + break; + case 4: + PinState = HAL_GPIO_ReadPin(IN_4_GPIO_Port, IN_4_Pin); + break; + case 5: + PinState = HAL_GPIO_ReadPin(IN_5_GPIO_Port, IN_5_Pin); + break; + } + return((uint8_t)PinState); +} diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_INTERCALL.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_INTERCALL.c new file mode 100644 index 0000000..8c5a95c --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_INTERCALL.c @@ -0,0 +1,41 @@ +/* + * bsp_INTERCALL.c + * + * Created on: 2023年11月8日 + * Author: shiya + */ +#include "BSP/bsp_include.h" + +typedef struct + { + uint8_t num; //调用函数指针数量 + void(*fn[DF_BSP_InterCall_Num])(void); //被调用函数指针,最多20个回调函数 + }SD_BSP_InterCall; + +SD_BSP_InterCall V_BSP_InterCall_Array[DF_BSP_InterCall_Type_Num] = {0}; + +//给中断函数链接一个回调函数,直接添加空函数指针 +//返回值1表示添加成功,返回值0表示添加失败 +uint8_t GF_BSP_Interrupt_Add_CallBack(enum DF_BSP_InterCall_Type _type,void(*_fn)(void)) +{ + V_BSP_InterCall_Array[_type].num++; + if(V_BSP_InterCall_Array[_type].num>=DF_BSP_InterCall_Num) + { + return 0; + } + V_BSP_InterCall_Array[_type].fn[V_BSP_InterCall_Array[_type].num-1]=_fn; + return 1; +} + +//放到中断函数中,运行相应的回调函数,有几个运行几个 +void GF_BSP_Interrupt_Run_CallBack(enum DF_BSP_InterCall_Type _type) +{ + uint8_t i=0; + if(V_BSP_InterCall_Array[_type].num>0) + { + for(i=0;i> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _num >> 8; /* 线圈(bit)个数 高字节 */ + Tx_Buf[TxCount++] = _num; /* 线圈(bit)个数 低字节 */ + + crc = MB_CRC16(Tx_Buf, TxCount); + Tx_Buf[TxCount++] = crc; /* crc 低字节 */ + Tx_Buf[TxCount++] = crc >> 8; /* crc 高字节 */ + *TxCount_t = TxCount; + //uartHandler->UART_Tx(uartHandler,(uint8_t *)&Tx_Buf,TxCount); + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); +} + +/** + * 函数功能: 写单个线圈状态(CoilStatue) + * 输入参数: _addr:从站地址,_reg:寄存器地址,_sta:待写入的线圈状态(0,1) + * 返 回 值: 无 + * 说 明: 填充数据发送缓存区,然后发送 + */ +void MB_WriteCoil(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _sta) +{ + uint16_t TxCount = 0; + uint16_t crc = 0; + Tx_Buf[TxCount++] = _addr; /* 从站地址 */ + Tx_Buf[TxCount++] = 0x05; /* 功能码 */ + Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _sta >> 8; /* 线圈(bit)个数 高字节 */ + Tx_Buf[TxCount++] = _sta; /* 线圈(bit)个数 低字节 */ + + + + crc = MB_CRC16(Tx_Buf, TxCount); + Tx_Buf[TxCount++] = crc; /* crc 低字节 */ + Tx_Buf[TxCount++] = crc >> 8; /* crc 高字节 */ + *TxCount_t = TxCount; + + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); + + //uartHandler->UART_Tx(uartHandler,(uint8_t *)&Tx_Buf,TxCount); +} + +void MB_WriteNumCoil(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _num, uint8_t *_databuf) +{ + + uint16_t i; + uint16_t TxCount = 0; + uint16_t crc = 0; + Tx_Buf[TxCount++] = _addr; /* 从站地址 */ + Tx_Buf[TxCount++] = 0x0F; /* 功能码 */ + Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _num >> 8; /* 寄存器(16bits)个数 高字节 */ + Tx_Buf[TxCount++] = _num; /* 低字节 */ + + if(_num%8==0) + { + Tx_Buf[TxCount++] = _num / 8; + }else + { + Tx_Buf[TxCount++] = _num / 8 + 1; + } + /* 数据个数 */ + uint16_t ij=TxCount++; + for (i = 0; i < _num; i++) + { + Tx_Buf[ij]|= _databuf[i]<> 8; /* crc 高字节 */ + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); + *TxCount_t = TxCount; +} + + + +/** + * 函数功能: 读输入状态状态(InputStatue) + * 输入参数: _addr:从站地址,_reg:寄存器地址,_num:待读取的输入数量 + * 返 回 值: 无 + * 说 明: 填充数据发送缓存区,然后发送 + */ +void MB_ReadInput(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _num) +{ + uint16_t TxCount = 0; + uint16_t crc = 0; + Tx_Buf[TxCount++] = _addr; /* 从站地址 */ + Tx_Buf[TxCount++] = 0x02; /* 功能码 */ + Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _num >> 8; /* 开关(Input)个数 高字节 */ + Tx_Buf[TxCount++] = _num; /* 开关(Input)个数 低字节 */ + + crc = MB_CRC16(Tx_Buf, TxCount); + Tx_Buf[TxCount++] = crc; /* crc 低字节 */ + Tx_Buf[TxCount++] = crc >> 8; /* crc 高字节 */ + *TxCount_t = TxCount; + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); + //uartHandler->UART_Tx(uartHandler,(uint8_t *)&Tx_Buf,TxCount); +} + +/** + * 函数功能: 读保持寄存器(HoldingRegister) + * 输入参数: _addr:从站地址,_reg:寄存器地址,_num:待读取的寄存器数量 + * 返 回 值: 无 + * 说 明: 填充数据发送缓存区,然后发送 + */ +void MB_ReadHoldingReg(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _num) +{ + MB_rx_flag = 2; + Read_Reg_Num = _num; + Read_Slave_ID = _addr; + + uint16_t TxCount = 0; + uint16_t crc = 0; + Tx_Buf[TxCount++] = _addr; /* 从站地址 */ + Tx_Buf[TxCount++] = 0x03; /* 功能码 */ + Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _num >> 8; /* 寄存器(16bits)个数 高字节 */ + Tx_Buf[TxCount++] = _num; /* 低字节 */ + + crc = MB_CRC16(Tx_Buf, TxCount); + Tx_Buf[TxCount++] = crc; /* crc 低字节 */ + Tx_Buf[TxCount++] = crc >> 8; /* crc 高字节 */ + + *TxCount_t = TxCount; + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); + //uartHandler->UART_Tx(uartHandler,(uint8_t *)&Tx_Buf,TxCount); +} + +/** + * 函数功能: 读N个输入寄存器(InputRegister) + * 输入参数: _addr:从站地址,_reg:寄存器地址,_num:待读取的寄存器数量 + * 返 回 值: 无 + * 说 明: 填充数据发送缓存区,然后发送. + */ +void MB_ReadInputReg(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _num) +{ + uint16_t TxCount = 0; + uint16_t crc = 0; + Tx_Buf[TxCount++] = _addr; /* 从站地址 */ + Tx_Buf[TxCount++] = 0x04; /* 功能码 */ + Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _num >> 8; /* 寄存器(16bits)个数 高字节 */ + Tx_Buf[TxCount++] = _num; /* 低字节 */ + + crc = MB_CRC16(Tx_Buf, TxCount); + Tx_Buf[TxCount++] = crc; /* crc 低字节 */ + Tx_Buf[TxCount++] = crc >> 8; /* crc 高字节 */ + *TxCount_t = TxCount; + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); +} + +/** + * 函数功能: 写单个保持寄存器(HoldingRegister) + * 输入参数: _addr:从站地址,_reg:寄存器地址,_data:待写入的寄存器数据 + * 返 回 值: 无 + * 说 明: 填充数据发送缓存区,然后发送 + */ +void MB_WriteHoldingReg(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _data) +{ + uint16_t TxCount = 0; + uint16_t crc = 0; + Tx_Buf[TxCount++] = _addr; /* 从站地址 */ + Tx_Buf[TxCount++] = 0x06; /* 功能码 */ + Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _data >> 8; /* 寄存器(16bits)个数 高字节 */ + Tx_Buf[TxCount++] = _data; /* 低字节 */ + + crc = MB_CRC16(Tx_Buf, TxCount); + Tx_Buf[TxCount++] = crc; /* crc 低字节 */ + Tx_Buf[TxCount++] = crc >> 8; /* crc 高字节 */ + *TxCount_t = TxCount; + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); + //uartHandler->UART_Tx(uartHandler,(uint8_t *)&Tx_Buf,TxCount); +} + +/** + * 函数功能: 写N个保持寄存器(HoldingRegister) + * 输入参数: _addr:从站地址,_reg:寄存器地址,_num:待写入的寄存器数量,_databuf:待写入的寄存器数据 + * 返 回 值: 无 + * 说 明: 填充数据发送缓存区,然后发送._databuf的长度需 >= _num*2 + */ +void MB_WriteNumHoldingReg(uint8_t *Tx_Buf, uint8_t *TxCount_t, uint8_t _addr, + uint16_t _reg, uint16_t _num, uint8_t *_databuf) +{ + + uint16_t i; + uint16_t TxCount = 0; + uint16_t crc = 0; + Tx_Buf[TxCount++] = _addr; /* 从站地址 */ + Tx_Buf[TxCount++] = 0x10; /* 功能码 */ + Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ + Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ + Tx_Buf[TxCount++] = _num >> 8; /* 寄存器(16bits)个数 高字节 */ + Tx_Buf[TxCount++] = _num; /* 低字节 */ + Tx_Buf[TxCount++] = _num << 1; /* 数据个数 */ + + for (i = 0; i < 2 * _num; i++) + { + Tx_Buf[TxCount++] = _databuf[i]; /* 后面的数据长度 */ + } + crc = MB_CRC16(Tx_Buf, TxCount); + Tx_Buf[TxCount++] = crc; /* crc 低字节 */ + Tx_Buf[TxCount++] = crc >> 8; /* crc 高字节 */ + //UART_Tx((uint8_t *)&Tx_Buf,TxCount); + *TxCount_t = TxCount; +} +/** + * 函数功能: 解析读取Read_Reg_Num个保持寄存器的值 (HoldingRegister) + * 输入参数: buffer:数据值,length:数据长度, Read_Reg_Num 读取几个保持寄存器, 将解析出来的数据存入 Decoded_Reg_Value 这个16进制的数据中 + * 返 回 值: 1 表示解析正确,0 表示解析错误 CRC验证错误 + * 说 明: + */ +uint8_t MB_Decode_HoldingRegs(uint8_t buffer[], uint16_t length,uint16_t Read_Reg_Num,uint16_t* Decoded_Reg_Value) +{ + /* CRC 校验 */ + uint16_t crc_check = ((buffer[length - 1] << 8) | buffer[length - 2]); + /* CRC 校验正确 */ + if (crc_check == MB_CRC16(buffer, length - 2)) + { + int i = 0; + for (i = 0; i < Read_Reg_Num; i++) + { + + Decoded_Reg_Value[ i] = + (buffer[3 + 2 * i] << 8) + buffer[4 + 2 * i]; + } + return 1; //Decoded successfully + } + else + { + return 0; //Decode Error; + } +} +uint8_t MB_Decode_InputRegs(uint8_t buffer[], uint16_t length,uint16_t Read_Reg_Num,uint16_t* Decoded_Reg_Value) +{ + /* CRC 校验 */ + uint16_t crc_check = ((buffer[length - 1] << 8) | buffer[length - 2]); + /* CRC 校验正确 */ + if (crc_check == MB_CRC16(buffer, length - 2)) + { + int i = 0; + for (i = 0; i < Read_Reg_Num; i++) + { + + Decoded_Reg_Value[ i] = + (buffer[3 + 2 * i] << 8) + buffer[4 + 2 * i]; + } + return 1; //Decoded successfully + } + else + { + + return 0; //Decode Error; + } +} + + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_TIMER.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_TIMER.c new file mode 100644 index 0000000..91c64f6 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_TIMER.c @@ -0,0 +1,70 @@ +/* + * bsp_TIMER.c + * + * Created on: Oct 26, 2023 + * Author: shiya + */ +#include "BSP/bsp_TIMER.h" + +#include "BSP/bsp_mqtt.h" + +//返回值::1-正常;0-错误 +uint8_t GF_BSP_TIMER_Init() +{ + HAL_TIM_Base_Start_IT(&htim1); + HAL_TIM_Base_Start_IT(&htim8); + return 1; +} + +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + //100ms - WatchDog + if(htim->Instance == TIM1)//APB2=200Mhz,htim1.Init.Prescaler = 2000-1;htim1.Init.Period = 10000-1; TIM1=100ms + { + GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_TIM1_100ms_PeriodElapsedCallback); + + } + //2ms - MainLoop + if(htim->Instance == TIM8)//APB2=200Mhz,htim8.Init.Prescaler = 2000-1;htim8.Init.Period = 200-1; TIM8=2ms + { + MX_LWIP_Process(); + GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback); + //bsp_mqtt_test(); + } +} + +void GF_BSP_TIMER_DelayUS(uint32_t n) +{ + uint32_t ticks; + uint32_t told; + uint32_t tnow; + uint32_t tcnt = 0; + uint32_t reload; + + reload = SysTick->LOAD; + ticks = n * (SystemCoreClock / 1000000); + + tcnt = 0; + told = SysTick->VAL; + + while (1) + { + tnow = SysTick->VAL; + if (tnow != told) + { + if (tnow < told) + { + tcnt += told - tnow; + } + else + { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) + { + break; + } + } + } +} diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_UART.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_UART.c new file mode 100644 index 0000000..b59a7c7 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_UART.c @@ -0,0 +1,636 @@ +#include "BSP/bsp_UART.h" +#include "main.h" +#include + +void GF_UART_Send_List_Send(struct UARTHandler *handler); +void Dispatcher_List_Add(struct UARTHandler *uartHandler, + void (*dispache)(void)); + + + +void UARTHandlerAddTxList(struct UARTHandler *uartHandler, uint8_t *data, + uint16_t length, uint32_t txListTimePeriod, void (*UART_Decode)(uint8_t*, uint16_t)); + +//Store all the data in these buffer +uint8_t RS485_1_RxMA_buf[UART_Receive_MAX_NUM]; +uint8_t RS485_2_RxDMA_buf[UART_Receive_MAX_NUM]; +uint8_t RS485_3_RxDMA_buf[UART_Receive_MAX_NUM]; +uint8_t RS485_4_RxDMA_buf[UART_Receive_MAX_NUM]; +uint8_t Debug_RxDMA_buf[UART_Receive_MAX_NUM]; +uint8_t ExternSerial_RxDMA_buf[UART_Receive_MAX_NUM]; + +uint8_t RS485_1_TxDMA_buf[UART_Transmit_MAX_NUM]; +uint8_t RS485_2_TxDMA_buf[UART_Transmit_MAX_NUM]; +uint8_t RS485_3_TxDMA_buf[UART_Transmit_MAX_NUM]; +uint8_t RS485_4_TxDMA_buf[UART_Transmit_MAX_NUM]; +uint8_t Debug_TxDMA_buf[UART_Transmit_MAX_NUM]; +uint8_t ExternSerial_TxDMA_buf[UART_Transmit_MAX_NUM]; +#define InterCall_DEBUG_UART huart4 +#define E28_SBUS_UART huart5 +#define RS485_4_UART huart7 +#define RS485_1_UART huart1 +#define LTE_7S0_Serial_UART huart2 + + +#define RS485_2_UART huart3 +#define RS485_3_UART huart6 + + +struct UARTHandler RS_485_1_UART_Handler; +struct UARTHandler RS_485_2_UART_Handler; +struct UARTHandler RS_485_3_UART_Handler; +struct UARTHandler RS_485_4_UART_Handler; +struct UARTHandler InterCall_DEBUG_UART_Handler; +struct UARTHandler E28_SBUS_UART_Handler; +struct UARTHandler LTE_7S0_Serial_UART_Handler; + + + +#if defined (hlpuart1Exit) + + #define LPUART1UART hlpuart1 + struct UARTHandler LPUART1_UART_Handler; + +#endif + +void GF_BSP_UARTHandlers_Intialize( + int32_t RS485_1_WaitTime, + int32_t RS485_2_WaitTime, + int32_t RS485_3_WaitTime, + int32_t RS485_4_WaitTime, + int32_t LTE_7S0_Serial_WaitTime, + int32_t InterCall_DEBUG_WaitTime, + int32_t E28_SBUS_WaitTime, + int32_t LPUART1_UART_WaitTime, + int32_t RS485_1_Dispacher_Time, + int32_t RS485_2_Dispacher_Time, + int32_t RS485_3_Dispacher_Time, + int32_t RS485_4_Dispacher_Time, + int32_t LTE_7S0_Serial_Dispacher_Time, + int32_t InterCall_DEBUG_Dispacher_Time, + int32_t E28_SBUS_Dispacher_Time, + int32_t LPUART1_UART_Dispacher_Time +) +{ + + IntializeUARTHandler(&RS_485_1_UART_Handler, &RS485_1_UART, RS485_1_WaitTime, 2,RS485_1_Dispacher_Time); + IntializeUARTHandler(&RS_485_2_UART_Handler, &RS485_2_UART, RS485_2_WaitTime, 2,RS485_2_Dispacher_Time); + IntializeUARTHandler(&RS_485_3_UART_Handler, &RS485_3_UART, RS485_3_WaitTime, 2,RS485_3_Dispacher_Time); + IntializeUARTHandler(&RS_485_4_UART_Handler, &RS485_4_UART, RS485_4_WaitTime, 2,RS485_4_Dispacher_Time); + IntializeUARTHandler(<E_7S0_Serial_UART_Handler, <E_7S0_Serial_UART, LTE_7S0_Serial_WaitTime, 2,LTE_7S0_Serial_Dispacher_Time); + IntializeUARTHandler(&InterCall_DEBUG_UART_Handler, &InterCall_DEBUG_UART, InterCall_DEBUG_WaitTime, 2,InterCall_DEBUG_Dispacher_Time); + IntializeUARTHandler(&E28_SBUS_UART_Handler, &E28_SBUS_UART, E28_SBUS_WaitTime, 2,E28_SBUS_Dispacher_Time); + + + HAL_UART_Receive_IT((E28_SBUS_UART_Handler.uart), + (uint8_t*) &E28_SBUS_UART_Handler.tmp_Rx_Buf, 1); + + + HAL_UART_Receive_IT((InterCall_DEBUG_UART_Handler.uart), + (uint8_t*) &InterCall_DEBUG_UART_Handler.tmp_Rx_Buf, 1); + HAL_UART_Receive_IT((RS_485_1_UART_Handler.uart), + (uint8_t*) &RS_485_1_UART_Handler.tmp_Rx_Buf, 1); + + HAL_UART_Receive_IT((RS_485_2_UART_Handler.uart), + (uint8_t*) &RS_485_2_UART_Handler.tmp_Rx_Buf, 1); + + HAL_UART_Receive_IT((RS_485_3_UART_Handler.uart), + (uint8_t*) &RS_485_3_UART_Handler.tmp_Rx_Buf, 1); + + HAL_UART_Receive_IT((RS_485_4_UART_Handler.uart), + (uint8_t*) &RS_485_4_UART_Handler.tmp_Rx_Buf, 1); + + HAL_UART_Receive_IT((LTE_7S0_Serial_UART_Handler.uart), + (uint8_t*) <E_7S0_Serial_UART_Handler.tmp_Rx_Buf, 1); + + + + +#if defined (hlpuart1Exit) + IntializeUARTHandler(&LPUART1_UART_Handler, &LPUART1UART, LPUART1_UART_WaitTime, 2,LPUART1_UART_Dispacher_Time); //10ms 剩余2ms + HAL_UART_Receive_IT((LPUART1_UART_Handler.uart), + (uint8_t*) &LPUART1_UART_Handler.tmp_Rx_Buf, 1); + +#endif + + + + + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, GF_BSP_UART_Timer); + + //RS_485_2_UART_Handler.send_finished=1; +} +//Count Every 2 ms +void GF_BSP_UART_Timer() +{ + Counting(&RS_485_1_UART_Handler); + Counting(&RS_485_2_UART_Handler); + Counting(&RS_485_3_UART_Handler); + Counting(&RS_485_4_UART_Handler); + Counting(<E_7S0_Serial_UART_Handler); + Counting(&InterCall_DEBUG_UART_Handler); + Counting(&E28_SBUS_UART_Handler); + +#if defined (hlpuart1Exit) + Counting(&LPUART1_UART_Handler); +#endif + +// RS_485_1_UART_Handler.Dispatcher_Run(&RS_485_1_UART_Handler); +// RS_485_2_UART_Handler.Dispatcher_Run(&RS_485_2_UART_Handler); +// RS_485_3_UART_Handler.Dispatcher_Run(&RS_485_3_UART_Handler); +// RS_485_4_UART_Handler.Dispatcher_Run(&RS_485_4_UART_Handler); +// E22_Serial_UART_Handler.Dispatcher_Run(&E22_Serial_UART_Handler); +// InterCall_DEBUG_UART_Handler.Dispatcher_Run(&InterCall_DEBUG_UART_Handler); +// InterCall_DEBUG_UART_Handler.Dispatcher_Run(&InterCall_DEBUG_UART_Handler); + +} + +void UARTHandlerAddTxList(struct UARTHandler *uartHandler, uint8_t *data, + uint16_t length, uint32_t txListTimePeriod, void (*UART_Decode)(uint8_t*, uint16_t)) +{ + + UARTSendHandler *pTmp = NULL; //临时指针 + //临时指针2用于逐个申请内存 + pTmp = (UARTSendHandler*) malloc(sizeof(UARTSendHandler)); + memcpy(pTmp->Tx_Buf, data, length); + pTmp->pNext = NULL; + pTmp->SendListTimePeriod=txListTimePeriod; + pTmp->SendLength = length; + pTmp->UART_Decode = UART_Decode; + +//if NULL, call intialize one + if (uartHandler->pCurrentUARTSendHadler == NULL) + { + uartHandler->pCurrentUARTSendHadler = pTmp; //空链表 + } else + { + char i = 0; + //插到尾部 + UARTSendHandler *phead = NULL; + phead = uartHandler->pCurrentUARTSendHadler; + while (phead->pNext != NULL) + { + i++; + phead = phead->pNext; + } + phead->pNext = pTmp; + + } + +} + +void UARTHandlerTx(struct UARTHandler *uartHandler) +{ + + if (uartHandler->uart == NULL) + { + LOGFF(DL_ERROR, + "the UART Hardware did not intialize,check the setting"); + return; + } + + uartHandler->RxCount=0;//设定RxCount为0 +#if defined (hlpuart1Exit) + if(uartHandler->uart->Instance == LPUART1) + { + + HAL_UART_Transmit(uartHandler->uart, uartHandler->Tx_Buf, + uartHandler->TxCount,100); + }else + { +#endif + + if (uartHandler->uart->Instance == UART4) //**DEBUG + { + + } else if (uartHandler->uart->Instance == USART1) //**RS485_1 + { + + HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin, GPIO_PIN_SET); + + } else if (uartHandler->uart->Instance == USART3) //**RS485_2 + { + + HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin, GPIO_PIN_SET); + + } else if (uartHandler->uart->Instance == USART6) //**RS485_3 + { + + HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port, RS485_3_DIR_Pin, GPIO_PIN_SET); + + } else if (uartHandler->uart->Instance == UART7) //**RS485_4 + { + HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port, RS485_4_DIR_Pin, GPIO_PIN_SET); + + } else if (uartHandler->uart->Instance == USART2)//**E22 // External serial port + { + + } else if (uartHandler->uart->Instance == UART5) //**E28 // SBUS + { + + } + + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) uartHandler->Tx_Buf, + uartHandler->TxCount); + + HAL_UART_Transmit_DMA(uartHandler->uart, uartHandler->Tx_Buf, + uartHandler->TxCount); +#if defined (hlpuart1Exit) + } +#endif + + + if (uartHandler->uart == UART4) //**DEBUG + { + + } else if (uartHandler->uart == USART1) //**RS485_1 + { + HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin, + GPIO_PIN_RESET); + } else if (uartHandler->uart == USART3) //**RS485_2 + { + HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin, + GPIO_PIN_RESET); + } else if (uartHandler->uart == USART6) //**RS485_3 + { + HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port, + RS485_3_DIR_Pin, GPIO_PIN_RESET); + } else if (uartHandler->uart == UART7) //**RS485_4 + { + HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port, + RS485_4_DIR_Pin, GPIO_PIN_RESET); + } else if (uartHandler->uart == USART2) //**E22 // External serial port + { + + } else if (uartHandler->uart == UART5) //**E28 // SBUS + { + + } +} +void UARTHandlerRX(struct UARTHandler *uartHandler) +{ + //uartHandler->Wait_Time_Count = 0; + if (uartHandler->startCountFlag == 0) + { + uartHandler->startCountFlag = 1; + uartHandler->RxCount = 0; + } + + uartHandler->Rx_Buf[uartHandler->RxCount] = uartHandler->tmp_Rx_Buf[0]; + uartHandler->RxCount++; + + HAL_UART_Receive_IT(uartHandler->uart, uartHandler->tmp_Rx_Buf, 1); + + uartHandler->Wait_Time_Count = 0; + if(uartHandler->RxCount>=1024)//接收数据过多,直接抛弃 + { + uartHandler->RxCount=0; + } + //HAL_UART_Receive_IT(uartHandler->uart, RS_485_2_UART_Handler.tmp_Rx_Buf, 1); +} + +void IntializeUARTHandler(struct UARTHandler *uartHandler, + UART_HandleTypeDef *uart, int32_t WaitTime, unsigned char timeSpan,int32_t Dispacher_Time) +{ + uartHandler->Wait_Time_Count = 0; + uartHandler->Wait_time = WaitTime; + + uartHandler->uart = uart; + uartHandler->UART_Rx = UARTHandlerRX; + uartHandler->UART_Tx = UARTHandlerTx; + uartHandler->AddSendList = UARTHandlerAddTxList; + + uartHandler->dispacherController = (DispacherController*) malloc( + sizeof(DispacherController)); + + uartHandler->dispacherController->pHead = NULL; + uartHandler->dispacherController->pTail = NULL; + uartHandler->dispacherController->Dispacher_Enable = 0; + uartHandler->dispacherController->DispacherCallTime = Dispacher_Time ; // call the function every 50 ms + uartHandler->dispacherController->Dispacher_Counter = 0; + uartHandler->dispacherController->DispacherNumber = 0; + uartHandler->dispacherController->Add_Dispatcher_List = Dispatcher_List_Add_t; + uartHandler->dispacherController->Dispatcher_Run = Dispatch_t; + + uartHandler->timeSpan = 2; + uartHandler->SendList_time_Count = 0; + uartHandler->SendList_Period = 100; + +} + +void Counting(struct UARTHandler *uartHandler) +{ + + if (uartHandler->UART_Decode == NULL) //不解析,直接返回true + { + uartHandler->decode_finished = 1; + } else + { + if (uartHandler->startCountFlag == 1) + { + uartHandler->Wait_Time_Count++; + if (uartHandler->timeSpan * uartHandler->Wait_Time_Count + >= uartHandler->Wait_time) + { + uartHandler->Wait_Time_Count = 0; + uartHandler->startCountFlag = 0; + //启动解析函数 + if (uartHandler->RxCount >= 1) + { + uartHandler->UART_Decode(uartHandler->Rx_Buf, + uartHandler->RxCount); + uartHandler->RxCount = 0; + } + } + + } + } + + if (uartHandler->pCurrentUARTSendHadler != NULL) + { + + GF_UART_Send_List_Send(uartHandler); + } else + { + uartHandler->dispacherController->Dispatcher_Run( + uartHandler->dispacherController); + } + +// uartHandler->Send_Time_Count++; +// if (uartHandler->timeSpan * uartHandler->Send_Time_Count +// >= uartHandler->DispacherCallPeriod) +// { +// uartHandler->Send_Time_Count = 0; +// if (uartHandler->pCurrentUARTSendHadler != NULL) +// { +// //拷贝数据到相关的代码中,然后发送 +// uartHandler->UART_Decode = +// uartHandler->pCurrentUARTSendHadler->UART_Decode; // +// memcpy(uartHandler->Tx_Buf, +// uartHandler->pCurrentUARTSendHadler->Tx_Buf, +// uartHandler->pCurrentUARTSendHadler->TxCount); +// +// uartHandler->TxCount = uartHandler->pCurrentUARTSendHadler->TxCount; +// uartHandler->UART_Tx(uartHandler); +// +// if (uartHandler->pCurrentUARTSendHadler->pNext != NULL) +// { +// UARTSendHandler *temp = +// uartHandler->pCurrentUARTSendHadler->pNext; +// free(uartHandler->pCurrentUARTSendHadler); //清除内存 +// uartHandler->pCurrentUARTSendHadler = temp; +// } else +// { +// free(uartHandler->pCurrentUARTSendHadler); //清除内存 +// uartHandler->pCurrentUARTSendHadler = NULL; +// } +// +// } +// +// } + +} +//_weak +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == UART4) //**DEBUG + { + UARTHandlerRX(&InterCall_DEBUG_UART_Handler); + + //GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_DEBUG_RxCpltCallback); + + } else if (huart->Instance == USART1) //**RS485_1 + { + //GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_RS485_1_RxCpltCallback); + + UARTHandlerRX(&RS_485_1_UART_Handler); + } else if (huart->Instance == USART3) //**RS485_2 + { + //GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_RS485_2_RxCpltCallback); + UARTHandlerRX(&RS_485_2_UART_Handler); + } else if (huart->Instance == USART6) //**RS485_3 + { + //GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_RS485_3_RxCpltCallback); + UARTHandlerRX(&RS_485_3_UART_Handler); + } else if (huart->Instance == UART7) //**RS485_4 + { +// UARTHandlerRX(&RS_485_4_UART_Handler); + //GF_BSP_Interrupt_Run_CallBack(DF_BSP_InterCall_RS485_4_RxCpltCallback); + UARTHandlerRX(&RS_485_4_UART_Handler); + + } else if (huart->Instance == USART2) //**E22 // External serial port + { +// GF_BSP_Interrupt_Run_CallBack( +// DF_BSP_InterCall_E22_Serial_RxCpltCallback); + UARTHandlerRX(<E_7S0_Serial_UART_Handler); + } else if (huart->Instance == UART5) //**E28 // SBUS + { + +// GF_BSP_Interrupt_Run_CallBack( +// DF_BSP_InterCall_E28_SBUS_RxFifo0Callback); + UARTHandlerRX(&E28_SBUS_UART_Handler); + } + + + #if defined (hlpuart1Exit) + else if (huart->Instance == LPUART1) //**E28 // SBUS + { + UARTHandlerRX(&LPUART1_UART_Handler); + } + + + #endif +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) +{ + + if (huart->Instance == UART4) //**DEBUG + { + + } else if (huart->Instance == USART1) //**RS485_1 + { + HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin, + GPIO_PIN_RESET); + } else if (huart->Instance == USART3) //**RS485_2 + { + HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin, + GPIO_PIN_RESET); + } else if (huart->Instance == USART6) //**RS485_3 + { + HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port, + RS485_3_DIR_Pin, GPIO_PIN_RESET); + } else if (huart->Instance == UART7) //**RS485_4 + { + HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port, + RS485_4_DIR_Pin, GPIO_PIN_RESET); + } else if (huart->Instance == USART2) //**E22 // External serial port + { + + } else if (huart->Instance == UART5) //**E28 // SBUS + { + + } + +} + +//RS485_Index:1-4 RS485; 5 ExternSerial; 6 Debug; +void GF_BSP_UART_Transmit(const uint8_t RS485_Index, const uint8_t *pData, + uint16_t Size) +{ + UART_HandleTypeDef *huart; + if (Size > UART_Transmit_MAX_NUM) + Size = UART_Transmit_MAX_NUM; + + switch (RS485_Index) + { + case 1: + huart = &huart1; + HAL_GPIO_WritePin(RS485_1_DIR_GPIO_Port, RS485_1_DIR_Pin, + GPIO_PIN_SET); + memcpy(RS485_1_TxDMA_buf, pData, Size); + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_1_TxDMA_buf, + Size); + HAL_UART_Transmit_DMA(huart, RS485_1_TxDMA_buf, Size); + //HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff); + + break; + case 2: + huart = &huart3; + HAL_GPIO_WritePin(RS485_2_DIR_GPIO_Port, RS485_2_DIR_Pin, + GPIO_PIN_SET); + memcpy(RS485_2_TxDMA_buf, pData, Size); + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_2_TxDMA_buf, + Size); + HAL_UART_Transmit_DMA(huart, RS485_2_TxDMA_buf, Size); + break; + case 3: + huart = &huart6; + HAL_GPIO_WritePin(RS485_3_DIR_GPIO_Port, RS485_3_DIR_Pin, + GPIO_PIN_SET); + memcpy(RS485_3_TxDMA_buf, pData, Size); + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_3_TxDMA_buf, + Size); + HAL_UART_Transmit_DMA(huart, RS485_3_TxDMA_buf, Size); + break; + case 4: + huart = &huart7; + HAL_GPIO_WritePin(RS485_4_DIR_GPIO_Port, RS485_4_DIR_Pin, + GPIO_PIN_SET); + memcpy(RS485_4_TxDMA_buf, pData, Size); + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) RS485_4_TxDMA_buf, + Size); + HAL_UART_Transmit_DMA(huart, RS485_4_TxDMA_buf, Size); + break; + case 5: + huart = &huart2; + memcpy(ExternSerial_TxDMA_buf, pData, Size); + SCB_CleanInvalidateDCache_by_Addr( + (uint32_t*) ExternSerial_TxDMA_buf, Size); + HAL_UART_Transmit_DMA(huart, ExternSerial_TxDMA_buf, Size); + break; + default: + huart = &huart4; + memcpy(Debug_TxDMA_buf, pData, Size); + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) Debug_TxDMA_buf, + Size); + HAL_UART_Transmit_DMA(huart, Debug_TxDMA_buf, Size); + break; + } +} +//void USART_Dispatch(struct UARTHandler *uartHandler) +//{ +////2ms +// if (uartHandler->Dispacher_Enable == 1) +// { +// uartHandler->Dispacher_Counter++; +// if (uartHandler->DispacherNumber > 0) //列表中有数据 +// { +// if (uartHandler->Dispacher_Counter * uartHandler->timeSpan +// >= uartHandler->DispacherCallPeriod +// / uartHandler->DispacherNumber) //多长时间运行一次 +// { +// +// uartHandler->Dispacher_Counter = 0; +// if (uartHandler->pHead != NULL +// && uartHandler->pHead->pNext != NULL) +// { +// uartHandler->pHead->dispache(); +// uartHandler->pHead = uartHandler->pHead->pNext; +// } else +// { +// +// } +// } +// } +// +// } +// +//} +// +//void Dispatcher_List_Add(struct UARTHandler *uartHandler, +// void (*dispache)(void)) +//{ +// Dispatcher *pTmp = NULL; //临时指针2 +// if (uartHandler->pHead == NULL && uartHandler->pTail == NULL) //头尾部都为空 +// { +// uartHandler->pHead = uartHandler->pTail = (Dispatcher*) malloc( +// sizeof(Dispatcher)); +// uartHandler->pTail->dispache = dispache; +// uartHandler->pTail->pNext = uartHandler->pHead; +// uartHandler->DispacherNumber++; +// } else +// { +// //临时指针2用于逐个申请内存 +// pTmp = (Dispatcher*) malloc(sizeof(Dispatcher)); +// pTmp->dispache = dispache; +// pTmp->pNext = uartHandler->pHead; //set the new dispatcher .next to the header, thus make it a circle +// //临时指针1的next指向刚分配内存的临时指针2 +// uartHandler->pTail->pNext = pTmp; +// +// uartHandler->pTail = pTmp; //set pTail the last node of this ring +// uartHandler->DispacherNumber++; +// } +//} +void GF_UART_Send_List_Send(struct UARTHandler *handler) +{ + + handler->SendList_time_Count++; + if (handler->timeSpan * handler->SendList_time_Count + >= handler->SendList_Period) + { + handler->SendList_time_Count = 0; + handler->SendListExists = 1; + if (handler->pCurrentUARTSendHadler != NULL) + { + //拷贝数据到相关的代码中,然后发送 + + //handler->CAN_Decode = handler->pCurrentCANSendHadler->CAN_Decode; // + memcpy(handler->Tx_Buf, handler->pCurrentUARTSendHadler->Tx_Buf, + handler->pCurrentUARTSendHadler->SendLength); + handler->SendList_Period = + handler->pCurrentUARTSendHadler->SendListTimePeriod; + handler->TxCount = handler->pCurrentUARTSendHadler->SendLength; + handler->UART_Tx(handler); + + if (handler->pCurrentUARTSendHadler->pNext != NULL) + { + UARTSendHandler *temp = handler->pCurrentUARTSendHadler->pNext; + free(handler->pCurrentUARTSendHadler); //清除内存 + handler->pCurrentUARTSendHadler = temp; + } else + { + free(handler->pCurrentUARTSendHadler); //清除内存 + handler->pCurrentUARTSendHadler = NULL; + } + + } else + { + handler->SendListExists = 0; + + } + + } + +} diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_UDP.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_UDP.c new file mode 100644 index 0000000..4c36223 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_UDP.c @@ -0,0 +1,438 @@ +/* + * bsp_UDP.c + * + * Created on: Aug 13, 2024 + * Author: akeguo + */ + +#include "stm32h7xx_hal.h" +#include "lwip.h" +#include "udp.h" +#include "string.h" +#include "bsp_UDP.h" +#include "bsp_DLT_Log.h" +#include +#include "BSP/bsp_GPIO.h" +void UDP_GV_Dispatch(); +void UDP_IV_Dispatch(); +void udp_cmd_send_GV(char *pData, uint16_t Size); +/* 定义端口号 */ +#define UDP_DLT_LOCAL_PORT 8000 /* 本地端口 */ +#define UDP_CMD_LOCAL_PORT 8002 /* 本地端口 */ +#define UDP_CMD_LOCAL_Android_Listen_PORT 8006 /* 本地端口 接收安卓 */ + +#define UDP_DLT_Send_LOCAL_PORT 7000 /* 本地端口 */ +#define UDP_CMD_Send_LOCAL_PORT 7002 /* 本地端口 */ +#define UDP_GV_Send_LOCAL_PORT 7004 /* 本地端口 */ +#define UDP_Android_Send_LOCAL_PORT 7006 /* 本地端口 发给安卓*/ +/*32从7006发往安卓9006*/ +/*安卓从9006发往32的8006*/ +#define UDP_REMOTE_DLT_PORT 9000 /* 远端端口 */ +#define UDP_REMOTE_CMD_PORT 9002 /* 远端端口 */ +#define UDP_REMOTE_GV_PORT 9004 /* 远端端口 */ +#define UDP_REMOTE_Android_PORT 9006 /* 远端端口 */ + +int8_t is_udp_GV_update_loop_enalbed = 0; +unsigned char received_data[1000]; + +/* udp控制块 */ +static struct udp_pcb *upcb_Rx_DLT; +static struct udp_pcb *upcb_Rx_Cmd; +static struct udp_pcb *upcb_Rx_From_Android; + +static struct udp_pcb *upcb_Tx_DLT; +static struct udp_pcb *upcb_Tx_Cmd; +static struct udp_pcb *upcb_Tx_GV; +static struct udp_pcb *upcb_Tx_Android; + +ip_addr_t serverIP; + +ip_addr_t Android_ServerIP; + +DLT_DecodeFuncPtr UDP_DLT_ReceivedCallback; + +/****************************************************************************** + * 描述 : 接收回调函数 + * 参数 : - + * 返回 : 无 + ******************************************************************************/ +static void udp_receive_callback(void *arg, struct udp_pcb *upcb, + struct pbuf *p, const ip_addr_t *addr, u16_t port) +{ + if (p == NULL) return; + + memcpy(received_data, p->payload, p->len); + + if (upcb->local_port == UDP_DLT_LOCAL_PORT) + { + UDP_DLT_ReceivedCallback(received_data, p->len); + //DLT_DataReceiveEndCallback(received_data, p->len); + } + else if (upcb->local_port == UDP_CMD_LOCAL_PORT) + { + + if (*received_data == 0x55 && *(received_data + 1) == 0x55 + && p->len >= 3) + { + decode_command_and_feedback(received_data + 2, p->len - 2, 2, + NULL); //0代表UDP + } + else if (*received_data == 0x66 && *(received_data + 1) == 0x66 + && p->len >= 3) + { + GF_BSP_GPIO_SetIO(received_data[3], received_data[2]); + + } + else + { + udp_cmd_send_back(received_data, p->len); + } + } + else if (upcb->local_port == UDP_CMD_LOCAL_Android_Listen_PORT) + { + //对PV数据进行修改 + //if (*buffer == 0x55 && *(buffer + 1) == 0x55 && length >= 4) + if (received_data[0] != 0x55 || received_data[1] != 0x55 || p->len < 4) + { + return; + } + + uint16_t crc_check = ((received_data[p->len - 1] << 8) + | received_data[p->len - 2]); + uint16_t crc_check1 = MB_CRC16(received_data, p->len - 2); + /* CRC 校验正确 */ + if (crc_check != MB_CRC16(received_data, p->len - 2)) return; + + if (received_data[2] != 0x01 || received_data[3] != 0x01) return; + + pb_istream_t i_pv_stream = + { 0 }; + + i_pv_stream = pb_istream_from_buffer(&received_data[4], p->len - 4); + pb_decode(&i_pv_stream, PV_struct_define_fields, &_decoded_PV_temp); + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController, + "mk32_UDP", 1); + if (_decoded_PV_temp.TimeStamp > decoded_PV.TimeStamp) + { + decoded_PV = _decoded_PV_temp; + } + + } + pbuf_free(p); + +} + +//char UDPprintf[100]; + +void udp_dlt_send_back(char *pData, uint16_t Size) +{ + struct pbuf *p; + + /* 分配缓冲区空间 */ + p = pbuf_alloc(PBUF_TRANSPORT, Size, PBUF_RAM); + if (p != NULL) + { + /* 填充缓冲区数据 */ + pbuf_take(p, pData, Size); + + /* 发送udp数据 */ + + //udp_send(upcb_DLT, p); + err_t t = udp_sendto(upcb_Tx_DLT, p, &serverIP, + UDP_REMOTE_DLT_PORT); + /* 释放缓冲区空间 */ + pbuf_free(p); + } +} +void udp_cmd_send_back(char *pData, uint16_t Size) +{ + struct pbuf *p; + + /* 分配缓冲区空间 */ + p = pbuf_alloc(PBUF_TRANSPORT, Size, PBUF_RAM); + + if (p != NULL) + { + /* 填充缓冲区数据 */ + pbuf_take(p, pData, Size); + + /* 发送udp数据 */ + err_t err = udp_send(upcb_Tx_Cmd, p); + if (err != ERR_OK) + { + // 发送失败 + printf("Failed to send UDP data: %d\n", err); + } + /* 释放缓冲区空间 */ + pbuf_free(p); + } +} + +void udp_cmd_send_GV(char *pData, uint16_t Size) +{ + struct pbuf *p; + + /* 分配缓冲区空间 */ + p = pbuf_alloc(PBUF_TRANSPORT, Size, PBUF_RAM); + + if (p != NULL) + { + /* 填充缓冲区数据 */ + pbuf_take(p, pData, Size); + + /* 发送udp数据 */ + err_t err = udp_send(upcb_Tx_GV, p); + if (err != ERR_OK) + { + // 发送失败 + //printf("Failed to send UDP data: %d\n", err); + } + /* 释放缓冲区空间 */ + pbuf_free(p); + } +} + +void udp_send_by_pcb(struct udp_pcb *upcb, char *pData, uint16_t Size) +{ + struct pbuf *p; + + /* 分配缓冲区空间 */ + p = pbuf_alloc(PBUF_TRANSPORT, Size, PBUF_RAM); + + if (p != NULL) + { + /* 填充缓冲区数据 */ + pbuf_take(p, pData, Size); + + /* 发送udp数据 */ + err_t err = udp_send(upcb, p); + if (err != ERR_OK) + { + // 发送失败 + //printf("Failed to send UDP data: %d\n", err); + } + /* 释放缓冲区空间 */ + pbuf_free(p); + } +} + +/****************************************************************************** + * 描述 : 创建udp客户端 + * 参数 : 无 + * 返回 : 无 + ******************************************************************************/ +void udp_client_init(void) +{ + + HardWareErrorController->Add_PCOMHardWare(HardWareErrorController, + "mk32_UDP", 0, ComError_MK32_UDP); + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, UDP_GV_Dispatch); + //将UDP上传IV关闭 + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, UDP_IV_Dispatch); + //Timer intialize(); + err_t err; + + IP4_ADDR(&serverIP, 192, 168, 144, 255); + IP4_ADDR(&Android_ServerIP, 192, 168, 144, 20); + + /* 创建udp控制块 */ + upcb_Rx_DLT = udp_new(); + + if (upcb_Rx_DLT != NULL) + { + /* 配置本地端口 */ + //upcb_DLT->local_port = UDP_DLT_LOCAL_PORT; + /* 配置服务器IP和端口 */ + //upcb_DLT->so_options |= SOF_BROADCAST; + //err = udp_connect(upcb_DLT, &serverIP, UDP_REMOTE_DLT_PORT); + err = udp_bind(upcb_Rx_DLT, IP_ADDR_ANY, UDP_DLT_LOCAL_PORT); + if (err == ERR_OK) + { + /* 注册接收回调函数 */ + /* 注册接收回调函数 */ + udp_recv(upcb_Rx_DLT, udp_receive_callback, NULL); + } + else + { + udp_remove(upcb_Rx_DLT); + + } + } + + upcb_Rx_From_Android = udp_new(); + + if (upcb_Rx_From_Android != NULL) + { + /* 配置本地端口 */ + //upcb_DLT->local_port = UDP_DLT_LOCAL_PORT; + /* 配置服务器IP和端口 */ + //upcb_DLT->so_options |= SOF_BROADCAST; + //err = udp_connect(upcb_DLT, &serverIP, UDP_REMOTE_DLT_PORT); + err = udp_bind(upcb_Rx_From_Android, IP_ADDR_ANY, + UDP_CMD_LOCAL_Android_Listen_PORT); + if (err == ERR_OK) + { + /* 注册接收回调函数 */ + /* 注册接收回调函数 */ + udp_recv(upcb_Rx_From_Android, udp_receive_callback, NULL); + } + else + { + udp_remove(upcb_Rx_From_Android); + + } + } + + upcb_Rx_Cmd = udp_new(); + + if (upcb_Rx_Cmd != NULL) + { + /* 配置本地端口 */ + //upcb_Cmd->local_port = UDP_CMD_LOCAL_PORT; + /* 配置服务器IP和端口 */ + //upcb_Cmd->so_options |= SOF_BROADCAST; + //err = udp_connect(upcb_Cmd, &serverIP, UDP_REMOTE_CMD_PORT); + err = udp_bind(upcb_Rx_Cmd, IP_ADDR_ANY, UDP_CMD_LOCAL_PORT); + if (err == ERR_OK) + { + /* 注册接收回调函数 */ + udp_recv(upcb_Rx_Cmd, udp_receive_callback, NULL); + } + else + { + udp_remove(upcb_Rx_Cmd); + } + } + + upcb_Tx_Cmd = udp_new(); + + if (upcb_Tx_Cmd != NULL) + { + /* 配置本地端口 */ + upcb_Tx_Cmd->local_port = UDP_CMD_Send_LOCAL_PORT; + + /* 配置服务器IP和端口 */ + //upcb_Cmd->so_options |= SOF_BROADCAST; + err = udp_connect(upcb_Tx_Cmd, &serverIP, UDP_REMOTE_CMD_PORT); + + if (err == ERR_OK) + { + /* 注册接收回调函数 */ + //udp_recv(upcb_Tx_Cmd, udp_receive_callback, NULL); + } + else + { + udp_remove(upcb_Tx_Cmd); + } + } + upcb_Tx_DLT = udp_new(); + + if (upcb_Tx_DLT != NULL) + { + /* 配置本地端口 */ + upcb_Tx_Cmd->local_port = UDP_DLT_Send_LOCAL_PORT; + /* 配置服务器IP和端口 */ + //upcb_Cmd->so_options |= SOF_BROADCAST; + err = udp_connect(upcb_Tx_DLT, &serverIP, UDP_REMOTE_DLT_PORT); + + if (err == ERR_OK) + { + /* 注册接收回调函数 */ + //udp_recv(upcb_Tx_Cmd, udp_receive_callback, NULL); + } + else + { + udp_remove(upcb_Tx_DLT); + } + } + + upcb_Tx_GV = udp_new(); + + if (upcb_Tx_GV != NULL) + { + /* 配置本地端口 */ + upcb_Tx_Cmd->local_port = UDP_GV_Send_LOCAL_PORT; + /* 配置服务器IP和端口 */ + //upcb_Cmd->so_options |= SOF_BROADCAST; + err = udp_connect(upcb_Tx_GV, &serverIP, UDP_REMOTE_GV_PORT); + + if (err == ERR_OK) + { + /* 注册接收回调函数 */ + //udp_recv(upcb_Tx_Cmd, udp_receive_callback, NULL); + } + else + { + udp_remove(upcb_Tx_GV); + } + } + + upcb_Tx_Android = udp_new(); + + if (upcb_Tx_Android != NULL) + { + /* 配置本地端口 */ + upcb_Tx_Android->local_port = UDP_Android_Send_LOCAL_PORT; + /* 配置服务器IP和端口 */ + //upcb_Cmd->so_options |= SOF_BROADCAST; + err = udp_connect(upcb_Tx_Android, &Android_ServerIP, + UDP_REMOTE_Android_PORT); + + if (err == ERR_OK) + { + /* 注册接收回调函数 */ + //udp_recv(upcb_Tx_Cmd, udp_receive_callback, NULL); + } + else + { + udp_remove(upcb_Tx_Android); + } + } + +} +int counter_index = 0; +int iv_counter_index = 0; +void UDP_GV_Dispatch() +{ + counter_index++; + if (counter_index <= 50) return; + if (is_udp_GV_update_loop_enalbed == 0) return; + counter_index = 0; + pb_ostream_t GV_o_stream = + { 0 }; + char buf[1024]; + GV_o_stream = pb_ostream_from_buffer(&buf[2], sizeof(buf)); + pb_encode(&GV_o_stream, GV_struct_define_fields, &GV); + buf[1] = 0xfe; + buf[0] = 0xfe; + //memcpy(&wh_LTE_7S0_Handler->Tx_Buf[2], buf, GV_o_stream.bytes_written); + udp_cmd_send_GV(buf, GV_o_stream.bytes_written + 2); + +} +//现在是每一百ms执行一次 +void UDP_IV_Dispatch() +{ + iv_counter_index++; + if (iv_counter_index <= 50) return; + iv_counter_index=0; + char Tx_Buf[1024]; + pb_ostream_t IV_o_stream = pb_ostream_from_buffer(&Tx_Buf[2], + sizeof(Tx_Buf) - 2); + pb_encode(&IV_o_stream, IV_struct_define_fields, &IV); + + Tx_Buf[0] = 0x55; + Tx_Buf[1] = 0x55; + int32_t TxCount = IV_o_stream.bytes_written + 4; + uint16_t crc = MB_CRC16(Tx_Buf, IV_o_stream.bytes_written + 2); + + Tx_Buf[IV_o_stream.bytes_written + 2] = (crc >> 8) & 0xff; + Tx_Buf[IV_o_stream.bytes_written + 3] = crc & 0xff; + + udp_send_by_pcb(upcb_Tx_Android, Tx_Buf, IV_o_stream.bytes_written + 4); + +} + +/******************************** END OF FILE ********************************/ + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_UpperComputer_Handler.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_UpperComputer_Handler.c new file mode 100644 index 0000000..503f1cc --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_UpperComputer_Handler.c @@ -0,0 +1,114 @@ +/* + * bsp_desulfurizer_handler.c + * + * Created on: Jul 29, 2024 + * Author: akeguo + */ +#include "msp_WH_LTE_7S0.h" + +#include "pb_decode.h" +#include "pb_encode.h" +#include "bsp_include.h" +#include "pb.h" + +#include "bsp_Cmd.pb.h" +#include +#include +#include + + +#include "BHBF_ROBOT.h" +#include "bsp_cpu_flash.h" +#include +#include + +#include "bsp_decode_command.h" +void decode_command_from_computer(uint8_t *buffer, uint16_t length); +struct UARTHandler *desulfurizer_message_UART_Handler; + +void upper_Computer_UART_Handler_intialize(struct UARTHandler *Handler) +{ + + //LOG("desulfurizer_message_UART_Handler_intialize"); + desulfurizer_message_UART_Handler = Handler; + desulfurizer_message_UART_Handler->dispacherController->Dispacher_Enable=0;//不周期性发送 + desulfurizer_message_UART_Handler->Wait_time=30; + desulfurizer_message_UART_Handler->UART_Decode = + decode_command_from_computer; //indicate that there is no need to listen + //desulfurizer_message_UART_Handler->DispacherCallPeriod=200; + + //desulfurizer_message_UART_Handler->Add_Dispatcher_List(desulfurizer_message_UART_Handler,steering_set_angle); + } + + + + +void send_data_to_upper_computer(double Angle, double WireLength, + double Thickness, char IsFittingPoint,char isMqtt,struct UARTHandler *send_UART_Handler) +{ +// LOG("send collected data to computer"); +// DesulfurizerMessage _desulfurizer = DesulfurizerMessage_init_default; +// pb_ostream_t output_stream = +// { 0 }; +// +// _desulfurizer.Angle = Angle; +// _desulfurizer.WireLength = WireLength; +// _desulfurizer.Thickness = Thickness; +// _desulfurizer.IsFittingPoint = IsFittingPoint; +// char buf[1024]; +// output_stream = pb_ostream_from_buffer(buf, sizeof(buf)); +// pb_encode(&output_stream, DesulfurizerMessage_fields, &_desulfurizer); //encode to buffer + +// Cmd send_Cmd = Cmd_init_default; +// +// //将数据拷贝到Command中 +// send_Cmd.CommadNum = 5; +// send_Cmd.Buff_Data_Length = output_stream.bytes_written; +// //拷贝数据到send_Cmd.Buff_Data中 +// memcpy(send_Cmd.Buff_Data, buf, send_Cmd.Buff_Data_Length); +// pb_ostream_t Cmd_out_stream = +// { 0 }; +// +// if(isMqtt==1) +// { +// Cmd_out_stream = pb_ostream_from_buffer( +// &send_UART_Handler->Tx_Buf[2], +// sizeof(desulfurizer_message_UART_Handler->Tx_Buf)-2); +// pb_encode(&Cmd_out_stream, Cmd_fields, &send_Cmd); //encode to buffer +// send_UART_Handler->Tx_Buf[0]='3'; +// send_UART_Handler->Tx_Buf[1]=','; +// send_UART_Handler->TxCount = Cmd_out_stream.bytes_written+2; +// send_UART_Handler->UART_Tx( +// send_UART_Handler); +// } +// else +// { +// Cmd_out_stream = pb_ostream_from_buffer( +// send_UART_Handler->Tx_Buf, +// sizeof(send_UART_Handler->Tx_Buf)); +// pb_encode(&Cmd_out_stream, Cmd_fields, &send_Cmd); //encode to buffer +// +// send_UART_Handler->TxCount = Cmd_out_stream.bytes_written; +// send_UART_Handler->UART_Tx( +// send_UART_Handler); +// } + +} + + + + + +void decode_command_from_computer(uint8_t *buffer, uint16_t length) +{ + + if(*buffer==0x55 && *(buffer+1)==0x55 && length>=3) + { + decode_command_and_feedback(buffer+2, length-2, 0, + desulfurizer_message_UART_Handler);//0代表非mqtt + } + +} + + + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_client_setting.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_client_setting.c new file mode 100644 index 0000000..9340681 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_client_setting.c @@ -0,0 +1,128 @@ +/* + * bsp_pv_setting.c + * + * Created on: Jan 8, 2025 + * Author: akeguo + */ +#include +#include "BHBF_ROBOT.h" + +#include "gpio.h" +#include "bsp_com_helper.h" +#include "BSP/bsp_UART.h" + +void UpdateIV(); +void decode_received_data_from_client(uint8_t *buffer, uint16_t length); + +struct UARTHandler *client_setting_Handler; +DispacherController *client_setting_dispacher; + +void client_setting_intialize(struct UARTHandler *Handler) +{ + + client_setting_Handler = Handler; + client_setting_Handler->Wait_time = 10; // 最低不要低于4; + + client_setting_dispacher = Handler->dispacherController; + client_setting_dispacher->Add_Dispatcher_List(client_setting_dispacher, + UpdateIV); + client_setting_dispacher->DispacherCallTime = 500; + client_setting_dispacher->Dispacher_Enable=1;//不周期性发送 + HardWareErrorController->Add_PCOMHardWare(HardWareErrorController, + "mk32_Serial", 0, ComError_MK32_Serial); + + client_setting_Handler->UART_Decode = decode_received_data_from_client; //indicate that there is no need to listen + LOG("client_setting_intialize"); +} + +void UpdateIV() +{ + + pb_ostream_t IV_o_stream = pb_ostream_from_buffer( + &client_setting_Handler->Tx_Buf[2], + sizeof(client_setting_Handler->Tx_Buf) - 2); + pb_encode(&IV_o_stream, IV_struct_define_fields, &IV); + + client_setting_Handler->Tx_Buf[0] = 0x55; + client_setting_Handler->Tx_Buf[1] = 0x55; + client_setting_Handler->TxCount = IV_o_stream.bytes_written + 4; + + uint16_t crc=MB_CRC16(&(client_setting_Handler->Tx_Buf[0]), IV_o_stream.bytes_written + 2); + + client_setting_Handler->Tx_Buf[IV_o_stream.bytes_written + 2] = (crc>>8) &0xff; + client_setting_Handler->Tx_Buf[IV_o_stream.bytes_written + 3] = crc & 0xff;; + + + client_setting_Handler->UART_Tx(client_setting_Handler); +} + +void decode_received_data_from_client(uint8_t *buffer, uint16_t length) +{ + if(length>100) + { + return; + } + uint8_t data[100]; + memcpy(data,buffer,length); + + //if (*buffer == 0x55 && *(buffer + 1) == 0x55 && length >= 4) + if (buffer[0] == 0x55 && buffer[1] == 0x55 && length >= 4) + { + uint16_t crc_check = ((buffer[length - 1] << 8) | buffer[length - 2]); + uint16_t crc_check1 = MB_CRC16(buffer, length - 2); + /* CRC 校验正确 */ + if (crc_check == MB_CRC16(buffer, length - 2)) + { + //if (*(buffer + 2) == 0x01 && *(buffer + 3) == 0x01) //01 01 设置PV + if (buffer[2] == 0x01 && buffer[3] == 0x01) //01 01 设置PV + { + + pb_istream_t i_pv_stream = + { 0 }; + + i_pv_stream = pb_istream_from_buffer(&buffer[4], length - 4); + pb_decode(&i_pv_stream, PV_struct_define_fields, &decoded_PV_variable); + //pb_decode(&i_pv_stream, PV_struct_define_fields, &decoded_PV); + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController, + "mk32_Serial", 1); + + if(decoded_PV_variable.TimeStamp>decoded_PV.TimeStamp) + { + decoded_PV=decoded_PV_variable; + } + //将CV写入EEPROM + //CV_struct_define saved_cV = GF_BSP_EEPROM_Get_CV(); + //GV.PV = decoded_PV; + //GF_BSP_EEPROM_Set_CV(CV); + } + else if (*(buffer + 2) == 0x02 && *(buffer + 3) == 0x01) //设置PV + { + + } + else if (*(buffer + 2) == 0x03 && *(buffer + 3) == 0x01) //返回IV + { + + } + else + { + + } + + } + else + { + //Decode Error; + //log_error("wire sensor decoding failed"); + LOGFF(DL_ERROR, "androidd decoding failed"); + + } + + } + +// client_setting_Handler->Tx_Buf[0]='1'; +// client_setting_Handler->Tx_Buf[1]=','; +// //wh_LTE_7S0_Handler->Tx_Buf[2]='1'; +// client_setting_Handler->TxCount = 2; +// client_setting_Handler->UART_Tx(client_setting_Handler); +} + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_com_helper.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_com_helper.c new file mode 100644 index 0000000..c1fc03e --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_com_helper.c @@ -0,0 +1,191 @@ +/* + * bsp_com_helper.c + * + * Created on: Oct 9, 2024 + * Author: akeguo + */ +#include "bsp_com_helper.h" +#include +#include "DLTuc.h" +#include "BHBF_ROBOT.h" + +void Dispatch_t(DispacherController *uartHandler) +{ +//2ms + + if (uartHandler->Dispacher_Enable == 1) + { + if (uartHandler->DispacherNumber > 0) //列表中有数据 + { + uartHandler->Dispacher_Counter++; + + if (uartHandler->Dispacher_Counter + >= uartHandler->DispacherCallTime / 2 + / (uartHandler->DispacherNumber)) //多长时间运行一次 + { + uartHandler->Dispacher_Counter = 0; + if (uartHandler->pHead != NULL + && uartHandler->pHead->pNext != NULL) + { + + uartHandler->pHead->dispache(); + + uartHandler->pHead = uartHandler->pHead->pNext; + + } else + { + + } + } + } + + } +} + +void Dispatcher_List_Add_t(DispacherController *uartHandler, + void (*dispache)(void)) +{ + Dispatcher *pTmp = NULL; //临时指针2 + + if (uartHandler->pHead == NULL && uartHandler->pTail == NULL) //头尾部都为空 + { + uartHandler->pHead = uartHandler->pTail = (Dispatcher*) malloc( + sizeof(Dispatcher)); + uartHandler->pHead->dispache = dispache; + uartHandler->pTail->dispache = dispache; + + + + uartHandler->pHead->pNext = uartHandler->pTail; + + uartHandler->pTail->pNext = uartHandler->pHead; + uartHandler->DispacherNumber++; + } else + { + //临时指针2用于逐个申请内存 + pTmp = (Dispatcher*) malloc(sizeof(Dispatcher)); + pTmp->dispache = dispache; + + + pTmp->pNext = uartHandler->pHead; //set the new dispatcher .next to the header, thus make it a circle + + //临时指针1的next指向刚分配内存的临时指针2 + uartHandler->pTail->pNext = pTmp; + + uartHandler->pTail = pTmp; //set pTail the last node of this ring + uartHandler->DispacherNumber++; + } +} + +void ComHardWare_List_Add_t(HardWareController *uartHandler, char *name, + char value,uint32_t bitFlag) +{ + + ComHardWare *pTmp = NULL; //临时指针2 + if (uartHandler->pComHWHead == NULL && uartHandler->pComHWTail == NULL) //头尾部都为空 + { + uartHandler->pComHWHead = uartHandler->pComHWTail = + (ComHardWare*) malloc(sizeof(ComHardWare)); + + memset(uartHandler->pComHWHead->Name, '\0', + sizeof(uartHandler->pComHWHead->Name)); + memcpy(uartHandler->pComHWHead->Name, name, strlen(name)); + uartHandler->pComHWHead->IsOnline = value; + uartHandler->pComHWHead->BitFlag = bitFlag; + uartHandler->pComHWHead->pNext = NULL; + } else + { + + pTmp = (ComHardWare*) malloc(sizeof(ComHardWare)); + memset(pTmp->Name, '\0', sizeof(pTmp->Name)); + memcpy(pTmp->Name, name, strlen(name)); + + pTmp->BitFlag = bitFlag; + pTmp->IsOnline = value; + pTmp->pNext = NULL; //set the new dispatcher .next to the header, thus make it a circle + uartHandler->pComHWTail->pNext = pTmp; + uartHandler->pComHWTail = pTmp; + + } + +} +//HardWareErrorController->Set_PCOMHardWare = Set_PCOMHardWare_t; +int Set_PCOMHardWare_t(HardWareController *uartHandler, char *name, char value) +{ + + ComHardWare *ptr = uartHandler->pComHWHead; + char finddata = 0; + + if (ptr == NULL) + { + + return 0; + } + + while (ptr != NULL) + { + if (strcmp(ptr->Name, name) == 0)//相等为0 + { + ptr->IsOnline = value; + finddata = 1; + return finddata; + } else + { + ptr = ptr->pNext; + } + + } + return finddata; + +} + +char str1[50] = "\0"; +void PCOMHardWare_Check_t(HardWareController *uartHandler) +{ + uartHandler->HardWare_Check_Counter++; +// if (uartHandler->HardWare_Check_Counter*2 +// >= uartHandler->DispacherCallTime * 6) //make sure every + if (uartHandler->HardWare_Check_Counter * 2 >= uartHandler->DispacherCallTime) //make sure every + { + ComHardWare *ptr = uartHandler->pComHWHead; + + if (!ptr) + { + uartHandler->HardWare_Check_Counter = 0; + //printf("链表为空\n"); + return; + } + char IsAbnornalStatus = 0; + + //check invalid state + while (ptr != NULL) + { + if (ptr->IsOnline != 1) //在线设为1 + { + memset(str1, '\0', 50); + memcpy(str1, ptr->Name, strlen(ptr->Name)); + LOGFF(DL_ERROR, "connecting Error %s", ptr->Name); + SET_BIT_1(SystemErrorCode,ptr->BitFlag); + //*SystemErrorCode=*SystemErrorCode|(1<BitFlag); + IsAbnornalStatus = 1; + }else + { + //*SystemErrorCode=*SystemErrorCode|(1<BitFlag); + SET_BIT_0(SystemErrorCode,ptr->BitFlag); + } + ptr = ptr->pNext; + } + + //set invalid state + ptr = uartHandler->pComHWHead; + while (ptr != NULL) + { + ptr->IsOnline = 0; + ptr = ptr->pNext; + } + uartHandler->HardWare_Check_Counter = 0;//perform the check of connection + } +} + + + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_cpu_flash.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_cpu_flash.c new file mode 100644 index 0000000..7d1959c --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_cpu_flash.c @@ -0,0 +1,499 @@ +/* +********************************************************************************************************* +* +* 模块名称 : cpu内部falsh操作模块(for STM32H743 H750) +* 文件名称 : bsp_cpu_flash.c +* 版 本 : V1.1 +* 说 明 : 提供读写CPU内部Flash的函数 +* 修改记录 : +* 版本号 日期 作者 说明 +* V1.0 2019-09-20 armfly 正式发布 +* V1.1 2019-10-03 armfly 写flash函数,修正长度不是32字节整数倍的bug,末尾补0写入。 +* 解决HAL库函数的 HAL_FLASH_Program()的bug, +* 问题现象是大批量连续编程失败(报编程指令顺序错, PGSERR1、 PGSERR2) +* Copyright (C), 2019-2030, 安富莱电子 www.armfly.com +* +********************************************************************************************************* +*/ + +#include "BSP/bsp_cpu_flash.h" +#include +/* +********************************************************************************************************* +* 函数 +********************************************************************************************************* +*/ + + +/* +********************************************************************************************************* +* 宏定义 +********************************************************************************************************* +*/ +//0x08020000 - 0x08000000 = 128k;//bootload 128k // every sector 448k + +/* +********************************************************************************************************* +* 变量 +********************************************************************************************************* +*/ +__IO uint32_t uwCRCValue; +__IO uint32_t uwExpectedCRCValue; +__IO uint32_t uwAppSize; + +uint8_t buf[1024]; +uint32_t RecCount = 0; +uint32_t RecCount0 = 0; +uint32_t RecSize = 0; +uint8_t RecCplt = 0; +uint32_t filesize = 0; + +uint32_t Bus_Error=0; +uint32_t update_index = 0; +uint32_t update_index_true = 0; +uint32_t update_sum = 0; +uint32_t update_sum_true = 0; + + +/* +********************************************************************************************************* +* 函 数 名: bsp_GetSector +* 功能说明: 根据地址计算扇区首地址 +* 形 参: 无 +* 返 回 值: 扇区号(0-7) +********************************************************************************************************* +*/ +uint32_t bsp_GetSector(uint32_t Address) +{ + uint32_t sector = 0; + + if (((Address < ADDR_FLASH_SECTOR_1_BANK1) && (Address >= ADDR_FLASH_SECTOR_0_BANK1)) || \ + ((Address < ADDR_FLASH_SECTOR_1_BANK2) && (Address >= ADDR_FLASH_SECTOR_0_BANK2))) + { + sector = FLASH_SECTOR_0; + } + else if (((Address < ADDR_FLASH_SECTOR_2_BANK1) && (Address >= ADDR_FLASH_SECTOR_1_BANK1)) || \ + ((Address < ADDR_FLASH_SECTOR_2_BANK2) && (Address >= ADDR_FLASH_SECTOR_1_BANK2))) + { + sector = FLASH_SECTOR_1; + } + else if (((Address < ADDR_FLASH_SECTOR_3_BANK1) && (Address >= ADDR_FLASH_SECTOR_2_BANK1)) || \ + ((Address < ADDR_FLASH_SECTOR_3_BANK2) && (Address >= ADDR_FLASH_SECTOR_2_BANK2))) + { + sector = FLASH_SECTOR_2; + } + else if (((Address < ADDR_FLASH_SECTOR_4_BANK1) && (Address >= ADDR_FLASH_SECTOR_3_BANK1)) || \ + ((Address < ADDR_FLASH_SECTOR_4_BANK2) && (Address >= ADDR_FLASH_SECTOR_3_BANK2))) + { + sector = FLASH_SECTOR_3; + } + else if (((Address < ADDR_FLASH_SECTOR_5_BANK1) && (Address >= ADDR_FLASH_SECTOR_4_BANK1)) || \ + ((Address < ADDR_FLASH_SECTOR_5_BANK2) && (Address >= ADDR_FLASH_SECTOR_4_BANK2))) + { + sector = FLASH_SECTOR_4; + } + else if (((Address < ADDR_FLASH_SECTOR_6_BANK1) && (Address >= ADDR_FLASH_SECTOR_5_BANK1)) || \ + ((Address < ADDR_FLASH_SECTOR_6_BANK2) && (Address >= ADDR_FLASH_SECTOR_5_BANK2))) + { + sector = FLASH_SECTOR_5; + } + else if (((Address < ADDR_FLASH_SECTOR_7_BANK1) && (Address >= ADDR_FLASH_SECTOR_6_BANK1)) || \ + ((Address < ADDR_FLASH_SECTOR_7_BANK2) && (Address >= ADDR_FLASH_SECTOR_6_BANK2))) + { + sector = FLASH_SECTOR_6; + } + else if (((Address < ADDR_FLASH_SECTOR_0_BANK2) && (Address >= ADDR_FLASH_SECTOR_7_BANK1)) || \ + ((Address < CPU_FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_7_BANK2))) + { + sector = FLASH_SECTOR_7; + } + else + { + sector = FLASH_SECTOR_7; + } + + return sector; +} + +/* +********************************************************************************************************* +* 函 数 名: bsp_ReadCpuFlash +* 功能说明: 读取CPU Flash的内容 +* 形 参: _ucpDst : 目标缓冲区 +* _ulFlashAddr : 起始地址 +* _ulSize : 数据大小(单位是字节) +* 返 回 值: 0=成功,1=失败 +********************************************************************************************************* +*/ +uint8_t bsp_ReadCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpDst, uint32_t _ulSize) +{ + uint32_t i; + + if (_ulFlashAddr + _ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE) + { + return 1; + } + + /* 长度为0时不继续操作,否则起始地址为奇地址会出错 */ + if (_ulSize == 0) + { + return 1; + } + + for (i = 0; i < _ulSize; i++) + { + *_ucpDst++ = *(uint8_t *)_ulFlashAddr++; + } + + return 0; +} + +/* +********************************************************************************************************* +* 函 数 名: bsp_CmpCpuFlash +* 功能说明: 比较Flash指定地址的数据. +* 形 参: _ulFlashAddr : Flash地址 +* _ucpBuf : 数据缓冲区 +* _ulSize : 数据大小(单位是字节) +* 返 回 值: +* FLASH_IS_EQU 0 Flash内容和待写入的数据相等,不需要擦除和写操作 +* FLASH_REQ_WRITE 1 Flash不需要擦除,直接写 +* FLASH_REQ_ERASE 2 Flash需要先擦除,再写 +* FLASH_PARAM_ERR 3 函数参数错误 +********************************************************************************************************* +*/ +uint8_t bsp_CmpCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpBuf, uint32_t _ulSize) +{ + uint32_t i; + uint8_t ucIsEqu; /* 相等标志 */ + uint8_t ucByte; + + /* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */ + if (_ulFlashAddr + _ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE) + { + return FLASH_PARAM_ERR; /* 函数参数错误 */ + } + + /* 长度为0时返回正确 */ + if (_ulSize == 0) + { + return FLASH_IS_EQU; /* Flash内容和待写入的数据相等 */ + } + + ucIsEqu = 1; /* 先假设所有字节和待写入的数据相等,如果遇到任何一个不相等,则设置为 0 */ + for (i = 0; i < _ulSize; i++) + { + ucByte = *(uint8_t *)_ulFlashAddr; + + if (ucByte != *_ucpBuf) + { + if (ucByte != 0xFF) + { + return FLASH_REQ_ERASE; /* 需要擦除后再写 */ + } + else + { + ucIsEqu = 0; /* 不相等,需要写 */ + } + } + + _ulFlashAddr++; + _ucpBuf++; + } + + if (ucIsEqu == 1) + { + return FLASH_IS_EQU; /* Flash内容和待写入的数据相等,不需要擦除和写操作 */ + } + else + { + return FLASH_REQ_WRITE; /* Flash不需要擦除,直接写 */ + } +} + +/* +********************************************************************************************************* +* 函 数 名: bsp_EraseCpuFlash +* 功能说明: 擦除CPU FLASH一个扇区 (128KB) +* 形 参: _ulFlashAddr : Flash地址 +* 返 回 值: 0 成功, 1 失败 +* HAL_OK = 0x00, +* HAL_ERROR = 0x01, +* HAL_BUSY = 0x02, +* HAL_TIMEOUT = 0x03 +* +********************************************************************************************************* +*/ +uint8_t bsp_EraseCpuFlash(uint32_t _ulFlashAddr) +{ + uint32_t FirstSector = 0, NbOfSectors = 0; + FLASH_EraseInitTypeDef EraseInitStruct; + uint32_t SECTORError = 0; + uint8_t re; + + /* 解锁 */ + HAL_FLASH_Unlock(); + + /* 获取此地址所在的扇区 */ + FirstSector = bsp_GetSector(_ulFlashAddr); + + /* 固定1个扇区 */ + NbOfSectors = 1; + + /* 擦除扇区配置 */ + EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; + EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; + + if (_ulFlashAddr >= ADDR_FLASH_SECTOR_0_BANK2) + { + EraseInitStruct.Banks = FLASH_BANK_2; + } + else + { + EraseInitStruct.Banks = FLASH_BANK_1; + } + + EraseInitStruct.Sector = FirstSector; + EraseInitStruct.NbSectors = NbOfSectors; + + /* 扇区擦除 */ + re = HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError); + + /* 擦除完毕后,上锁 */ + HAL_FLASH_Lock(); + + return re; +} + +/* +********************************************************************************************************* +* 函 数 名: bsp_WriteCpuFlash +* 功能说明: 写数据到CPU 内部Flash。 必须按32字节整数倍写。不支持跨扇区。扇区大小128KB. \ +* 写之前需要擦除扇区. 长度不是32字节整数倍时,最后几个字节末尾补0写入. +* 形 参: _ulFlashAddr : Flash地址 +* _ucpSrc : 数据缓冲区 +* _ulSize : 数据大小(单位是字节, 必须是32字节整数倍) +* 返 回 值: 0-成功,1-数据长度或地址溢出,2-写Flash出错(估计Flash寿命到) +********************************************************************************************************* +*/ +uint8_t bsp_WriteCpuFlash(uint32_t _ulFlashAddr, uint8_t *_ucpSrc, uint32_t _ulSize) +{ + uint32_t i; + uint8_t ucRet; + + /* 如果偏移地址超过芯片容量,则不改写输出缓冲区 */ + if (_ulFlashAddr + _ulSize > CPU_FLASH_BASE_ADDR + CPU_FLASH_SIZE) + { + return 1; + } + + /* 长度为0时不继续操作 */ + if (_ulSize == 0) + { + return 0; + } + + ucRet = bsp_CmpCpuFlash(_ulFlashAddr, _ucpSrc, _ulSize); + + if (ucRet == FLASH_IS_EQU) + { + return 0; + } + + __set_PRIMASK(1); /* 关中断 */ + + /* FLASH 解锁 */ + HAL_FLASH_Unlock(); + + for (i = 0; i < _ulSize / 32; i++) + { + uint64_t FlashWord[4]; + + memcpy((char *)FlashWord, _ucpSrc, 32); + _ucpSrc += 32; + + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, _ulFlashAddr, (uint64_t)((uint32_t)FlashWord)) == HAL_OK) + { + _ulFlashAddr = _ulFlashAddr + 32; /* 递增,操作下一个256bit */ + } + else + { + goto err; + } + } + + /* 长度不是32字节整数倍 */ + if (_ulSize % 32) + { + uint64_t FlashWord[4]; + + FlashWord[0] = 0; + FlashWord[1] = 0; + FlashWord[2] = 0; + FlashWord[3] = 0; + memcpy((char *)FlashWord, _ucpSrc, _ulSize % 32); + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, _ulFlashAddr, (uint64_t)((uint32_t)FlashWord)) == HAL_OK) + { + ; // _ulFlashAddr = _ulFlashAddr + 32; + } + else + { + goto err; + } + } + + /* Flash 加锁,禁止写Flash控制寄存器 */ + HAL_FLASH_Lock(); + + __set_PRIMASK(0); /* 开中断 */ + + return 0; + +err: + /* Flash 加锁,禁止写Flash控制寄存器 */ + HAL_FLASH_Lock(); + + __set_PRIMASK(0); /* 开中断 */ + + return 1; +} +/* +********************************************************************************************************* +* 函 数 名: JumpToApp +* 功能说明: 跳转到应用JumpToApp +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void JumpToApp(void) +{ + uint32_t i=0; + void (*AppJump)(void); /* 声明一个函数指针 */ + + /* 关闭全局中断 */ + DISABLE_INT(); + + /* 设置所有时钟到默认状态,使用HSI时钟 */ + + __HAL_RCC_GPIOH_CLK_DISABLE(); + __HAL_RCC_GPIOB_CLK_DISABLE(); + HAL_RCC_DeInit(); + + /* 关闭滴答定时器,复位到默认值 */ + SysTick->CTRL = 0; + SysTick->LOAD = 0; + SysTick->VAL = 0; + + /* 关闭所有中断,清除所有中断挂起标志 */ + for (i = 0; i < 8; i++) + { + NVIC->ICER[i]=0xFFFFFFFF; + NVIC->ICPR[i]=0xFFFFFFFF; + } + + /* 使能全局中断 */ + ENABLE_INT(); + + /* 跳转到应用程序,首地址是MSP,地址+4是复位中断服务程序地址 */ + AppJump = (void (*)(void)) (*((uint32_t *) (App_Run_Addr + 4))); + + /* 设置主堆栈指针 */ + __set_MSP(*(uint32_t *)App_Run_Addr); + + /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */ + __set_CONTROL(0); + + /* 跳转到系统BootLoader */ + AppJump(); + + /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */ + while (1) + { + + } +} + +/* +********************************************************************************************************* +* 函 数 名: JumpToApp +* 功能说明: 跳转到应用JumpToApp +* 形 参: 无 +* 返 回 值: 无 +********************************************************************************************************* +*/ +void Copy_Download_Flash_to_Start() +{ + + uint32_t startIndex=0; + + for(startIndex = 0; startIndex < 3; startIndex++) + { + bsp_EraseCpuFlash((uint32_t)(App_Run_Addr + startIndex*128*1024));//Erase this function + } + + + uint8_t readData[32]; + uint32_t total=3*128*1024/sizeof(readData); + uint8_t retult=0; + for(startIndex=0;startIndex= 1) + { + + i_stream = pb_istream_from_buffer(buffer, length); + + pb_decode(&i_stream, Cmd_fields, &decoded_Cmd); + + memcpy(&decoded_Cmd.Buff_Data, + &buffer[length - decoded_Cmd.Buff_Data_Length], + decoded_Cmd.Buff_Data_Length); + + switch (decoded_Cmd.CommadNum) + { + + case 17: // 上位机获取控制权 + { + + switch (decoded_Cmd.Parameter0) + { + case 0: + { + + //read CV + CV = GF_BSP_EEPROM_Get_CV(); //重新配置CV + is_upper_computer_take_over_control = 0; + + WrapInCmdAndSendMessage(send_Cmd, 10, success, + "return contorl to Remote Controller success", + sendWay, send_Handler); + fsm_state_set(¤t_robot_move_state, + &robot_halt_state); + //设置电机供电为 On + //fsm_state_set(¤t_motor_power_state, &motor_power_off_state); + break; + } + case 1: + { + + is_upper_computer_take_over_control = 1; + WrapInCmdAndSendMessage(send_Cmd, 17, success, + "Take control success", sendWay, send_Handler); + fsm_state_set(¤t_motor_power_state, + &motor_power_on_state); + fsm_state_set(¤t_robot_move_state, + &robot_halt_state); + GV.Robot_Move_Speed = speed_M_min_toE01_M_min( 5 ); + CV.LeftTurnSpeed = speed_M_min_toE01_M_min( 3 ); + CV.RightTurnSpeed = speed_M_min_toE01_M_min( 3 ); + break; + } + + default: + break; + + } + + break; + } + case 16: // 上位机手动控制机器人运动 + { + + switch (decoded_Cmd.Parameter0) + { + case 0: + { + + WrapInCmdAndSendMessage(send_Cmd, 16, success, + "manual control halt success", sendWay, + send_Handler); + fsm_state_set(¤t_robot_move_state, + &robot_halt_state); + break; + } + case 1: + { + WrapInCmdAndSendMessage(send_Cmd, 16, success, + "manual control forward success", sendWay, + send_Handler); + fsm_state_set(¤t_robot_move_state, + &robot_forwards_state); + break; + } + case 2: + { + WrapInCmdAndSendMessage(send_Cmd, 16, success, + "manual control backward success", sendWay, + send_Handler); + fsm_state_set(¤t_robot_move_state, + &robot_backwards_state); + break; + } + case 3: + { + WrapInCmdAndSendMessage(send_Cmd, 16, success, + "manual control turn left success", sendWay, + send_Handler); + fsm_state_set(¤t_robot_move_state, + &robot_turn_left_state); + break; + } + case 4: + { + WrapInCmdAndSendMessage(send_Cmd, 16, success, + "manual control turn right success", sendWay, + send_Handler); + fsm_state_set(¤t_robot_move_state, + &robot_turn_right_state); + break; + } + default: + break; + + } + + break; + } + + case 15: // 返回错误信息 + { + + pb_ostream_t Error_o_stream = + { 0 }; + char buf[1024]; + Error_o_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + pb_encode(&Error_o_stream, ErrorData_fields, + &GV.SystemErrorData); + + //将数据拷贝到Command中 + send_Cmd.CommadNum = 16; + send_Cmd.Buff_Data_Length = Error_o_stream.bytes_written; + + WrapInCmdAndSend(send_Cmd, buf, sendWay, send_Handler); + + break; + } + + case 14: //这里是初始化Flash 好重新写入 + { + NeedToFeedBackToComputer = 1; + + WrapInCmdAndSendMessage(send_Cmd, 14, success, + "disable periodical call of serialports and can", + sendWay, send_Handler); + + Error_Detect_Enable = 0; //disable ErrorDetect Function; + + DLT_LOG_ENABLE_LEVEL = 0; //7 send all information //0 send nothing + + //将所有串口的周期性调用暂停 + RS_485_1_UART_Handler.dispacherController->Dispacher_Enable = 0; + RS_485_2_UART_Handler.dispacherController->Dispacher_Enable = 0; + RS_485_3_UART_Handler.dispacherController->Dispacher_Enable = 0; + RS_485_4_UART_Handler.dispacherController->Dispacher_Enable = 0; + E28_SBUS_UART_Handler.dispacherController->Dispacher_Enable = 0; + LPUART1_UART_Handler.dispacherController->Dispacher_Enable = 0; + InterCall_DEBUG_UART_Handler.dispacherController->Dispacher_Enable = + 0; + LTE_7S0_Serial_UART_Handler.dispacherController->Dispacher_Enable = + 0; + RS_485_4_UART_Handler.dispacherController->Dispacher_Enable = 0; + is_udp_GV_update_loop_enalbed = 0; + + //将CAN总线的周期性调用停掉 + //因为电机有可能处于运动状态,所有CAN线不能停,得发送下去 + //FD_CAN_1_Handler.dispacherController->Dispacher_Enable = 0; + //FD_CAN_2_Handler.dispacherController->Dispacher_Enable = 0; + fsm_state_set(¤t_robot_move_state, &robot_halt_state); + + break; + } + case 13: // 使能 GV 周期性性发送数据 + { + if (decoded_Cmd.Parameter0 == 0) //关闭上传 + { + NeedToFeedBackToComputer = 1; + LTE_7S0_Serial_UART_Handler.dispacherController->Dispacher_Enable = + 0; + WrapInCmdAndSendMessage(send_Cmd, 14, success, + "disable send GV", sendWay, send_Handler); + + is_udp_GV_update_loop_enalbed = 0; + } + + if (decoded_Cmd.Parameter0 == 1) //打开上传 + { + NeedToFeedBackToComputer = 0; + LTE_7S0_Serial_UART_Handler.dispacherController->Dispacher_Enable = + 1; + WrapInCmdAndSendMessage(send_Cmd, 14, success, + "enable send GV", sendWay, send_Handler); + + is_udp_GV_update_loop_enalbed = 1; + } + + break; + } + case 12: //重启系统,进入bootloader + { + + WrapInCmdAndSendMessage(send_Cmd, 12, success, "STM32 reboot", + sendWay, send_Handler); + NVIC_SystemReset(); + + break; + } + case 11: //配置无线网络模块,此处为透传指令 + { + Send_WH_LTE_7S0_Data(decoded_Cmd.Buff_Data, + decoded_Cmd.Parameter0); + break; + } + case 10: //擦除flash + { + WrapInCmdAndSendMessage(send_Cmd, 10, success, + "start erasing flash ", sendWay, send_Handler); + QSPI_W25Qx_EraseDownLoadFlash(); + downloadCount = 0; + WrapInCmdAndSendMessage(send_Cmd, 10, success, + "erase flash success", sendWay, send_Handler); + break; + } + case 9: //上位机下发保存软件代码指令 + { + memcpy(ReceivedData, + &buffer[length - decoded_Cmd.Buff_Data_Length], + decoded_Cmd.Buff_Data_Length); + + calbriation = MB_CRC16(&ReceivedData, + decoded_Cmd.Buff_Data_Length); + + if (calbriation == decoded_Cmd.Parameter4) //Parameter4是校验 + { + + if (downloadCount == decoded_Cmd.Parameter3) + { + QSPI_W25Qx_Write_Buffer(&decoded_Cmd.Buff_Data, + CODE_DOWNLOAD_FLASH_BEGIN_ADDRESS + + decoded_Cmd.Parameter3, + decoded_Cmd.Buff_Data_Length); + downloadCount += decoded_Cmd.Buff_Data_Length; + send_Cmd.Parameter3 = length; + WrapInCmdAndSendMessage(send_Cmd, 9, success, + "download success", sendWay, send_Handler); + + } + else + { + decoded_Cmd.Parameter2 = downloadCount; //返回download count; + send_Cmd.Parameter3 = length; + WrapInCmdAndSendMessage(send_Cmd, 9, fail, + "downloadCount!=Parameter3", sendWay, + send_Handler); + } + + if (decoded_Cmd.Parameter1 == 1) + { + WrapInCmdAndSendMessage(send_Cmd, 9, success, + "download new software sucess", sendWay, + send_Handler); + IAP_struct_define iap = GF_BSP_EEPROM_Get_IAP();//Get the version of the code + iap.UpgradeSucceeded = 1; + iap.Total_Bytes = decoded_Cmd.Parameter2; + StartDownLoadFlag = 0; + downloadCount = 0; + GF_BSP_EEPROM_Set_IAP(iap); + + } + } + else + { + + decoded_Cmd.Parameter2 = downloadCount; //返回download count; + send_Cmd.Parameter3 = length; + WrapInCmdAndSendMessage(send_Cmd, 9, fail, + "MB CRC failed and the length ", sendWay, + send_Handler); + + } + + break; + } + +// 定义 7 上位机获取拟合点 +// 定义 8 上位机获取位置点 */ + case 8: + { +// send_data_to_upper_computer(*Desulfurizer_Angle, +// *Desulfurizer_Wire_Length, *Desulfurizer_Thickness, 0, +// 0, desulfurizer_message_UART_Handler); + break; + } + case 7: + { +// send_data_to_upper_computer(*Desulfurizer_Angle, +// *Desulfurizer_Wire_Length, *Desulfurizer_Thickness, 1, +// 0, desulfurizer_message_UART_Handler); + break; + } + //定义 6 上位机设定编码器角度值为0 + case 6: + { + //reset_current_value_0(); + break; + } + //定义 4 上位机设定Trace等级值,无返回 + case 4: + { + + break; + } + //定义 3 上位机设定CV值 + case 3: + { + CV_struct_define decoded_CV = CV_struct_define_init_default; + pb_istream_t i_cv_stream = + { 0 }; + + i_cv_stream = pb_istream_from_buffer(decoded_Cmd.Buff_Data, + decoded_Cmd.Buff_Data_Length); + pb_decode(&i_cv_stream, CV_struct_define_fields, &decoded_CV); + //将CV写入EEPROM + GF_BSP_EEPROM_Set_CV(decoded_CV); + CV = decoded_CV; + send_Cmd.Parameter3 = length; + WrapInCmdAndSendMessage(send_Cmd, 3, success, + "Set CV succeeded", sendWay, send_Handler); + CV_GV_Init(); + break; + } + //定义 1 上位机获取默认CV值, 下位机返回CV的值, + //定义 2 下位机返回CV值 + case 1: + { + CV = GF_BSP_EEPROM_Get_CV(); + pb_ostream_t CV_o_stream = + { 0 }; + char buf[1024]; + CV_o_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + pb_encode(&CV_o_stream, CV_struct_define_fields, &CV); + + //将数据拷贝到Command中 + send_Cmd.CommadNum = 2; + send_Cmd.Buff_Data_Length = CV_o_stream.bytes_written; + + WrapInCmdAndSend(send_Cmd, buf, sendWay, send_Handler); + + break; + } + default: + WrapInCmdAndSendMessage(send_Cmd, -1, fail, + "Not the right command", sendWay, send_Handler); + break; + + } + + } + else + { + + } + +} +void WrapInCmdAndSend(ReCmd send_Cmd, uint8_t *buf, int8_t sendWay, + struct UARTHandler *send_Handler) +{ + + memcpy(send_Cmd.Buff_Data, buf, send_Cmd.Buff_Data_Length); + pb_ostream_t ReCmd_out_stream = + { 0 }; + + if (sendWay == 1) //MQTT + { + ReCmd_out_stream = pb_ostream_from_buffer(&send_Handler->Tx_Buf[4], + sizeof(send_Handler->Tx_Buf) - 4); + pb_encode(&ReCmd_out_stream, ReCmd_fields, &send_Cmd); //encode to buffer + + send_Handler->Tx_Buf[0] = '3'; + send_Handler->Tx_Buf[1] = ','; + send_Handler->Tx_Buf[2] = 0xfe; + send_Handler->Tx_Buf[3] = 0xfe; + send_Handler->TxCount = ReCmd_out_stream.bytes_written + 4; + send_Handler->UART_Tx(send_Handler); + } + else if (sendWay == 2) //UDP 发送 + { + uint8_t Tx_Buf[2048]; + ReCmd_out_stream = pb_ostream_from_buffer(&Tx_Buf[2], + sizeof(Tx_Buf) - 2); + pb_encode(&ReCmd_out_stream, ReCmd_fields, &send_Cmd); //encode to buffer + Tx_Buf[0] = 0xfe; + Tx_Buf[1] = 0xfe; + udp_cmd_send_back(Tx_Buf, ReCmd_out_stream.bytes_written + 2); + + } + else //485发送 + { + ReCmd_out_stream = pb_ostream_from_buffer(&send_Handler->Tx_Buf[2], + sizeof(send_Handler->Tx_Buf) - 2); + pb_encode(&ReCmd_out_stream, ReCmd_fields, &send_Cmd); //encode to buffer + send_Handler->Tx_Buf[0] = 0xfe; + send_Handler->Tx_Buf[1] = 0xfe; + //send_Handler->AddSendList(send_Handler,send_Handler->Tx_Buf,send_Handler->TxCount,NULL); + send_Handler->TxCount = ReCmd_out_stream.bytes_written + 2; + //send_Handler->TxCount = 200; + send_Handler->UART_Tx(send_Handler); + } + +} + +//send_Cmd.CommadNum=0xff;//代表返回信息 +//send_Cmd.Parameter0 代表执行的指令,发过来的命令号; +//send_Cmd.Parameter1 1 代表成功,0 代表失败; +//send_Cmd.databuf 存的是相关信息,可以通过ACII转成string; + +void WrapInCmdAndSendMessage(ReCmd send_Cmd, int8_t functionNum, + int8_t isSuccess, uint8_t *buf, int8_t sendWay, + struct UARTHandler *send_Handler) +{ + + send_Cmd.CommadNum = 0xff; //代表返回信息 + send_Cmd.Parameter0 = functionNum; //代表返回信息 + send_Cmd.Parameter1 = isSuccess; //1 代表成功,0 代表失败; + send_Cmd.Buff_Data_Length = strlen(buf); + WrapInCmdAndSend(send_Cmd, buf, sendWay, send_Handler); +} + +void send_received_data_to_upper_computer(uint8_t *buffer, uint16_t length) +{ + send_Cmd.CommadNum = 12; //定义12为设定Mqtt透传向上返回的数据 + send_Cmd.Buff_Data_Length = length; + + WrapInCmdAndSend(send_Cmd, buffer, 0, desulfurizer_message_UART_Handler); + +} diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_qspi_w25q128.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_qspi_w25q128.c new file mode 100644 index 0000000..35131e5 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_qspi_w25q128.c @@ -0,0 +1,488 @@ +/* + * bsp_quadspi_W25Q128.c + * + * Created on: Apr 25, 2021 + * Author: Administrator + * + * + * + * + * + */ +#include +#include "quadspi.h" + +/* 仅限本文件使用的函数 */ +static void QSPI_W25Qx_Write_Enable(QSPI_HandleTypeDef *hqspi); +static uint8_t QSPI_W25Qx_AutoPollingMemRead(uint32_t Timeout); +static void QSPI_W25Qx_Enter(QSPI_HandleTypeDef *hqspi); +static void QSPI_W25Qx_Exit(QSPI_HandleTypeDef *hqspi); + +/** + * 函数功能: 读取Flash状态并等待操作结束 + * 输入参数: Timeout:等待时间 + * + * 返回值: Flash的状态 + * 说明: + * + * + */ + + + +static uint8_t QSPI_W25Qx_AutoPollingMemRead(uint32_t Timeout) +{ + QSPI_CommandTypeDef s_command={0}; + QSPI_AutoPollingTypeDef s_config={0}; + + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; //1线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /* 配置自动轮询模式 */ + s_command.Instruction = READ_STATUS_REG1_CMD; //读取状态寄存器 + s_command.AddressMode = QSPI_ADDRESS_NONE; //没有地址 + s_command.DataMode = QSPI_DATA_1_LINE; //1线数据 + s_command.DummyCycles = 0; //无空周期 + + /* 配置自动轮询寄存器(不断查询状态寄存器bit0,等待其为0) */ + s_config.Match = 0x00; //等待其为0 + s_config.Mask = W25Q128FV_FSR_BUSY; //状态寄存器bit0 + s_config.MatchMode = QSPI_MATCH_MODE_AND; //逻辑与 + s_config.StatusBytesSize = 1; + s_config.Interval = 0x10; + s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; + + /* 自动轮询模式等待编程结束 */ + if(HAL_QSPI_AutoPolling(&hqspi,&s_command,&s_config,Timeout) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + return FLASH_OK; + +} + +/** + * 函数功能: 读取外部FLASH的ID + * 输入参数: 无 + * + * 返回值: uint32_t + * 说明: + * 1、使用SPI模式的指令 + * + */ +uint32_t QSPI_W25Qx_ReadID(void) +{ + uint32_t uiID; + + QSPI_CommandTypeDef s_command = {0}; + uint8_t buf[3]; + + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; //1线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /* 读取JEDEC ID */ + s_command.Instruction = READ_JEDEC_ID_CMD; //读取ID命令: 0x9F + s_command.AddressMode = QSPI_ADDRESS_NONE; //没有地址 + s_command.DataMode = QSPI_DATA_1_LINE; //1线数据 + s_command.DummyCycles = 0; //无空周期 + s_command.NbData = 3; //读取三个数据 + + /* 发送指令 */ + if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 启动接收 */ + if(HAL_QSPI_Receive(&hqspi,buf,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + uiID = (buf[0] << 16) | (buf[1] << 8) | buf[2]; + + return uiID; +} + +/** + * 函数功能: 外部FLASH写使能 + * 输入参数: hqspi QSPI_HandleTypeDef句柄 + * + * 返回值: 无 + * 说明: + * 1、使用SPI模式的指令 + * + */ +static void QSPI_W25Qx_Write_Enable(QSPI_HandleTypeDef *hqspi) +{ + QSPI_CommandTypeDef s_command = {0}; + QSPI_AutoPollingTypeDef s_config={0}; + + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; //1线方式发送指令 + //s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /* 写入使能配置 */ + s_command.Instruction = WRITE_ENABLE_CMD; //写使能命令 + s_command.AddressMode = QSPI_ADDRESS_NONE; //没有地址 + s_command.DataMode = QSPI_DATA_NONE; //没有数据 + s_command.DummyCycles = 0; //无空周期 + s_command.NbData = 0; //空数据 + + /* 发送指令 */ + if(HAL_QSPI_Command(hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 配置自动轮询模式等待操作完成 */ + s_config.Match = W25Q128FV_FSR_WREN; + s_config.Mask = W25Q128FV_FSR_WREN; + s_config.MatchMode = QSPI_MATCH_MODE_AND; + s_config.StatusBytesSize = 1; + s_config.Interval = 0x10; + s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE; + + s_command.Instruction = READ_STATUS_REG1_CMD; + s_command.DataMode = QSPI_DATA_1_LINE; + s_command.NbData = 1; + + if(HAL_QSPI_AutoPolling(hqspi,&s_command,&s_config,HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + +} + +/** + * 函数功能: 擦除外部FLASH的扇区(大小:4KB) + * 输入参数: _uiSectorAddr: 扇区地址,以4KB为单位的地址,比如0,4096,8192等 + * + * 返回值: 无 + * 说明: + * 1、 + * + */ +void QSPI_W25Qx_EraseSector(uint32_t _SectorAddr) +{ + QSPI_CommandTypeDef s_command = {0}; + + /* 写使能 */ + QSPI_W25Qx_Write_Enable(&hqspi); + + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; //1线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /* 擦除扇区配置 */ + s_command.Instruction = SECTOR_ERASE_CMD; //扇区擦除指令 + s_command.AddressMode = QSPI_ADDRESS_1_LINE; //1线地址方式 + s_command.DataMode = QSPI_DATA_NONE; //没有数据 + s_command.Address = _SectorAddr; //扇区的首地址,保证是4KB整数倍 + s_command.DummyCycles = 0; //无空周期 + + /* 发送指令 */ + if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 自动轮询模式等待编程结束 */ + if(QSPI_W25Qx_AutoPollingMemRead(W25Q128FV_SUBSECTOR_ERASE_MAX_TIME) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + +} + +/** + * 函数功能: 页编程,通过QSPI将数据写入外部FALSH + * 输入参数: _pBuf: 需要存入数据的指针 + * _write_Addr: 目标区域首地址,即页首地址,比如0,256,512等。 + * _write_Size: 数据个数,不能超过页的大小,可以填入(1 ~ 256) + * 返回值: 无 + * 说明: + * 1、华邦的W25Q128FV仅仅支持SPI模式写入 + */ +uint8_t QSPI_W25Qx_Write_Buffer(uint8_t *_pBuf,uint32_t _write_Addr,uint16_t _write_Size) +{ + QSPI_CommandTypeDef s_command = {0}; + + /* 防止写入的大小超过256字节 */ + if(_write_Size > W25Q128FV_PAGE_SIZE) + { + /* 进入断言,提示错误 */ + user_Assert(__FILE__,__LINE__); + } + + QSPI_W25Qx_Write_Enable(&hqspi); //写使能 + + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; //1线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /*写入序列配置 */ + s_command.Instruction = QUAD_INPUT_PAGE_PROG_CMD; //24位四线快速写入指令 + s_command.AddressMode = QSPI_ADDRESS_1_LINE; //1线地址方式 + s_command.DataMode = QSPI_DATA_4_LINES; //4线数据方式 + s_command.Address = _write_Addr; //写入数据的地址 + s_command.NbData = _write_Size; //写入数据的大小 + s_command.DummyCycles = 0; //无空周期 + + /* 发送指令 */ + if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 启动传输 */ + if(HAL_QSPI_Transmit(&hqspi,_pBuf,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 自动轮询模式等待编程结束 */ + if(QSPI_W25Qx_AutoPollingMemRead(W25Q128FV_SUBSECTOR_ERASE_MAX_TIME) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + return 1; +} + +/** + * 函数功能: 外部FLASH芯片进入QSPI模式 + * 输入参数: *hqspi: qspi句柄 + * + * 返回值: 无 + * 说明: + * + */ +static void QSPI_W25Qx_Enter(QSPI_HandleTypeDef *hqspi) +{ + QSPI_CommandTypeDef s_command = {0}; + /* 配置FLASH进入QPSI模式 */ + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; //1线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /* 写入序列配置 */ + s_command.Instruction = ENTER_QPI_MODE_CMD; //进入QSPI模式 + s_command.AddressMode = QSPI_ADDRESS_NONE; //无地址方式 + s_command.DataMode = QSPI_DATA_NONE; //无数据方式 + s_command.DummyCycles = 0; //0空闲状态周期 + + /* 发送指令 */ + if(HAL_QSPI_Command(hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + +} + +/** + * 函数功能: 外部FLASH芯片退出QSPI模式 + * 输入参数: *hqspi: qspi句柄 + * + * 返回值: 无 + * 说明: + * + */ +static void QSPI_W25Qx_Exit(QSPI_HandleTypeDef *hqspi) +{ + QSPI_CommandTypeDef s_command = {0}; + + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES; //4线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /* 写入序列配置 */ + s_command.Instruction = EXIT_QPI_MODE_CMD; //进入QSPI模式 + s_command.AddressMode = QSPI_ADDRESS_NONE; //无地址方式 + s_command.DataMode = QSPI_DATA_NONE; //无数据方式 + s_command.DummyCycles = 0; //0空闲状态周期 + + /* 发送指令 */ + if(HAL_QSPI_Command(hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } +} + +/** + * 函数功能: 连续读取若干字节,字节的个数不能超出芯片容量 + * 输入参数: _pBuf: 读取数据的存放地址 + * _read_Addr: 起始的地址 + * _read_Size: 数据个数,可以大于W25Q128FV_PAGE_SIZE,但不能超出芯片总容量 + * 返回值: 无 + * 说明: + * 1、从SPI模式切换到QSPI模式,读取完毕后切换回SPI模式(其他函数仅仅支持SPI模式)。 + */ +void QSPI_W25Qx_Read_Buffer(uint8_t *_pBuf,uint32_t _read_Addr,uint32_t _read_Size) +{ + QSPI_CommandTypeDef s_command = {0}; + + /* 进入QSPI模式 */ + QSPI_W25Qx_Enter(&hqspi); + + /* 开始从FLASH读取数据 */ + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_4_LINES; //1线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /*读取序列配置 */ + s_command.Instruction = QUAD_INOUT_FAST_READ_CMD; //24位四线快速写入指令 + s_command.AddressMode = QSPI_ADDRESS_4_LINES; //4线地址方式 + s_command.DataMode = QSPI_DATA_4_LINES; //4线数据方式 + s_command.Address = _read_Addr; //写入数据的地址 + s_command.NbData = _read_Size; //写入数据的大小 + s_command.DummyCycles = 2; //两个空闲状态周期(4个时钟周期),结合时序理解 + + /* 发送指令 */ + if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 读取数据 */ + if(HAL_QSPI_Receive(&hqspi,_pBuf,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 退出QSPI模式 */ + QSPI_W25Qx_Exit(&hqspi); + +} + +/** + * 函数功能: 复位外部Flash + * 输入参数: 无 + * + * 返回值: void + * 说明: + * + */ +void QSPI_W25Qx_Reset_Memory() +{ + QSPI_CommandTypeDef s_command = {0}; + + /* 基本配置 */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; //1线方式发送指令 + s_command.AddressSize = QSPI_ADDRESS_24_BITS; //24位地址 + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; //无交替字节 + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; //W25Q128FV不支持DDR模式 + s_command.DdrHoldHalfCycle = QSPI_DDR_HHC_ANALOG_DELAY; //DDR模式,数据输出延迟 + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; //每次传输都发指令 + + /* 复位使能W25x */ + s_command.Instruction = RESET_ENABLE_CMD; //复位使能命令 + s_command.AddressMode = QSPI_ADDRESS_NONE; //没有地址 + s_command.DataMode = QSPI_DATA_NONE; //没有数据 + s_command.DummyCycles = 0; //无空周期 + + /* 发送复位使能命令 */ + if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 发送复位命令 */ + s_command.Instruction = RESET_MEMORY_CMD; //复位命令 + /* 发送复位使能命令 */ + if(HAL_QSPI_Command(&hqspi,&s_command,HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + + /* 自动轮询模式等待等待完成 */ + if(QSPI_W25Qx_AutoPollingMemRead(HAL_QPSI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + user_Assert(__FILE__,__LINE__); + } + +} + + + +/** + * 函数功能: 检查代码异常,打印出异常的位置(文件名与行号) + * 输入参数: file: 源代码文件名称。关键字__FILE__表示源代码文件名。 + * line: 代码行号,关键字__LINE__表示源代码行号 + * 返回值: void + + * 说明: + * 1、在需要断言的地方直接调用user_Assert(__FILE__,__LINE__); + */ +void user_Assert(char *file,uint32_t line) +{ + printf("Wrong parameters value: file %s on line %d\r\n",file, (unsigned int)line); + + /* 这是一个死循环,断言失败时程序会卡此处死机,以便于用户差错 */ + if(line == 0) + { + return; + } + while(1) + { + + } +} + + +/** + * 函数功能: 读取Flash状态并等待操作结束 + * 输入参数: Timeout:等待时间 + * + * 返回值: Flash的状态 + * 说明: + * + * + */ + +void QSPI_W25Qx_EraseDownLoadFlash() +{ + int i =0; + int count=CODE_FLASH_STORAGE_SIZE/4/1024; + for(i=0;i<=count;i++) + { + QSPI_W25Qx_EraseSector(i*4*1024); + // HAL_Delay(10); + } + i=10; +} diff --git a/project_old/paint_robot_old/BASE/Src/BSP/bsp_tempature.c b/project_old/paint_robot_old/BASE/Src/BSP/bsp_tempature.c new file mode 100644 index 0000000..74a68f7 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/bsp_tempature.c @@ -0,0 +1,81 @@ +/* + * bsp_adc.c + * + * Created on: Feb 21, 2025 + * Author: akeguo + */ + +#include +#include "adc.h" +#include "BSP/bsp_include.h" +#include "stm32h7xx_hal_adc.h" + +#include + +// 硬件相关参数配置 +#define ADC_MAX_VALUE 0xffff // 16位ADC最大值,若为10位ADC改为1023 +#define VREF 3.3f // ADC参考电压 + +// 热敏电阻参数 (需根据实际型号确认) +#define R_REF 10000.0f // 分压电阻阻值(与热敏电阻串联) +#define B_VALUE 3380.0f // B常数 (需确认具体型号参数) +#define R0 10000.0f // 25°C时的标称阻值 +#define T0 298.15f // 25°C对应的开尔文温度(25 + 273.15) +int32_t adc_value; + +void GF_ADC_Collect(); + +int32_t * tempature; + +void ADC_Intialize() +{ + + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM1_100ms_PeriodElapsedCallback, GF_ADC_Collect); +} + +void GF_ADC_Collect() +{ + *tempature = read_temperature(); +} +int32_t read_temperature() +{ + + HAL_ADC_Start(&hadc2); //开启ADC1 + + if (HAL_ADC_PollForConversion(&hadc2, 100) == HAL_OK) + { + //16 bit resolution + adc_value = HAL_ADC_GetValue(&hadc2); + + HAL_ADC_Stop(&hadc2); + // 1. 计算热敏电阻两端电压 + float voltage = (adc_value / (float) ADC_MAX_VALUE) * VREF; + + // 2. 计算热敏电阻阻值(分压电路公式) + float ntc_resistance = (voltage * R_REF) / (VREF - voltage); + //float ntc_resistance = (voltage * R_REF) / (VREF); + // 3. 使用Steinhart-Hart方程计算温度 + float steinhart; + steinhart = ntc_resistance / R0; // (R/R0) + steinhart = log(steinhart); // ln(R/R0) + steinhart /= B_VALUE; // 1/B * ln(R/R0) + steinhart += 1.0 / T0; // + (1/T0) + steinhart = 1.0 / steinhart; // 取倒数得到开尔文温度 + + + // 4. 转换为摄氏度并返回 + return (int32_t)((steinhart - 273.15)*100); + } + else + { + adc_value = 0; + HAL_ADC_Stop(&hadc2); + return 0; + } + +} + +int32_t temperature; + + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/pb_common.c b/project_old/paint_robot_old/BASE/Src/BSP/pb_common.c new file mode 100644 index 0000000..6aee76b --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/pb_common.c @@ -0,0 +1,388 @@ +/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c. + * + * 2014 Petteri Aimonen + */ + +#include "pb_common.h" + +static bool load_descriptor_values(pb_field_iter_t *iter) +{ + uint32_t word0; + uint32_t data_offset; + int_least8_t size_offset; + + if (iter->index >= iter->descriptor->field_count) + return false; + + word0 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + iter->type = (pb_type_t)((word0 >> 8) & 0xFF); + + switch(word0 & 3) + { + case 0: { + /* 1-word format */ + iter->array_size = 1; + iter->tag = (pb_size_t)((word0 >> 2) & 0x3F); + size_offset = (int_least8_t)((word0 >> 24) & 0x0F); + data_offset = (word0 >> 16) & 0xFF; + iter->data_size = (pb_size_t)((word0 >> 28) & 0x0F); + break; + } + + case 1: { + /* 2-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + + iter->array_size = (pb_size_t)((word0 >> 16) & 0x0FFF); + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 28) << 6)); + size_offset = (int_least8_t)((word0 >> 28) & 0x0F); + data_offset = word1 & 0xFFFF; + iter->data_size = (pb_size_t)((word1 >> 16) & 0x0FFF); + break; + } + + case 2: { + /* 4-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); + + iter->array_size = (pb_size_t)(word0 >> 16); + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); + size_offset = (int_least8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + break; + } + + default: { + /* 8-word format */ + uint32_t word1 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 1]); + uint32_t word2 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 2]); + uint32_t word3 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 3]); + uint32_t word4 = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index + 4]); + + iter->array_size = (pb_size_t)word4; + iter->tag = (pb_size_t)(((word0 >> 2) & 0x3F) | ((word1 >> 8) << 6)); + size_offset = (int_least8_t)(word1 & 0xFF); + data_offset = word2; + iter->data_size = (pb_size_t)word3; + break; + } + } + + if (!iter->message) + { + /* Avoid doing arithmetic on null pointers, it is undefined */ + iter->pField = NULL; + iter->pSize = NULL; + } + else + { + iter->pField = (char*)iter->message + data_offset; + + if (size_offset) + { + iter->pSize = (char*)iter->pField - size_offset; + } + else if (PB_HTYPE(iter->type) == PB_HTYPE_REPEATED && + (PB_ATYPE(iter->type) == PB_ATYPE_STATIC || + PB_ATYPE(iter->type) == PB_ATYPE_POINTER)) + { + /* Fixed count array */ + iter->pSize = &iter->array_size; + } + else + { + iter->pSize = NULL; + } + + if (PB_ATYPE(iter->type) == PB_ATYPE_POINTER && iter->pField != NULL) + { + iter->pData = *(void**)iter->pField; + } + else + { + iter->pData = iter->pField; + } + } + + if (PB_LTYPE_IS_SUBMSG(iter->type)) + { + iter->submsg_desc = iter->descriptor->submsg_info[iter->submessage_index]; + } + else + { + iter->submsg_desc = NULL; + } + + return true; +} + +static void advance_iterator(pb_field_iter_t *iter) +{ + iter->index++; + + if (iter->index >= iter->descriptor->field_count) + { + /* Restart */ + iter->index = 0; + iter->field_info_index = 0; + iter->submessage_index = 0; + iter->required_field_index = 0; + } + else + { + /* Increment indexes based on previous field type. + * All field info formats have the following fields: + * - lowest 2 bits tell the amount of words in the descriptor (2^n words) + * - bits 2..7 give the lowest bits of tag number. + * - bits 8..15 give the field type. + */ + uint32_t prev_descriptor = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + pb_type_t prev_type = (prev_descriptor >> 8) & 0xFF; + pb_size_t descriptor_len = (pb_size_t)(1 << (prev_descriptor & 3)); + + /* Add to fields. + * The cast to pb_size_t is needed to avoid -Wconversion warning. + * Because the data is is constants from generator, there is no danger of overflow. + */ + iter->field_info_index = (pb_size_t)(iter->field_info_index + descriptor_len); + iter->required_field_index = (pb_size_t)(iter->required_field_index + (PB_HTYPE(prev_type) == PB_HTYPE_REQUIRED)); + iter->submessage_index = (pb_size_t)(iter->submessage_index + PB_LTYPE_IS_SUBMSG(prev_type)); + } +} + +bool pb_field_iter_begin(pb_field_iter_t *iter, const pb_msgdesc_t *desc, void *message) +{ + memset(iter, 0, sizeof(*iter)); + + iter->descriptor = desc; + iter->message = message; + + return load_descriptor_values(iter); +} + +bool pb_field_iter_begin_extension(pb_field_iter_t *iter, pb_extension_t *extension) +{ + const pb_msgdesc_t *msg = (const pb_msgdesc_t*)extension->type->arg; + bool status; + + uint32_t word0 = PB_PROGMEM_READU32(msg->field_info[0]); + if (PB_ATYPE(word0 >> 8) == PB_ATYPE_POINTER) + { + /* For pointer extensions, the pointer is stored directly + * in the extension structure. This avoids having an extra + * indirection. */ + status = pb_field_iter_begin(iter, msg, &extension->dest); + } + else + { + status = pb_field_iter_begin(iter, msg, extension->dest); + } + + iter->pSize = &extension->found; + return status; +} + +bool pb_field_iter_next(pb_field_iter_t *iter) +{ + advance_iterator(iter); + (void)load_descriptor_values(iter); + return iter->index != 0; +} + +bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag) +{ + if (iter->tag == tag) + { + return true; /* Nothing to do, correct field already. */ + } + else if (tag > iter->descriptor->largest_tag) + { + return false; + } + else + { + pb_size_t start = iter->index; + uint32_t fieldinfo; + + if (tag < iter->tag) + { + /* Fields are in tag number order, so we know that tag is between + * 0 and our start position. Setting index to end forces + * advance_iterator() call below to restart from beginning. */ + iter->index = iter->descriptor->field_count; + } + + do + { + /* Advance iterator but don't load values yet */ + advance_iterator(iter); + + /* Do fast check for tag number match */ + fieldinfo = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + + if (((fieldinfo >> 2) & 0x3F) == (tag & 0x3F)) + { + /* Good candidate, check further */ + (void)load_descriptor_values(iter); + + if (iter->tag == tag && + PB_LTYPE(iter->type) != PB_LTYPE_EXTENSION) + { + /* Found it */ + return true; + } + } + } while (iter->index != start); + + /* Searched all the way back to start, and found nothing. */ + (void)load_descriptor_values(iter); + return false; + } +} + +bool pb_field_iter_find_extension(pb_field_iter_t *iter) +{ + if (PB_LTYPE(iter->type) == PB_LTYPE_EXTENSION) + { + return true; + } + else + { + pb_size_t start = iter->index; + uint32_t fieldinfo; + + do + { + /* Advance iterator but don't load values yet */ + advance_iterator(iter); + + /* Do fast check for field type */ + fieldinfo = PB_PROGMEM_READU32(iter->descriptor->field_info[iter->field_info_index]); + + if (PB_LTYPE((fieldinfo >> 8) & 0xFF) == PB_LTYPE_EXTENSION) + { + return load_descriptor_values(iter); + } + } while (iter->index != start); + + /* Searched all the way back to start, and found nothing. */ + (void)load_descriptor_values(iter); + return false; + } +} + +static void *pb_const_cast(const void *p) +{ + /* Note: this casts away const, in order to use the common field iterator + * logic for both encoding and decoding. The cast is done using union + * to avoid spurious compiler warnings. */ + union { + void *p1; + const void *p2; + } t; + t.p2 = p; + return t.p1; +} + +bool pb_field_iter_begin_const(pb_field_iter_t *iter, const pb_msgdesc_t *desc, const void *message) +{ + return pb_field_iter_begin(iter, desc, pb_const_cast(message)); +} + +bool pb_field_iter_begin_extension_const(pb_field_iter_t *iter, const pb_extension_t *extension) +{ + return pb_field_iter_begin_extension(iter, (pb_extension_t*)pb_const_cast(extension)); +} + +bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field) +{ + if (field->data_size == sizeof(pb_callback_t)) + { + pb_callback_t *pCallback = (pb_callback_t*)field->pData; + + if (pCallback != NULL) + { + if (istream != NULL && pCallback->funcs.decode != NULL) + { + return pCallback->funcs.decode(istream, field, &pCallback->arg); + } + + if (ostream != NULL && pCallback->funcs.encode != NULL) + { + return pCallback->funcs.encode(ostream, field, &pCallback->arg); + } + } + } + + return true; /* Success, but didn't do anything */ + +} + +#ifdef PB_VALIDATE_UTF8 + +/* This function checks whether a string is valid UTF-8 text. + * + * Algorithm is adapted from https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c + * Original copyright: Markus Kuhn 2005-03-30 + * Licensed under "Short code license", which allows use under MIT license or + * any compatible with it. + */ + +bool pb_validate_utf8(const char *str) +{ + const pb_byte_t *s = (const pb_byte_t*)str; + while (*s) + { + if (*s < 0x80) + { + /* 0xxxxxxx */ + s++; + } + else if ((s[0] & 0xe0) == 0xc0) + { + /* 110XXXXx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[0] & 0xfe) == 0xc0) /* overlong? */ + return false; + else + s += 2; + } + else if ((s[0] & 0xf0) == 0xe0) + { + /* 1110XXXX 10Xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ + (s[0] == 0xef && s[1] == 0xbf && + (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ + return false; + else + s += 3; + } + else if ((s[0] & 0xf8) == 0xf0) + { + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[3] & 0xc0) != 0x80 || + (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */ + (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */ + return false; + else + s += 4; + } + else + { + return false; + } + } + + return true; +} + +#endif + diff --git a/project_old/paint_robot_old/BASE/Src/BSP/pb_decode.c b/project_old/paint_robot_old/BASE/Src/BSP/pb_decode.c new file mode 100644 index 0000000..788998e --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/pb_decode.c @@ -0,0 +1,1727 @@ +/* pb_decode.c -- decode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +#include "pb.h" +#include "pb_decode.h" +#include "pb_common.h" + +/************************************** + * Declarations internal to this file * + **************************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count); +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof); +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size); +static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field); +static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type); +static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension); +static bool pb_field_set_to_default(pb_field_iter_t *field); +static bool pb_message_set_to_defaults(pb_field_iter_t *iter); +static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_skip_varint(pb_istream_t *stream); +static bool checkreturn pb_skip_string(pb_istream_t *stream); + +#ifdef PB_ENABLE_MALLOC +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size); +static void initialize_pointer_field(void *pItem, pb_field_iter_t *field); +static bool checkreturn pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field); +static void pb_release_single_field(pb_field_iter_t *field); +#endif + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +typedef struct { + uint32_t bitfield[(PB_MAX_REQUIRED_FIELDS + 31) / 32]; +} pb_fields_seen_t; + +/******************************* + * pb_istream_t implementation * + *******************************/ + +static bool checkreturn buf_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ + const pb_byte_t *source = (const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + count; + + if (buf != NULL) + { + memcpy(buf, source, count * sizeof(pb_byte_t)); + } + + return true; +} + +bool checkreturn pb_read(pb_istream_t *stream, pb_byte_t *buf, size_t count) +{ + if (count == 0) + return true; + +#ifndef PB_BUFFER_ONLY + if (buf == NULL && stream->callback != buf_read) + { + /* Skip input bytes */ + pb_byte_t tmp[16]; + while (count > 16) + { + if (!pb_read(stream, tmp, 16)) + return false; + + count -= 16; + } + + return pb_read(stream, tmp, count); + } +#endif + + if (stream->bytes_left < count) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!buf_read(stream, buf, count)) + return false; +#endif + + if (stream->bytes_left < count) + stream->bytes_left = 0; + else + stream->bytes_left -= count; + + return true; +} + +/* Read a single byte from input stream. buf may not be NULL. + * This is an optimization for the varint decoding. */ +static bool checkreturn pb_readbyte(pb_istream_t *stream, pb_byte_t *buf) +{ + if (stream->bytes_left == 0) + PB_RETURN_ERROR(stream, "end-of-stream"); + +#ifndef PB_BUFFER_ONLY + if (!stream->callback(stream, buf, 1)) + PB_RETURN_ERROR(stream, "io error"); +#else + *buf = *(const pb_byte_t*)stream->state; + stream->state = (pb_byte_t*)stream->state + 1; +#endif + + stream->bytes_left--; + + return true; +} + +pb_istream_t pb_istream_from_buffer(const pb_byte_t *buf, size_t msglen) +{ + pb_istream_t stream; + /* Cast away the const from buf without a compiler error. We are + * careful to use it only in a const manner in the callbacks. + */ + union { + void *state; + const void *c_state; + } state; +#ifdef PB_BUFFER_ONLY + stream.callback = NULL; +#else + stream.callback = &buf_read; +#endif + state.c_state = buf; + stream.state = state.state; + stream.bytes_left = msglen; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +/******************** + * Helper functions * + ********************/ + +static bool checkreturn pb_decode_varint32_eof(pb_istream_t *stream, uint32_t *dest, bool *eof) +{ + pb_byte_t byte; + uint32_t result; + + if (!pb_readbyte(stream, &byte)) + { + if (stream->bytes_left == 0) + { + if (eof) + { + *eof = true; + } + } + + return false; + } + + if ((byte & 0x80) == 0) + { + /* Quick case, 1 byte value */ + result = byte; + } + else + { + /* Multibyte case */ + uint_fast8_t bitpos = 7; + result = byte & 0x7F; + + do + { + if (!pb_readbyte(stream, &byte)) + return false; + + if (bitpos >= 32) + { + /* Note: The varint could have trailing 0x80 bytes, or 0xFF for negative. */ + pb_byte_t sign_extension = (bitpos < 63) ? 0xFF : 0x01; + bool valid_extension = ((byte & 0x7F) == 0x00 || + ((result >> 31) != 0 && byte == sign_extension)); + + if (bitpos >= 64 || !valid_extension) + { + PB_RETURN_ERROR(stream, "varint overflow"); + } + } + else if (bitpos == 28) + { + if ((byte & 0x70) != 0 && (byte & 0x78) != 0x78) + { + PB_RETURN_ERROR(stream, "varint overflow"); + } + result |= (uint32_t)(byte & 0x0F) << bitpos; + } + else + { + result |= (uint32_t)(byte & 0x7F) << bitpos; + } + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + } + + *dest = result; + return true; +} + +bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest) +{ + return pb_decode_varint32_eof(stream, dest, NULL); +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_decode_varint(pb_istream_t *stream, uint64_t *dest) +{ + pb_byte_t byte; + uint_fast8_t bitpos = 0; + uint64_t result = 0; + + do + { + if (!pb_readbyte(stream, &byte)) + return false; + + if (bitpos >= 63 && (byte & 0xFE) != 0) + PB_RETURN_ERROR(stream, "varint overflow"); + + result |= (uint64_t)(byte & 0x7F) << bitpos; + bitpos = (uint_fast8_t)(bitpos + 7); + } while (byte & 0x80); + + *dest = result; + return true; +} +#endif + +bool checkreturn pb_skip_varint(pb_istream_t *stream) +{ + pb_byte_t byte; + do + { + if (!pb_read(stream, &byte, 1)) + return false; + } while (byte & 0x80); + return true; +} + +bool checkreturn pb_skip_string(pb_istream_t *stream) +{ + uint32_t length; + if (!pb_decode_varint32(stream, &length)) + return false; + + if ((size_t)length != length) + { + PB_RETURN_ERROR(stream, "size too large"); + } + + return pb_read(stream, NULL, (size_t)length); +} + +bool checkreturn pb_decode_tag(pb_istream_t *stream, pb_wire_type_t *wire_type, uint32_t *tag, bool *eof) +{ + uint32_t temp; + *eof = false; + *wire_type = (pb_wire_type_t) 0; + *tag = 0; + + if (!pb_decode_varint32_eof(stream, &temp, eof)) + { + return false; + } + + *tag = temp >> 3; + *wire_type = (pb_wire_type_t)(temp & 7); + return true; +} + +bool checkreturn pb_skip_field(pb_istream_t *stream, pb_wire_type_t wire_type) +{ + switch (wire_type) + { + case PB_WT_VARINT: return pb_skip_varint(stream); + case PB_WT_64BIT: return pb_read(stream, NULL, 8); + case PB_WT_STRING: return pb_skip_string(stream); + case PB_WT_32BIT: return pb_read(stream, NULL, 4); + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Read a raw value to buffer, for the purpose of passing it to callback as + * a substream. Size is maximum size on call, and actual size on return. + */ +static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, pb_byte_t *buf, size_t *size) +{ + size_t max_size = *size; + switch (wire_type) + { + case PB_WT_VARINT: + *size = 0; + do + { + (*size)++; + if (*size > max_size) + PB_RETURN_ERROR(stream, "varint overflow"); + + if (!pb_read(stream, buf, 1)) + return false; + } while (*buf++ & 0x80); + return true; + + case PB_WT_64BIT: + *size = 8; + return pb_read(stream, buf, 8); + + case PB_WT_32BIT: + *size = 4; + return pb_read(stream, buf, 4); + + case PB_WT_STRING: + /* Calling read_raw_value with a PB_WT_STRING is an error. + * Explicitly handle this case and fallthrough to default to avoid + * compiler warnings. + */ + + default: PB_RETURN_ERROR(stream, "invalid wire_type"); + } +} + +/* Decode string length from stream and return a substream with limited length. + * Remember to close the substream using pb_close_string_substream(). + */ +bool checkreturn pb_make_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + uint32_t size; + if (!pb_decode_varint32(stream, &size)) + return false; + + *substream = *stream; + if (substream->bytes_left < size) + PB_RETURN_ERROR(stream, "parent stream too short"); + + substream->bytes_left = (size_t)size; + stream->bytes_left -= (size_t)size; + return true; +} + +bool checkreturn pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream) +{ + if (substream->bytes_left) { + if (!pb_read(substream, NULL, substream->bytes_left)) + return false; + } + + stream->state = substream->state; + +#ifndef PB_NO_ERRMSG + stream->errmsg = substream->errmsg; +#endif + return true; +} + +/************************* + * Decode a single field * + *************************/ + +static bool checkreturn decode_basic_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_BOOL: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_bool(stream, field); + + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + if (wire_type != PB_WT_VARINT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_varint(stream, field); + + case PB_LTYPE_FIXED32: + if (wire_type != PB_WT_32BIT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_decode_fixed32(stream, field->pData); + + case PB_LTYPE_FIXED64: + if (wire_type != PB_WT_64BIT && wire_type != PB_WT_PACKED) + PB_RETURN_ERROR(stream, "wrong wire type"); + +#ifdef PB_CONVERT_DOUBLE_FLOAT + if (field->data_size == sizeof(float)) + { + return pb_decode_double_as_float(stream, (float*)field->pData); + } +#endif + +#ifdef PB_WITHOUT_64BIT + PB_RETURN_ERROR(stream, "invalid data_size"); +#else + return pb_decode_fixed64(stream, field->pData); +#endif + + case PB_LTYPE_BYTES: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_bytes(stream, field); + + case PB_LTYPE_STRING: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_string(stream, field); + + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_submessage(stream, field); + + case PB_LTYPE_FIXED_LENGTH_BYTES: + if (wire_type != PB_WT_STRING) + PB_RETURN_ERROR(stream, "wrong wire type"); + + return pb_dec_fixed_length_bytes(stream, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + return decode_basic_field(stream, wire_type, field); + + case PB_HTYPE_OPTIONAL: + if (field->pSize != NULL) + *(bool*)field->pSize = true; + return decode_basic_field(stream, wire_type, field); + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array */ + bool status = true; + pb_istream_t substream; + pb_size_t *size = (pb_size_t*)field->pSize; + field->pData = (char*)field->pField + field->data_size * (*size); + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left > 0 && *size < field->array_size) + { + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) + { + status = false; + break; + } + (*size)++; + field->pData = (char*)field->pData + field->data_size; + } + + if (substream.bytes_left != 0) + PB_RETURN_ERROR(stream, "array overflow"); + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Repeated field */ + pb_size_t *size = (pb_size_t*)field->pSize; + field->pData = (char*)field->pField + field->data_size * (*size); + + if ((*size)++ >= field->array_size) + PB_RETURN_ERROR(stream, "array overflow"); + + return decode_basic_field(stream, wire_type, field); + } + + case PB_HTYPE_ONEOF: + if (PB_LTYPE_IS_SUBMSG(field->type) && + *(pb_size_t*)field->pSize != field->tag) + { + /* We memset to zero so that any callbacks are set to NULL. + * This is because the callbacks might otherwise have values + * from some other union field. + * If callbacks are needed inside oneof field, use .proto + * option submsg_callback to have a separate callback function + * that can set the fields before submessage is decoded. + * pb_dec_submessage() will set any default values. */ + memset(field->pData, 0, (size_t)field->data_size); + + /* Set default values for the submessage fields. */ + if (field->submsg_desc->default_value != NULL || + field->submsg_desc->field_callback != NULL || + field->submsg_desc->submsg_info[0] != NULL) + { + pb_field_iter_t submsg_iter; + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) + { + if (!pb_message_set_to_defaults(&submsg_iter)) + PB_RETURN_ERROR(stream, "failed to set defaults"); + } + } + } + *(pb_size_t*)field->pSize = field->tag; + + return decode_basic_field(stream, wire_type, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +#ifdef PB_ENABLE_MALLOC +/* Allocate storage for the field and store the pointer at iter->pData. + * array_size is the number of entries to reserve in an array. + * Zero size is not allowed, use pb_free() for releasing. + */ +static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t data_size, size_t array_size) +{ + void *ptr = *(void**)pData; + + if (data_size == 0 || array_size == 0) + PB_RETURN_ERROR(stream, "invalid size"); + +#ifdef __AVR__ + /* Workaround for AVR libc bug 53284: http://savannah.nongnu.org/bugs/?53284 + * Realloc to size of 1 byte can cause corruption of the malloc structures. + */ + if (data_size == 1 && array_size == 1) + { + data_size = 2; + } +#endif + + /* Check for multiplication overflows. + * This code avoids the costly division if the sizes are small enough. + * Multiplication is safe as long as only half of bits are set + * in either multiplicand. + */ + { + const size_t check_limit = (size_t)1 << (sizeof(size_t) * 4); + if (data_size >= check_limit || array_size >= check_limit) + { + const size_t size_max = (size_t)-1; + if (size_max / array_size < data_size) + { + PB_RETURN_ERROR(stream, "size too large"); + } + } + } + + /* Allocate new or expand previous allocation */ + /* Note: on failure the old pointer will remain in the structure, + * the message must be freed by caller also on error return. */ + ptr = pb_realloc(ptr, array_size * data_size); + if (ptr == NULL) + PB_RETURN_ERROR(stream, "realloc failed"); + + *(void**)pData = ptr; + return true; +} + +/* Clear a newly allocated item in case it contains a pointer, or is a submessage. */ +static void initialize_pointer_field(void *pItem, pb_field_iter_t *field) +{ + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES) + { + *(void**)pItem = NULL; + } + else if (PB_LTYPE_IS_SUBMSG(field->type)) + { + /* We memset to zero so that any callbacks are set to NULL. + * Default values will be set by pb_dec_submessage(). */ + memset(pItem, 0, field->data_size); + } +} +#endif + +static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ +#ifndef PB_ENABLE_MALLOC + PB_UNUSED(wire_type); + PB_UNUSED(field); + PB_RETURN_ERROR(stream, "no malloc support"); +#else + switch (PB_HTYPE(field->type)) + { + case PB_HTYPE_REQUIRED: + case PB_HTYPE_OPTIONAL: + case PB_HTYPE_ONEOF: + if (PB_LTYPE_IS_SUBMSG(field->type) && *(void**)field->pField != NULL) + { + /* Duplicate field, have to release the old allocation first. */ + /* FIXME: Does this work correctly for oneofs? */ + pb_release_single_field(field); + } + + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)field->pSize = field->tag; + } + + if (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES) + { + /* pb_dec_string and pb_dec_bytes handle allocation themselves */ + field->pData = field->pField; + return decode_basic_field(stream, wire_type, field); + } + else + { + if (!allocate_field(stream, field->pField, field->data_size, 1)) + return false; + + field->pData = *(void**)field->pField; + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, wire_type, field); + } + + case PB_HTYPE_REPEATED: + if (wire_type == PB_WT_STRING + && PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Packed array, multiple items come in at once. */ + bool status = true; + pb_size_t *size = (pb_size_t*)field->pSize; + size_t allocated_size = *size; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + while (substream.bytes_left) + { + if (*size == PB_SIZE_MAX) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = "too many array entries"; +#endif + status = false; + break; + } + + if ((size_t)*size + 1 > allocated_size) + { + /* Allocate more storage. This tries to guess the + * number of remaining entries. Round the division + * upwards. */ + size_t remain = (substream.bytes_left - 1) / field->data_size + 1; + if (remain < PB_SIZE_MAX - allocated_size) + allocated_size += remain; + else + allocated_size += 1; + + if (!allocate_field(&substream, field->pField, field->data_size, allocated_size)) + { + status = false; + break; + } + } + + /* Decode the array entry */ + field->pData = *(char**)field->pField + field->data_size * (*size); + if (field->pData == NULL) + { + /* Shouldn't happen, but satisfies static analyzers */ + status = false; + break; + } + initialize_pointer_field(field->pData, field); + if (!decode_basic_field(&substream, PB_WT_PACKED, field)) + { + status = false; + break; + } + + (*size)++; + } + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; + } + else + { + /* Normal repeated field, i.e. only one item at a time. */ + pb_size_t *size = (pb_size_t*)field->pSize; + + if (*size == PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "too many array entries"); + + if (!allocate_field(stream, field->pField, field->data_size, (size_t)(*size + 1))) + return false; + + field->pData = *(char**)field->pField + field->data_size * (*size); + (*size)++; + initialize_pointer_field(field->pData, field); + return decode_basic_field(stream, wire_type, field); + } + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +#endif +} + +static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ + if (!field->descriptor->field_callback) + return pb_skip_field(stream, wire_type); + + if (wire_type == PB_WT_STRING) + { + pb_istream_t substream; + size_t prev_bytes_left; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + do + { + prev_bytes_left = substream.bytes_left; + if (!field->descriptor->field_callback(&substream, NULL, field)) + { + PB_SET_ERROR(stream, substream.errmsg ? substream.errmsg : "callback failed"); + return false; + } + } while (substream.bytes_left > 0 && substream.bytes_left < prev_bytes_left); + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return true; + } + else + { + /* Copy the single scalar value to stack. + * This is required so that we can limit the stream length, + * which in turn allows to use same callback for packed and + * not-packed fields. */ + pb_istream_t substream; + pb_byte_t buffer[10]; + size_t size = sizeof(buffer); + + if (!read_raw_value(stream, wire_type, buffer, &size)) + return false; + substream = pb_istream_from_buffer(buffer, size); + + return field->descriptor->field_callback(&substream, NULL, field); + } +} + +static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *field) +{ +#ifdef PB_ENABLE_MALLOC + /* When decoding an oneof field, check if there is old data that must be + * released first. */ + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) + { + if (!pb_release_union_field(stream, field)) + return false; + } +#endif + + switch (PB_ATYPE(field->type)) + { + case PB_ATYPE_STATIC: + return decode_static_field(stream, wire_type, field); + + case PB_ATYPE_POINTER: + return decode_pointer_field(stream, wire_type, field); + + case PB_ATYPE_CALLBACK: + return decode_callback_field(stream, wire_type, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Default handler for extension fields. Expects to have a pb_msgdesc_t + * pointer in the extension->type->arg field, pointing to a message with + * only one field in it. */ +static bool checkreturn default_extension_decoder(pb_istream_t *stream, + pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type) +{ + pb_field_iter_t iter; + + if (!pb_field_iter_begin_extension(&iter, extension)) + PB_RETURN_ERROR(stream, "invalid extension"); + + if (iter.tag != tag || !iter.message) + return true; + + extension->found = true; + return decode_field(stream, wire_type, &iter); +} + +/* Try to decode an unknown field as an extension field. Tries each extension + * decoder in turn, until one of them handles the field or loop ends. */ +static bool checkreturn decode_extension(pb_istream_t *stream, + uint32_t tag, pb_wire_type_t wire_type, pb_extension_t *extension) +{ + size_t pos = stream->bytes_left; + + while (extension != NULL && pos == stream->bytes_left) + { + bool status; + if (extension->type->decode) + status = extension->type->decode(stream, extension, tag, wire_type); + else + status = default_extension_decoder(stream, extension, tag, wire_type); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/* Initialize message fields to default values, recursively */ +static bool pb_field_set_to_default(pb_field_iter_t *field) +{ + pb_type_t type; + type = field->type; + + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + pb_extension_t *ext = *(pb_extension_t* const *)field->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + if (pb_field_iter_begin_extension(&ext_iter, ext)) + { + ext->found = false; + if (!pb_message_set_to_defaults(&ext_iter)) + return false; + } + ext = ext->next; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + bool init_data = true; + if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) + { + /* Set has_field to false. Still initialize the optional field + * itself also. */ + *(bool*)field->pSize = false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* REPEATED: Set array count to 0, no need to initialize contents. + ONEOF: Set which_field to 0. */ + *(pb_size_t*)field->pSize = 0; + init_data = false; + } + + if (init_data) + { + if (PB_LTYPE_IS_SUBMSG(field->type) && + (field->submsg_desc->default_value != NULL || + field->submsg_desc->field_callback != NULL || + field->submsg_desc->submsg_info[0] != NULL)) + { + /* Initialize submessage to defaults. + * Only needed if it has default values + * or callback/submessage fields. */ + pb_field_iter_t submsg_iter; + if (pb_field_iter_begin(&submsg_iter, field->submsg_desc, field->pData)) + { + if (!pb_message_set_to_defaults(&submsg_iter)) + return false; + } + } + else + { + /* Initialize to zeros */ + memset(field->pData, 0, (size_t)field->data_size); + } + } + } + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + /* Initialize the pointer to NULL. */ + *(void**)field->pField = NULL; + + /* Initialize array count to 0. */ + if (PB_HTYPE(type) == PB_HTYPE_REPEATED || + PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + *(pb_size_t*)field->pSize = 0; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) + { + /* Don't overwrite callback */ + } + + return true; +} + +static bool pb_message_set_to_defaults(pb_field_iter_t *iter) +{ + pb_istream_t defstream = PB_ISTREAM_EMPTY; + uint32_t tag = 0; + pb_wire_type_t wire_type = PB_WT_VARINT; + bool eof; + + if (iter->descriptor->default_value) + { + defstream = pb_istream_from_buffer(iter->descriptor->default_value, (size_t)-1); + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) + return false; + } + + do + { + if (!pb_field_set_to_default(iter)) + return false; + + if (tag != 0 && iter->tag == tag) + { + /* We have a default value for this field in the defstream */ + if (!decode_field(&defstream, wire_type, iter)) + return false; + if (!pb_decode_tag(&defstream, &wire_type, &tag, &eof)) + return false; + + if (iter->pSize) + *(bool*)iter->pSize = false; + } + } while (pb_field_iter_next(iter)); + + return true; +} + +/********************* + * Decode all fields * + *********************/ + +static bool checkreturn pb_decode_inner(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) +{ + uint32_t extension_range_start = 0; + pb_extension_t *extensions = NULL; + + /* 'fixed_count_field' and 'fixed_count_size' track position of a repeated fixed + * count field. This can only handle _one_ repeated fixed count field that + * is unpacked and unordered among other (non repeated fixed count) fields. + */ + pb_size_t fixed_count_field = PB_SIZE_MAX; + pb_size_t fixed_count_size = 0; + pb_size_t fixed_count_total_size = 0; + + pb_fields_seen_t fields_seen = {{0, 0}}; + const uint32_t allbits = ~(uint32_t)0; + pb_field_iter_t iter; + + if (pb_field_iter_begin(&iter, fields, dest_struct)) + { + if ((flags & PB_DECODE_NOINIT) == 0) + { + if (!pb_message_set_to_defaults(&iter)) + PB_RETURN_ERROR(stream, "failed to set defaults"); + } + } + + while (stream->bytes_left) + { + uint32_t tag; + pb_wire_type_t wire_type; + bool eof; + + if (!pb_decode_tag(stream, &wire_type, &tag, &eof)) + { + if (eof) + break; + else + return false; + } + + if (tag == 0) + { + if (flags & PB_DECODE_NULLTERMINATED) + { + break; + } + else + { + PB_RETURN_ERROR(stream, "zero tag"); + } + } + + if (!pb_field_iter_find(&iter, tag) || PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) + { + /* No match found, check if it matches an extension. */ + if (extension_range_start == 0) + { + if (pb_field_iter_find_extension(&iter)) + { + extensions = *(pb_extension_t* const *)iter.pData; + extension_range_start = iter.tag; + } + + if (!extensions) + { + extension_range_start = (uint32_t)-1; + } + } + + if (tag >= extension_range_start) + { + size_t pos = stream->bytes_left; + + if (!decode_extension(stream, tag, wire_type, extensions)) + return false; + + if (pos != stream->bytes_left) + { + /* The field was handled */ + continue; + } + } + + /* No match found, skip data */ + if (!pb_skip_field(stream, wire_type)) + return false; + continue; + } + + /* If a repeated fixed count field was found, get size from + * 'fixed_count_field' as there is no counter contained in the struct. + */ + if (PB_HTYPE(iter.type) == PB_HTYPE_REPEATED && iter.pSize == &iter.array_size) + { + if (fixed_count_field != iter.index) { + /* If the new fixed count field does not match the previous one, + * check that the previous one is NULL or that it finished + * receiving all the expected data. + */ + if (fixed_count_field != PB_SIZE_MAX && + fixed_count_size != fixed_count_total_size) + { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + fixed_count_field = iter.index; + fixed_count_size = 0; + fixed_count_total_size = iter.array_size; + } + + iter.pSize = &fixed_count_size; + } + + if (PB_HTYPE(iter.type) == PB_HTYPE_REQUIRED + && iter.required_field_index < PB_MAX_REQUIRED_FIELDS) + { + uint32_t tmp = ((uint32_t)1 << (iter.required_field_index & 31)); + fields_seen.bitfield[iter.required_field_index >> 5] |= tmp; + } + + if (!decode_field(stream, wire_type, &iter)) + return false; + } + + /* Check that all elements of the last decoded fixed count field were present. */ + if (fixed_count_field != PB_SIZE_MAX && + fixed_count_size != fixed_count_total_size) + { + PB_RETURN_ERROR(stream, "wrong size for fixed count field"); + } + + /* Check that all required fields were present. */ + { + pb_size_t req_field_count = iter.descriptor->required_field_count; + + if (req_field_count > 0) + { + pb_size_t i; + + if (req_field_count > PB_MAX_REQUIRED_FIELDS) + req_field_count = PB_MAX_REQUIRED_FIELDS; + + /* Check the whole words */ + for (i = 0; i < (req_field_count >> 5); i++) + { + if (fields_seen.bitfield[i] != allbits) + PB_RETURN_ERROR(stream, "missing required field"); + } + + /* Check the remaining bits (if any) */ + if ((req_field_count & 31) != 0) + { + if (fields_seen.bitfield[req_field_count >> 5] != + (allbits >> (uint_least8_t)(32 - (req_field_count & 31)))) + { + PB_RETURN_ERROR(stream, "missing required field"); + } + } + } + } + + return true; +} + +bool checkreturn pb_decode_ex(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct, unsigned int flags) +{ + bool status; + + if ((flags & PB_DECODE_DELIMITED) == 0) + { + status = pb_decode_inner(stream, fields, dest_struct, flags); + } + else + { + pb_istream_t substream; + if (!pb_make_string_substream(stream, &substream)) + return false; + + status = pb_decode_inner(&substream, fields, dest_struct, flags); + + if (!pb_close_string_substream(stream, &substream)) + return false; + } + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; +} + +bool checkreturn pb_decode(pb_istream_t *stream, const pb_msgdesc_t *fields, void *dest_struct) +{ + bool status; + + status = pb_decode_inner(stream, fields, dest_struct, 0); + +#ifdef PB_ENABLE_MALLOC + if (!status) + pb_release(fields, dest_struct); +#endif + + return status; +} + +#ifdef PB_ENABLE_MALLOC +/* Given an oneof field, if there has already been a field inside this oneof, + * release it before overwriting with a different one. */ +static bool pb_release_union_field(pb_istream_t *stream, pb_field_iter_t *field) +{ + pb_field_iter_t old_field = *field; + pb_size_t old_tag = *(pb_size_t*)field->pSize; /* Previous which_ value */ + pb_size_t new_tag = field->tag; /* New which_ value */ + + if (old_tag == 0) + return true; /* Ok, no old data in union */ + + if (old_tag == new_tag) + return true; /* Ok, old data is of same type => merge */ + + /* Release old data. The find can fail if the message struct contains + * invalid data. */ + if (!pb_field_iter_find(&old_field, old_tag)) + PB_RETURN_ERROR(stream, "invalid union tag"); + + pb_release_single_field(&old_field); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + /* Initialize the pointer to NULL to make sure it is valid + * even in case of error return. */ + *(void**)field->pField = NULL; + field->pData = NULL; + } + + return true; +} + +static void pb_release_single_field(pb_field_iter_t *field) +{ + pb_type_t type; + type = field->type; + + if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + if (*(pb_size_t*)field->pSize != field->tag) + return; /* This is not the current field in the union */ + } + + /* Release anything contained inside an extension or submsg. + * This has to be done even if the submsg itself is statically + * allocated. */ + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + /* Release fields from all extensions in the linked list */ + pb_extension_t *ext = *(pb_extension_t**)field->pData; + while (ext != NULL) + { + pb_field_iter_t ext_iter; + if (pb_field_iter_begin_extension(&ext_iter, ext)) + { + pb_release_single_field(&ext_iter); + } + ext = ext->next; + } + } + else if (PB_LTYPE_IS_SUBMSG(type) && PB_ATYPE(type) != PB_ATYPE_CALLBACK) + { + /* Release fields in submessage or submsg array */ + pb_size_t count = 1; + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + field->pData = *(void**)field->pField; + } + else + { + field->pData = field->pField; + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + count = *(pb_size_t*)field->pSize; + + if (PB_ATYPE(type) == PB_ATYPE_STATIC && count > field->array_size) + { + /* Protect against corrupted _count fields */ + count = field->array_size; + } + } + + if (field->pData) + { + for (; count > 0; count--) + { + pb_release(field->submsg_desc, field->pData); + field->pData = (char*)field->pData + field->data_size; + } + } + } + + if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + if (PB_HTYPE(type) == PB_HTYPE_REPEATED && + (PB_LTYPE(type) == PB_LTYPE_STRING || + PB_LTYPE(type) == PB_LTYPE_BYTES)) + { + /* Release entries in repeated string or bytes array */ + void **pItem = *(void***)field->pField; + pb_size_t count = *(pb_size_t*)field->pSize; + for (; count > 0; count--) + { + pb_free(*pItem); + *pItem++ = NULL; + } + } + + if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* We are going to release the array, so set the size to 0 */ + *(pb_size_t*)field->pSize = 0; + } + + /* Release main pointer */ + pb_free(*(void**)field->pField); + *(void**)field->pField = NULL; + } +} + +void pb_release(const pb_msgdesc_t *fields, void *dest_struct) +{ + pb_field_iter_t iter; + + if (!dest_struct) + return; /* Ignore NULL pointers, similar to free() */ + + if (!pb_field_iter_begin(&iter, fields, dest_struct)) + return; /* Empty message type */ + + do + { + pb_release_single_field(&iter); + } while (pb_field_iter_next(&iter)); +} +#else +void pb_release(const pb_msgdesc_t *fields, void *dest_struct) +{ + /* Nothing to release without PB_ENABLE_MALLOC. */ + PB_UNUSED(fields); + PB_UNUSED(dest_struct); +} +#endif + +/* Field decoders */ + +bool pb_decode_bool(pb_istream_t *stream, bool *dest) +{ + uint32_t value; + if (!pb_decode_varint32(stream, &value)) + return false; + + *(bool*)dest = (value != 0); + return true; +} + +bool pb_decode_svarint(pb_istream_t *stream, pb_int64_t *dest) +{ + pb_uint64_t value; + if (!pb_decode_varint(stream, &value)) + return false; + + if (value & 1) + *dest = (pb_int64_t)(~(value >> 1)); + else + *dest = (pb_int64_t)(value >> 1); + + return true; +} + +bool pb_decode_fixed32(pb_istream_t *stream, void *dest) +{ + union { + uint32_t fixed32; + pb_byte_t bytes[4]; + } u; + + if (!pb_read(stream, u.bytes, 4)) + return false; + +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* fast path - if we know that we're on little endian, assign directly */ + *(uint32_t*)dest = u.fixed32; +#else + *(uint32_t*)dest = ((uint32_t)u.bytes[0] << 0) | + ((uint32_t)u.bytes[1] << 8) | + ((uint32_t)u.bytes[2] << 16) | + ((uint32_t)u.bytes[3] << 24); +#endif + return true; +} + +#ifndef PB_WITHOUT_64BIT +bool pb_decode_fixed64(pb_istream_t *stream, void *dest) +{ + union { + uint64_t fixed64; + pb_byte_t bytes[8]; + } u; + + if (!pb_read(stream, u.bytes, 8)) + return false; + +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* fast path - if we know that we're on little endian, assign directly */ + *(uint64_t*)dest = u.fixed64; +#else + *(uint64_t*)dest = ((uint64_t)u.bytes[0] << 0) | + ((uint64_t)u.bytes[1] << 8) | + ((uint64_t)u.bytes[2] << 16) | + ((uint64_t)u.bytes[3] << 24) | + ((uint64_t)u.bytes[4] << 32) | + ((uint64_t)u.bytes[5] << 40) | + ((uint64_t)u.bytes[6] << 48) | + ((uint64_t)u.bytes[7] << 56); +#endif + return true; +} +#endif + +static bool checkreturn pb_dec_bool(pb_istream_t *stream, const pb_field_iter_t *field) +{ + return pb_decode_bool(stream, (bool*)field->pData); +} + +static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_iter_t *field) +{ + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) + { + pb_uint64_t value, clamped; + if (!pb_decode_varint(stream, &value)) + return false; + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_uint64_t)) + clamped = *(pb_uint64_t*)field->pData = value; + else if (field->data_size == sizeof(uint32_t)) + clamped = *(uint32_t*)field->pData = (uint32_t)value; + else if (field->data_size == sizeof(uint_least16_t)) + clamped = *(uint_least16_t*)field->pData = (uint_least16_t)value; + else if (field->data_size == sizeof(uint_least8_t)) + clamped = *(uint_least8_t*)field->pData = (uint_least8_t)value; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != value) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; + } + else + { + pb_uint64_t value; + pb_int64_t svalue; + pb_int64_t clamped; + + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) + { + if (!pb_decode_svarint(stream, &svalue)) + return false; + } + else + { + if (!pb_decode_varint(stream, &value)) + return false; + + /* See issue 97: Google's C++ protobuf allows negative varint values to + * be cast as int32_t, instead of the int64_t that should be used when + * encoding. Nanopb versions before 0.2.5 had a bug in encoding. In order to + * not break decoding of such messages, we cast <=32 bit fields to + * int32_t first to get the sign correct. + */ + if (field->data_size == sizeof(pb_int64_t)) + svalue = (pb_int64_t)value; + else + svalue = (int32_t)value; + } + + /* Cast to the proper field size, while checking for overflows */ + if (field->data_size == sizeof(pb_int64_t)) + clamped = *(pb_int64_t*)field->pData = svalue; + else if (field->data_size == sizeof(int32_t)) + clamped = *(int32_t*)field->pData = (int32_t)svalue; + else if (field->data_size == sizeof(int_least16_t)) + clamped = *(int_least16_t*)field->pData = (int_least16_t)svalue; + else if (field->data_size == sizeof(int_least8_t)) + clamped = *(int_least8_t*)field->pData = (int_least8_t)svalue; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (clamped != svalue) + PB_RETURN_ERROR(stream, "integer too large"); + + return true; + } +} + +static bool checkreturn pb_dec_bytes(pb_istream_t *stream, const pb_field_iter_t *field) +{ + uint32_t size; + size_t alloc_size; + pb_bytes_array_t *dest; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + alloc_size = PB_BYTES_ARRAY_T_ALLOCSIZE(size); + if (size > alloc_size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (stream->bytes_left < size) + PB_RETURN_ERROR(stream, "end-of-stream"); + + if (!allocate_field(stream, field->pData, alloc_size, 1)) + return false; + dest = *(pb_bytes_array_t**)field->pData; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "bytes overflow"); + dest = (pb_bytes_array_t*)field->pData; + } + + dest->size = (pb_size_t)size; + return pb_read(stream, dest->bytes, (size_t)size); +} + +static bool checkreturn pb_dec_string(pb_istream_t *stream, const pb_field_iter_t *field) +{ + uint32_t size; + size_t alloc_size; + pb_byte_t *dest = (pb_byte_t*)field->pData; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size == (uint32_t)-1) + PB_RETURN_ERROR(stream, "size too large"); + + /* Space for null terminator */ + alloc_size = (size_t)(size + 1); + + if (alloc_size < size) + PB_RETURN_ERROR(stream, "size too large"); + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { +#ifndef PB_ENABLE_MALLOC + PB_RETURN_ERROR(stream, "no malloc support"); +#else + if (stream->bytes_left < size) + PB_RETURN_ERROR(stream, "end-of-stream"); + + if (!allocate_field(stream, field->pData, alloc_size, 1)) + return false; + dest = *(pb_byte_t**)field->pData; +#endif + } + else + { + if (alloc_size > field->data_size) + PB_RETURN_ERROR(stream, "string overflow"); + } + + dest[size] = 0; + + if (!pb_read(stream, dest, (size_t)size)) + return false; + +#ifdef PB_VALIDATE_UTF8 + if (!pb_validate_utf8((const char*)dest)) + PB_RETURN_ERROR(stream, "invalid utf8"); +#endif + + return true; +} + +static bool checkreturn pb_dec_submessage(pb_istream_t *stream, const pb_field_iter_t *field) +{ + bool status = true; + bool submsg_consumed = false; + pb_istream_t substream; + + if (!pb_make_string_substream(stream, &substream)) + return false; + + if (field->submsg_desc == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + /* Submessages can have a separate message-level callback that is called + * before decoding the message. Typically it is used to set callback fields + * inside oneofs. */ + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) + { + /* Message callback is stored right before pSize. */ + pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; + if (callback->funcs.decode) + { + status = callback->funcs.decode(&substream, field, &callback->arg); + + if (substream.bytes_left == 0) + { + submsg_consumed = true; + } + } + } + + /* Now decode the submessage contents */ + if (status && !submsg_consumed) + { + unsigned int flags = 0; + + /* Static required/optional fields are already initialized by top-level + * pb_decode(), no need to initialize them again. */ + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + PB_HTYPE(field->type) != PB_HTYPE_REPEATED) + { + flags = PB_DECODE_NOINIT; + } + + status = pb_decode_inner(&substream, field->submsg_desc, field->pData, flags); + } + + if (!pb_close_string_substream(stream, &substream)) + return false; + + return status; +} + +static bool checkreturn pb_dec_fixed_length_bytes(pb_istream_t *stream, const pb_field_iter_t *field) +{ + uint32_t size; + + if (!pb_decode_varint32(stream, &size)) + return false; + + if (size > PB_SIZE_MAX) + PB_RETURN_ERROR(stream, "bytes overflow"); + + if (size == 0) + { + /* As a special case, treat empty bytes string as all zeros for fixed_length_bytes. */ + memset(field->pData, 0, (size_t)field->data_size); + return true; + } + + if (size != field->data_size) + PB_RETURN_ERROR(stream, "incorrect fixed length bytes size"); + + return pb_read(stream, (pb_byte_t*)field->pData, (size_t)field->data_size); +} + +#ifdef PB_CONVERT_DOUBLE_FLOAT +bool pb_decode_double_as_float(pb_istream_t *stream, float *dest) +{ + uint_least8_t sign; + int exponent; + uint32_t mantissa; + uint64_t value; + union { float f; uint32_t i; } out; + + if (!pb_decode_fixed64(stream, &value)) + return false; + + /* Decompose input value */ + sign = (uint_least8_t)((value >> 63) & 1); + exponent = (int)((value >> 52) & 0x7FF) - 1023; + mantissa = (value >> 28) & 0xFFFFFF; /* Highest 24 bits */ + + /* Figure if value is in range representable by floats. */ + if (exponent == 1024) + { + /* Special value */ + exponent = 128; + mantissa >>= 1; + } + else + { + if (exponent > 127) + { + /* Too large, convert to infinity */ + exponent = 128; + mantissa = 0; + } + else if (exponent < -150) + { + /* Too small, convert to zero */ + exponent = -127; + mantissa = 0; + } + else if (exponent < -126) + { + /* Denormalized */ + mantissa |= 0x1000000; + mantissa >>= (-126 - exponent); + exponent = -127; + } + + /* Round off mantissa */ + mantissa = (mantissa + 1) >> 1; + + /* Check if mantissa went over 2.0 */ + if (mantissa & 0x800000) + { + exponent += 1; + mantissa &= 0x7FFFFF; + mantissa >>= 1; + } + } + + /* Combine fields */ + out.i = mantissa; + out.i |= (uint32_t)(exponent + 127) << 23; + out.i |= (uint32_t)sign << 31; + + *dest = out.f; + return true; +} +#endif diff --git a/project_old/paint_robot_old/BASE/Src/BSP/pb_encode.c b/project_old/paint_robot_old/BASE/Src/BSP/pb_encode.c new file mode 100644 index 0000000..7f56201 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/pb_encode.c @@ -0,0 +1,1000 @@ +/* pb_encode.c -- encode a protobuf using minimal resources + * + * 2011 Petteri Aimonen + */ + +#include "pb.h" +#include "pb_encode.h" +#include "pb_common.h" + +/* Use the GCC warn_unused_result attribute to check that all return values + * are propagated correctly. On other compilers and gcc before 3.4.0 just + * ignore the annotation. + */ +#if !defined(__GNUC__) || ( __GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) + #define checkreturn +#else + #define checkreturn __attribute__((warn_unused_result)) +#endif + +/************************************** + * Declarations internal to this file * + **************************************/ +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count); +static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field); +static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field); +static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field); +static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension); +static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high); +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field); +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field); + +#ifdef PB_WITHOUT_64BIT +#define pb_int64_t int32_t +#define pb_uint64_t uint32_t +#else +#define pb_int64_t int64_t +#define pb_uint64_t uint64_t +#endif + +/******************************* + * pb_ostream_t implementation * + *******************************/ + +static bool checkreturn buf_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + pb_byte_t *dest = (pb_byte_t*)stream->state; + stream->state = dest + count; + + memcpy(dest, buf, count * sizeof(pb_byte_t)); + + return true; +} + +pb_ostream_t pb_ostream_from_buffer(pb_byte_t *buf, size_t bufsize) +{ + pb_ostream_t stream; +#ifdef PB_BUFFER_ONLY + /* In PB_BUFFER_ONLY configuration the callback pointer is just int*. + * NULL pointer marks a sizing field, so put a non-NULL value to mark a buffer stream. + */ + static const int marker = 0; + stream.callback = ▮ +#else + stream.callback = &buf_write; +#endif + stream.state = buf; + stream.max_size = bufsize; + stream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + stream.errmsg = NULL; +#endif + return stream; +} + +bool checkreturn pb_write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) +{ + if (count > 0 && stream->callback != NULL) + { + if (stream->bytes_written + count < stream->bytes_written || + stream->bytes_written + count > stream->max_size) + { + PB_RETURN_ERROR(stream, "stream full"); + } + +#ifdef PB_BUFFER_ONLY + if (!buf_write(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#else + if (!stream->callback(stream, buf, count)) + PB_RETURN_ERROR(stream, "io error"); +#endif + } + + stream->bytes_written += count; + return true; +} + +/************************* + * Encode a single field * + *************************/ + +/* Read a bool value without causing undefined behavior even if the value + * is invalid. See issue #434 and + * https://stackoverflow.com/questions/27661768/weird-results-for-conditional + */ +static bool safe_read_bool(const void *pSize) +{ + const char *p = (const char *)pSize; + size_t i; + for (i = 0; i < sizeof(bool); i++) + { + if (p[i] != 0) + return true; + } + return false; +} + +/* Encode a static array. Handles the size calculations and possible packing. */ +static bool checkreturn encode_array(pb_ostream_t *stream, pb_field_iter_t *field) +{ + pb_size_t i; + pb_size_t count; +#ifndef PB_ENCODE_ARRAYS_UNPACKED + size_t size; +#endif + + count = *(pb_size_t*)field->pSize; + + if (count == 0) + return true; + + if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size) + PB_RETURN_ERROR(stream, "array max size exceeded"); + +#ifndef PB_ENCODE_ARRAYS_UNPACKED + /* We always pack arrays if the datatype allows it. */ + if (PB_LTYPE(field->type) <= PB_LTYPE_LAST_PACKABLE) + { + if (!pb_encode_tag(stream, PB_WT_STRING, field->tag)) + return false; + + /* Determine the total size of packed array. */ + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32) + { + size = 4 * (size_t)count; + } + else if (PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + size = 8 * (size_t)count; + } + else + { + pb_ostream_t sizestream = PB_OSTREAM_SIZING; + void *pData_orig = field->pData; + for (i = 0; i < count; i++) + { + if (!pb_enc_varint(&sizestream, field)) + PB_RETURN_ERROR(stream, PB_GET_ERROR(&sizestream)); + field->pData = (char*)field->pData + field->data_size; + } + field->pData = pData_orig; + size = sizestream.bytes_written; + } + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing.. */ + + /* Write the data */ + for (i = 0; i < count; i++) + { + if (PB_LTYPE(field->type) == PB_LTYPE_FIXED32 || PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + if (!pb_enc_fixed(stream, field)) + return false; + } + else + { + if (!pb_enc_varint(stream, field)) + return false; + } + + field->pData = (char*)field->pData + field->data_size; + } + } + else /* Unpacked fields */ +#endif + { + for (i = 0; i < count; i++) + { + /* Normally the data is stored directly in the array entries, but + * for pointer-type string and bytes fields, the array entries are + * actually pointers themselves also. So we have to dereference once + * more to get to the actual data. */ + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER && + (PB_LTYPE(field->type) == PB_LTYPE_STRING || + PB_LTYPE(field->type) == PB_LTYPE_BYTES)) + { + bool status; + void *pData_orig = field->pData; + field->pData = *(void* const*)field->pData; + + if (!field->pData) + { + /* Null pointer in array is treated as empty string / bytes */ + status = pb_encode_tag_for_field(stream, field) && + pb_encode_varint(stream, 0); + } + else + { + status = encode_basic_field(stream, field); + } + + field->pData = pData_orig; + + if (!status) + return false; + } + else + { + if (!encode_basic_field(stream, field)) + return false; + } + field->pData = (char*)field->pData + field->data_size; + } + } + + return true; +} + +/* In proto3, all fields are optional and are only encoded if their value is "non-zero". + * This function implements the check for the zero value. */ +static bool checkreturn pb_check_proto3_default_value(const pb_field_iter_t *field) +{ + pb_type_t type = field->type; + + if (PB_ATYPE(type) == PB_ATYPE_STATIC) + { + if (PB_HTYPE(type) == PB_HTYPE_REQUIRED) + { + /* Required proto2 fields inside proto3 submessage, pretty rare case */ + return false; + } + else if (PB_HTYPE(type) == PB_HTYPE_REPEATED) + { + /* Repeated fields inside proto3 submessage: present if count != 0 */ + return *(const pb_size_t*)field->pSize == 0; + } + else if (PB_HTYPE(type) == PB_HTYPE_ONEOF) + { + /* Oneof fields */ + return *(const pb_size_t*)field->pSize == 0; + } + else if (PB_HTYPE(type) == PB_HTYPE_OPTIONAL && field->pSize != NULL) + { + /* Proto2 optional fields inside proto3 message, or proto3 + * submessage fields. */ + return safe_read_bool(field->pSize) == false; + } + else if (field->descriptor->default_value) + { + /* Proto3 messages do not have default values, but proto2 messages + * can contain optional fields without has_fields (generator option 'proto3'). + * In this case they must always be encoded, to make sure that the + * non-zero default value is overwritten. + */ + return false; + } + + /* Rest is proto3 singular fields */ + if (PB_LTYPE(type) <= PB_LTYPE_LAST_PACKABLE) + { + /* Simple integer / float fields */ + pb_size_t i; + const char *p = (const char*)field->pData; + for (i = 0; i < field->data_size; i++) + { + if (p[i] != 0) + { + return false; + } + } + + return true; + } + else if (PB_LTYPE(type) == PB_LTYPE_BYTES) + { + const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)field->pData; + return bytes->size == 0; + } + else if (PB_LTYPE(type) == PB_LTYPE_STRING) + { + return *(const char*)field->pData == '\0'; + } + else if (PB_LTYPE(type) == PB_LTYPE_FIXED_LENGTH_BYTES) + { + /* Fixed length bytes is only empty if its length is fixed + * as 0. Which would be pretty strange, but we can check + * it anyway. */ + return field->data_size == 0; + } + else if (PB_LTYPE_IS_SUBMSG(type)) + { + /* Check all fields in the submessage to find if any of them + * are non-zero. The comparison cannot be done byte-per-byte + * because the C struct may contain padding bytes that must + * be skipped. Note that usually proto3 submessages have + * a separate has_field that is checked earlier in this if. + */ + pb_field_iter_t iter; + if (pb_field_iter_begin(&iter, field->submsg_desc, field->pData)) + { + do + { + if (!pb_check_proto3_default_value(&iter)) + { + return false; + } + } while (pb_field_iter_next(&iter)); + } + return true; + } + } + else if (PB_ATYPE(type) == PB_ATYPE_POINTER) + { + return field->pData == NULL; + } + else if (PB_ATYPE(type) == PB_ATYPE_CALLBACK) + { + if (PB_LTYPE(type) == PB_LTYPE_EXTENSION) + { + const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; + return extension == NULL; + } + else if (field->descriptor->field_callback == pb_default_field_callback) + { + pb_callback_t *pCallback = (pb_callback_t*)field->pData; + return pCallback->funcs.encode == NULL; + } + else + { + return field->descriptor->field_callback == NULL; + } + } + + return false; /* Not typically reached, safe default for weird special cases. */ +} + +/* Encode a field with static or pointer allocation, i.e. one whose data + * is available to the encoder directly. */ +static bool checkreturn encode_basic_field(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (!field->pData) + { + /* Missing pointer field */ + return true; + } + + if (!pb_encode_tag_for_field(stream, field)) + return false; + + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_BOOL: + return pb_enc_bool(stream, field); + + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + return pb_enc_varint(stream, field); + + case PB_LTYPE_FIXED32: + case PB_LTYPE_FIXED64: + return pb_enc_fixed(stream, field); + + case PB_LTYPE_BYTES: + return pb_enc_bytes(stream, field); + + case PB_LTYPE_STRING: + return pb_enc_string(stream, field); + + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + return pb_enc_submessage(stream, field); + + case PB_LTYPE_FIXED_LENGTH_BYTES: + return pb_enc_fixed_length_bytes(stream, field); + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } +} + +/* Encode a field with callback semantics. This means that a user function is + * called to provide and encode the actual data. */ +static bool checkreturn encode_callback_field(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (field->descriptor->field_callback != NULL) + { + if (!field->descriptor->field_callback(NULL, stream, field)) + PB_RETURN_ERROR(stream, "callback error"); + } + return true; +} + +/* Encode a single field of any callback, pointer or static type. */ +static bool checkreturn encode_field(pb_ostream_t *stream, pb_field_iter_t *field) +{ + /* Check field presence */ + if (PB_HTYPE(field->type) == PB_HTYPE_ONEOF) + { + if (*(const pb_size_t*)field->pSize != field->tag) + { + /* Different type oneof field */ + return true; + } + } + else if (PB_HTYPE(field->type) == PB_HTYPE_OPTIONAL) + { + if (field->pSize) + { + if (safe_read_bool(field->pSize) == false) + { + /* Missing optional field */ + return true; + } + } + else if (PB_ATYPE(field->type) == PB_ATYPE_STATIC) + { + /* Proto3 singular field */ + if (pb_check_proto3_default_value(field)) + return true; + } + } + + if (!field->pData) + { + if (PB_HTYPE(field->type) == PB_HTYPE_REQUIRED) + PB_RETURN_ERROR(stream, "missing required field"); + + /* Pointer field set to NULL */ + return true; + } + + /* Then encode field contents */ + if (PB_ATYPE(field->type) == PB_ATYPE_CALLBACK) + { + return encode_callback_field(stream, field); + } + else if (PB_HTYPE(field->type) == PB_HTYPE_REPEATED) + { + return encode_array(stream, field); + } + else + { + return encode_basic_field(stream, field); + } +} + +/* Default handler for extension fields. Expects to have a pb_msgdesc_t + * pointer in the extension->type->arg field, pointing to a message with + * only one field in it. */ +static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension) +{ + pb_field_iter_t iter; + + if (!pb_field_iter_begin_extension_const(&iter, extension)) + PB_RETURN_ERROR(stream, "invalid extension"); + + return encode_field(stream, &iter); +} + + +/* Walk through all the registered extensions and give them a chance + * to encode themselves. */ +static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + const pb_extension_t *extension = *(const pb_extension_t* const *)field->pData; + + while (extension) + { + bool status; + if (extension->type->encode) + status = extension->type->encode(stream, extension); + else + status = default_extension_encoder(stream, extension); + + if (!status) + return false; + + extension = extension->next; + } + + return true; +} + +/********************* + * Encode all fields * + *********************/ + +bool checkreturn pb_encode(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) +{ + pb_field_iter_t iter; + if (!pb_field_iter_begin_const(&iter, fields, src_struct)) + return true; /* Empty message type */ + + do { + if (PB_LTYPE(iter.type) == PB_LTYPE_EXTENSION) + { + /* Special case for the extension field placeholder */ + if (!encode_extension_field(stream, &iter)) + return false; + } + else + { + /* Regular field */ + if (!encode_field(stream, &iter)) + return false; + } + } while (pb_field_iter_next(&iter)); + + return true; +} + +bool checkreturn pb_encode_ex(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct, unsigned int flags) +{ + if ((flags & PB_ENCODE_DELIMITED) != 0) + { + return pb_encode_submessage(stream, fields, src_struct); + } + else if ((flags & PB_ENCODE_NULLTERMINATED) != 0) + { + const pb_byte_t zero = 0; + + if (!pb_encode(stream, fields, src_struct)) + return false; + + return pb_write(stream, &zero, 1); + } + else + { + return pb_encode(stream, fields, src_struct); + } +} + +bool pb_get_encoded_size(size_t *size, const pb_msgdesc_t *fields, const void *src_struct) +{ + pb_ostream_t stream = PB_OSTREAM_SIZING; + + if (!pb_encode(&stream, fields, src_struct)) + return false; + + *size = stream.bytes_written; + return true; +} + +/******************** + * Helper functions * + ********************/ + +/* This function avoids 64-bit shifts as they are quite slow on many platforms. */ +static bool checkreturn pb_encode_varint_32(pb_ostream_t *stream, uint32_t low, uint32_t high) +{ + size_t i = 0; + pb_byte_t buffer[10]; + pb_byte_t byte = (pb_byte_t)(low & 0x7F); + low >>= 7; + + while (i < 4 && (low != 0 || high != 0)) + { + byte |= 0x80; + buffer[i++] = byte; + byte = (pb_byte_t)(low & 0x7F); + low >>= 7; + } + + if (high) + { + byte = (pb_byte_t)(byte | ((high & 0x07) << 4)); + high >>= 3; + + while (high) + { + byte |= 0x80; + buffer[i++] = byte; + byte = (pb_byte_t)(high & 0x7F); + high >>= 7; + } + } + + buffer[i++] = byte; + + return pb_write(stream, buffer, i); +} + +bool checkreturn pb_encode_varint(pb_ostream_t *stream, pb_uint64_t value) +{ + if (value <= 0x7F) + { + /* Fast path: single byte */ + pb_byte_t byte = (pb_byte_t)value; + return pb_write(stream, &byte, 1); + } + else + { +#ifdef PB_WITHOUT_64BIT + return pb_encode_varint_32(stream, value, 0); +#else + return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)(value >> 32)); +#endif + } +} + +bool checkreturn pb_encode_svarint(pb_ostream_t *stream, pb_int64_t value) +{ + pb_uint64_t zigzagged; + pb_uint64_t mask = ((pb_uint64_t)-1) >> 1; /* Satisfy clang -fsanitize=integer */ + if (value < 0) + zigzagged = ~(((pb_uint64_t)value & mask) << 1); + else + zigzagged = (pb_uint64_t)value << 1; + + return pb_encode_varint(stream, zigzagged); +} + +bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value) +{ +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* Fast path if we know that we're on little endian */ + return pb_write(stream, (const pb_byte_t*)value, 4); +#else + uint32_t val = *(const uint32_t*)value; + pb_byte_t bytes[4]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + return pb_write(stream, bytes, 4); +#endif +} + +#ifndef PB_WITHOUT_64BIT +bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value) +{ +#if defined(PB_LITTLE_ENDIAN_8BIT) && PB_LITTLE_ENDIAN_8BIT == 1 + /* Fast path if we know that we're on little endian */ + return pb_write(stream, (const pb_byte_t*)value, 8); +#else + uint64_t val = *(const uint64_t*)value; + pb_byte_t bytes[8]; + bytes[0] = (pb_byte_t)(val & 0xFF); + bytes[1] = (pb_byte_t)((val >> 8) & 0xFF); + bytes[2] = (pb_byte_t)((val >> 16) & 0xFF); + bytes[3] = (pb_byte_t)((val >> 24) & 0xFF); + bytes[4] = (pb_byte_t)((val >> 32) & 0xFF); + bytes[5] = (pb_byte_t)((val >> 40) & 0xFF); + bytes[6] = (pb_byte_t)((val >> 48) & 0xFF); + bytes[7] = (pb_byte_t)((val >> 56) & 0xFF); + return pb_write(stream, bytes, 8); +#endif +} +#endif + +bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number) +{ + pb_uint64_t tag = ((pb_uint64_t)field_number << 3) | wiretype; + return pb_encode_varint(stream, tag); +} + +bool pb_encode_tag_for_field ( pb_ostream_t* stream, const pb_field_iter_t* field ) +{ + pb_wire_type_t wiretype; + switch (PB_LTYPE(field->type)) + { + case PB_LTYPE_BOOL: + case PB_LTYPE_VARINT: + case PB_LTYPE_UVARINT: + case PB_LTYPE_SVARINT: + wiretype = PB_WT_VARINT; + break; + + case PB_LTYPE_FIXED32: + wiretype = PB_WT_32BIT; + break; + + case PB_LTYPE_FIXED64: + wiretype = PB_WT_64BIT; + break; + + case PB_LTYPE_BYTES: + case PB_LTYPE_STRING: + case PB_LTYPE_SUBMESSAGE: + case PB_LTYPE_SUBMSG_W_CB: + case PB_LTYPE_FIXED_LENGTH_BYTES: + wiretype = PB_WT_STRING; + break; + + default: + PB_RETURN_ERROR(stream, "invalid field type"); + } + + return pb_encode_tag(stream, wiretype, field->tag); +} + +bool checkreturn pb_encode_string(pb_ostream_t *stream, const pb_byte_t *buffer, size_t size) +{ + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + return pb_write(stream, buffer, size); +} + +bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_msgdesc_t *fields, const void *src_struct) +{ + /* First calculate the message size using a non-writing substream. */ + pb_ostream_t substream = PB_OSTREAM_SIZING; + size_t size; + bool status; + + if (!pb_encode(&substream, fields, src_struct)) + { +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + return false; + } + + size = substream.bytes_written; + + if (!pb_encode_varint(stream, (pb_uint64_t)size)) + return false; + + if (stream->callback == NULL) + return pb_write(stream, NULL, size); /* Just sizing */ + + if (stream->bytes_written + size > stream->max_size) + PB_RETURN_ERROR(stream, "stream full"); + + /* Use a substream to verify that a callback doesn't write more than + * what it did the first time. */ + substream.callback = stream->callback; + substream.state = stream->state; + substream.max_size = size; + substream.bytes_written = 0; +#ifndef PB_NO_ERRMSG + substream.errmsg = NULL; +#endif + + status = pb_encode(&substream, fields, src_struct); + + stream->bytes_written += substream.bytes_written; + stream->state = substream.state; +#ifndef PB_NO_ERRMSG + stream->errmsg = substream.errmsg; +#endif + + if (substream.bytes_written != size) + PB_RETURN_ERROR(stream, "submsg size changed"); + + return status; +} + +/* Field encoders */ + +static bool checkreturn pb_enc_bool(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + uint32_t value = safe_read_bool(field->pData) ? 1 : 0; + PB_UNUSED(field); + return pb_encode_varint(stream, value); +} + +static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (PB_LTYPE(field->type) == PB_LTYPE_UVARINT) + { + /* Perform unsigned integer extension */ + pb_uint64_t value = 0; + + if (field->data_size == sizeof(uint_least8_t)) + value = *(const uint_least8_t*)field->pData; + else if (field->data_size == sizeof(uint_least16_t)) + value = *(const uint_least16_t*)field->pData; + else if (field->data_size == sizeof(uint32_t)) + value = *(const uint32_t*)field->pData; + else if (field->data_size == sizeof(pb_uint64_t)) + value = *(const pb_uint64_t*)field->pData; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + return pb_encode_varint(stream, value); + } + else + { + /* Perform signed integer extension */ + pb_int64_t value = 0; + + if (field->data_size == sizeof(int_least8_t)) + value = *(const int_least8_t*)field->pData; + else if (field->data_size == sizeof(int_least16_t)) + value = *(const int_least16_t*)field->pData; + else if (field->data_size == sizeof(int32_t)) + value = *(const int32_t*)field->pData; + else if (field->data_size == sizeof(pb_int64_t)) + value = *(const pb_int64_t*)field->pData; + else + PB_RETURN_ERROR(stream, "invalid data_size"); + + if (PB_LTYPE(field->type) == PB_LTYPE_SVARINT) + return pb_encode_svarint(stream, value); +#ifdef PB_WITHOUT_64BIT + else if (value < 0) + return pb_encode_varint_32(stream, (uint32_t)value, (uint32_t)-1); +#endif + else + return pb_encode_varint(stream, (pb_uint64_t)value); + + } +} + +static bool checkreturn pb_enc_fixed(pb_ostream_t *stream, const pb_field_iter_t *field) +{ +#ifdef PB_CONVERT_DOUBLE_FLOAT + if (field->data_size == sizeof(float) && PB_LTYPE(field->type) == PB_LTYPE_FIXED64) + { + return pb_encode_float_as_double(stream, *(float*)field->pData); + } +#endif + + if (field->data_size == sizeof(uint32_t)) + { + return pb_encode_fixed32(stream, field->pData); + } +#ifndef PB_WITHOUT_64BIT + else if (field->data_size == sizeof(uint64_t)) + { + return pb_encode_fixed64(stream, field->pData); + } +#endif + else + { + PB_RETURN_ERROR(stream, "invalid data_size"); + } +} + +static bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + const pb_bytes_array_t *bytes = NULL; + + bytes = (const pb_bytes_array_t*)field->pData; + + if (bytes == NULL) + { + /* Treat null pointer as an empty bytes field */ + return pb_encode_string(stream, NULL, 0); + } + + if (PB_ATYPE(field->type) == PB_ATYPE_STATIC && + bytes->size > field->data_size - offsetof(pb_bytes_array_t, bytes)) + { + PB_RETURN_ERROR(stream, "bytes size exceeded"); + } + + return pb_encode_string(stream, bytes->bytes, (size_t)bytes->size); +} + +static bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + size_t size = 0; + size_t max_size = (size_t)field->data_size; + const char *str = (const char*)field->pData; + + if (PB_ATYPE(field->type) == PB_ATYPE_POINTER) + { + max_size = (size_t)-1; + } + else + { + /* pb_dec_string() assumes string fields end with a null + * terminator when the type isn't PB_ATYPE_POINTER, so we + * shouldn't allow more than max-1 bytes to be written to + * allow space for the null terminator. + */ + if (max_size == 0) + PB_RETURN_ERROR(stream, "zero-length string"); + + max_size -= 1; + } + + + if (str == NULL) + { + size = 0; /* Treat null pointer as an empty string */ + } + else + { + const char *p = str; + + /* strnlen() is not always available, so just use a loop */ + while (size < max_size && *p != '\0') + { + size++; + p++; + } + + if (*p != '\0') + { + PB_RETURN_ERROR(stream, "unterminated string"); + } + } + +#ifdef PB_VALIDATE_UTF8 + if (!pb_validate_utf8(str)) + PB_RETURN_ERROR(stream, "invalid utf8"); +#endif + + return pb_encode_string(stream, (const pb_byte_t*)str, size); +} + +static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + if (field->submsg_desc == NULL) + PB_RETURN_ERROR(stream, "invalid field descriptor"); + + if (PB_LTYPE(field->type) == PB_LTYPE_SUBMSG_W_CB && field->pSize != NULL) + { + /* Message callback is stored right before pSize. */ + pb_callback_t *callback = (pb_callback_t*)field->pSize - 1; + if (callback->funcs.encode) + { + if (!callback->funcs.encode(stream, field, &callback->arg)) + return false; + } + } + + return pb_encode_submessage(stream, field->submsg_desc, field->pData); +} + +static bool checkreturn pb_enc_fixed_length_bytes(pb_ostream_t *stream, const pb_field_iter_t *field) +{ + return pb_encode_string(stream, (const pb_byte_t*)field->pData, (size_t)field->data_size); +} + +#ifdef PB_CONVERT_DOUBLE_FLOAT +bool pb_encode_float_as_double(pb_ostream_t *stream, float value) +{ + union { float f; uint32_t i; } in; + uint_least8_t sign; + int exponent; + uint64_t mantissa; + + in.f = value; + + /* Decompose input value */ + sign = (uint_least8_t)((in.i >> 31) & 1); + exponent = (int)((in.i >> 23) & 0xFF) - 127; + mantissa = in.i & 0x7FFFFF; + + if (exponent == 128) + { + /* Special value (NaN etc.) */ + exponent = 1024; + } + else if (exponent == -127) + { + if (!mantissa) + { + /* Zero */ + exponent = -1023; + } + else + { + /* Denormalized */ + mantissa <<= 1; + while (!(mantissa & 0x800000)) + { + mantissa <<= 1; + exponent--; + } + mantissa &= 0x7FFFFF; + } + } + + /* Combine fields */ + mantissa <<= 29; + mantissa |= (uint64_t)(exponent + 1023) << 52; + mantissa |= (uint64_t)sign << 63; + + return pb_encode_fixed64(stream, &mantissa); +} +#endif diff --git a/project_old/paint_robot_old/BASE/Src/BSP/tcp_server.c b/project_old/paint_robot_old/BASE/Src/BSP/tcp_server.c new file mode 100644 index 0000000..5d17443 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/BSP/tcp_server.c @@ -0,0 +1,251 @@ +#include "tcp_server.h" +#include "lwip/tcp.h" +#include "lwip/memp.h" +#include +#include "lwip.h" + +#include "string.h" +#include "bsp_UDP.h" +#include "bsp_DLT_Log.h" +#include +#include "BSP/bsp_GPIO.h" +static client_conn_t clients[MAX_CLIENTS]; +static struct tcp_pcb *server_pcb = NULL; +void send_tcp(SendDataNode **head); +// 回调函数声明 +static err_t tcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err); +static err_t tcp_recv_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, + err_t err); +static void tcp_err_cb(void *arg, err_t err); +static void tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len); +SendDataNode *pTcpHead = NULL; /*初始化链表头指针,使其为空*/ +void tcp_server_timer_callback(); +char listIndex = 0; +SendDataNode* CreateSendDataNode(uint8_t *tx_Buf, uint8_t tx_count) +{ + SendDataNode *newNode = (SendDataNode*) malloc(sizeof(SendDataNode)); + if (newNode == NULL) + { + return NULL; + } + memcpy(newNode->Tx_Buf, tx_Buf, tx_count); + newNode->Tx_Count = tx_count; + newNode->next = NULL; + return newNode; +} + +void insertAtTail(SendDataNode **head, uint8_t *tx_Buf, uint8_t tx_count) +{ + SendDataNode *newNode = CreateSendDataNode(tx_Buf, tx_count); + // 如果链表为空 + if (*head == NULL) + { + + *head = newNode; + return; + } + listIndex = 0; + // 遍历到链表尾部 + SendDataNode *current = *head; + while (current->next != NULL) + { +// listIndex++; +// if (listIndex >= 50) +// { +// free(current); +// return; +// } + current = current->next; + } + //SendDataNode *newNode = CreateSendDataNode(tx_Buf, tx_count); + current->next = newNode; // 尾部节点指向新节点 + +} + +void tcp_add_sendList(uint8_t *tx_Buf, uint8_t tx_count) +{ + + for (int i = 0; i < MAX_CLIENTS; i++) + { + if (clients[i].active) + { + insertAtTail(&pTcpHead, tx_Buf, tx_count); + return; + } + } +} + +void send_tcp(SendDataNode **head) +{ + if (*head == NULL) + { + return; + } + tcp_send_to_all_clients((*head)->Tx_Buf, (*head)->Tx_Count); + SendDataNode *temp = *head; + *head = (*head)->next; + free(temp); + +} + +// 初始化TCP服务器 +void tcp_server_init(uint16_t port) +{ + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, + tcp_server_timer_callback); + err_t err; + + // 创建TCP控制块 + server_pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); + if (!server_pcb) return; + + // 绑定到指定端口 + err = tcp_bind(server_pcb, IP_ANY_TYPE, port); + if (err != ERR_OK) + { + memp_free(MEMP_TCP_PCB, server_pcb); + server_pcb = NULL; + return; + } + + // 开始监听 + server_pcb = tcp_listen(server_pcb); + if (!server_pcb) return; + + // 设置接受连接回调 + tcp_accept(server_pcb, tcp_accept_cb); + + // 初始化客户端数组 + memset(clients, 0, sizeof(clients)); + +} + +// 接受新连接回调 +static err_t tcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) +{ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(err); + + // 查找空闲的客户端槽位 + int free_index = -1; + for (int i = 0; i < MAX_CLIENTS; i++) + { + if (!clients[i].active) + { + free_index = i; + break; + } + } + + if (free_index == -1) + { + // 没有可用槽位,拒绝连接 + tcp_abort(newpcb); + return ERR_ABRT; + } + + // 配置新连接 + tcp_setprio(newpcb, TCP_PRIO_MIN); + tcp_recv(newpcb, tcp_recv_cb); + tcp_err(newpcb, tcp_err_cb); + tcp_sent(newpcb, tcp_sent_cb); + + // 保存客户端信息 + clients[free_index].pcb = newpcb; + clients[free_index].active = 1; + + return ERR_OK; +} + +// 接收数据回调 +static err_t tcp_recv_cb(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, + err_t err) +{ + LWIP_UNUSED_ARG(arg); + + if (!p) + { + // 连接关闭 + for (int i = 0; i < MAX_CLIENTS; i++) + { + if (clients[i].pcb == tpcb) + { + clients[i].active = 0; + break; + } + } + tcp_close(tpcb); + return ERR_OK; + } + + // 处理接收到的数据(这里简单释放) + tcp_recved(tpcb, p->tot_len); + pbuf_free(p); + + return ERR_OK; +} + +// 错误回调 +static void tcp_err_cb(void *arg, err_t err) +{ + LWIP_UNUSED_ARG(err); + + for (int i = 0; i < MAX_CLIENTS; i++) + { + if (clients[i].pcb == arg) + { + clients[i].active = 0; + break; + } + } +} + +// 数据发送完成回调 +static void tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len) +{ + LWIP_UNUSED_ARG(arg); + LWIP_UNUSED_ARG(tpcb); + LWIP_UNUSED_ARG(len); + // 可在此实现流量控制 +} + +// 向所有活跃客户端发送数据 +void tcp_send_to_all_clients(const char *data, uint16_t len) +{ + for (int i = 0; i < MAX_CLIENTS; i++) + { + if (clients[i].active) + { + //clients[i].pcb->flags= +// err_t err = tcp_write(clients[i].pcb, data, len, +// TCP_WRITE_FLAG_COPY); + err_t err = tcp_write(clients[i].pcb, data, len, + TCP_WRITE_FLAG_COPY); + if (err == ERR_OK) + { + tcp_output(clients[i].pcb); + } + else + { + // 发送失败,关闭连接 + //clients[i].active = 0; + //tcp_close(clients[i].pcb); + } + } + } +} +int32_t counter = 0; +// 定时器回调(从主定时器中断调用) +void tcp_server_timer_callback() +{ + + counter++; + if (counter > 5) + { + counter = 0; + send_tcp(&pTcpHead); + }; + +} + diff --git a/project_old/paint_robot_old/BASE/Src/MSP/msp_LeiSai_ISV2_CAN.c b/project_old/paint_robot_old/BASE/Src/MSP/msp_LeiSai_ISV2_CAN.c new file mode 100644 index 0000000..7862e4a --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/MSP/msp_LeiSai_ISV2_CAN.c @@ -0,0 +1,390 @@ +/* + * msp_LeiSai_ISV2_CAN.c + * + * Created on: Oct 22, 2024 + * Author: akeguo + */ + +#include "msp_LeiSai_ISV2_CAN.h" +#include "BHBF_ROBOT.h" + + + + + + +double wheel_diameter_m = 0.260; //1m 260mm +double motor_pulses_rer_rotation = 10000; //1 pulse +double wheel_reduction_ratio = 70; +double wheel_001m_per_min_to_plus_per_s_ratio = 1;//mmm +double wheel_plus_per_s_to_m_per_min_ratio = 1; + +HardWareController *LeiSaiISV_HardController; +DispacherController *LeiSaiISV_DispacherController; + +LS_MotorParameters *LS_Motor[7]; +#define Wheel_Diameters 280 + + +void CANSendMessageSDO_ADD_To_SendList(int32_t MotorID, uint8_t Function, + uint16_t ControlWord, uint8_t subWord, int32_t ControlWordValue, + FDCANHandler *Motor_Controller, int32_t WaitTime); + +/* SDO 队列发送 + * @MotorID:COB-ID + * @Function: SDO命令字 + * @ControlWord:对象索引 + * @subWord:对象子索引 + * @ControlWordValue: 数据 + * CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, Motor_Controller, 100); + * */ +void CANSendMessageSDO_ADD_To_SendList(int32_t MotorID, uint8_t Function, + uint16_t ControlWord, uint8_t subWord, int32_t ControlWordValue, + FDCANHandler *Motor_Controller, int32_t WaitTime) +{ + //copy the corresponsiding data to the send Array + Motor_Controller->Tx_Buf[0] = Function; //FDCAN1 2b + memcpy(&Motor_Controller->Tx_Buf[1], &ControlWord, 2); //6040 + Motor_Controller->Tx_Buf[3] = subWord; //00 + memcpy(&Motor_Controller->Tx_Buf[4], &ControlWordValue, 4); + //send 8 bytes data + + Motor_Controller->AddCANSendList(Motor_Controller, 0x600 + MotorID, 8, + Motor_Controller->Tx_Buf, WaitTime, NULL); +} +/* + * 解析函数 + * */ +void LS_Analytic_Fun(int32_t MotorID, uint8_t *buffer) +{ + + uint16_t Function_code = (uint16_t) (buffer[1] | buffer[2] << 8); + switch (Function_code) + { + case 0x6064: + { + LS_Motor[MotorID]->Real_Position = (int) (buffer[4] + | (buffer[5]) << 8 | (buffer[6]) << 16 | (buffer[7] << 24)); + + if (LS_Motor[MotorID]->Start_Measuring == 1) + { + LS_Motor[MotorID]->Start_Measuring = 0; + LS_Motor[MotorID]->Number_Of_Rounds = 0; + + LS_Motor[MotorID]->Start_Measuring_Position =LS_Motor[MotorID]->Real_Position;//起始位置 + LS_Motor[MotorID]->Last_Real_Position =LS_Motor[MotorID]->Real_Position; //最后位置 + } + else + { + if (abs(LS_Motor[MotorID]->Real_Position- LS_Motor[MotorID]->Last_Real_Position) + >= 0x3fffffff) + { + if (LS_Motor[MotorID]->Real_Position > 0) + { + LS_Motor[MotorID]->Number_Of_Rounds -= 1; + } + else + { + LS_Motor[MotorID]->Number_Of_Rounds += 1; + } + } + } + + LS_Motor[MotorID]->Last_Real_Position = + LS_Motor[MotorID]->Real_Position; + + double CircleLength = 3.14 * wheel_diameter_m ; //pi*d //m + + double _tempDeltCounts = LS_Motor[MotorID]->Real_Position + - LS_Motor[MotorID]->Start_Measuring_Position; + /**除10000是电机圈数 除70是车轮圈数*/ + LS_Motor[MotorID]->Real_Disatnce = (_tempDeltCounts / 10000 / 70 + + (double) LS_Motor[MotorID]->Number_Of_Rounds) + * CircleLength; + + } + + break; + case 0x603f: + LS_Motor[MotorID]->Motor_Fault = (int) (buffer[4] | (buffer[5]) << 8 + | (buffer[6]) << 16 | (buffer[7] << 24)); + + break; + + case 0x606C: + LS_Motor[MotorID]->Real_Velcity = (int) (buffer[4] + | (buffer[5]) << 8 | (buffer[6]) << 16 | (buffer[7] << 24)); + break; + + default: + + break; + } +} + +/* DO输出 + * @Do: 1/2 + * @state: 1:ON; 0:OFF; + * */ +void LS_DO_Set(int32_t MotorID, int32_t Do, uint8_t state, + FDCANHandler *Motor_Controller, int32_t WaitTime) +{ + uint16_t ControlWord = 0; + int32_t ControlWordValue = 0; + switch (Do) + { + case 1: + { + + ControlWord = 0x2410; + break; + } + case 2: + { + + ControlWord = 0x2411; + break; + } + default: + break; + } + if (ControlWord != 0) + { + if (state == 1) + { + ControlWordValue = 1; + } + else + { + ControlWordValue = 0; + } + } + + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, ControlWord, 0x00, + ControlWordValue, Motor_Controller, WaitTime); + //uint8_t DO1_ON[8]= {0x23, 0x10, 0x24, 0x00, 0x01, 0x00, 0x00, 0x00}; + //uint8_t DO1_OFF[8]={0x23, 0x10, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00}; +} + +void LS_Set_Current_Positon_Zero(uint8_t MotorID, + FDCANHandler *Motor_Controller, int32_t WaitTime) // Home 设置当前位置为零点 +{ + + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2f, 0x6060, 0x00, 0x06, + Motor_Controller, WaitTime); //2:设置操作模式,向索引0x6060:00写入0x06 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2f, 0x6098, 0x00, 0x23, + Motor_Controller, WaitTime); //1. 设置定位的方式,向索引0x6098:00写入0X23 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, + Motor_Controller, WaitTime); + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x07, + Motor_Controller, WaitTime); + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x0f, + Motor_Controller, WaitTime); + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x1f, + Motor_Controller, 8 * WaitTime); +// CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x07, Motor_Controller, WaitTime); +// CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, Motor_Controller, WaitTime); + +} + +/*5004 06 watchdog 1000ms*/ +void LS_Set_WatchDogTime(int32_t MotorID, FDCANHandler *Motor_Controller, + int32_t WaitTime) +{ + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2B, 0x5004, 0x06, 0x03E8, + Motor_Controller, WaitTime); +} + +/* 读电机位置 (单位pulse) + * */ +void LS_Request_Position(int32_t MotorID, FDCANHandler *Motor_Controller, + int32_t WaitTime) +{ + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x40, 0x6064, 0x00, 0x00, + Motor_Controller, WaitTime); +} + +/* 读电机速度(单位pulse/s) + * */ +void LS_Request_Velocity(int32_t MotorID, FDCANHandler *Motor_Controller, + int32_t WaitTime) +{ + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x40, 0x606C, 0x00, 0x00, + Motor_Controller, WaitTime); + +} + +/* 读电机电流(单位 ) 此处为实际转矩 + * */ +void LS_Request_Current(int32_t MotorID, FDCANHandler *Motor_Controller, + int32_t WaitTime) +{ + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x40, 0x6077, 0x00, 0x00, + Motor_Controller, WaitTime); +} + +/* 读错误码 + * */ +void LS_Request_Fault(int32_t MotorID, FDCANHandler *Motor_Controller, + int32_t WaitTime) +{ + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x40, 0x603f, 0x00, 0, + Motor_Controller, WaitTime); +} + +/* 复位所有节点*/ +void LS_Reset_All_Motors(FDCANHandler *Motor_Controller, int32_t WaitTime) +{ + Motor_Controller->SendFrameID=0; + Motor_Controller->SendLength=8; + memset(Motor_Controller->Tx_Buf, 0, 8); + Motor_Controller->Tx_Buf[0] = 0x81; + Motor_Controller->AddCANSendList(Motor_Controller, 0, 2, + Motor_Controller->Tx_Buf, WaitTime, NULL); + +} +/* 启动所有节点的远程控制 */ +void LS_Activate_All_Motors(FDCANHandler *Motor_Controller, int32_t WaitTime) +{ + Motor_Controller->SendFrameID=0; + Motor_Controller->SendLength=8; + + memset(Motor_Controller->Tx_Buf, 0, 8); + Motor_Controller->Tx_Buf[0] = 0x01; + Motor_Controller->Tx_Buf[1] = 0x01; + + Motor_Controller->AddCANSendList(Motor_Controller, 0, 2, + Motor_Controller->Tx_Buf, WaitTime, NULL); //wait for 5 seconds to send + + memset(Motor_Controller->Tx_Buf, 0, 8); + Motor_Controller->Tx_Buf[0] = 0x01; + Motor_Controller->Tx_Buf[1] = 0x02; + + Motor_Controller->AddCANSendList(Motor_Controller, 0, 2, + Motor_Controller->Tx_Buf, WaitTime, NULL); //wait for 5 seconds to send + +} + +/* 速度模式 + * MotorID:电机ID + * Motor_Controller:FDCANHandler + * WaitTime: + * Acc:加速度 (单位为pulse/s2)//不用 + * Dec:减速度 (单位为pulse/s2)不用 + * TargetSpeed:(单位pulse/s) + * 只发送一次 + * */ +void LS_SpeedModeSetup(int32_t MotorID, FDCANHandler *Motor_Controller, + int32_t WaitTime, int32_t AccTime, int32_t DecTime, int32_t TargetSpeed) //设定速度模式,并更改相关速度 +{ + //写控制字0x6040为06H,状态机切换状态 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, + Motor_Controller, 100); + //写控制字为07H,状态机切换状态 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x07, + Motor_Controller, WaitTime); + //写控制字为0fH,状态机切换状态 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x0F, + Motor_Controller, WaitTime); + //写操作模式0x6060为3H,即速度控制模式 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2f, 0x6060, 0x00, 0x03, + Motor_Controller, WaitTime); + +// //写协议加速度为3D090H(即1秒加速到1500转/分,默认10000PP/r”)(单位为pulse/s2)。 +// CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x6083, 0x00, AccTime, Motor_Controller, WaitTime); +// //写协议减速度为3D090H(即1秒加速到1500转/分,默认10000PP/r”)(单位为pulse/s2)。 +// CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x6084, 0x00, DecTime, Motor_Controller, WaitTime); +// //写协议速度为3D090H(即1500转/分,默认10000PP/r”)(单位pulse/s) + + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x60ff, 0x00, TargetSpeed, + Motor_Controller, 4*WaitTime); + //写控制字为07H,状态机切换状态 + //CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, Motor_Controller, WaitTime); + //写控制字为06H,状态机切换状态 + //CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, Motor_Controller, WaitTime); + +} + +/* 速度模式 + * 设置目标速度 + *TargetSpeed:(单位pulse/s) + * */ +void LS_SpeedMode_Set_TargetSpeed(int32_t MotorID, + FDCANHandler *Motor_Controller, int32_t WaitTime, int32_t TargetSpeed) +{ + //写协议速度为3D090H(即1500转/分,默认10000PP/r”)(单位pulse/s) + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x60ff, 0x00, TargetSpeed, + Motor_Controller, WaitTime); +} + +/* 位置速度模式 + * MotorID:电机ID + * Motor_Controller:FDCANHandler + * WaitTime: + * Acc:加速度 + * Dec:减速度 + * TargetSpeed:(单位pulse/s) + * TargetPosition :(单位pulse) + * */ +void LS_PostionModeSetUp(int32_t MotorID, int32_t TargetPosition, + int32_t TargetSpeed, int32_t AccTime, int32_t DecTime, + FDCANHandler *Motor_Controller, int32_t WaitTime) +{ + //写控制字0x6040为06H,状态机切换状态 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, + Motor_Controller, 100); + //写控制字为07H,状态机切换状态 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6060, 0x00, 0x07, + Motor_Controller, WaitTime); + //写控制字为0fH,状态机切换状态 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x0F, + Motor_Controller, WaitTime); + //写操作模式0x6060为3H,即速度控制模式 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2f, 0x6060, 0x00, 0x01, + Motor_Controller, WaitTime); + //写协议加速度为3D090H(即1秒加速到1500转/分,默认10000PP/r”)(单位为pulse/s2)。 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x6083, 0x00, AccTime, + Motor_Controller, WaitTime); + //写协议减速度为3D090H(即1秒加速到1500转/分,默认10000PP/r”)(单位为pulse/s2)。 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x6084, 0x00, DecTime, + Motor_Controller, WaitTime); + //写协议速度为3D090H(即1500转/分,默认10000PP/r”)(单位pulse/s) + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x60ff, 0x00, TargetSpeed, + Motor_Controller, WaitTime); + //写目标位置为4E20H(即2圈,默认10000PP/r”) + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x607a, 0x00, + TargetPosition, Motor_Controller, WaitTime); + //写控制字为4fH,设置为相对运动模式 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x4F, + Motor_Controller, WaitTime); + //写控制字为5fH,电机开始运动 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x5F, + Motor_Controller, WaitTime); + //写控制字为07H,状态机切换状态 + //CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, Motor_Controller, WaitTime); + //写控制字为06H,状态机切换状态 + //CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x06, Motor_Controller, WaitTime); + +} + +/* 位置速度模式 + * MotorID:电机ID + * Motor_Controller:FDCANHandler + * WaitTime: + * TargetPosition :(单位pulse) + * */ +void LS_PostionMode_Set_Position(int32_t MotorID, int32_t TargetPosition, + FDCANHandler *Motor_Controller, int32_t WaitTime) +{ + //写目标位置为4E20H(即2圈,默认10000PP/r”) + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x23, 0x607a, 0x00, + TargetPosition, Motor_Controller, WaitTime); + //写控制字为4fH,设置为相对运动模式 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x4F, + Motor_Controller, WaitTime); + //写控制字为5fH,电机开始运动 + CANSendMessageSDO_ADD_To_SendList(MotorID, 0x2b, 0x6040, 0x00, 0x5F, + Motor_Controller, WaitTime); + +} + diff --git a/project_old/paint_robot_old/BASE/Src/MSP/msp_MK32_1.c b/project_old/paint_robot_old/BASE/Src/MSP/msp_MK32_1.c new file mode 100644 index 0000000..84dcb72 --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/MSP/msp_MK32_1.c @@ -0,0 +1,118 @@ +/* + * msp_MK32_1.c + * + * Created on: Oct 8, 2024 + * Author: akeguo + */ +#include "MSP/msp_MK32_1.h" +#include "BHBF_ROBOT.h" + +char Is_All_Button_Reset = 0; +SP_MSP_MK32_Button *P_MK32; + +struct UARTHandler *MK32_Sbus_Controller; + +void decode_MK32Data(uint8_t *buffer, uint16_t length) +{ + if (length != 25) + { + return; + } + if (buffer[0] == 0X0f && buffer[24] == 0X00) + { + Sbus_Data_Count(&buffer[1], (int32_t*) (P_MK32)); + } +// int32_t RxIndex; +// int32_t CH0_RY_H; /* 上1000,下-1000 */ +// int32_t CH1_RY_V; /* 上1000,下-1000 */ +// int32_t CH2_LY_V; /* 上1000,下-1000 */ +// int32_t CH3_LY_H; /* 上1000,下-1000 */ +// int32_t CH4_SA; /* 上-1000,下1000 */ +// int32_t CH5_SB; /* 上-1000,下1000 */ +// int32_t CH6_SC; /* 上-1000,下1000 */ +// int32_t CH7_SD; /* 上-1000,下1000 */ +// int32_t CH8_SE; /* 上-1000,下1000 */ +// int32_t CH9_SF; /* 上-1000,下1000 */ +// int32_t CH10_LD1; +// int32_t CH11_RD1; +// int32_t CH12_S1; +// int32_t CH13_S2; +// int32_t CH14_LT; +// int32_t CH15_RT; +// int32_t IsOnline; + + if (Is_All_Button_Reset == 0) + { + if (P_MK32->CH4_SA == 0 && P_MK32->CH5_SB == 0 && P_MK32->CH6_SC == 0 + && P_MK32->CH7_SD == 0 && P_MK32->IsOnline == 1) + { + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController, + "Need_To_Reset", 1); + Is_All_Button_Reset = 1; + } + } + else if (Is_All_Button_Reset == 1) + { + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController, + "Need_To_Reset", 1); + } + + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController, + "mk32_sbus", 1); + +} + +void Sbus_Data_Count(uint8_t *buf, int32_t *But_Value) +{ + + int16_t CH[16]; + int Start_byte = -1; + + CH[0] = ((buf[Start_byte + 1] | buf[Start_byte + 2] << 8) & 0x07FF); + CH[1] = ((buf[Start_byte + 2] >> 3 | buf[Start_byte + 3] << 5) & 0x07FF); + CH[2] = ((buf[Start_byte + 3] >> 6 | buf[Start_byte + 4] << 2 + | buf[Start_byte + 5] << 10) & 0x07FF); + CH[3] = ((buf[Start_byte + 5] >> 1 | buf[Start_byte + 6] << 7) & 0x07FF); + CH[4] = ((buf[Start_byte + 6] >> 4 | buf[Start_byte + 7] << 4) & 0x07FF); + CH[5] = ((buf[Start_byte + 7] >> 7 | buf[Start_byte + 8] << 1 + | buf[Start_byte + 9] << 9) & 0x07FF); + CH[6] = ((buf[Start_byte + 9] >> 2 | buf[Start_byte + 10] << 6) & 0x07FF); + CH[7] = ((buf[Start_byte + 10] >> 5 | buf[Start_byte + 11] << 3) & 0x07FF); + CH[8] = ((buf[Start_byte + 12] | buf[Start_byte + 13] << 8) & 0x07FF); + CH[9] = ((buf[Start_byte + 13] >> 3 | buf[Start_byte + 14] << 5) & 0x07FF); + CH[10] = ((buf[Start_byte + 14] >> 6 | buf[Start_byte + 15] << 2 + | buf[Start_byte + 16] << 10) & 0x07FF); + CH[11] = ((buf[Start_byte + 16] >> 1 | buf[Start_byte + 17] << 7) & 0x07FF); + CH[12] = ((buf[Start_byte + 17] >> 4 | buf[Start_byte + 18] << 4) & 0x07FF); + CH[13] = ((buf[Start_byte + 18] >> 7 | buf[Start_byte + 19] << 1 + | buf[Start_byte + 20] << 9) & 0x07FF); + CH[14] = ((buf[Start_byte + 20] >> 2 | buf[Start_byte + 21] << 6) & 0x07FF); + CH[15] = ((buf[Start_byte + 21] >> 5 | buf[Start_byte + 22] << 3) & 0x07FF); + + //按键数值:1050为中间值,272-1712 + for (int i = 0; i < 16; i++) + { + But_Value[i + 1] = (int32_t) ((CH[i] - 992) * 1.388889); + } + + //遥控器地面站在线状态 + if (buf[22] == 0) But_Value[17] = 1; + else + But_Value[17] = 0; + + But_Value[0]++; +} + +void MK32_Sbus_UART_Handler_intialize(struct UARTHandler *Handler) +{ + MK32_Sbus_Controller = Handler; + MK32_Sbus_Controller->UART_Decode = decode_MK32Data; + MK32_Sbus_Controller->Wait_time = 4; + MK32_Sbus_Controller->dispacherController->Dispacher_Enable = 0; //不周期性发送 + + HardWareErrorController->Add_PCOMHardWare(HardWareErrorController, + "Need_To_Reset", 0, ComError_Remote_Button_Reset_State); + HardWareErrorController->Add_PCOMHardWare(HardWareErrorController, + "mk32_sbus", 0, ComError_MK32_SBus); + LOG("MK32_Sbus_intialize"); +} diff --git a/project_old/paint_robot_old/BASE/Src/MSP/msp_PID.c b/project_old/paint_robot_old/BASE/Src/MSP/msp_PID.c new file mode 100644 index 0000000..55c817d --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/MSP/msp_PID.c @@ -0,0 +1,96 @@ +/* + * msp_PID.c + * + * Created on: 2024年1月18日 + * Author: Administrator + */ + +#include "MSP/msp_PID.h" +#include + +void Speedl_PID(double CurrentValue, double TargetValue, double Sys_T, + double *Gain_speed); +double Desire_Angle = 0; +double PID_KP = 50; +double PID_KD = 12; +//double Sys_T=0.01;//System time +double k_1_error = 0; + + +/* PID + * CurrentAngle :0.01度 + * TargetAngle :0.01度 + * MaxValue :0.1rpm + * */ +double Angle_Tune_PID(double CurrentAngle, double TargetAngle, double Position_KP, + double Position_KI, double Position_KD, double MaxValue) +{ + static double Bias, delta_Speed, Integral_bias, Last_Bias; + /* + if (TargetValue - CurrentValue >= 180) + { + Bias = (TargetValue - CurrentValue) - 360; + } + if (pidTargetValue - pidCurrentValue <= -180) + { + Bias = TargetValue - CurrentValue + 360; + } + */ + + Bias = CurrentAngle - TargetAngle; + Integral_bias += Bias; + + + delta_Speed = Position_KP * Bias + Position_KI * Integral_bias + + Position_KD * (Bias - Last_Bias); + Last_Bias = Bias; + if (delta_Speed >= MaxValue) + { + delta_Speed = MaxValue; + } + if (delta_Speed <= -MaxValue) + { + delta_Speed = -MaxValue; + } + + return delta_Speed; +} + + + +//喷漆机器人PID算法 +int32_t PositionalPID(double pidTargetValue, double pidCurrentValue, double Kp, + double Kd) +{ + double Error = 0; + double P_Error = 0; + double I_Error = 0; + double D_Error = 0; + double delta = 0; + + Error = pidTargetValue - pidCurrentValue; + // + if (pidTargetValue - pidCurrentValue >= 180) + { + Error = (pidTargetValue - pidCurrentValue) - 360; + } + if (pidTargetValue - pidCurrentValue <= -180) + { + Error = pidTargetValue - pidCurrentValue + 360; + } + //计算误差 + P_Error = Error; //比例环节 + + D_Error = Error - k_1_error; //微分环节 + + //deltaSpeed = Kp * P_Error + Ki * I_Error + Kd * D_Error; //计算Speed输出值 + + delta = Kp * P_Error + Kd * D_Error; + + k_1_error = Error; + + return (int32_t) (delta); +} + + + diff --git a/project_old/paint_robot_old/BASE/Src/MSP/msp_TL720D.c b/project_old/paint_robot_old/BASE/Src/MSP/msp_TL720D.c new file mode 100644 index 0000000..d7e715d --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/MSP/msp_TL720D.c @@ -0,0 +1,114 @@ +/* + * msp_TL720D.c + * + * Created on: Jul 19, 2024 + * Author: bihon + */ + +#include "MSP/msp_TL720D.h" +#include "BHBF_ROBOT.h" +#include "msp_TL720D.pb.h" + +//Roll:0.01° +int32_t *RobotAngle; + +struct UARTHandler *TL720D_UART_Handler; + +MSP_TL720DParameters* SP_MSP_RF_TL720D_Parameters_In; + + + +void decode_TL720D(uint8_t *buffer, uint16_t length); +int16_t getDeci(uint8_t *data); + +void TL720D_intialize(struct UARTHandler *Handler) +{ + + //TL720D_UART_Handler->UART_Decode = NULL; + TL720D_UART_Handler = Handler; + TL720D_UART_Handler->Wait_time=6; + TL720D_UART_Handler->dispacherController->Dispacher_Enable=0;//不周期性发送 + TL720D_UART_Handler->UART_Decode = decode_TL720D; + HardWareErrorController->Add_PCOMHardWare(HardWareErrorController,"TL720D",0,ComError_TL720D); + //log_info("TL720D_intialize"); + LOGFF(DL_ERROR,"TL720D_intialize"); +} +void decode_TL720D(uint8_t *buffer, uint16_t length) +{ + + + if(length<32) + { + return; + } + uint8_t check_sum = 0; + // 遍历除SOF(0号字节)和校验和(31号字节)之外的所有待校验字节 + for(uint8_t i = 1; i < 31; i++) + { + check_sum += buffer[i]; + } + // 校验和不匹配则直接丢弃该帧,避免错误数据被解析 + if(check_sum != buffer[31]) + { + return; + } + if (buffer[0] == 0x68 && buffer[1] == 0x1F && buffer[2] == 0x00 + && buffer[3] == 0x84) + { + //SP_MSP_RF_TL720D_Parameters_In. + SP_MSP_RF_TL720D_Parameters_In->RF_Angle_Roll = getDeci(&buffer[4]); + SP_MSP_RF_TL720D_Parameters_In->RF_Angle_Pitch = getDeci(&buffer[7]); + SP_MSP_RF_TL720D_Parameters_In->RF_Angle_Yaw = getDeci(&buffer[10]); + SP_MSP_RF_TL720D_Parameters_In->RF_Acc_X = getDeci(&buffer[13]); + SP_MSP_RF_TL720D_Parameters_In->RF_Acc_Y = getDeci(&buffer[16]); + SP_MSP_RF_TL720D_Parameters_In->RF_Acc_Z = getDeci(&buffer[19]); + SP_MSP_RF_TL720D_Parameters_In->RF_Gro_X = getDeci(&buffer[22]); + SP_MSP_RF_TL720D_Parameters_In->RF_Gro_Y = getDeci(&buffer[25]); + SP_MSP_RF_TL720D_Parameters_In->RF_Gro_Z = getDeci(&buffer[28]); + + *RobotAngle=SP_MSP_RF_TL720D_Parameters_In->RF_Angle_Roll; + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController,"TL720D",1); + + LOGF(DL_INFO,"decode angle succeed,and the angle is %d ",SP_MSP_RF_TL720D_Parameters_In->RF_Angle_Roll); + } + else + { + LOGF(DL_ERROR,"TL720D decoding failed"); + } +} + +/* 数值计算 + * data: 数据地址 + * return: 单位: 0.01 + * */ +int16_t getDeci(uint8_t *data) +{ + char isNegative = 0; + + if (*data >> 4) + { + isNegative = 1; + } else + { + isNegative = 0; + } + + int16_t data_value = 0; + data_value = ((*data) & 0x0f) * 10000; + data++; + data_value += (*data >> 4) * 1000; + data_value += ((*data) & 0x0f) * 100; + data++; + + int16_t xiaoshu = 0; + xiaoshu = (*data >> 4) * 10; + xiaoshu += (*data) & 0x0f; + if (isNegative) + { + return -(data_value + xiaoshu); + } else + { + return (data_value + xiaoshu); + } + +} diff --git a/project_old/paint_robot_old/BASE/Src/MSP/msp_WH_LTE_7S0.c b/project_old/paint_robot_old/BASE/Src/MSP/msp_WH_LTE_7S0.c new file mode 100644 index 0000000..5e8e5da --- /dev/null +++ b/project_old/paint_robot_old/BASE/Src/MSP/msp_WH_LTE_7S0.c @@ -0,0 +1,98 @@ + +#include "BHBF_ROBOT.h" +#include "bsp_decode_command.h" +#include "gpio.h" + +#include "BSP/bsp_UART.h" + +#include + + +char NeedToFeedBackToComputer = 0; + +struct UARTHandler *wh_LTE_7S0_Handler; +DispacherController* wh_LTE_7S0_dispacher; + + +void Reset() +{ + HAL_GPIO_WritePin(S0_RESET_GPIO_Port, S0_RESET_Pin, GPIO_PIN_RESET); +} +void NormalState() +{ + HAL_GPIO_WritePin(S0_RESET_GPIO_Port, S0_RESET_Pin, GPIO_PIN_SET); +} +void WH_LTE_7S0_intialize(struct UARTHandler *Handler) +{ + //NormalState(); + HAL_GPIO_WritePin(S0_RESET_GPIO_Port, GPIO_PIN_10, GPIO_PIN_SET); + wh_LTE_7S0_Handler = Handler; + wh_LTE_7S0_Handler->Wait_time = 40; // 最低不要低于4; + wh_LTE_7S0_dispacher=Handler->dispacherController; + //不周期性发送 + wh_LTE_7S0_dispacher->Dispacher_Enable=1; + wh_LTE_7S0_dispacher->Add_Dispatcher_List(wh_LTE_7S0_dispacher,UpdateGV); + wh_LTE_7S0_dispacher->DispacherCallTime=1000; + //DispacherController* disp=wh_LTE_7S0_Handler->dispacherController; + + //disp->Add_Dispatcher_List(disp,UpdateGV);//周期性update GV数据 + + LOG("WH_LTE_7S0_intialize"); + + wh_LTE_7S0_Handler->UART_Decode = decode_received_data_from_computer; //indicate that there is no need to listen + +} + +void Send_WH_LTE_7S0_Data(uint8_t *data, int length) +{ + + char datass[100]; + memcpy(datass, data, length); + wh_LTE_7S0_Handler->UART_Decode = decode_received_data_from_computer; + memcpy(wh_LTE_7S0_Handler->Tx_Buf, data, length); + wh_LTE_7S0_Handler->TxCount = length; + wh_LTE_7S0_Handler->UART_Tx(wh_LTE_7S0_Handler); + +} +void UpdateGV() +{ + + //wh_LTE_7S0_Handler->UART_Decode = decode_received_data_from_computer; + pb_ostream_t GV_o_stream = + { 0 }; + char buf[1024]; + GV_o_stream = pb_ostream_from_buffer(buf, sizeof(buf)); + pb_encode(&GV_o_stream, GV_struct_define_fields, &GV); + + + memcpy(&wh_LTE_7S0_Handler->Tx_Buf[2], buf, GV_o_stream.bytes_written); + wh_LTE_7S0_Handler->Tx_Buf[0]='1'; + wh_LTE_7S0_Handler->Tx_Buf[1]=','; + //wh_LTE_7S0_Handler->Tx_Buf[2]='1'; + + wh_LTE_7S0_Handler->TxCount = GV_o_stream.bytes_written+2; + wh_LTE_7S0_Handler->UART_Tx(wh_LTE_7S0_Handler); +} + +void decode_received_data_from_computer(uint8_t *buffer, uint16_t length) +{ + char buf[1024]; + memcpy(buf, buffer, length); + if(buffer[0]=='2'&&buffer[1]==',') + { + //Decode protobuf + //decode_command_from_computer(buffer+2,length-2); + decode_command_and_feedback(buffer+2,length-2,1,wh_LTE_7S0_Handler); + + } + if(NeedToFeedBackToComputer==1) + { + send_received_data_to_upper_computer(buffer, length); + } + +} + + + + + diff --git a/project/paint_robot_old/CMakeLists.txt b/project_old/paint_robot_old/CMakeLists.txt similarity index 100% rename from project/paint_robot_old/CMakeLists.txt rename to project_old/paint_robot_old/CMakeLists.txt diff --git a/project_old/paint_robot_old/FSM/Inc/change_line_control.h b/project_old/paint_robot_old/FSM/Inc/change_line_control.h new file mode 100644 index 0000000..e1e08a8 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Inc/change_line_control.h @@ -0,0 +1,56 @@ +/* + * change_line_control.h + * + * Created on: 2025年8月12日 + * Author: xsq + */ + +#ifndef FSM_INC_CHANGE_LINE_CONTROL_H_ +#define FSM_INC_CHANGE_LINE_CONTROL_H_ + + +typedef enum _vertical_LaneChangeState +{ + VerticalChange_TurnToUP, + VerticalChange_TurnToDown, + VerticalChange_TurnToLeft, + VerticalChange_TurnToRight, + VerticalChange_DelayMove, + VerticalChange_End, + VerticalChange_StateZero, + //0---6 +} Lane_Vertical_ChangeState; +/**********************************************************/ +typedef enum _horizontal_LaneChangeState +{ + HorizontalChange_TurnToUP, + HorizontalChange_TurnToDown, + HorizontalChange_TurnToLeft, + HorizontalChange_TurnToRight, + HorizontalChange_DelayMove, + HorizontalChange_End, + HorizontalChange_StateZero, + +} Lane_Horizontal_ChangeState; +/***********************************************************************/ +//设置 换道距离和设置后退距离 +typedef enum _laneChangeControlSTATE_t +{ + Lane_Change_Stop = 0, Lane_Change_Start, + +} LaneChangeControlSTATE; +/*****************************************************************************/ +extern Lane_Vertical_ChangeState Current_Vertical_ChangeState; + +extern LaneChangeControlSTATE VerticalLaneChangeState; /*当前换道处于开始或者结束*/ +extern int LaneChangeControl_Paint(); + + + +extern void Vertical_Lane_Change_From_Left_To_Right_UP_Control(); +extern void Vertical_Lane_Change_From_Left_To_Right_Down_Control(); +extern void Vertical_Lane_Change_From_Right_To_Left_UP_Control(); +extern void Vertical_Lane_Change_From_Right_To_Left_Down_Control(); + +extern int LaneChangeWaittime ; +#endif /* FSM_INC_CHANGE_LINE_CONTROL_H_ */ diff --git a/project_old/paint_robot_old/FSM/Inc/fsm_state.h b/project_old/paint_robot_old/FSM/Inc/fsm_state.h new file mode 100644 index 0000000..2bd95b7 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Inc/fsm_state.h @@ -0,0 +1,44 @@ +/* + * fsm.h + * + * Created on: 2025年7月14日 + * Author: akeguo + */ + +#ifndef FSM_INC_FSM_STATE_H_ +#define FSM_INC_FSM_STATE_H_ +#include "stdint.h" +#include + + +struct _transition_t; +typedef struct _transition_t transition_t; + + +//抽象类,用于派生其他类 将事件处理方法包含在基类中 + +typedef struct _transition_state_t +{ + + void (*robotEnter)(transition_t* p_transition); //执行Enter 激活标志位 + void (*robotRun)(transition_t* p_transition); //执行相关动作 + void (*robotExit)(transition_t* p_transition); //执行Exit + int State; //状态 + +}transition_state_t; + + + +typedef struct _transition_t { + transition_state_t* p_state; +}transition_t; + + +extern void fsm_state_set(transition_t* p_this, transition_state_t* p_new_state); +extern void fsm_state_run(transition_t* p_this); + +extern void fsm_state_init(transition_t* p_this,transition_state_t* inti_state); + + + +#endif /* FSM_INC_FSM_STATE_H_ */ diff --git a/project_old/paint_robot_old/FSM/Inc/fsm_state_control.h b/project_old/paint_robot_old/FSM/Inc/fsm_state_control.h new file mode 100644 index 0000000..0f1281c --- /dev/null +++ b/project_old/paint_robot_old/FSM/Inc/fsm_state_control.h @@ -0,0 +1,24 @@ +/* + * fsm_state_control.h + * + * Created on: 2025年7月14日 + * Author: akeguo + */ + +#ifndef FSM_INC_FSM_STATE_CONTROL_H_ +#define FSM_INC_FSM_STATE_CONTROL_H_ + + + + + +void Fsm_Init(); +void GF_Dispatch(); + + +void IV_control(); +void MoveControl(); +int32_t GetVehicleSpeed( ); +extern int32_t speed_selection; +extern char is_upper_computer_take_over_control; +#endif /* FSM_INC_FSM_STATE_CONTROL_H_ */ diff --git a/project_old/paint_robot_old/FSM/Inc/motors.h b/project_old/paint_robot_old/FSM/Inc/motors.h new file mode 100644 index 0000000..2b45289 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Inc/motors.h @@ -0,0 +1,15 @@ +/* + * motors.h + * + * Created on: Nov 11, 2024 + * Author: akeguo + */ +#ifndef FSM_INC_MOTORS_H_ +#define FSM_INC_MOTORS_H_ + + +#include "bsp_FDCAN.h" +#include "bsp_Error_Detect.h" +#include "BHBF_ROBOT.h" + +#endif diff --git a/project_old/paint_robot_old/FSM/Inc/motors_power_action.h b/project_old/paint_robot_old/FSM/Inc/motors_power_action.h new file mode 100644 index 0000000..fa01361 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Inc/motors_power_action.h @@ -0,0 +1,31 @@ +/* + * motors_power_action.h + * + * Created on: 2025年7月14日 + * Author: akeguo + */ + +#ifndef FSM_INC_MOTORS_POWER_ACTION_H_ +#define FSM_INC_MOTORS_POWER_ACTION_H_ + +#include "fsm_state.h" + + + + + +void Motors_Power_On_Do(transition_t *p_this); +void Motors_Power_Off_Do(transition_t *p_this); +void Motors_Power_On_Enter(transition_t *p_this); +void Motors_Power_On_Exit(transition_t *p_this); + + + +extern transition_t current_motor_power_state; + +extern transition_state_t motor_power_on_state; +extern transition_state_t motor_power_off_state; + + + +#endif /* FSM_INC_MOTORS_POWER_ACTION_H_ */ diff --git a/project_old/paint_robot_old/FSM/Inc/paint_gun_action.h b/project_old/paint_robot_old/FSM/Inc/paint_gun_action.h new file mode 100644 index 0000000..e4d0208 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Inc/paint_gun_action.h @@ -0,0 +1,22 @@ +/* + * paint_gun_action.h + * + * Created on: 2025年8月7日 + * Author: xsq + */ + +#ifndef FSM_INC_PAINT_GUN_ACTION_H_ +#define FSM_INC_PAINT_GUN_ACTION_H_ + +#include "fsm_state.h" +extern transition_t current_paintgun_state; +extern transition_state_t paintgun_on_state; +extern transition_state_t paintgun_off_state; +extern void PaintGun_ON_Do(); +extern void PaintGun_OFF_Do(); +extern void PaintGun_ON_Enter(); +extern void PaintGun_ON_Exit(); +extern void PaintGun_OFF_Enter(); +extern void PaintGun_OFF_Exit(); +extern char Paint_Gun_ButtonReset_Flag; //喷枪开启 1yes +#endif /* FSM_INC_PAINT_GUN_ACTION_H_ */ diff --git a/project_old/paint_robot_old/FSM/Inc/robot_move_actions.h b/project_old/paint_robot_old/FSM/Inc/robot_move_actions.h new file mode 100644 index 0000000..b6a6421 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Inc/robot_move_actions.h @@ -0,0 +1,69 @@ +/* + * robot_move_actions.h + * + * Created on: 2025年7月14日 + * Author: akeguo + */ + +#ifndef FSM_INC_ROBOT_MOVE_ACTIONS_H_ +#define FSM_INC_ROBOT_MOVE_ACTIONS_H_ +#include "BHBF_ROBOT.h" +#include "fsm_state.h" +#include "fsm_state.h" + + +extern void Forwards_State_Do(transition_t *p_this); +extern void Backwards_State_Do(transition_t *p_this); +extern void TurnLeft_State_Do(transition_t *p_this); +extern void TurnRight_State_Do(transition_t *p_this); +extern void HALT_State_Do(transition_t *p_this); + +extern void Move_Vertical_Task_Forwards_Do(transition_t *p_this); +extern void Move_Vertical_Task_Backwards_Do(transition_t *p_this); + +extern void Move_Horizontal_Task_Forwards_Right_Do(transition_t *p_this); +extern void Move_Horizontal_Task_Forwards_Left_Do(transition_t *p_this); +extern void Move_Horizontal_Task_Backwards_Right_Do(transition_t *p_this); +extern void Move_Horizontal_Task_Backwards_Left_Do(transition_t *p_this); + + +extern void Move_Head_To_UP_Do(transition_t *p_this); +extern void Move_Head_To_Down_Do(transition_t *p_this); +extern void Move_Head_To_Left_Do(transition_t *p_this); +extern void Move_Head_To_Right_Do(transition_t *p_this); + + +extern void HALT_State_Enter(transition_t *p_this); +extern void HALT_State_Exit(transition_t *p_this); + +extern int32_t GetVehicleSpeed(int speed_selection); + +extern int32_t* DHRoughening_Speed[10]; + + +extern transition_t current_robot_move_state; + +extern transition_state_t robot_halt_state; +extern transition_state_t robot_forwards_state; +extern transition_state_t robot_backwards_state; +extern transition_state_t robot_turn_left_state; +extern transition_state_t robot_turn_right_state; + +extern transition_state_t robot_move_vertical_task_forwards_state; +extern transition_state_t robot_move_vertical_task_backwards_state; + +extern transition_state_t robot_move_horizontal_task_forwards_left_state; /* 水平纠偏前进 头朝左*/ +extern transition_state_t robot_move_horizontal_task_backwards_left_state;/* 水平纠偏后退 头朝左*/ +extern transition_state_t robot_move_horizontal_task_forwards_right_state; /* 水平纠偏前进 头朝右*/ +extern transition_state_t robot_move_horizontal_task_backwards_right_state;/* 水平纠偏后退 头朝右*/ + + + +extern transition_state_t robot_move_head_to_left_enum_state; +extern transition_state_t robot_move_head_to_up_enum_state; +extern transition_state_t robot_move_head_to_right_enum_state; +extern transition_state_t robot_move_head_to_down_enum_state; + + +extern char IsRobotHaltSateChangedFlag; +#endif /* FSM_INC_ROBOT_MOVE_ACTIONS_H_ */ diff --git a/project_old/paint_robot_old/FSM/Src/change_line_control.c b/project_old/paint_robot_old/FSM/Src/change_line_control.c new file mode 100644 index 0000000..93e5abe --- /dev/null +++ b/project_old/paint_robot_old/FSM/Src/change_line_control.c @@ -0,0 +1,404 @@ +/* + * change_line_control.c + * + * Created on: 2025年8月12日 + * Author: xsq + */ +#include "change_line_control.h" +#include "BHBF_ROBOT.h" + +#define Veritical_To_Left_Flag 1 +#define Veritical_To_Right_Flag 2 + + +int LaneChangeWaittime_ms = 0; +/* + * return: ms + */ +int32_t RunTime_DistanceCm_SpeedE_2MPMin(); +int LaneChangeWaittime = 0; + +char LaneChangeFlage = -1; + + +Lane_Vertical_ChangeState Current_Vertical_ChangeState; + +LaneChangeControlSTATE VerticalLaneChangeState; /*当前换道处于开始或者结束*/ + +/* 手动换道 + * 换道依据当前车头朝向 + * */ +int LaneChangeControl_Paint() +{ +//机器人SA按键处于中间状态 + if (P_MK32->CH4_SA == 0) + { + VerticalLaneChangeState = Lane_Change_Start; + Current_Vertical_ChangeState = VerticalChange_StateZero; + + if (abs(GV.Robot_Angle - CV.RobotUpAngleValue) //头朝上 + <= 45 * 100) + { + if (GV.PV.RunMode == Move_Vertical_Move_To_Left) + { + LaneChangeFlage = Veritical_To_Left_Flag; + + } + if (GV.PV.RunMode == Move_Vertical_Move_To_Right) + { + LaneChangeFlage = Veritical_To_Right_Flag; + + } + return 0; + } + LaneChangeFlage = -1; + return 0; + } + + if (P_MK32->CH4_SA == -1000) /*竖直上or水平换道*/ + { + + if (GV.PV.RunMode != Move_Vertical_Move_To_Left + && GV.PV.RunMode != Move_Vertical_Move_To_Right)/*竖直换道*/ + { + return 0; + } + + + if (VerticalLaneChangeState != Lane_Change_Start) + { + fsm_state_set(¤t_robot_move_state, &robot_halt_state); + return 1; + } + + if (LaneChangeFlage == Veritical_To_Left_Flag) /*向左作业*/ + { + Vertical_Lane_Change_From_Right_To_Left_UP_Control(); /*竖直上换道*/ + return 1; + } + if (LaneChangeFlage == Veritical_To_Right_Flag) /*向右作业*/ + { + Vertical_Lane_Change_From_Left_To_Right_UP_Control(); /*竖直上换道*/ + return 1; + } + return 1; + + } + + if (P_MK32->CH4_SA == 1000) //竖直下换道 + { + if (GV.PV.RunMode != Move_Vertical_Move_To_Left + && GV.PV.RunMode != Move_Vertical_Move_To_Right) + { + return 0; + } + + if (VerticalLaneChangeState != Lane_Change_Start) /*换道结束了*/ + { + fsm_state_set(¤t_robot_move_state, &robot_halt_state); + return 1; + } + if (LaneChangeFlage == Veritical_To_Left_Flag) /*向左作业*/ + { + Vertical_Lane_Change_From_Right_To_Left_Down_Control(); /*竖直下换道*/ + return 1; + } + if (LaneChangeFlage == Veritical_To_Right_Flag) /*向右作业*/ + { + Vertical_Lane_Change_From_Left_To_Right_Down_Control(); /*竖直下换道*/ + return 1; + } + return 1; + } + + return 0; + +} + + + +/* 竖直从左往右作业 上端 向右换道 最终头朝上 + * */ +void Vertical_Lane_Change_From_Left_To_Right_UP_Control() +{ + + GV.Robot_Move_Speed = speed_M_min_toE01_M_min( CV.Lane_Change_Speed_m_per_min); + switch (Current_Vertical_ChangeState) + { + case VerticalChange_StateZero: + { + Current_Vertical_ChangeState = VerticalChange_TurnToLeft; + break; + } + case VerticalChange_TurnToLeft: + { + if (abs(GV.Robot_Angle - CV.RobotLeftAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_left_enum_state); /* 移动至头朝左 */ + } + else + { + + fsm_state_set(¤t_robot_move_state, + &robot_move_horizontal_task_backwards_left_state);/* 水平纠偏后退 头朝左*/ + //开启计时 + timer_handler_1.start_timer = 1; + Current_Vertical_ChangeState = VerticalChange_DelayMove; + } + break; + } + case VerticalChange_DelayMove: + { + LaneChangeWaittime = RunTime_DistanceCm_SpeedE_2MPMin(); + if (CompareTimer(LaneChangeWaittime, &timer_handler_1)) + { + + Current_Vertical_ChangeState = VerticalChange_TurnToUP; + } + break; + } + case VerticalChange_TurnToUP: + { + if (abs(GV.Robot_Angle - CV.RobotUpAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_up_enum_state); /* 移动至头朝上 */ + } + else + { + Current_Vertical_ChangeState = VerticalChange_End; + } + + break; + } + case VerticalChange_End: + { + VerticalLaneChangeState = Lane_Change_Stop; + break; + } + default: + break; + } +} + +/* 竖直从左往右作业 下端 向右换道 最终头朝上 + * */ +void Vertical_Lane_Change_From_Left_To_Right_Down_Control() +{ + + GV.Robot_Move_Speed = speed_M_min_toE01_M_min( CV.Lane_Change_Speed_m_per_min); + switch (Current_Vertical_ChangeState) + { + case VerticalChange_StateZero: + { + Current_Vertical_ChangeState = VerticalChange_TurnToRight; + + break; + } + case VerticalChange_TurnToRight: + { + if (abs(GV.Robot_Angle - CV.RobotRightAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_right_enum_state); /* 移动至头朝右 */ + } + else + { + + fsm_state_set(¤t_robot_move_state, + &robot_move_horizontal_task_forwards_right_state);/* 水平纠偏前进 头朝右*/ + //开启计时 + timer_handler_1.start_timer = 1; + Current_Vertical_ChangeState = VerticalChange_DelayMove; + } + break; + } + case VerticalChange_DelayMove: + { + LaneChangeWaittime = RunTime_DistanceCm_SpeedE_2MPMin(); + if (CompareTimer(LaneChangeWaittime, &timer_handler_1)) + { + + Current_Vertical_ChangeState = VerticalChange_TurnToUP; + + } + break; + } + case VerticalChange_TurnToUP: + { + if (abs(GV.Robot_Angle - CV.RobotUpAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) //误差在1度内 + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_up_enum_state); /* 移动至头朝上 */ + } + else + { + Current_Vertical_ChangeState = VerticalChange_End; + } + break; + } + case VerticalChange_End: + { + VerticalLaneChangeState = Lane_Change_Stop; + break; + } + default: + break; + } + +} + + +/* 竖直从右往左作业 上端 向左换道 最终头朝上 + * */ +void Vertical_Lane_Change_From_Right_To_Left_UP_Control() +{ + + GV.Robot_Move_Speed = speed_M_min_toE01_M_min( CV.Lane_Change_Speed_m_per_min); + switch (Current_Vertical_ChangeState) + { + case VerticalChange_StateZero: + { + Current_Vertical_ChangeState = VerticalChange_TurnToRight; + break; + } + case VerticalChange_TurnToRight: + { + if (abs(GV.Robot_Angle - CV.RobotRightAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_right_enum_state); /* 移动至头朝右 */ + } + else + { + + fsm_state_set(¤t_robot_move_state, + &robot_move_horizontal_task_backwards_right_state);/* 水平纠偏后退 头朝右*/ + //开启计时 + timer_handler_1.start_timer = 1; + Current_Vertical_ChangeState = VerticalChange_DelayMove; + } + break; + } + case VerticalChange_DelayMove: + { + LaneChangeWaittime = RunTime_DistanceCm_SpeedE_2MPMin(); + if (CompareTimer(LaneChangeWaittime, &timer_handler_1)) + { + Current_Vertical_ChangeState = VerticalChange_TurnToUP; + } + break; + } + case VerticalChange_TurnToUP: + { + if (abs(GV.Robot_Angle - CV.RobotUpAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_up_enum_state); /* 移动至头朝上 */ + } + else + { + Current_Vertical_ChangeState = VerticalChange_End; + } + + break; + } + case VerticalChange_End: + { + VerticalLaneChangeState = Lane_Change_Stop; + break; + } + default: + break; + } + +} + +/* 竖直从右往左作业 下端 向左换道 最终头朝上 + * */ +void Vertical_Lane_Change_From_Right_To_Left_Down_Control() +{ + + GV.Robot_Move_Speed = speed_M_min_toE01_M_min( CV.Lane_Change_Speed_m_per_min);//转完 前进or后退得速度 + switch (Current_Vertical_ChangeState) + { + case VerticalChange_StateZero: + { + Current_Vertical_ChangeState = VerticalChange_TurnToLeft; + + break; + } + case VerticalChange_TurnToLeft: + { + if (abs(GV.Robot_Angle - CV.RobotLeftAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_left_enum_state); /* 移动至头朝左 */ + } + else + { + fsm_state_set(¤t_robot_move_state, + &robot_move_horizontal_task_forwards_left_state);/* 水平纠偏前进 头朝左*/ + //开启计时 + timer_handler_1.start_timer = 1; + Current_Vertical_ChangeState = VerticalChange_DelayMove; + } + break; + } + case VerticalChange_DelayMove: + { + LaneChangeWaittime = RunTime_DistanceCm_SpeedE_2MPMin(); + if (CompareTimer(LaneChangeWaittime, &timer_handler_1)) + { + + Current_Vertical_ChangeState = VerticalChange_TurnToUP; + + } + break; + } + case VerticalChange_TurnToUP: + { + if (abs(GV.Robot_Angle - CV.RobotUpAngleValue) + >= CV.Allowable_Error_For_Angle_Tracking) //误差在1度内 + { + fsm_state_set(¤t_robot_move_state, + &robot_move_head_to_up_enum_state); /* 移动至头朝上 */ + } + else + { + Current_Vertical_ChangeState = VerticalChange_End; + } + break; + } + case VerticalChange_End: + { + VerticalLaneChangeState = Lane_Change_Stop; + break; + } + default: + break; + } + +} + +/* + * return: ms + */ +int32_t RunTime_DistanceCm_SpeedE_2MPMin() +{ + + LaneChangeWaittime_ms = 600 * (GV.PV.LaneChangeDistance+CV.Vertical_ChangeLane_Compensation) + / CV.Lane_Change_Speed_m_per_min; + + return LaneChangeWaittime_ms; + +} + diff --git a/project_old/paint_robot_old/FSM/Src/fsm_state.c b/project_old/paint_robot_old/FSM/Src/fsm_state.c new file mode 100644 index 0000000..366c394 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Src/fsm_state.c @@ -0,0 +1,51 @@ +/* + * fsm.c + * + * Created on: 2025年7月14日 + * Author: akeguo + */ +#include "fsm_state.h" +#include "stdint.h" + + + + +void fsm_state_run(transition_t* p_this) +{ + // turnstile_pass(&turnstile) + if (p_this->p_state->robotRun!= NULL) + { + p_this->p_state->robotRun(p_this); + } + +} + + +//修改状态机状态,若状态机修改后,则查看是否有enter 和 exit命令进行运动 +void fsm_state_set(transition_t* p_this, transition_state_t* p_new_state) +{ + if(p_this==NULL){return;} + // turnstile_pass(&turnstile) + if (p_this->p_state!= p_new_state) /* 状态不等 */ + { + if (p_this->p_state->robotExit!=NULL) + { + p_this->p_state->robotExit(p_this); + } + + p_this->p_state = p_new_state; + if (p_this->p_state->robotEnter != NULL) + { + p_this->p_state->robotEnter(p_this); + } + //exit + + } + +} +//状态机初始化设定 +void fsm_state_init(transition_t* p_this,transition_state_t* inti_state) +{ + p_this->p_state =inti_state; +} + diff --git a/project_old/paint_robot_old/FSM/Src/fsm_state_control.c b/project_old/paint_robot_old/FSM/Src/fsm_state_control.c new file mode 100644 index 0000000..4b2483f --- /dev/null +++ b/project_old/paint_robot_old/FSM/Src/fsm_state_control.c @@ -0,0 +1,465 @@ +/* + * fsm.c + * + * Created on: Oct 18, 2024 + * Author: akeguo + */ +// 自动运行 换道 左补偿/右补偿 control +#include +#include + +#include "BHBF_ROBOT.h" +#include "bsp_include.h" +#include "msp_PID.h" +#include "msp_MK32_1.h" +#include "motors.h" +#include "fsm_state.h" +#include "motors_power_action.h" +#include "fsm_state_control.h" +#include "robot_move_actions.h" + +#define M_PI 3.14159265358979323846 +#define Move_Horizontal_AngleThreshold_D 85 + +void PaintGunControl(); +void IV_control(); +void PV_Data_Reading(); +void MoveControl(); +uint8_t MotorErrorDetect(); + +int Move_Halt_AngleError(); +void paintrobot_backwards(); +void paintrobot_forwards(); +void paint_joysticker_manual_control(); +int AbnormalDetect();//异常检测); +char is_upper_computer_take_over_control=0; +int CH13_S2_Value ; +int32_t speed_selection=0; //旋钮速度0-30 +int paintOffCount=0; //5° 计数 超过1s 关枪 +uint8_t angle_protect_lock=0; //作业时角度偏差过5°,停车标记位 +int32_t power_on_lock = 0; /*上电锁*/ +uint8_t error = 99; +int32_t serialAndUDP_DisconnectCount=0;//串口网口断联一段时间后在处理 + + +void Fsm_Init() +{ + + //机器人运动状态初始化 + fsm_state_init(¤t_robot_move_state, &robot_halt_state); + //喷漆初始化 + fsm_state_init(¤t_paintgun_state, &paintgun_off_state); + //机器人电机供电状态初始化 + fsm_state_init(¤t_motor_power_state, &motor_power_off_state); + + GF_BSP_Interrupt_Add_CallBack( + DF_BSP_InterCall_TIM8_2ms_PeriodElapsedCallback, GF_Dispatch); + IV.IsRestart=1; /* 是否重启 0否 1是 */ + +} + +/* + * 主逻辑函数 + * */ +void GF_Dispatch() +{ + fsm_state_run(¤t_robot_move_state); + fsm_state_run(¤t_paintgun_state); + fsm_state_run(¤t_motor_power_state); + + if (current_robot_move_state.p_state != &robot_halt_state) + { + IsRobotHaltSateChangedFlag = 1; //机器人动了就是1 + } + PV_Data_Reading(); ////按钮复位时 app数据生效 + + GV.LaneChangeDistance = GV.PV.LaneChangeDistance; + IV_control(); + + /*包含上电按钮检测 急停 SBUS 串口 等*/ + error=AbnormalDetect(); + if(AbnormalDetect()==1) + { + return; + } + + if(0 == power_on_lock && 0 == AbnormalDetect() ) /*只执行一次上电*/ + { + fsm_state_set(¤t_motor_power_state, &motor_power_on_state); + power_on_lock=1; + timer_handler_2.start_timer = 1; /*上电开始计时,10s通讯未连接 断电*/ + } + + + /*moetor alarm*/ + if (MotorErrorDetect() == 1) + { /*报警断48v,会导致错误码不更新,持续检测到错误无法上电,只能重启机器人*/ + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + fsm_state_set(¤t_motor_power_state, &motor_power_off_state); /*关闭电机电磁阀*/ + return; + + } +// //电机断线 + if (Get_BIT(SystemErrorCode, ComError_LS_LeftMotor) == DISCONNECTED || Get_BIT(SystemErrorCode, ComError_LS_RightMotor) == DISCONNECTED ) + { + if(CompareTimer(20000, &timer_handler_2)) /*上电20s未连接 断电*/ + { + fsm_state_set(¤t_motor_power_state, &motor_power_off_state); /*关闭电机电磁阀*/ + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + return; + } + + } + /*按下遥控 app无法选择*/ + if ((fabs(P_MK32->CH2_LY_V) <= 200) && (fabs(P_MK32->CH3_LY_H) <= 200) + && (fabs(P_MK32->CH0_RY_H) <= 200) && (fabs(P_MK32->CH1_RY_V) <= 200) + && (P_MK32->CH4_SA ==0) && (P_MK32->CH5_SB == 0) + && (P_MK32->CH6_SC != -1000) ) + { + + IV.IsWorking = 0; + angle_protect_lock = 0; // 拨杆复位 → 解开角度锁 + paintOffCount = 0; //计数清零 + } + else + { + IV.IsWorking = 1; + } + + + if (GV.PV.RunMode == Move_Manual) //app 无 的时候才能使用测试开启按钮 + { + PaintGunControl(); //测试开启关闭 + } + else if (GV.PV.RunMode >= Move_Vertical_Move_To_Left + && GV.PV.RunMode <= Move_Vertical_Move_To_Right) //不是app无 时 控制开喷枪 + { + + if (P_MK32->CH13_S2 != CH13_S2_Value) + { + if(GV.LeftMotor.Real_Velcity!=0) + { + fsm_state_set(¤t_paintgun_state, &paintgun_on_state); /*打开喷枪电磁阀*/ + CH13_S2_Value = P_MK32->CH13_S2; + + } + + } + CH13_S2_Value = P_MK32->CH13_S2;/**防止补作业得时候按s2导致下次前进直接开枪*/ + + } + + + if(Move_Halt_AngleError()==1) + { + return; + } + + MoveControl(); + +} +/* 机器人运动状态调度 */ +void MoveControl() +{ + if (GV.PV.RunMode == 0) //app发0 无法行走(app重启时) + { + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + return; + } + + /* 速度选择索引 0-30 */ + speed_selection = 3 * (P_MK32->CH11_RD1 + 1000) / 200; + GV.Robot_Move_Speed = speed_M_min_toE01_M_min( GetVehicleSpeed(speed_selection) );/*获取旋钮速度*/ + IV.RobotMoveSpeed= GetVehicleSpeed(speed_selection); + + //换道优先级优于普通的运行; + if (LaneChangeControl_Paint() == 1) + { + fsm_state_set(¤t_paintgun_state, &paintgun_off_state); /*换道关闭喷枪电磁阀*/ + return; + } + + if (P_MK32->CH5_SB == -1000) //自动巡航前进模式 不是换道和自动就能用 + { + paintrobot_forwards(); + return; + } + if (P_MK32->CH5_SB == 1000) //自动巡航后退模式,根据app,模式自动选择纠偏与否 + { + paintrobot_backwards(); + return; + } + paint_joysticker_manual_control(); //摇杆手动控制 +} + + /* @brief: 电机出现报警返回1,电机正常返回0 */ +uint8_t MotorErrorDetect() +{ + if (GV.LeftMotor.Motor_Fault != 0 || GV.RightMotor.Motor_Fault != 0) + { + return 1; + } + return 0; +} + + + + +/** + * @brief 手动模式下自动巡航前进, + * @function 前进 + * @param 无 + * @retval 无 + */ +void paintrobot_forwards() +{ + + /* 竖直向左 向右 */ + if (GV.PV.RunMode == Move_Vertical_Move_To_Left || GV.PV.RunMode == Move_Vertical_Move_To_Right) + { + fsm_state_set(¤t_robot_move_state, &robot_move_vertical_task_forwards_state);/* 前进纠偏 */ + return; + } + fsm_state_set(¤t_robot_move_state, &robot_forwards_state);/* app 无 前进纠偏 */ + return; +} + +/** + * @brief 手动模式下自动巡航后退, + * @function 自动后退: 竖直模式下 + * @param 无 + * @retval 无 + */ +void paintrobot_backwards() +{ + /*竖直*/ + if (GV.PV.RunMode == Move_Vertical_Move_To_Left + || GV.PV.RunMode == Move_Vertical_Move_To_Right) + { + + fsm_state_set(¤t_robot_move_state, + &robot_move_vertical_task_backwards_state);/* 后退纠偏 */ + + return; + } + fsm_state_set(¤t_robot_move_state, &robot_backwards_state);/* 后退 */ + return; + +} + + + +/** + * @brief 手动模式下运动,根据左侧控制按钮的值进行控制 + * @detail 前进,后退;水平模式下的前进后退,需要有校准,竖直的前进后退也需要有校准 + */ +void paint_joysticker_manual_control() +{ + + /*停止*/ + if (abs(P_MK32->CH2_LY_V) <= CV.Joy_Sticker_Value_Allowance && abs(P_MK32->CH3_LY_H) <= CV.Joy_Sticker_Value_Allowance) + { + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + return; + } + int angle = atan2(P_MK32->CH2_LY_V, P_MK32->CH3_LY_H) * 180 / M_PI; + + if (abs(angle - 90) <= CV.Joy_Sticker_Angle_Allowance) + { + /*前进*/ + paintrobot_forwards(); //根据app模式选择纠偏与不纠偏 + return; + } + /*后退*/ + if (abs(angle - (-90)) <= CV.Joy_Sticker_Angle_Allowance) + { + paintrobot_backwards(); + return; + } + /*右转*/ + if (abs(angle - 0) <= CV.Joy_Sticker_Angle_Allowance) + { + fsm_state_set(¤t_robot_move_state, &robot_turn_right_state); /*右转*/ + return; + } + /*左转*/ + if (abs(angle - 180) <= CV.Joy_Sticker_Angle_Allowance || abs(angle - (-180)) <= CV.Joy_Sticker_Angle_Allowance) + { + fsm_state_set(¤t_robot_move_state, &robot_turn_left_state); /*左转*/ + return; + } + +} + + +///* 作业过程中,角度偏差超过允许值时 关闭喷枪并停车 +// * 扫描当前车体运动状态 及 当前车体角度 +// * */ +int Move_Halt_AngleError() +{ + + if (angle_protect_lock == 1) + { + return 1; // 锁死:不执行运动代码 + } + + /**********竖直方向**************/ + if (GV.PV.RunMode != Move_Vertical_Move_To_Right + && GV.PV.RunMode != Move_Vertical_Move_To_Left) + { + return 0; + } + + if (current_robot_move_state.p_state + != &robot_move_vertical_task_forwards_state + && (current_robot_move_state.p_state + != &robot_move_vertical_task_backwards_state)) + { + return 0; + } + + if ( (abs(GV.Robot_Angle - CV.RobotUpAngleValue) > CV.Robot_Permitted_Angler_Error_Value_E_2D) + && (current_paintgun_state.p_state==&paintgun_on_state) ) + { + if(++paintOffCount>500) + { + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + angle_protect_lock = 1; + return 1; // 本次立即返回1,停止运动 + } + } + else + { + //计数器清零 + paintOffCount = 0; + } + + return 0; + + +} + +/* 暂存App传输的PV数据,用于在业务执行过程中进行数据隔离 + */ +void PV_Data_Reading() //按钮复位时 app数据生效 +{ + + if(decoded_PV.IV_IsRestart_Notified==1)//收到安卓的重启1 双方都知道了重启了 + { + IV.IsRestart=0;//置为非重启装态 + } + + + if (P_MK32->CH4_SA == 0 && P_MK32->CH5_SB == 0 && P_MK32->CH7_SD == 0 ) + { + GV.PV = decoded_PV; + + } + +} + +/* IV 更新 */ +void IV_control() +{ + + + /* 返回值是脉冲/s P*60/10000/70/(Πd)=V */ + IV.CurrentSpeed=GV.LeftMotor.Real_Velcity*60.0/CV.pulse_Per_Circle/CV.wheel_Reduction_Ratio*M_PI*CV.wheel_Diameter_m; + + IV.RobotMoveSpeed=GetVehicleSpeed(speed_selection); + IV.CurrentAngle = GV.Robot_Angle; + IV.SBUS_State=GV.P_MK32.IsOnline; + IV.SystemError = GV.SystemErrorData.Com_Error_Code; /* SystemErrorCode = &GV.SystemErrorData.Com_Error_Code; */ + IV.Left_Motor_Err = GV.LeftMotor.Motor_Fault; + IV.Right_Motor_Err = GV.RightMotor.Motor_Fault; + IV.TimeStamp = SystemTimeMiliCount; +} +/* 测试喷枪控制* */ +void PaintGunControl() +{ + if (P_MK32->CH6_SC == -1000) + { + if (Paint_Gun_ButtonReset_Flag == 0) + { + fsm_state_set(¤t_paintgun_state, &paintgun_on_state); /*开启喷枪电磁阀*/ + Paint_Gun_ButtonReset_Flag = 1; + } + } + else if (P_MK32->CH6_SC == 0) + { + fsm_state_set(¤t_paintgun_state, &paintgun_off_state); /*关闭喷枪电磁阀*/ + Paint_Gun_ButtonReset_Flag = 0; + } + else if (P_MK32->CH6_SC == 1000) + { + fsm_state_set(¤t_paintgun_state, &paintgun_off_state); /*关闭喷枪电磁阀*/ + Paint_Gun_ButtonReset_Flag = 0; + } +} + +int AbnormalDetect(){ + + //上位机此时,其他设备全部处于不可操作状态,喷漆停止、摆臂上抬,只保持轮子的基本操作(为处理遥控器无法使用的情况) + if (is_upper_computer_take_over_control == Taken_Over) + { + GV.PV.RunMode = Move_Manual; + fsm_state_set(¤t_paintgun_state, &paintgun_off_state); + fsm_state_set(¤t_motor_power_state, &motor_power_on_state); //电机上电,上电后,激活电机, + return 1; + } + /* SBUS出错 断电 */ + if (Get_BIT(SystemErrorCode, ComError_MK32_SBus) == DISCONNECTED) + { + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + fsm_state_set(¤t_motor_power_state, &motor_power_off_state); /*关闭电机电磁阀*/ + return 1; + } + /*急停*/ + if (P_MK32->CH8_SE == -1000 && P_MK32->CH9_SF == -1000) + { + + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + fsm_state_set(¤t_motor_power_state, &motor_power_off_state); /*关闭电机电磁阀*/ + Is_All_Button_Reset = 0;//急停之后必须复位才能动 + return 1; + } + + /* 按钮未复位 第一次上电 SystemErrorCode不为0 计算值为1 未复位 */ + if (Get_BIT(SystemErrorCode, ComError_Remote_Button_Reset_State) //按钮未复位 SystemErrorCode 右移ComError_Remote_Button_Reset_State位 + != Has_Reset) //Has_Reset 0 复位 1未复位 + { + CH13_S2_Value = P_MK32->CH13_S2; + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + + return 1; + } + if (P_MK32->IsOnline == 0) //等于0时 subus有数,但是遥控器关机了,或者失联 + { + fsm_state_set(¤t_robot_move_state, &robot_halt_state); /*停止机器人*/ + fsm_state_set(¤t_motor_power_state, &motor_power_off_state); /*关闭电机电磁阀*/ + Is_All_Button_Reset = 0;//急停之后必须复位才能动 + return 1; + } +// /******网口,串口同时断联 成功******/ +// +// if(Get_BIT(SystemErrorCode, ComError_MK32_Serial) == DISCONNECTED +// && Get_BIT(SystemErrorCode, ComError_MK32_UDP) == DISCONNECTED) +// { +// if(++serialAndUDP_DisconnectCount>=2000) /*x s*/ +// { +// GV.PV.RunMode=1;//只允许手动操作 +// fsm_state_set(¤t_paintgun_state, &paintgun_off_state); /*关闭喷枪电磁阀*/ +// return 0; +// } +// +// } +// else{serialAndUDP_DisconnectCount=0; /*重新计数*/} + //陀螺仪无信号 + if (Get_BIT(SystemErrorCode, ComError_TL720D) == DISCONNECTED) + { + GV.PV.RunMode=1;//只允许手动操作 + fsm_state_set(¤t_paintgun_state, &paintgun_off_state); /*关闭喷枪电磁阀*/ + return 0; + } + return 0; +} diff --git a/project_old/paint_robot_old/FSM/Src/motors.c b/project_old/paint_robot_old/FSM/Src/motors.c new file mode 100644 index 0000000..367aafa --- /dev/null +++ b/project_old/paint_robot_old/FSM/Src/motors.c @@ -0,0 +1,152 @@ +/* + * LS_CAN_Motor_Frames.c + * + * Created on: Mar 21, 2025 + * Author: BingooRobotFJX + */ + +#include +#include "fsm_state_control.h" +#include "BHBF_ROBOT.h" +FDCANHandler *LS_Motor_Controller; +DispacherController *LS_DispacherController; + +void MotorCommandsLoop(); +void MotorDecodeCAN(uint32_t canID, uint8_t *buffer, uint32_t length); +int32_t speed_E01m_per_min_to_pulse_s(int32_t speed_E01m_per_min); + + + +char LS_Motor_Need_To_Activate = 0; +char LS_Motor_Config_Count = 0; + +/* + * + * */ +void LS_Motor_Controller_intialize(FDCANHandler *Handler) +{ + + + //初始化 + LS_Motor_Controller = Handler; + LS_Motor_Controller->CAN_Decode = MotorDecodeCAN; + + HardWareErrorController->Add_PCOMHardWare(HardWareErrorController, + "LS_CAN_ID1_LeftMotor", 0, ComError_LS_LeftMotor); + + HardWareErrorController->Add_PCOMHardWare(HardWareErrorController, + "LS_CAN_ID2_RightMotor", 0, ComError_LS_RightMotor); + + LS_DispacherController = Handler->dispacherController; + LS_DispacherController->DispacherCallTime = 2; + LS_DispacherController->Add_Dispatcher_List(LS_DispacherController, + MotorCommandsLoop); +} + +/* + * + * */ +void MotorCommandsLoop() +{ + if (LS_Motor_Need_To_Activate == 1) + { + + + LS_Reset_All_Motors(LS_Motor_Controller, 1000);//等待1s + LS_Reset_All_Motors(LS_Motor_Controller, 500); + + LS_Activate_All_Motors(LS_Motor_Controller, 1000); + LS_Activate_All_Motors(LS_Motor_Controller, 1000); + LS_Activate_All_Motors(LS_Motor_Controller, 500); + LS_Activate_All_Motors(LS_Motor_Controller, 500); + LS_Activate_All_Motors(LS_Motor_Controller, 500); + + + LS_Set_Current_Positon_Zero(GV.LeftMotor.MotorID, LS_Motor_Controller, 50); + LS_Set_Current_Positon_Zero(GV.RightMotor.MotorID, LS_Motor_Controller, 50); + LS_SpeedModeSetup(GV.LeftMotor.MotorID, LS_Motor_Controller, 10, 1500000, 1500000, + 0); + LS_SpeedModeSetup(GV.RightMotor.MotorID, LS_Motor_Controller, 10, 1500000, 1500000, + 0); + + LS_Motor_Need_To_Activate = 0; + } + else + { + if(LS_Motor_Config_Count <= 200) /*confirm complete config -->stop send*/ + { + LS_Motor_Config_Count++; + LS_Set_WatchDogTime(GV.LeftMotor.MotorID, LS_Motor_Controller, 5); + LS_Set_WatchDogTime(GV.RightMotor.MotorID, LS_Motor_Controller, 5); + + } + LS_Request_Position(GV.LeftMotor.MotorID, LS_Motor_Controller, 2); + LS_Request_Fault(GV.LeftMotor.MotorID, LS_Motor_Controller, 2); + LS_Request_Velocity(GV.LeftMotor.MotorID, LS_Motor_Controller, 2); + LS_Request_Position(GV.RightMotor.MotorID, LS_Motor_Controller, 2); + LS_Request_Fault(GV.RightMotor.MotorID, LS_Motor_Controller, 2); + + LS_SpeedMode_Set_TargetSpeed(GV.LeftMotor.MotorID, LS_Motor_Controller, 2, + speed_E01m_per_min_to_pulse_s(GV.LeftMotor.Target_Velcity) ); + + LS_SpeedMode_Set_TargetSpeed(GV.RightMotor.MotorID, LS_Motor_Controller, 2, + speed_E01m_per_min_to_pulse_s(GV.RightMotor.Target_Velcity) ); + + } + +} + +/* + * 解析函数 + * + * */ +void MotorDecodeCAN(uint32_t canID, uint8_t *buffer, uint32_t length) +{ + switch (canID - 0x580) + { + + case 1: + { + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController, + "LS_CAN_ID1_LeftMotor", 1); + LS_Analytic_Fun(GV.LeftMotor.MotorID, buffer); //ID 和数据 + } + break; + case 2: + { + HardWareErrorController->Set_PCOMHardWare(HardWareErrorController, + "LS_CAN_ID2_RightMotor", 1); + LS_Analytic_Fun(GV.RightMotor.MotorID, buffer); + } + break; + } + +} + +/* DO输出 + * @state: 1:ON; 0:OFF; + * */ +void LS_Motor_DOSet(uint8_t state) +{ + if (state == 1) + { + LS_DO_Set(GV.LeftMotor.MotorID, 1, state, LS_Motor_Controller, 10); + } + else if (state == 0) + { + LS_DO_Set(GV.LeftMotor.MotorID, 1, state, LS_Motor_Controller, 10); + } +} + +/* + * SpeedMPMin:0.1 m/min + * P*60/10000/70/(Πd)=V + * return:1 pulse/s + * */ +int32_t speed_E01m_per_min_to_pulse_s(int32_t speed_E01m_per_min) +{ + return (int32_t) (speed_E01m_per_min*0.1 *CV.pulse_Per_Circle * CV.wheel_Reduction_Ratio / 60 + / (3.14 * CV.wheel_Diameter_m)); +} + + diff --git a/project_old/paint_robot_old/FSM/Src/motors_power_action.c b/project_old/paint_robot_old/FSM/Src/motors_power_action.c new file mode 100644 index 0000000..9511bd5 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Src/motors_power_action.c @@ -0,0 +1,35 @@ +/* + * motors_power_action.c + * + * Created on: 2025年7月14日 + * Author: akeguo + */ +#include "motors_power_action.h" +#include "motors.h" + +transition_t current_motor_power_state; + +transition_state_t motor_power_on_state={Motors_Power_On_Enter,Motors_Power_On_Do,Motors_Power_On_Exit}; +transition_state_t motor_power_off_state={NULL,Motors_Power_Off_Do,NULL}; + + + +void Motors_Power_On_Do(transition_t *p_this) +{ + GF_BSP_GPIO_SetIO(Motor_Power_IO_CTL, K_ON_Motor); +} + +void Motors_Power_Off_Do(transition_t *p_this) +{ + GF_BSP_GPIO_SetIO(Motor_Power_IO_CTL, K_OFF_Motor); +} + +void Motors_Power_On_Enter(transition_t *p_this) +{ + LS_Motor_Need_To_Activate=1; +} +void Motors_Power_On_Exit(transition_t *p_this) +{ + +} + diff --git a/project_old/paint_robot_old/FSM/Src/paint_gun_action.c b/project_old/paint_robot_old/FSM/Src/paint_gun_action.c new file mode 100644 index 0000000..83b2f03 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Src/paint_gun_action.c @@ -0,0 +1,46 @@ +/* + * paint_gun_action.c + * + * Created on: 2025年8月7日 + * Author: xsq + */ +#include "paint_gun_action.h" +#include "fsm_state.h" +#include "BHBF_ROBOT.h" +transition_t current_paintgun_state; /*transition_t 成员是 指针的 transition_state_t */ + +transition_state_t paintgun_on_state={PaintGun_ON_Enter,PaintGun_ON_Do,NULL}; /* State 成员,它会被默认初始化为 0 */ +transition_state_t paintgun_off_state={PaintGun_OFF_Enter,PaintGun_OFF_Do,NULL}; + +char Paint_Gun_ButtonReset_Flag = 0; //喷枪开启 1yes + +/* 喷枪控制 */ +void PaintGun_ON_Do() +{ + GF_BSP_GPIO_SetIO(PaintGun_IO_CTL, K_ON_PaintGun);//0开 +} + +void PaintGun_OFF_Do() +{ + GF_BSP_GPIO_SetIO(PaintGun_IO_CTL, K_OFF_PaintGun);//1关 +} + +void PaintGun_ON_Enter() +{ + +} +void PaintGun_ON_Exit() +{ + +} +void PaintGun_OFF_Enter() +{ + + +} +void PaintGun_OFF_Exit() +{ + +} + + diff --git a/project_old/paint_robot_old/FSM/Src/robot_move_actions.c b/project_old/paint_robot_old/FSM/Src/robot_move_actions.c new file mode 100644 index 0000000..2bf8be0 --- /dev/null +++ b/project_old/paint_robot_old/FSM/Src/robot_move_actions.c @@ -0,0 +1,312 @@ +/* + * robot_move_actions.c + * + * Created on: 2025年7月14日 + * Author: akeguo + */ +#include "robot_move_actions.h" +#include "fsm_state.h" +#include "fsm_state_control.h" +#include "paint_gun_action.h" +#include "MSP/msp_PID.h" +transition_t current_robot_move_state; +transition_t current_robot_automove_state; + +transition_state_t robot_halt_state={HALT_State_Enter,HALT_State_Do,HALT_State_Exit}; /* 停 */ +transition_state_t robot_forwards_state={NULL,Forwards_State_Do,NULL}; /* 前 */ +transition_state_t robot_backwards_state={NULL,Backwards_State_Do,NULL}; /* 后 */ +transition_state_t robot_turn_left_state={NULL,TurnLeft_State_Do,NULL}; /* 左 */ +transition_state_t robot_turn_right_state={NULL,TurnRight_State_Do,NULL}; /* 右 */ + +transition_state_t robot_move_vertical_task_forwards_state={NULL,Move_Vertical_Task_Forwards_Do,NULL}; /* 竖直纠偏前进 */ +transition_state_t robot_move_vertical_task_backwards_state={NULL,Move_Vertical_Task_Backwards_Do,NULL}; /* 竖直纠偏后退 */ + +transition_state_t robot_move_horizontal_task_forwards_left_state={NULL,Move_Horizontal_Task_Forwards_Left_Do,NULL}; /* 水平纠偏前进 头朝左*/ +transition_state_t robot_move_horizontal_task_backwards_left_state={NULL,Move_Horizontal_Task_Backwards_Left_Do,NULL};/* 水平纠偏后退 头朝左*/ +transition_state_t robot_move_horizontal_task_forwards_right_state={NULL,Move_Horizontal_Task_Forwards_Right_Do,NULL}; /* 水平纠偏前进 头朝右*/ +transition_state_t robot_move_horizontal_task_backwards_right_state={NULL,Move_Horizontal_Task_Backwards_Right_Do,NULL};/* 水平纠偏后退 头朝右*/ + +transition_state_t robot_move_head_to_left_enum_state={NULL,Move_Head_To_Left_Do,NULL}; /* 移动至头朝左 */ +transition_state_t robot_move_head_to_up_enum_state={NULL,Move_Head_To_UP_Do,NULL}; /* 移动至头朝上 */ +transition_state_t robot_move_head_to_right_enum_state={NULL,Move_Head_To_Right_Do,NULL}; /* 移动至头朝右 */ +transition_state_t robot_move_head_to_down_enum_state={NULL,Move_Head_To_Down_Do,NULL}; /* 移动至头朝下 */ + + +/* 声明最底层函数 */ +void Move_Forwards_Do(int32_t Target_Angle); +void Move_Backwards_Do(int32_t Target_Angle); +void Calbrate_Robot_Positon(int Target_Angle); + + +static int dletAngle = 0; +char IsRobotHaltSateChangedFlag = 0; + +void Forwards_State_Do(transition_t *p_this) +{ + GV.LeftMotor.Target_Velcity = GV.Robot_Move_Speed; + GV.RightMotor.Target_Velcity = GV.Robot_Move_Speed; +} + +void Backwards_State_Do(transition_t *p_this) +{ + + GV.LeftMotor.Target_Velcity = -GV.Robot_Move_Speed; + GV.RightMotor.Target_Velcity = -GV.Robot_Move_Speed; +} +/* 向左转 + * + * */ +void TurnLeft_State_Do(transition_t *p_this) +{ + + GV.LeftMotor.Target_Velcity = -CV.LeftTurnSpeed; + GV.RightMotor.Target_Velcity = CV.RightTurnSpeed; +} + +/* 向右转 + * + * */ +void TurnRight_State_Do(transition_t *p_this) +{ + + GV.LeftMotor.Target_Velcity =CV.LeftTurnSpeed; + GV.RightMotor.Target_Velcity = -CV.RightTurnSpeed; +} + +/* 停止 + * 零速停止,不关闭抱闸 + * */ +void HALT_State_Do(transition_t *p_this) +{ + if (IsRobotHaltSateChangedFlag == 1)//机器人为运动状态 + { + + if (current_paintgun_state.p_state == &paintgun_on_state) //停车看喷枪状态 开了关喷枪计时停车 + { + fsm_state_set(¤t_paintgun_state, &paintgun_off_state); + timer_handler_3.start_timer = 1; //开始计时 + return; + } + + if (CompareTimer( + 600 * CV.Paint_Gun_Shutdown_Distance / GetVehicleSpeed( speed_selection), + &timer_handler_3)) //喷枪开 计时停 关 直接停 + { + IsRobotHaltSateChangedFlag = 0; + GV.LeftMotor.Target_Velcity = 0; + GV.RightMotor.Target_Velcity = 0; + + } + + } + else + { + GV.LeftMotor.Target_Velcity = 0; + GV.RightMotor.Target_Velcity = 0; + IsRobotHaltSateChangedFlag=0; + } + +} +/* 竖直前进,保持目标角度 CV.RobotUpAngleValue + * Target_Angle: 0.01度 + * */ +void Move_Vertical_Task_Forwards_Do(transition_t *p_this) +{ + Move_Forwards_Do(CV.RobotUpAngleValue + GV.PV.Vertical_Calibration); +} + +/* 竖直后退,保持目标角度 CV.RobotUpAngleValue + * Target_Angle: 0.01度 + * */ +void Move_Vertical_Task_Backwards_Do(transition_t *p_this) +{ + Move_Backwards_Do(CV.RobotUpAngleValue + GV.PV.Vertical_Calibration); +} + + +void HALT_State_Enter(transition_t *p_this) +{ + +} +void HALT_State_Exit(transition_t *p_this) +{ + + +} + +/* 水平头朝右前进 + * 带补偿 + * */ +void Move_Horizontal_Task_Forwards_Right_Do(transition_t *p_this) +{ + Move_Forwards_Do(CV.RobotRightAngleValue - GV.Right_Compensation); +} +/* 水平头朝右后退 ,向左退 左补偿生效 + * 带补偿 + * */ +void Move_Horizontal_Task_Backwards_Right_Do(transition_t *p_this) +{ + Move_Backwards_Do(CV.RobotRightAngleValue + GV.Left_Compensation); +} +/* 水平头朝左前进 + * 带补偿 + * */ +void Move_Horizontal_Task_Forwards_Left_Do(transition_t *p_this) +{ + Move_Forwards_Do(CV.RobotLeftAngleValue + GV.Left_Compensation); +} + + +/* 水平头朝左后退 向右退 右补偿 + * 带补偿 + * */ +void Move_Horizontal_Task_Backwards_Left_Do(transition_t *p_this) +{ + Move_Backwards_Do(CV.RobotLeftAngleValue - GV.Right_Compensation); +} + + +/* 原地PID转向至目标角度 CV.RobotUpAngleValue + * Target_Angle: 目标角度 (单位 0.01 度) + * */ +void Move_Head_To_UP_Do(transition_t *p_this) +{ + Calbrate_Robot_Positon(CV.RobotUpAngleValue); + +} + +/* 原地PID转向至目标角度 CV.RobotDownAngleValue + * Target_Angle: 目标角度 (单位 0.01 度) + * */ +void Move_Head_To_Down_Do(transition_t *p_this) +{ + Calbrate_Robot_Positon(CV.RobotDownAngleValue); +} + +/* 原地PID转向至目标角度 CV.RobotLeftAngleValue + * Target_Angle: 目标角度 (单位 0.01 度) + * */ +void Move_Head_To_Left_Do(transition_t *p_this) +{ + Calbrate_Robot_Positon(CV.RobotLeftAngleValue); +} + +/* 原地PID转向至目标角度 CV.RobotRightAngleValue + * Target_Angle: 目标角度 (单位 0.01 度) + * */ +void Move_Head_To_Right_Do(transition_t *p_this) +{ + Calbrate_Robot_Positon(CV.RobotRightAngleValue); +} + + +/*******************以下纠偏底层函数**********************************/ +/* + * 底层前进,保持目标角度 纠偏 被调用 + * Target_Angle: 0.1度 + * */ +int delt=0; +void Move_Forwards_Do(int32_t Target_Angle) +{ + + + + if (abs(GV.Robot_Angle - Target_Angle) <= CV.PID_mid.PID_Angle) //// 误差在正负5度内 + { + if (abs(GV.Robot_Angle - Target_Angle) < CV.PID_low.PID_Angle) //// 误差在正负0.3度内 + { + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, + CV.PID_low.Kp, CV.PID_low.Ki, CV.PID_low.Kd, 10); + } + else //中角度 + { + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, + CV.PID_mid.Kp, CV.PID_mid.Ki, CV.PID_mid.Kd, 10); + + } + GV.LeftMotor.Target_Velcity = GV.Robot_Move_Speed - dletAngle ; + GV.RightMotor.Target_Velcity =GV.Robot_Move_Speed + dletAngle ; + + + } + else //大于CV.PID_high.PID_Angle + { + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, + CV.PID_high.Kp, CV.PID_high.Ki, CV.PID_high.Kd,50); + GV.LeftMotor.Target_Velcity = -dletAngle ; + GV.RightMotor.Target_Velcity = dletAngle ; + } + delt=dletAngle; +} + + + +/* 后退,保持目标角度 纠偏 + * Target_Angle: 0.01度 + * */ +void Move_Backwards_Do(int32_t Target_Angle) +{ + + if (abs(GV.Robot_Angle - Target_Angle) <= CV.PID_mid.PID_Angle) //// 误差在正负4度内 + { + if (abs(GV.Robot_Angle - Target_Angle) < CV.PID_low.PID_Angle) //// 误差在正负1度内 + { + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, + CV.PID_low.Kp, CV.PID_low.Ki, CV.PID_low.Kd, 10); + } + else /*1-4*/ + { + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, + CV.PID_mid.Kp, CV.PID_mid.Ki, CV.PID_mid.Kd, 10); + } + GV.LeftMotor.Target_Velcity = -GV.Robot_Move_Speed - dletAngle ; + GV.RightMotor.Target_Velcity = -GV.Robot_Move_Speed + dletAngle; + } + else /*大于4*/ + { + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, + CV.PID_high.Kp, CV.PID_high.Ki, CV.PID_high.Kd, 50); + GV.LeftMotor.Target_Velcity = -dletAngle ; + GV.RightMotor.Target_Velcity = dletAngle ; + } + +} + +/* 原地PID转向至目标角度 + * Target_Angle: 目标角度 (单位 0.01 度) + * */ +void Calbrate_Robot_Positon(int Target_Angle) +{ + + + + if (abs(GV.Robot_Angle - Target_Angle) <= 50) //误差在正负1度内 + { + GV.LeftMotor.Target_Velcity = 0; + GV.RightMotor.Target_Velcity = 0; + } + else if (abs(GV.Robot_Angle - Target_Angle) <= 1000) //误差在正负1度内 1-5° + { + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, 1, 0,0.5, 10); + GV.LeftMotor.Target_Velcity = -dletAngle ; + GV.RightMotor.Target_Velcity = dletAngle; + } + else//大于2° + { + + dletAngle = Angle_Tune_PID((double)GV.Robot_Angle, Target_Angle, 2, 0, 0.5, 85); + GV.LeftMotor.Target_Velcity = -dletAngle ; + GV.RightMotor.Target_Velcity = dletAngle ; + } +} + + +/* 车体速度选择 具体车速在配置结构体CV 0.01m/min */ +int32_t GetVehicleSpeed(int speed_selection) +{ + if(speed_selection==0) + { + return 1; + } + return CV.Speed_m_per_min*speed_selection/30; +} diff --git a/project_old/paint_robot_old/include/bsp_fsm.h b/project_old/paint_robot_old/include/bsp_fsm.h new file mode 100644 index 0000000..e7a93a3 --- /dev/null +++ b/project_old/paint_robot_old/include/bsp_fsm.h @@ -0,0 +1,13 @@ +/* + * bsp_fsm.h + * + * Created on: Oct 18, 2024 + * Author: akeguo + */ + +#ifndef INC_BSP_FSM_H_ +#define INC_BSP_FSM_H_ + + + +#endif /* INC_BSP_FSM_H_ */ diff --git a/project_old/paint_robot_old/include/com.pb.h b/project_old/paint_robot_old/include/com.pb.h new file mode 100644 index 0000000..0904289 --- /dev/null +++ b/project_old/paint_robot_old/include/com.pb.h @@ -0,0 +1,57 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.8 */ + +#ifndef PB_COM_PB_H_INCLUDED +#define PB_COM_PB_H_INCLUDED +#include "BSP/pb.h" + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Struct definitions */ +typedef struct _UplaodtoSerial { + int32_t Speed_1; + int32_t Speed_2; + int32_t Speed_3; + int32_t Speed_4; +} UplaodtoSerial; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define UplaodtoSerial_init_default {0, 0, 0, 0} +#define UplaodtoSerial_init_zero {0, 0, 0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define UplaodtoSerial_Speed_1_tag 1 +#define UplaodtoSerial_Speed_2_tag 2 +#define UplaodtoSerial_Speed_3_tag 3 +#define UplaodtoSerial_Speed_4_tag 4 + +/* Struct field encoding specification for nanopb */ +#define UplaodtoSerial_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, INT32, Speed_1, 1) \ +X(a, STATIC, SINGULAR, INT32, Speed_2, 2) \ +X(a, STATIC, SINGULAR, INT32, Speed_3, 3) \ +X(a, STATIC, SINGULAR, INT32, Speed_4, 4) +#define UplaodtoSerial_CALLBACK NULL +#define UplaodtoSerial_DEFAULT NULL + +extern const pb_msgdesc_t UplaodtoSerial_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define UplaodtoSerial_fields &UplaodtoSerial_msg + +/* Maximum encoded size of messages (where known) */ +#define COM_PB_H_MAX_SIZE UplaodtoSerial_size +#define UplaodtoSerial_size 44 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/project_old/paint_robot_old/include/motors.h b/project_old/paint_robot_old/include/motors.h new file mode 100644 index 0000000..7367d58 --- /dev/null +++ b/project_old/paint_robot_old/include/motors.h @@ -0,0 +1,22 @@ +/* + * LS_CAN_Motor_Frames.h + * + * Created on: Mar 21, 2025 + * Author: BingooRobotFJX + */ + +#ifndef SRC_LS_CAN_MOTOR_FRAMES_H_ +#define SRC_LS_CAN_MOTOR_FRAMES_H_ + +#include "BHBF_ROBOT.h" +#include "BSP/bsp_FDCAN.h" +#include "bsp_Error_Detect.h" +#include "MSP/msp_LeiSai_ISV2_CAN.h" +extern char LS_Motor_Need_To_Activate; +void LS_Motor_Controller_intialize(FDCANHandler *Handler); +void LS_Motor_DOSet(uint8_t state); +int32_t speed_m_per_min_to_pulse_s(int32_t speed_m_per_min); + +int32_t RunTime_DistanceCm_SpeedE_2MPMin(); + +#endif /* SRC_LS_CAN_MOTOR_FRAMES_H_ */ diff --git a/project_old/paint_robot_old/paint_robot_old.c b/project_old/paint_robot_old/paint_robot_old.c new file mode 100644 index 0000000..e69de29 diff --git a/project_old/paint_robot_old/paint_robot_old.h b/project_old/paint_robot_old/paint_robot_old.h new file mode 100644 index 0000000..e5a0ccb --- /dev/null +++ b/project_old/paint_robot_old/paint_robot_old.h @@ -0,0 +1,20 @@ +#ifndef __PAINT_ROBOT_OLD_H__ +#define __PAINT_ROBOT_OLD_H__ + + +#ifdef __cplusplus +#if __cplusplus +extern "C"{ +#endif +#endif /* __cplusplus */ + + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + + +#endif \ No newline at end of file