gaochunhui 1 год назад
Сommit
b93c7df92b

+ 47 - 0
APP_0104.ve

@@ -0,0 +1,47 @@
+SYSCLK 100
+
+HSECLK 8
+
+
+#串口初始化
+UART0_UARTRXD PIN_69    #DEGUG口
+UART0_UARTTXD PIN_68
+
+#4G口
+UART1_UARTRXD PIN_83    #4G串口 AT_NET2MCU
+UART1_UARTTXD PIN_80    #AT_MCU2NET
+
+#485口
+UART2_UARTRXD PIN_26    #RS485_BUS2MCU
+UART2_UARTTXD PIN_25    #RS485_MCU2BUS
+GPIO1_2 PIN_24          #RS485_CTL
+
+
+#LED_RUN  LED_MOD 初始化
+GPIO1_0 PIN_3 # LED_RUN
+GPIO1_1 PIN_2 # LED_MOD
+GPIO1_3 PIN_4 #LED_PWR
+
+
+#按键
+GPIO1_4 PIN_92 #MCU_KEY1
+GPIO1_5 PIN_91 #MCU_KEY2
+GPIO1_6 PIN_88 #MCU_KEY3
+
+
+#硬件id
+GPIO0_4 PIN_15
+GPIO0_5 PIN_16
+GPIO0_6 PIN_17
+GPIO0_7 PIN_18
+
+#4G模块
+GPIO5_0         PIN_23 # +VDD_EXT 检测4G模块的电压,判断4G模块是否上电
+GPIO5_1         PIN_93 #MCU_NET_PWR
+GPIO5_2         PIN_98 #MCU_NET_RST
+GPIO5_3         PIN_7  #NET_DETECH 检测4G是否焊接
+
+#i2c eeprom
+GPIO2_0         PIN_97 #I2C_WP
+GPIO2_1         PIN_95 #I2C_SCL
+GPIO2_2         PIN_96 #I2C_SDA

+ 11 - 0
myboard.asf

@@ -0,0 +1,11 @@
+if { [info exists BOARD_PLL_CLKIN] } {
+  if { $BOARD_PLL_CLKIN == "PIN_OSC" } {
+    set_config -loc 18 0 0 CFG_RCOSC_EN 1'b1
+  }
+}
+if { [info exists USB0_MODE] } {
+  alta::tcl_info "USB0_MODE = $USB0_MODE"
+  set_config -loc 0 1 3 CFG_PULLUP_ENB 1'b0
+  set_config -loc 0 1 3 CFG_PULLDN_ENB 1'b0
+}
+set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to PIN_26

+ 84 - 0
platformio.ini

@@ -0,0 +1,84 @@
+[setup]
+boards_dir = boards
+board = agrv2k_407
+board_logic.ve = APP_0104.ve
+
+#ips_dir = ../ips
+ip_name = APP_0104_fpga
+logic_dir = logic
+
+framework = agrv_sdk
+program = APP_0104_MCU_01043004
+
+src_dir = src
+include_dir = src
+src_filter = "-<*> +<*.c>+<agm_board/*.c>+<app/*.c>"
+src_build_flags = -Iuser -Iuser/agm_board -Iuser/app
+
+lwip_imp_dir =
+tinyusb_imp_dir =
+
+board_logic.asf = myboard.asf
+
+
+board_upload.address = 0x80020000
+board_build.boot_addr = 0x80020000
+
+
+board_logic.compress = true
+build_unflags = -O2
+build_flags = -Os
+            -DLOGGER_BAUD_RATE=${setup.monitor_speed}
+            -DAGRV_FP_STACK=0
+            -DDFU_FPGA_CONFIG=\"APP_0104.inc\"
+build_src_flags = -Wno-cast-align
+
+
+
+
+
+logger_if = UART0
+upload_port = COM3
+monitor_port = COM3
+monitor_speed = 57600
+debug_speed = 10000
+
+debug_tool = jlink-openocd
+upload_protocol = jlink-openocd
+
+
+[setup_rtt]
+logger_if = RTT
+monitor_port = socket://localhost:19021
+
+
+[platformio]
+boards_dir = ${setup.boards_dir}
+src_dir = ${setup.src_dir}
+include_dir = ${setup.include_dir}
+default_envs = dev
+#board_upload.address = 0x80020000
+
+[env]
+platform = AgRV
+extends = setup
+
+[env:dev]
+build_type = debug
+board_upload.address = 0x80020000
+
+[env:release]
+build_type = release
+board_upload.address = 0x80020000
+
+[env:rtt]
+build_type = debug
+extends = setup_rtt
+
+[env:serial]
+build_type = release
+board_upload.address = 0x80020000
+
+upload_protocol = serial
+upload_speed = 460800
+custom_speed = 115200

+ 282 - 0
src/APP_0104.inc

@@ -0,0 +1,282 @@
+0x40,0x20,0x00,0x01,0x00,0x00,0xff,0xff,0x51,0x00,0x00,0x02,0x00,0x00,0x0c,0x82,
+0x20,0x04,0x00,0x80,0x08,0x08,0x4c,0x2e,0x1b,0x0a,0x86,0x43,0xa2,0x51,0x14,0x20,
+0x81,0x42,0x00,0x20,0x04,0x00,0x80,0x18,0xc8,0x42,0x07,0x11,0x40,0x08,0x64,0x30,
+0x92,0x00,0x02,0x36,0x01,0x04,0x49,0xe2,0xc8,0x49,0x19,0x08,0x21,0x22,0x04,0x4b,
+0xe6,0x32,0xf9,0x6c,0x28,0x21,0x23,0x61,0x45,0x21,0xf1,0x38,0x84,0xf2,0x49,0x2a,
+0x81,0x80,0x20,0x40,0x01,0x0c,0x0d,0xdc,0x20,0x14,0xc9,0xa0,0x94,0x2a,0x10,0x05,
+0xfc,0xff,0x3f,0xaf,0xdb,0xee,0xf7,0xbb,0xed,0xf8,0x81,0x40,0x0f,0x8d,0xf0,0x30,
+0x08,0x19,0x49,0x03,0xa2,0x00,0x01,0x82,0xd3,0xf8,0x81,0xff,0x68,0x7f,0xbc,0x29,
+0xb6,0xcb,0x6d,0xba,0xde,0x00,0xb4,0xdc,0xae,0x77,0x4b,0xad,0xda,0xef,0x78,0xbc,
+0xde,0xae,0x57,0x1b,0x4d,0xae,0xe1,0x80,0xc0,0xde,0xf0,0x78,0x4c,0x2e,0x1a,0xf9,
+0x72,0xbf,0x82,0x01,0x98,0x1c,0x6d,0x37,0x0f,0x90,0xc8,0xe4,0x9f,0xf7,0xdb,0x45,
+0xad,0x80,0x88,0x09,0x58,0xe8,0x20,0x06,0x02,0x02,0x06,0x0c,0xce,0x67,0xb4,0x1a,
+0x2c,0xfe,0x4f,0x4f,0xa8,0xbc,0x65,0x6d,0x58,0xed,0x6e,0x3f,0x53,0xb0,0xd8,0xea,
+0xed,0x68,0x3a,0x16,0x86,0x85,0xa3,0xcd,0xee,0x33,0xfb,0xa8,0x1e,0x8f,0x63,0xc0,
+0xd4,0x6c,0xf5,0xdc,0x4e,0x0f,0x1b,0x23,0xc3,0x60,0x6d,0xb4,0xba,0x4d,0xdf,0x37,
+0x7d,0xa6,0xe3,0xf4,0xb0,0x9c,0x30,0x1f,0x13,0x1d,0xd3,0xec,0xde,0xb8,0x7b,0xcd,
+0xee,0x77,0x79,0xb7,0xe8,0x73,0xfb,0xfa,0xbe,0xd7,0x9b,0x11,0x69,0x79,0xd3,0x46,
+0x14,0x2e,0xb5,0x0b,0xd9,0x03,0xf7,0x40,0xfe,0x10,0x6d,0x7f,0x9f,0xef,0x68,0xd5,
+0xfa,0xbd,0xfe,0xdf,0x5f,0xf7,0xf8,0xf8,0xbe,0xcf,0xc3,0xce,0xfd,0x3f,0xd0,0x0c,
+0x00,0xfa,0xc1,0x0f,0x93,0xcb,0x01,0xbb,0x30,0x2c,0x15,0x03,0x41,0x2f,0x9b,0xfe,
+0x81,0xc1,0xaf,0xbb,0x86,0x8e,0xba,0xec,0x14,0x2c,0xf3,0x38,0x64,0x12,0x84,0x04,
+0x39,0x8e,0xf3,0x72,0xf0,0xbc,0x90,0xe4,0x3a,0xc4,0x80,0x10,0xcc,0x34,0xb8,0x44,
+0xee,0xd3,0x86,0x42,0x39,0x6e,0x74,0x46,0xf0,0x39,0x91,0x74,0x1d,0x14,0xa1,0x71,
+0x64,0x5b,0x1b,0xba,0x4e,0x19,0x03,0x10,0x44,0x51,0x2c,0x49,0x1b,0x47,0xae,0x3b,
+0x86,0x02,0x81,0x01,0x14,0x76,0xb7,0x48,0xd2,0x3c,0x52,0x40,0x01,0x00,0x54,0x68,
+0xf1,0xc8,0x8e,0x74,0x9c,0xe3,0x49,0x92,0xd3,0x88,0x07,0xcb,0x0b,0xa4,0xb7,0x30,
+0x31,0xb2,0xec,0xbc,0xbe,0x4c,0x33,0x32,0xdd,0x31,0xcc,0x8f,0xcc,0xcf,0x36,0x28,
+0x53,0x4c,0xd5,0x36,0xce,0x33,0x7c,0xc9,0x38,0xcd,0xb3,0x9c,0xbd,0x3a,0xcd,0x93,
+0xbc,0xb1,0x3c,0xcc,0xf3,0xdc,0x9d,0x3e,0xcc,0xd3,0xfc,0x8d,0x40,0xcc,0x34,0x1c,
+0x7b,0x42,0xcc,0x14,0x3c,0x6f,0x44,0xcb,0x74,0x5c,0x5d,0x46,0xcb,0x54,0x7c,0x4f,
+0x48,0xc9,0x94,0x9c,0x39,0x48,0xa0,0xb1,0x65,0x2f,0x0b,0x52,0xb1,0xdd,0x39,0x06,
+0xd3,0x34,0xfc,0xd4,0xb4,0xd3,0xd4,0xdd,0x49,0x35,0xd1,0x34,0xd4,0x35,0x50,0x40,
+0x75,0x35,0x59,0x54,0x32,0x94,0x6d,0x56,0xeb,0xd5,0xaf,0xc5,0x5f,0x5a,0xd6,0x35,
+0x15,0x4f,0x54,0x57,0x12,0xe5,0x75,0x59,0xd4,0x75,0xed,0x7c,0xd6,0xd6,0xd0,0xbd,
+0x83,0x5e,0x54,0x96,0x25,0x8b,0x60,0x55,0x56,0x15,0x95,0x65,0xcc,0x56,0x6d,0x0b,
+0x5a,0x57,0xf6,0x1d,0xa2,0xc0,0x58,0xd0,0x25,0xb1,0x6c,0xda,0x76,0xe2,0xdb,0x6d,
+0x43,0xb6,0xfa,0xdf,0x70,0xc5,0xf7,0x1c,0xd1,0x6f,0x4f,0xb6,0xab,0x5d,0x72,0xc1,
+0xd7,0x3d,0xc1,0x74,0xcf,0x37,0x5d,0x99,0x6b,0xdd,0xf3,0x75,0xe3,0x3a,0xde,0x6c,
+0x75,0xda,0xe9,0xde,0xcb,0x65,0xf9,0x1f,0x5f,0xd7,0xbd,0xeb,0x7f,0x60,0x12,0x3e,
+0x04,0x81,0xe0,0xd2,0xcd,0x91,0x58,0x60,0x97,0x55,0x9f,0x38,0x61,0x00,0x06,0x14,
+0xe0,0xe2,0x58,0x9d,0xf1,0x71,0xe2,0x8e,0x06,0x2d,0x8d,0x36,0x58,0x96,0x3a,0xd8,
+0x63,0x98,0xc5,0xbf,0x90,0x35,0x39,0x16,0x1d,0x77,0xe4,0xae,0x16,0x3f,0x91,0xdb,
+0x99,0x53,0x4f,0x93,0xda,0x18,0x46,0x5e,0xc9,0xe6,0x38,0x8e,0x67,0x96,0xdb,0x19,
+0xa3,0x25,0x9b,0x4e,0x99,0x66,0x51,0x73,0xe7,0x6e,0x46,0x7f,0x99,0x60,0x5a,0x13,
+0x21,0x9e,0xcf,0x1a,0x26,0x6f,0xa3,0x67,0x36,0x8e,0x8e,0xc3,0xe9,0x33,0xe6,0x97,
+0x9f,0x67,0x1a,0x06,0x33,0xa7,0x59,0x7a,0x83,0x0d,0xa9,0x50,0x1a,0xa6,0x95,0xab,
+0x68,0xb4,0x0d,0xf5,0x69,0x6a,0xf9,0x26,0xb3,0x30,0x6c,0x8c,0x0e,0xb6,0xc2,0xeb,
+0xb4,0x26,0x19,0x5c,0xec,0xd9,0x76,0xd1,0x2d,0xed,0x56,0xee,0xe5,0x9d,0x6e,0x92,
+0xd6,0xec,0xb8,0x6d,0x8e,0xa6,0xbf,0xa9,0xd9,0xd6,0x4e,0x99,0x82,0xef,0x52,0x66,
+0xf9,0x72,0x70,0xd5,0x36,0xfc,0xc1,0xd7,0x78,0x6e,0xc5,0x7b,0x71,0x8b,0xdf,0x1d,
+0xb8,0xf2,0x19,0x4f,0x15,0x16,0x71,0x17,0x46,0xf1,0xa7,0xf3,0x14,0xaf,0x24,0xed,
+0xf0,0x1a,0xf6,0xc3,0xc2,0x72,0x3c,0xf3,0xaf,0xcd,0x5e,0x1c,0xe6,0xb5,0xd3,0xb8,
+0x9d,0x4d,0xff,0xd6,0xd1,0x3d,0x02,0xf3,0xca,0x5a,0xdc,0xb6,0x83,0xd8,0xd0,0xbd,
+0x9b,0x55,0xd1,0x6d,0xfd,0x26,0xab,0x6a,0x62,0x1e,0x06,0xc7,0xe1,0x6c,0x1a,0x6f,
+0x57,0x62,0x77,0x6b,0xbe,0xdd,0x44,0x77,0xbe,0x6f,0x05,0xc7,0xf4,0xb7,0x97,0x8b,
+0xc0,0xf8,0xfd,0xbe,0xb1,0xe4,0x57,0xde,0x52,0xed,0xe6,0x51,0x9b,0x87,0x6d,0xe9,
+0x5f,0x3e,0xa7,0x47,0xeb,0x7c,0x3e,0xc7,0xaf,0xb3,0xfb,0x35,0xc7,0xb6,0xba,0xfb,
+0xb4,0x87,0x9d,0xef,0x77,0xfe,0x32,0x9b,0xd7,0xd0,0x3f,0x64,0xbe,0xb7,0x33,0x9c,
+0xef,0xd5,0x57,0xfe,0xeb,0x9a,0x00,0x00,0x81,0x40,0xe0,0x90,0x58,0x34,0x1e,0x11,
+0x09,0x85,0x41,0x01,0xef,0xf8,0x74,0x3e,0x21,0x11,0x89,0x44,0xe2,0x91,0x58,0xb3,
+0xfe,0x17,0x19,0x8d,0x46,0xe1,0x30,0xd8,0xbc,0x7e,0x41,0x21,0x88,0xc7,0x24,0x92,
+0x58,0x5c,0x7a,0x45,0x29,0x95,0x44,0xa4,0xd2,0xd9,0x74,0x0a,0x51,0x2b,0x99,0x4a,
+0x65,0xf3,0x59,0x24,0xc6,0x67,0x39,0x8b,0xcd,0xa7,0x91,0x99,0xc4,0xea,0x81,0x2c,
+0x9e,0xd0,0xe0,0xf3,0xfa,0x0d,0x1e,0x31,0x44,0xa5,0x40,0xe8,0xd4,0x8a,0x05,0x2e,
+0xa1,0x4d,0xa7,0x4e,0x6a,0x14,0xba,0x95,0x4e,0x65,0x55,0xa5,0x55,0xeb,0x12,0xaa,
+0xd4,0x18,0x41,0x2e,0xae,0x57,0x64,0x55,0xfa,0x1d,0x8e,0xc9,0x20,0xb3,0x4f,0x6d,
+0x16,0x99,0xdd,0xae,0x6d,0x6d,0xb7,0x45,0x6e,0x10,0x2b,0x0c,0xb6,0xe5,0x73,0x89,
+0xdd,0x66,0xb7,0x9b,0xd4,0x8e,0xeb,0x77,0x93,0x5f,0xaf,0xf0,0xfb,0xe4,0xbf,0x09,
+0x85,0xa4,0xdc,0x30,0x52,0x5c,0x4e,0x17,0x0f,0x62,0xc5,0x4a,0xef,0x98,0xd9,0xbe,
+0x4e,0xbd,0x91,0xc1,0xe6,0x26,0x98,0x1c,0x96,0x72,0x43,0x9a,0xcd,0xe8,0x2d,0x59,
+0xeb,0xc6,0x93,0x4b,0xa2,0x8e,0x63,0xef,0xf9,0x5c,0xfe,0xa2,0x2d,0xaa,0xcb,0xec,
+0x36,0x3a,0x6d,0x1e,0xd2,0x29,0xb2,0xd5,0xee,0x2e,0x9b,0xa8,0xd6,0xb2,0xf5,0xbe,
+0xdf,0xef,0x37,0x3c,0x29,0x3f,0x12,0xf7,0xc6,0x85,0x70,0x2e,0x7a,0xed,0x3f,0x23,
+0x01,0xca,0x84,0x73,0x2d,0xdc,0xed,0xbf,0x42,0x1d,0xd2,0x8e,0xf6,0x22,0x1d,0x6c,
+0x77,0x73,0x0d,0xda,0xa2,0xf8,0x3b,0x3e,0x28,0x37,0x52,0xd3,0xe6,0xf3,0xf9,0x31,
+0x7e,0xa9,0x87,0xb3,0xbd,0xb3,0xf0,0x7c,0x77,0x7e,0x4f,0x74,0x33,0xe1,0xf7,0xf7,
+0xfd,0xbf,0x40,0x0f,0x45,0x91,0xfd,0x7f,0x9f,0x97,0xe9,0xff,0x57,0x60,0x18,0x15,
+0x58,0x81,0xe0,0x37,0xde,0x08,0x54,0xe0,0xa7,0xf2,0x04,0x82,0xde,0xe8,0x35,0x4e,
+0x83,0xdf,0x37,0xf6,0x14,0x52,0x21,0x67,0x72,0x1b,0x76,0x21,0xd7,0x42,0x1f,0x72,
+0x22,0x17,0x12,0x23,0x6f,0x22,0x56,0xe2,0x27,0x6d,0x22,0x96,0xc2,0x2b,0x6a,0x22,
+0xd6,0x92,0x2f,0x68,0x23,0x16,0x72,0x33,0x66,0x10,0x80,0x21,0x43,0x03,0x17,0x18,
+0x49,0x03,0x8e,0x1c,0xa8,0x65,0x47,0x8d,0x59,0x35,0x0c,0x02,0x65,0x96,0x78,0xf1,
+0xe6,0x90,0x14,0x19,0x09,0x8a,0x7d,0x11,0xb9,0x29,0x4f,0x86,0x24,0x85,0x56,0x46,
+0x93,0xe5,0x37,0x6a,0x50,0x4e,0x90,0x80,0x05,0x4b,0x95,0x5c,0x38,0x41,0x05,0x97,
+0x23,0xf9,0x5c,0x40,0x52,0xa5,0xe4,0xfa,0x53,0x98,0x9c,0x69,0x65,0x54,0x6d,0x9d,
+0xf9,0x82,0x13,0x95,0xe5,0xd6,0xbe,0x1c,0x94,0xa7,0x05,0x7e,0x67,0x71,0xe7,0x74,
+0x0c,0x05,0x98,0xe7,0xb9,0x52,0x74,0x87,0x94,0x30,0x49,0x55,0x9b,0x13,0x39,0x3a,
+0x5f,0x85,0xe1,0x19,0xfd,0x50,0x9e,0x5c,0xb9,0xca,0x7e,0xa2,0xa0,0xca,0x42,0x6b,
+0xa5,0x1c,0x2a,0x19,0x59,0x9d,0xa9,0x24,0x24,0x10,0x4f,0x28,0xe7,0x6e,0x8c,0x41,
+0x29,0xd6,0xca,0x98,0x65,0x26,0xe7,0xca,0x75,0xa2,0xe9,0xb9,0xe2,0x81,0x88,0x29,
+0xaa,0xa5,0x05,0xa7,0xd7,0xca,0x95,0x99,0x41,0xa3,0xea,0x56,0xa1,0xa4,0x6b,0x05,
+0x9a,0xb2,0x78,0xe8,0xca,0xdd,0x3d,0xaf,0x5e,0xba,0x30,0x02,0xae,0xa8,0x2a,0xaa,
+0xbb,0x7a,0xab,0x46,0x76,0xc8,0xb1,0xe9,0x3a,0xe6,0xb8,0xaa,0xe4,0x9a,0x59,0xbe,
+0xb2,0xd6,0x5a,0xbe,0xce,0x9c,0x6d,0x0a,0x5e,0xd4,0x6e,0xad,0x66,0x86,0xd8,0xab,
+0x90,0x79,0x96,0xd1,0xb2,0x50,0x29,0xaa,0xdc,0xb6,0xed,0x5b,0x76,0xa4,0xbb,0x1a,
+0xab,0x7d,0xa9,0xb3,0xed,0x27,0x8a,0xf0,0x47,0xe4,0xc6,0x42,0xe1,0x88,0xaf,0x98,
+0x92,0xfb,0x89,0xaf,0xd8,0xa2,0xff,0x8a,0xb0,0x18,0xb3,0x03,0x8b,0xb0,0x58,0xc3,
+0x07,0x8c,0xb0,0x98,0xd3,0x0b,0x8d,0xb0,0xd9,0x0e,0xa7,0x7d,0x6f,0x39,0x62,0xee,
+0x4b,0xec,0x24,0x16,0xf5,0x5b,0xec,0xdb,0x89,0x6b,0xc5,0xdf,0x8b,0xaa,0xde,0xc5,
+0x52,0xec,0x79,0x4c,0xc8,0x99,0x1c,0x65,0xb5,0x63,0x2a,0xdb,0xeb,0x1b,0xcb,0x31,
+0xdc,0xae,0xfc,0xcb,0x73,0x1c,0xbd,0xcf,0xc4,0xdd,0x2c,0xa1,0xbd,0xca,0xb3,0x5b,
+0x9a,0xf4,0xc9,0x92,0x6c,0x91,0xfb,0xcd,0xac,0x6c,0x72,0xbc,0xcc,0x2f,0xec,0xcb,
+0x47,0xbc,0xb3,0xcc,0x53,0x20,0xbb,0x74,0xdb,0xbf,0x3e,0x49,0x74,0x08,0x0b,0x4f,
+0x68,0xb3,0x87,0x17,0x3a,0x75,0xed,0x9b,0x2b,0x51,0x49,0x35,0x3d,0x5d,0xc9,0xd2,
+0x30,0x0d,0x8b,0x02,0xd9,0x30,0x4d,0x9b,0x06,0xd6,0x66,0xfd,0x09,0x44,0xd7,0xf5,
+0xd5,0xc3,0x60,0x50,0xb6,0x8c,0x23,0x73,0xc2,0xb7,0x5c,0x33,0x77,0xc3,0xb7,0x9c,
+0x43,0x7b,0x93,0x70,0xfd,0xfb,0x7d,0xbe,0x38,0x16,0xb7,0x7f,0xe0,0xb4,0xad,0x6e,
+0xd3,0xd5,0x59,0xad,0xc5,0xd1,0xe1,0xf4,0x4d,0x73,0x8a,0xc9,0xf6,0xf5,0xaf,0x8c,
+0x77,0x78,0x5e,0x13,0x83,0x70,0x79,0x7e,0x6b,0x99,0x73,0x79,0xbe,0x7b,0x9d,0x75,
+0x79,0xfe,0x8b,0xa1,0x7a,0x7a,0x3e,0x99,0x5f,0x09,0x23,0xbe,0x45,0x87,0xe5,0x5e,
+0x1e,0x96,0x00,0xe9,0xfb,0x14,0x1e,0xc5,0xb9,0x78,0x8b,0x9f,0x43,0xcb,0x95,0x51,
+0x11,0x76,0xd1,0xb6,0x3e,0x3b,0xba,0xab,0x33,0xbe,0xdf,0x4c,0xdb,0x14,0x3d,0xbb,
+0xac,0xac,0xf9,0x34,0x6b,0xc8,0xf1,0xae,0xbf,0x27,0x5e,0xef,0xb6,0x5f,0x03,0x33,
+0x55,0x7a,0xa0,0x03,0xcd,0xd2,0xf3,0x7f,0x2d,0x19,0xf6,0x7c,0x4f,0x6f,0xd0,0x47,
+0x3d,0xee,0x3f,0x89,0xf3,0xa9,0xef,0x4b,0x67,0xf5,0x34,0x9e,0xef,0xbd,0xf0,0xfe,
+0x4c,0xf7,0xe1,0xe5,0x3d,0xc5,0x6b,0xae,0x79,0x7b,0x08,0x1b,0xb2,0xfe,0x36,0xaa,
+0xa3,0xdf,0xee,0x7d,0x54,0x00,0x01,0x02,0x81,0xc1,0x20,0xb0,0x68,0x3c,0x14,0x41,
+0x08,0x85,0xc0,0xc1,0xef,0xf8,0x7c,0x42,0x23,0x12,0x89,0xc5,0x22,0xb1,0x68,0xbb,
+0xfe,0x19,0x1a,0x8d,0xc7,0x23,0x90,0xe8,0xc4,0x82,0x43,0x22,0x89,0x47,0x64,0xb0,
+0xb8,0x54,0x9a,0x1b,0x23,0x95,0xcb,0x22,0xb2,0x99,0x7c,0xc2,0x0b,0x1f,0x96,0xcd,
+0x25,0x90,0x89,0x44,0xc6,0x73,0x07,0x99,0xcd,0x67,0xb2,0x08,0x40,0x22,0x75,0x42,
+0x99,0x4f,0xa8,0xb1,0x8a,0x1d,0x22,0x19,0x3c,0xa3,0x53,0x22,0x14,0x98,0xdc,0xe2,
+0x53,0x4b,0xa6,0xd3,0x29,0xf5,0x68,0x25,0x4e,0xa9,0x45,0xab,0xd7,0x2b,0x35,0xa9,
+0xed,0x72,0xaf,0x5e,0xaf,0xcd,0x2c,0x35,0x6b,0x1d,0x92,0x6d,0x66,0xa4,0xda,0x2d,
+0x32,0x3b,0x5d,0xb2,0xdd,0x46,0xb8,0x52,0x2d,0xb7,0x29,0xfd,0xd2,0x85,0x76,0xbb,
+0xc5,0xee,0x80,0x1b,0xd5,0xf2,0xc1,0x70,0x01,0x60,0x30,0x36,0x5b,0xcc,0xea,0xf7,
+0x86,0x89,0xca,0x42,0x98,0x8a,0xc6,0x2e,0x5b,0x8f,0x9c,0xe2,0xb2,0x34,0xec,0x9c,
+0xc3,0x2b,0x96,0x8c,0xe6,0x25,0xf9,0xac,0xb6,0x77,0x3d,0x9b,0xb7,0xe8,0x64,0xd9,
+0xfc,0x8e,0x97,0x4d,0xa3,0x91,0x6a,0x64,0xba,0x7c,0x5e,0xb6,0x3b,0xaf,0xc3,0x6c,
+0x63,0xda,0xb9,0x0e,0xd6,0x37,0xb3,0xc0,0xe2,0x2f,0xf3,0x1d,0xdd,0xf3,0x73,0x1a,
+0xe0,0x5d,0xf7,0xb9,0x4d,0xbd,0xe2,0xae,0x24,0xa7,0xf1,0x2e,0x5c,0x2a,0x57,0x22,
+0x8f,0x79,0xdf,0x66,0x7a,0x37,0xdb,0x87,0x2f,0x13,0xd6,0x8b,0x42,0x31,0xd0,0x7e,
+0xf0,0x00,0x08,0x80,0x8e,0xf5,0x34,0x5d,0xb8,0xa7,0x3e,0x17,0xcd,0xb7,0x50,0x8a,
+0x11,0xcf,0x2d,0x4b,0xcf,0xe8,0xf4,0xce,0xfe,0x58,0xc8,0x27,0xbb,0xe9,0xeb,0xb4,
+0xdd,0x08,0x90,0x2a,0x8b,0x54,0xfb,0x22,0x29,0xc8,0x02,0x20,0x2f,0x2f,0xda,0xc8,
+0xc7,0xc0,0x0d,0x74,0x05,0x01,0xbe,0x88,0x34,0x10,0xaf,0xc1,0x4d,0xfc,0x1a,0xcb,
+0xc1,0xec,0x84,0x2a,0xce,0x2f,0x30,0x5b,0x65,0x0c,0xc3,0x50,0xba,0x05,0x08,0xab,
+0x50,0x9b,0xab,0x0c,0xc4,0x10,0xc4,0x2a,0xba,0x3b,0x30,0xe3,0x6d,0x13,0x44,0xf1,
+0x0c,0x3c,0xbc,0xc0,0xd1,0x63,0x75,0x18,0xa1,0x00,0x2a,0x06,0x14,0x27,0x2c,0x23,
+0xb5,0x17,0x29,0x00,0x22,0x19,0x1a,0x38,0x71,0xb2,0x90,0xf8,0x2e,0x31,0xf2,0xcc,
+0xff,0x00,0x12,0x13,0xa1,0x24,0x44,0x11,0x12,0xa8,0xba,0x25,0x12,0x63,0xd5,0x22,
+0x2c,0xd2,0x04,0x7b,0x14,0xc5,0xe0,0x04,0xa0,0xa6,0xcb,0x72,0xe4,0xad,0x27,0xcc,
+0x30,0xbc,0xba,0xaa,0xb0,0x71,0x9c,0x29,0x27,0x4c,0x93,0x1a,0xcd,0x2a,0x21,0x13,
+0x2a,0xe7,0x2d,0xce,0x0a,0xdb,0x11,0x37,0x3e,0xb3,0x54,0x1f,0x39,0xa7,0xd1,0x94,
+0xb3,0x06,0xae,0x91,0xe3,0x8f,0x3c,0x2a,0xc0,0x14,0xed,0x37,0xcd,0x89,0x80,0x05,
+0x03,0x24,0xf3,0x4c,0xb5,0x1f,0xc8,0x34,0x64,0xfc,0xa4,0xc8,0xc0,0x04,0x0b,0x3e,
+0xc0,0x52,0xfc,0xf4,0xc1,0x45,0xf4,0xca,0x6b,0x29,0x30,0xb4,0x6c,0xae,0xff,0xd2,
+0x14,0xbc,0xe5,0x43,0xbd,0x34,0xe3,0x0e,0xb8,0x51,0x55,0x1b,0xec,0x94,0x80,0x4f,
+0x1a,0x4b,0x40,0x55,0x8f,0x95,0x31,0x53,0x3b,0xa9,0x4c,0x75,0x4b,0x55,0xb5,0x2d,
+0x05,0x53,0xd6,0xce,0x15,0x50,0xc9,0x27,0x4f,0xca,0xd7,0x60,0xad,0x54,0xdd,0x7e,
+0xdc,0xd8,0xc9,0x5d,0x6b,0x5e,0xb9,0xf6,0x5b,0x48,0xb5,0xc9,0x54,0x0d,0x41,0x31,
+0x59,0xd2,0xfd,0xb1,0x6c,0xdb,0x56,0xdd,0xb9,0x6e,0xc4,0x89,0x2d,0x0b,0x6f,0x56,
+0x35,0x75,0xc4,0x9d,0x00,0x77,0x2d,0xd1,0x74,0xaa,0xc0,0x85,0xd4,0xd4,0xdd,0x89,
+0xd5,0x27,0x76,0xde,0x57,0x9d,0xe8,0xae,0x3c,0xb5,0x5a,0x6f,0x7a,0xa8,0x55,0x5c,
+0xb0,0x83,0x57,0x37,0xd3,0x27,0x70,0xe0,0x18,0x1a,0x87,0x59,0x2a,0xf8,0x15,0xb9,
+0x77,0xa4,0xa0,0x92,0x36,0x00,0x86,0x38,0x22,0x0f,0x78,0xa7,0x38,0x45,0xc5,0x83,
+0x62,0x12,0xdd,0x5f,0x8b,0xa0,0x6f,0x06,0x35,0x78,0x14,0x08,0xd9,0xf0,0x83,0x5f,
+0xa9,0x38,0x41,0x44,0xe3,0xa8,0x40,0xf3,0x7c,0x00,0x18,0x52,0x16,0x03,0x62,0xf8,
+0xa2,0x4d,0x58,0x64,0xea,0x7e,0x2d,0x79,0xe6,0x08,0xee,0x6b,0x99,0xa8,0x59,0x95,
+0xeb,0x21,0x65,0x48,0xd6,0x6b,0x9f,0xe3,0x59,0x1a,0x3b,0x95,0x67,0x37,0x6e,0x6f,
+0x9d,0x34,0x20,0x0e,0x79,0x81,0x82,0x01,0x06,0x59,0xa5,0x27,0x22,0x16,0xa5,0xaa,
+0xea,0xd7,0x96,0x92,0x86,0x64,0xda,0x16,0xae,0x92,0xe2,0x57,0x56,0xb3,0x20,0xeb,
+0xfa,0xae,0x19,0xa0,0x20,0x5a,0x6d,0xe9,0xa2,0x21,0x1a,0xe6,0xba,0x00,0x6d,0x19,
+0x12,0x53,0x69,0xe0,0x69,0x46,0x32,0xab,0xee,0xbb,0x6e,0xf0,0x82,0x6c,0x28,0x45,
+0x09,0x8d,0x3b,0x2a,0xb8,0x23,0x93,0x6b,0xbb,0x1a,0x17,0xb7,0xde,0x7b,0xfa,0x0b,
+0x7f,0xe8,0xe8,0x45,0x2b,0xbc,0xa5,0xe2,0x07,0x09,0xc7,0x20,0x9c,0x8e,0xba,0xa0,
+0xf2,0x48,0xd7,0x1a,0xf0,0xa3,0x5b,0xdf,0x2f,0xce,0xed,0xbc,0x32,0x5f,0xa8,0xc7,
+0x68,0xe7,0x40,0xc4,0x71,0x69,0x4f,0x28,0x86,0x3c,0x72,0x02,0x83,0x2c,0x3c,0x70,
+0x37,0x2c,0x85,0x75,0xe0,0x07,0x5b,0xb3,0x80,0x1d,0x87,0x35,0xb7,0x20,0x7d,0xaf,
+0x75,0xdc,0x6d,0x49,0x7f,0x7e,0xb8,0x47,0x08,0x45,0xfa,0x30,0x20,0x7e,0x0b,0x07,
+0xd2,0xa0,0x5a,0x17,0x04,0x00,0x5f,0xe9,0xd6,0x65,0xde,0x76,0x7c,0xb7,0x6c,0xc2,
+0x7a,0x5d,0xbf,0x69,0xdc,0xfa,0x7e,0xd7,0xb0,0x81,0x79,0x08,0x17,0xa8,0xa1,0x7c,
+0x3f,0x12,0x16,0xf0,0x73,0x89,0x8f,0xc6,0x83,0xbc,0x48,0xdf,0xd3,0x02,0x78,0xe8,
+0x25,0xf1,0x55,0xdf,0x9f,0x87,0xdf,0xde,0xfe,0xbe,0x5f,0xee,0x83,0x0f,0x3f,0x3e,
+0x74,0x3c,0x21,0x88,0x00,0x50,0x01,0x03,0x82,0x41,0x60,0xa9,0x08,0x20,0x2a,0x0d,
+0x0b,0x86,0x43,0x61,0xd0,0xf8,0x84,0x46,0x25,0x05,0x64,0x44,0x01,0x10,0xc0,0x0c,
+0x34,0x04,0x20,0x89,0xc7,0x62,0x04,0x08,0x24,0x5e,0x3d,0x23,0x85,0x8c,0x63,0x90,
+0xe0,0x14,0x32,0x53,0x24,0x91,0xc8,0x20,0x60,0x48,0x2c,0xba,0x07,0x27,0x00,0x4a,
+0xc0,0x13,0x08,0x24,0xca,0x71,0x03,0x9d,0x4c,0x60,0x93,0xb9,0x64,0x7a,0x65,0x41,
+0x89,0x84,0x22,0x54,0x3a,0x25,0x26,0x06,0x02,0x40,0x44,0x68,0x14,0xa9,0xec,0xe6,
+0x7f,0x3e,0x97,0xd5,0x26,0xf5,0x6a,0x05,0x46,0x95,0x5b,0xae,0x43,0xc1,0x35,0xd8,
+0xf0,0xa2,0xc1,0x60,0xad,0x00,0x2c,0xb0,0x5a,0xcd,0x4e,0xa5,0x55,0xb5,0xd5,0xec,
+0x76,0xfb,0x85,0xc6,0xe5,0x73,0xba,0x47,0x41,0x14,0x6b,0xad,0xe6,0xf5,0x73,0xa6,
+0x46,0x29,0x17,0x48,0x15,0x04,0x03,0x7f,0x86,0xdd,0xef,0x78,0x79,0x56,0x23,0x15,
+0x44,0x12,0x41,0x2f,0xb0,0xca,0x6c,0x42,0xc5,0x13,0xc3,0x62,0xf2,0xd7,0xbc,0x0e,
+0x5e,0x55,0x34,0x89,0x11,0x2e,0x79,0x58,0x66,0x12,0x0d,0x36,0xb3,0x5d,0x00,0x79,
+0xa8,0xf4,0x66,0x23,0x34,0xd2,0x00,0x14,0x1a,0x8b,0xae,0x82,0x3b,0xa4,0xd1,0x6c,
+0x36,0xd0,0x42,0x84,0x13,0x55,0x33,0xdb,0xe2,0xb6,0x50,0x5b,0xc6,0xf7,0x85,0x4e,
+0xe1,0xf1,0x77,0xf8,0x98,0x26,0x73,0x8b,0xcb,0xc8,0x80,0x24,0x50,0xbc,0xf5,0xbc,
+0x11,0xcd,0xe8,0xed,0xf8,0xf6,0xd8,0x9f,0x2b,0x97,0x72,0xc7,0x80,0x37,0x71,0x3d,
+0x6e,0xeb,0x9b,0xdb,0xf2,0x79,0x7b,0x9e,0x3f,0x37,0xa6,0x09,0xe8,0xf5,0x62,0x30,
+0x71,0x88,0x6e,0x67,0x7b,0xd5,0xf6,0xdc,0xe9,0xff,0x5d,0xb7,0x06,0xc1,0xdd,0xfc,
+0x7f,0x61,0x63,0x07,0xe0,0x11,0x57,0x00,0x26,0xd5,0xfe,0x81,0x9f,0xb8,0x15,0x41,
+0x6e,0x54,0xb7,0x69,0x9a,0x80,0x17,0x08,0x25,0x2c,0x7e,0x9b,0x68,0x3d,0x63,0x77,
+0xd6,0x07,0xdd,0xbd,0x84,0xe0,0x76,0x5a,0x1b,0x52,0xdc,0xd7,0xca,0x1c,0x88,0xa2,
+0x38,0x92,0x25,0x89,0xa2,0x78,0xa2,0x29,0x8a,0xa2,0xb8,0x66,0x2b,0x5c,0x21,0xe4,
+0x19,0xef,0x8b,0x90,0xc8,0x56,0x33,0x5c,0xa3,0x54,0x8d,0xfc,0x5c,0x1d,0x38,0xd9,
+0xe4,0x83,0x58,0xa6,0x4d,0xe9,0x01,0x16,0x75,0xbe,0x0f,0x82,0xe2,0x87,0x85,0x71,
+0x8b,0x51,0x06,0x66,0x3a,0x6d,0x9e,0xc5,0x75,0xcf,0x89,0xe1,0x78,0xf5,0x6f,0x4d,
+0x01,0x25,0xca,0x52,0x51,0x65,0x59,0x66,0x5c,0x44,0x65,0xa9,0x79,0x6f,0x92,0xd2,
+0x47,0x76,0x21,0x47,0xa4,0xe4,0x3e,0x65,0x67,0xdd,0xc9,0x86,0x56,0x5c,0x26,0x86,
+0x59,0xd7,0x9b,0x57,0x59,0x06,0x70,0x9b,0x67,0x24,0x3a,0x30,0x7e,0x23,0xf6,0xc5,
+0x97,0x46,0xd1,0x10,0x89,0xc4,0x52,0xa7,0x84,0x92,0x50,0x9c,0xd2,0xc6,0x92,0x81,
+0x8d,0xa8,0x48,0x1a,0x49,0x62,0x80,0x58,0x1a,0x7c,0x58,0xe8,0xc4,0x7a,0x60,0x40,
+0xe8,0x6a,0x16,0x2e,0x95,0x1d,0xe5,0x76,0x8e,0x41,0xa6,0x65,0xc6,0x94,0xa1,0xea,
+0x39,0xda,0x93,0x9e,0xaa,0x36,0x5a,0xa0,0x8c,0xd8,0x60,0x28,0x02,0xa5,0xaa,0x84,
+0x74,0x60,0x16,0x2b,0x04,0xb1,0x95,0x1a,0x2b,0x45,0x26,0x9e,0x68,0xe9,0x84,0x62,
+0xbc,0x81,0xd9,0x59,0x1e,0x27,0xa9,0xd6,0x0a,0x6d,0x03,0x00,0x6b,0xe7,0x6e,0x63,
+0xa0,0xd7,0x84,0x82,0x11,0xae,0x10,0xc0,0x86,0xca,0xb3,0xd0,0x5a,0x8a,0xd3,0x43,
+0x88,0x08,0xca,0xd6,0x43,0xed,0x5b,0x69,0x0b,0xb2,0x2d,0xd6,0x1a,0x7f,0xb7,0x51,
+0x31,0x52,0xce,0xb6,0x98,0x60,0x40,0x40,0x81,0x2e,0x34,0x44,0x40,0xb0,0xee,0x3b,
+0x72,0xec,0xbc,0x92,0x4a,0x4a,0xf3,0x52,0xef,0x64,0x3e,0x43,0xbe,0x11,0x3a,0xaa,
+0xfb,0xbf,0xaf,0xf4,0x45,0xa7,0x49,0x2a,0xf9,0x72,0x38,0x44,0xa9,0x06,0xf2,0xec,
+0xae,0x9c,0x39,0x4a,0xe6,0x57,0x70,0x21,0x81,0x8e,0x57,0x70,0x85,0xcd,0xdf,0xbd,
+0x55,0xd8,0x3f,0x02,0xc0,0x00,0x0c,0x19,0x6f,0x06,0x31,0xbc,0x83,0x21,0xc8,0xb2,
+0x3c,0x93,0x25,0xc9,0xb2,0x7b,0x8f,0x1a,0xc0,0x31,0x9c,0x87,0x1d,0x9a,0x6d,0xfc,
+0xa2,0x55,0xca,0xaf,0xf8,0x03,0x0b,0xa2,0xd4,0x90,0x13,0x30,0x41,0xb1,0xf8,0x8e,
+0xef,0x43,0x12,0x2c,0x47,0x24,0xce,0xad,0x3c,0x13,0x1b,0xd0,0xec,0xfd,0x15,0x85,
+0xb8,0xf3,0x0d,0x25,0x0b,0xcf,0x15,0xbb,0xf5,0x8b,0xd3,0x55,0xbb,0x16,0x27,0x20,
+0x5e,0x0d,0x0f,0x55,0x88,0xaf,0x1b,0xcb,0x57,0xc6,0xd8,0x6c,0x3a,0xe3,0x08,0x35,
+0xab,0xb3,0x5c,0xbb,0x36,0x4b,0xc3,0x3e,0xbe,0x36,0x84,0x32,0x8a,0xa1,0xf6,0x6b,
+0x8f,0x6c,0xcb,0xe6,0x1d,0xc2,0xdd,0xd7,0xb0,0x0d,0xd6,0xda,0xdd,0xef,0xfd,0xe6,
+0xd6,0xde,0xef,0xed,0x81,0x0a,0xc8,0x82,0x0d,0x1e,0xb8,0xdf,0x6d,0x3d,0xfd,0x60,
+0xd4,0x61,0xce,0x1e,0xcf,0x14,0x72,0x00,0x23,0x41,0x7a,0xb3,0x35,0xc3,0x94,0x44,
+0xb8,0x94,0x3b,0x14,0xdb,0x90,0xfc,0x51,0x72,0x57,0xd0,0xc0,0x1a,0x59,0xda,0xae,
+0x34,0xef,0x98,0xbd,0x80,0x1e,0x8e,0xda,0x50,0x3a,0x68,0x89,0xf4,0x58,0xea,0xee,
+0xa6,0xf2,0xe1,0x57,0x98,0xf3,0x15,0xec,0xdb,0x2c,0x5d,0x24,0xdc,0xa2,0x3c,0xdb,
+0xba,0x71,0x6c,0x77,0xb7,0xb9,0x9c,0xf9,0xb4,0x6b,0x31,0xf1,0xbc,0x7f,0x23,0x93,
+0xcb,0x7c,0x9c,0x6f,0x96,0xbe,0x32,0xcc,0x83,0x2e,0x81,0xfc,0x0f,0x33,0xd5,0xf5,
+0xbd,0x7f,0x63,0xd9,0xf6,0xa2,0x7e,0xf7,0x29,0x00,0x3b,0x1f,0x12,0x6d,0xcb,0x3b,
+0x3a,0xa2,0x35,0xd8,0x7d,0xb8,0xdb,0xce,0xbe,0x7e,0x78,0xa3,0xd2,0x7e,0x3e,0xc5,
+0x83,0xe4,0x6d,0xbd,0xda,0x4f,0x28,0xfc,0xaa,0x3d,0x4d,0x0f,0xfd,0xe2,0x6e,0xcf,
+0xf0,0x89,0x50,0x00,0x40,0x02,0x07,0x04,0x82,0xc1,0xa0,0xf0,0x88,0x4c,0x2a,0x17,
+0x0c,0x86,0xc3,0xa1,0xf0,0xf4,0x04,0x3c,0x29,0x10,0x8a,0xc5,0xa2,0xf1,0x88,0x64,
+0x0a,0x33,0x1c,0x8e,0xc7,0xa3,0xf0,0x94,0x0c,0x82,0x47,0x24,0x92,0xc1,0x81,0x01,
+0x09,0x34,0xaa,0x57,0x25,0x91,0x4b,0x25,0xf3,0x08,0x6c,0xa4,0x81,0x31,0x9a,0xcd,
+0xa1,0x02,0x09,0x74,0xde,0x5e,0x22,0x9b,0x4a,0x27,0x74,0x09,0xdc,0xea,0x83,0x44,
+0x90,0x1a,0x25,0x34,0x5a,0x4c,0xaa,0x87,0x4a,0xa6,0xc5,0x67,0xf4,0xea,0x8c,0x74,
+0x03,0x52,0xaa,0xc3,0x6a,0x15,0x6a,0xcc,0x39,0x02,0x02,0x89,0x56,0xab,0xe0,0x0a,
+0xc5,0x82,0xc7,0x05,0xa6,0x59,0x29,0xd3,0xd0,0x04,0xcc,0xa5,0x67,0xb1,0x88,0x00,
+0x96,0xda,0xcd,0x40,0x15,0x71,0xaf,0x98,0x2b,0xd7,0x5a,0x8d,0x42,0x91,0x79,0xa4,
+0x80,0xa6,0x90,0x52,0x0c,0x4e,0xb4,0x24,0xa2,0x54,0x0c,0x10,0xfa,0xa5,0xf6,0xac,
+0x02,0xc5,0xcb,0x2c,0x52,0xcc,0x6e,0x3a,0x21,0x78,0x86,0x81,0x62,0xd9,0x2c,0x9c,
+0x2a,0x37,0x9a,0xaa,0xd9,0xb3,0xb3,0xeb,0xe5,0xff,0x41,0x45,0x03,0x14,0x34,0x94,
+0x1c,0x86,0xa2,0x89,0x95,0xd5,0xcd,0x6f,0x9a,0xed,0x8e,0xca,0x4d,0xb0,0xd9,0xcc,
+0x44,0x1b,0x68,0xce,0x03,0x73,0x30,0xb8,0x45,0x40,0x9b,0xbd,0xe4,0x97,0x39,0xc2,
+0xc7,0xf1,0x63,0x00,0x3e,0x3c,0xa8,0x61,0xca,0x9b,0x61,0x79,0xb2,0x5e,0x4f,0x42,
+0x47,0xcc,0x00,0x74,0xa5,0x5c,0x4d,0x97,0x56,0x5f,0xd9,0xe9,0xf7,0xbb,0xfe,0x0f,
+0x0f,0x8b,0xc7,0xe4,0xf2,0xf9,0xbc,0xfe,0x88,0xf7,0x5f,0xd3,0x0c,0xea,0xfa,0xfd,
+0x90,0xae,0xdc,0x3e,0xbb,0xf0,0xfa,0xc3,0xfd,0xff,0x68,0x37,0x33,0x83,0x26,0xc5,
+0x51,0x3f,0xc9,0x78,0x40,0xd6,0xa4,0x90,0x02,0x80,0xcc,0xbb,0x08,0x1c,0x0e,0xfc,
+0xa1,0x20,0x24,0x07,0x05,0xac,0x30,0x7a,0x22,0x96,0x22,0x8d,0xb3,0xbb,0x04,0x2e,
+0xad,0xac,0x24,0x95,0xc2,0xcb,0x03,0x7c,0x87,0x43,0x90,0x8a,0x0c,0xcf,0xa1,0x0f,
+0xa3,0xca,0xd5,0x44,0x31,0x14,0x50,0x82,0x44,0xf1,0x50,0x00,0x30,0x40,0xad,0x5c,
+0x4a,0x95,0xc3,0x31,0x6a,0x07,0x11,0xbf,0x31,0x64,0x5b,0x18,0x41,0xf1,0xcc,0x55,
+0x1d,0xa1,0x00,0x0c,0x1c,0xef,0xc7,0xb1,0x44,0x6e,0xfb,0x48,0x91,0x0c,0x8c,0xfa,
+0xa7,0xe7,0xfc,0x9a,0x7f,0x9e,0x00,0x01,0x00,0xba,0x00,0x00,0x60,0x10,0x20,0x22,
+0x46,0x01,0x02,0x81,0x23,0x6c,0x41,0x80,0xaf,0x4a,0xa8,0x24,0xbc,0x90,0x4c,0x52,
+0xa3,0x39,0x32,0x4c,0x08,0x19,0x80,0x44,0x20,0x73,0x40,0x01,0x2c,0xb1,0xb3,0x6c,
+0xcf,0x33,0x4b,0xe8,0x10,0x1f,0x26,0x80,0x12,0x74,0x9e,0x00,0x00,0xa0,0x42,0xbc,
+0x00,0xb3,0x20,0x0b,0x70,0x00,0x3e,0x4a,0xfc,0x39,0x3f,0xa3,0xb3,0xb1,0xff,0x3c,
+0x49,0xd2,0x84,0xc8,0x04,0x50,0x53,0x74,0xe9,0x30,0xd2,0x53,0x4c,0x84,0x8b,0x4e,
+0x54,0x9c,0xd8,0xce,0x27,0x53,0x8d,0x29,0x48,0xd3,0x54,0xcc,0xca,0x00,0x51,0x34,
+0x5c,0x9b,0x28,0x20,0xd1,0xa2,0xdb,0x0f,0x25,0x55,0x24,0xf3,0x28,0x10,0x68,0x25,
+0x3a,0x81,0xca,0xd5,0x0d,0x64,0x8f,0xd3,0x14,0xad,0x41,0x5c,0xca,0x88,0x29,0x81,
+0x58,0xce,0x75,0xd5,0x3f,0x51,0x55,0xb4,0x62,0x21,0x54,0xb9,0x56,0x25,0x4d,0x61,
+0x01,0x0e,0xdc,0xcf,0x5e,0xd3,0xd3,0x22,0x3d,0x5c,0x58,0x53,0x6d,0x61,0x60,0xda,
+0x76,0xc5,0x25,0x64,0xcf,0x50,0x8d,0xb6,0x79,0xa0,0xae,0xdb,0xd7,0x70,0xdc,0x08,
+0x23,0xf0,0x8c,0xdc,0x57,0x2d,0xc8,0x81,0xdd,0x17,0x5d,0xd4,0xeb,0x5d,0xd7,0x65,
+0x47,0x3b,0xcf,0x36,0xfa,0x09,0x71,0xde,0xd7,0x4d,0xf1,0x76,0xa4,0x17,0x8d,0xfb,
+0x78,0x5f,0xf7,0xd5,0xdf,0x80,0xdb,0xd8,0x02,0x07,0x7b,0xe0,0xd7,0xca,0x3f,0x7f,
+0x60,0x38,0x5e,0x11,0x7d,0xe1,0xd8,0x16,0x21,0x82,0x61,0x98,0x2d,0x07,0x84,0xbd,
+0x58,0xae,0x0f,0x8b,0x61,0xf8,0xde,0x23,0x8e,0xde,0x36,0xdd,0x1b,0x15,0xaf,0x84,
+0x15,0x7f,0x5a,0xd8,0x15,0xbd,0xa1,0x95,0x56,0x73,0x36,0x4d,0x5d,0xd6,0xd3,0x06,
+0x42,0x83,0xd2,0x11,0xfb,0xbf,0x99,0x10,0xb9,0x70,0x01,0x9c,0x5a,0xf9,0x5e,0x53,
+0x9e,0x67,0xf5,0x12,0x06,0x42,0x67,0x36,0xcd,0x41,0x99,0x38,0xb9,0xaa,0x21,0x99,
+0x51,0xc8,0x2a,0xf1,0x98,0x65,0x16,0x96,0x7b,0x5b,0x01,0x19,0x46,0x9f,0x93,0xde,
+0x54,0x55,0x5c,0x83,0xe3,0x4f,0x1e,0x64,0x40,0xd0,0xf2,0xaa,0x5d,0xaf,0xa5,0x32,
+0xab,0x15,0xa2,0xe7,0xda,0x0d,0xa9,0x33,0x25,0xd3,0x6e,0x77,0xb4,0xec,0xf9,0x8d,
+0xe7,0x62,0x80,0x80,0x14,0x3d,0x2b,0x80,0x1b,0xa3,0x89,0x4b,0x29,0xda,0x4d,0x11,
+0xb9,0x59,0x56,0xee,0xff,0x6e,0x41,0xf5,0x20,0x54,0x00,0x1f,0x8c,0x90,0x1e,0x47,
+0x99,0x26,0x49,0x58,0x2d,0x80,

+ 67 - 0
src/agm_board/Timer.c

@@ -0,0 +1,67 @@
+#include "Timer.h"
+#include "led.h"
+
+volatile uint32_t g_iDelayfinish = 0;
+void TIMER0_isr(void)
+{
+    if(TIM_IsRawIntActive1(TIMER0))
+	{
+        TIM_DisableInt1(TIMER0);
+        TIM_DisableTimer1(TIMER0);
+        g_iDelayfinish = 1;
+		TIM_ClearInt1(TIMER0);
+    }
+}
+void timer0_int(void)
+{
+
+}
+void start_delay_ms(uint32_t delayms)
+{
+    SYS_EnableAPBClock(APB_MASK_TIMER0);
+    TIM_Init1(TIMER0,delayms*1000,TIMER_MODE_ONE_SHOT);// 1ms
+	TIM_EnableInt1(TIMER0);
+	TIM_EnableTimer1(TIMER0);
+	INT_EnableIRQ(TIMER0_IRQn,2);
+    g_iDelayfinish = 0;
+}
+void stop_delay_ms(void)
+{
+    TIM_ClearInt1(TIMER0);
+    TIM_DisableInt1(TIMER0);
+    TIM_DisableTimer1(TIMER0);
+
+}
+
+volatile uint32_t TickCounter = 0;
+volatile uint32_t TickSec = 0;
+
+uint32_t Get_SysTick(void)
+{
+	return TickCounter;
+}
+
+void TIMER1_isr(void)
+{
+    if(TIM_IsRawIntActive1(TIMER1))
+	{
+        TickCounter++;
+        display_led_status(TickCounter);
+        if(TickCounter>=0xFFFFFFFF)
+            TickSec += 1;
+		if((TickCounter %2000) == 0) {
+			IWDG_ReloadCounter();
+
+		}
+		TIM_ClearInt1(TIMER1);
+    }
+}
+void timer1_int(void)
+{
+    SYS_EnableAPBClock(APB_MASK_TIMER1);
+    TIM_Init1(TIMER1,1000,TIMER_MODE_PERIODIC);// 1ms
+	TIM_EnableInt1(TIMER1);
+	TIM_EnableTimer1(TIMER1);
+	INT_EnableIRQ(TIMER1_IRQn,1);
+}
+

+ 18 - 0
src/agm_board/Timer.h

@@ -0,0 +1,18 @@
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+#include "board.h"
+
+
+extern volatile uint32_t g_iDelayfinish;
+extern volatile uint32_t gTimer_tickt;
+
+extern void timer0_int(void);
+extern void start_delay_ms(uint32_t delayms);
+extern void stop_delay_ms(void);
+
+
+extern void timer1_int(void);
+extern uint32_t Get_SysTick(void);
+
+#endif

+ 175 - 0
src/agm_board/agmboard.c

@@ -0,0 +1,175 @@
+#include "agmboard.h"
+#include "./app/ota_update.h"
+
+
+uint32_t apb_clken;
+uint32_t misc_ctrl;
+void m_fpga_init(void)
+{
+    apb_clken = SYS->APB_CLKENABLE;
+    misc_ctrl = SYS->MISC_CNTL;
+
+    SYS_SetHSIConfig(0xf);
+    SYS_SwitchHSIClock();
+
+    // Provide a minimal working FPGA configuration to avoid problems if the default configuration is corrupted.
+#ifdef DFU_FPGA_CONFIG
+    SYS->APB_CLKENABLE = APB_MASK_FCB0; // Disable all peripherial clocks execpt for FCB to avoid any noise from FPGA
+    __attribute__ ((aligned(4))) uint8_t fpga_config[] = {
+#include DFU_FPGA_CONFIG
+    };
+    FCB_AutoDecompress((uint32_t)fpga_config);
+#endif
+    SYS_SwitchPLLClock(SYS_HSE_BYPASS_OFF); //use hse
+}
+
+__attribute__((weak)) uint32_t FCB_GetPLLFreq(uint32_t clkin_freq);
+void agm_board_init(void)
+{
+#if(1)
+    m_fpga_init();
+    PERIPHERAL_ENABLE(DMAC, 0);
+    DMAC_Init();
+#else
+    PERIPHERAL_ENABLE(DMAC, 0);
+    DMAC_Init();
+
+    if (FCB_GetPLLFreq) {
+        uint32_t freq = BOARD_PLL_FREQUENCY;
+        SYS_EnableAPBClock(APB_MASK_FCB0);
+        if (FCB_IsActive()) {
+            freq = FCB_GetPLLFreq(board_pll_clkin_freq());
+        } else {
+            FCB_Activate();
+        }
+        SYS_SetPLLFreq(freq);
+    }
+    SYS_SwitchPLLClock(board_hse_source());
+#endif
+    INT_Init();
+    INT_EnableIntGlobal();
+    INT_EnableIntExternal();
+
+
+}
+
+void device_board_init(void)
+{
+    timer0_int();
+    timer1_int();
+
+    i2c_init();
+    uart_init();
+}
+
+/*--------------------------------------------------------------------------------
+ *  上电时读取复位类型
+ * -------------------------------------------------------------------------------*/
+uint32_t power_up_system_resettype(void)
+{
+    uint8_t RestFlag = 0;
+
+
+    if(SYS_IsActiveResetFlag_LPWR()){
+        RestFlag |= 1<<5;
+    }
+    if(SYS_IsActiveResetFlag_WDOG()){
+        RestFlag |= 1<<4;
+    }
+    if(SYS_IsActiveResetFlag_IWDG()){
+        RestFlag |= 1<<3;
+    }
+    if(SYS_IsActiveResetFlag_SFT()){
+        RestFlag |= 1<<2;
+    }
+    if(SYS_IsActiveResetFlag_POR()){
+        RestFlag |= 1<<1;
+    }
+    if(SYS_IsActiveResetFlag_PIN()){
+        RestFlag |= 1<<0;
+    }
+    if(SYS_IsActiveResetFlag_EXT()){
+        RestFlag |= 1<<6;
+    }
+    SYS_ClearResetFlags();
+    printf("复位类型:%x\n",RestFlag);
+	return RestFlag;
+
+}
+void uart_init(void)
+{
+    uart1_4g_init(115200);
+    uart2_485_init(115200);
+}
+
+void int_disable(void)
+{
+    //#define GPIO0_IRQn 7
+    uint32_t i;
+    for(i = 7; i < 45; i++)
+    {
+        INT_DisableIRQ(i);
+    }
+}
+
+void deinit_all(void)
+{
+    UART_DeInit(UARTx(0));
+    SYS_DisableAPBClock(APB_MASK_UARTx(0));
+    UART_DeInit(UARTx(1));
+    SYS_DisableAPBClock(APB_MASK_UARTx(1));
+    UART_DeInit(UARTx(2));
+    SYS_DisableAPBClock(APB_MASK_UARTx(2));
+    UART_DeInit(UARTx(3));
+    SYS_DisableAPBClock(APB_MASK_UARTx(3));
+    UART_DeInit(UARTx(4));
+    SYS_DisableAPBClock(APB_MASK_UARTx(4));
+
+    GPIO_DisableInt(GPIO6,0b01010101);
+    GPIO_DisableInt(GPIO7,0b11101);
+    GPIO_DisableInt(GPIO8,0b10101010);
+    SYS_DisableAPBClock(APB_MASK_GPIO6);
+    SYS_DisableAPBClock(APB_MASK_GPIO7);
+    SYS_DisableAPBClock(APB_MASK_GPIO8);
+    //GPIO_DisableInt(RADIO_DIO1_PORT,RADIO_DIO1_PIN);
+   // SYS_DisableAPBClock(RADIO_APB_MASK);
+
+
+    TIM_DisableInt1(TIMER1);
+    TIM_DisableInt1(TIMER0);
+    SYS_DisableAPBClock(APB_MASK_TIMER1);
+    SYS_DisableAPBClock(APB_MASK_TIMER0);
+
+    INT_DisableIntTimer();
+
+}
+//跳转
+uint32_t run_pt(void)
+{
+    uint32_t appxaddr = OTA_UPDATE_PT_FLASH_START_ADDR;
+    printf("jump to 0x%08X\r\n",appxaddr);
+    // delay_us(1200);
+
+    UTIL_JumpToAddress(appxaddr);
+}
+
+
+//跳转
+void run_app(void)
+{
+    int_disable();//关中断
+    deinit_all();
+
+    // UART_DeInit(UARTx(0));
+    // SYS_DisableAPBClock(APB_MASK_UARTx(0));
+    SYS->APB_CLKENABLE = apb_clken;
+    SYS->MISC_CNTL = misc_ctrl;
+    SYS_SwitchHSIClock();
+
+    // SYS_EnableAPBClock(APB_MASK_FCB0);
+    // FCB_AutoConfig(DFU_APP_LOGIC_ADDRESS); //restore APP logic
+    // //FCB_AutoDecompress(DFU_APP_LOGIC_ADDRESS);
+    // SYS_DisableAPBClock(APB_MASK_FCB0);
+
+    run_pt();
+}

+ 31 - 0
src/agm_board/agmboard.h

@@ -0,0 +1,31 @@
+#ifndef _AGM_BOARD_H_
+#define _AGM_BOARD_H_
+
+#include "board.h"
+#include "agmconfig.h"
+#include "led.h"
+#include "uart_agm.h"
+#include "Timer.h"
+#include "i2c.h"
+#include "fifo.h"
+#include "timeout.h"
+#include "epprom.h"
+#include "flash.h"
+#include "rtc.h"
+#include "delay.h"
+
+
+extern void agm_board_init(void);
+extern void device_board_init(void);
+
+
+extern uint32_t power_up_system_resettype(void);
+extern void uart_init(void);
+
+extern void run_app(void);
+
+
+extern void m_fpga_init(void);
+
+
+#endif

+ 27 - 0
src/agm_board/agmconfig.h

@@ -0,0 +1,27 @@
+#ifndef _AGM_CONFIG_H_
+#define _AGM_CONFIG_H_
+
+#include "board.h"
+
+
+
+#define MIN_IRQ_PRIORITY 1
+#define MAX_IRQ_PRIORITY PLIC_MAX_PRIORITY
+
+#define I2C_PRIORITY    (MIN_IRQ_PRIORITY + 1)
+#define TIMER_PRIORITY  (MIN_IRQ_PRIORITY + 2)
+#define DMAC_PRIORITY   (MIN_IRQ_PRIORITY + 8)
+#define UART_PRIORITY   (MIN_IRQ_PRIORITY + 9)
+#define CAN_PRIORITY    (MIN_IRQ_PRIORITY + 7)
+#define RTC_PRIORITY    (MIN_IRQ_PRIORITY + 6)
+#define EXT_PRIORITY    (MIN_IRQ_PRIORITY + 4)
+#define SPI_PRIORITY    (MIN_IRQ_PRIORITY + 5)
+#define MEMSPI_PRIORITY (MIN_IRQ_PRIORITY + 1)
+#define GPIO_PRIORITY   (MIN_IRQ_PRIORITY + 1)
+#define FLASH_PRIORITY  (MAX_IRQ_PRIORITY - 5)
+#define USB_PRIORITY    (MAX_IRQ_PRIORITY - 1)
+#define MAC_PRIORITY    (MAX_IRQ_PRIORITY - 1)
+#define WDOG_PRIORITY   (MAX_IRQ_PRIORITY - 0)
+
+
+#endif

+ 29 - 0
src/agm_board/delay.c

@@ -0,0 +1,29 @@
+/*
+ * @Description: 
+ * @Version: 2.0
+ * @Author: Seven
+ * @Date: 2023-09-04 09:34:28
+ * @LastEditors: Seven
+ * @LastEditTime: 2023-09-07 16:58:33
+ */
+#include "delay.h"
+
+void delay_us(uint32_t us)
+{
+    // volatile uint32_t i,j;
+    // for(i = 0; i < us; i++)
+    // {
+    //   for(j = 0; j < 16; j++)
+    //   {
+    //     // ;
+    //   }
+    // }
+    UTIL_IdleUs(us);
+}
+
+void delay_ms(uint32_t ms)
+{
+    // delay_us(ms*1000);
+    UTIL_IdleMs(ms);
+}
+

+ 16 - 0
src/agm_board/delay.h

@@ -0,0 +1,16 @@
+/*
+ * @Description: 
+ * @Version: 2.0
+ * @Author: Seven
+ * @Date: 2023-08-09 17:46:14
+ * @LastEditors: Seven
+ * @LastEditTime: 2023-08-09 17:47:05
+ */
+#ifndef DELAY_H__
+#define DELAY_H__
+#include "board.h"
+
+void delay_us(uint32_t us);
+void delay_ms(uint32_t ms);
+
+#endif // !

+ 158 - 0
src/agm_board/epprom.c

@@ -0,0 +1,158 @@
+/*--------------------------------------------------
+ *  用的芯片是AT24C128
+ *  一共256页,每页64个字节
+ * -------------------------------------------------*/
+#include "epprom.h"
+#include "i2c.h"
+#include "timeout.h"
+#include "delay.h"
+
+/*--------------------------------------------------------
+ * 在AT24CXX里面的指定地址开始读出指定个数的数据
+ * ReadAddr :开始读出的地址 对24c02为0~255
+ *pBuffer  :数据数组首地址
+ *NumToRead:要读出数据的个数
+ * --------------------------------------------------------*/
+void epprom_read(uint32_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead)
+{
+    uint8_t addrH,addrL;
+    uint16_t lentmp,lentow,lens;
+    uint8_t tmp;
+
+    if(NumToRead==0) return;
+
+   // i2c_init();
+    //int_disable();//关总中断
+    delay_ms(100);//两次写操作,必须加间隔,否则写不进去
+    //fwdgt_feed();
+
+    lentmp=NumToRead;
+    while(lentmp)
+    {
+        tmp=ReadAddr%PAGE_SIZE_EPPROM;
+        tmp=PAGE_SIZE_EPPROM-tmp;
+        if(tmp>=lentmp)//当页剩余空间大于要写入的长度
+        {
+            lentow=lentmp;
+        }
+        else
+        {
+            lentow=tmp;//写入长度只能是剩余空间长度
+        }
+        lentmp=lentmp-lentow;//计算要在下一页写入的长度
+        lens=lentow;
+        addrH=ReadAddr>>8;
+        addrL=ReadAddr&0xff;
+
+        i2c_start();
+        i2c_send_byte(0xa0);//写
+        i2c_wait_ack();
+        i2c_send_byte(addrH);   //发送高地址
+        i2c_wait_ack();
+        i2c_send_byte(addrL);   //发送低地址
+        i2c_wait_ack();
+
+        delay_us(4);
+        i2c_start();
+        i2c_send_byte(0xa1);  //读       //进入接收模式
+        i2c_wait_ack();
+
+        while(lentow)
+        {
+            *pBuffer=i2c_read_byte(1);
+            pBuffer++;
+            //ReadAddr++;
+            lentow--;
+        }
+        i2c_read_byte(0);
+        i2c_stop();//产生一个停止条件
+
+        delay_us(4);
+        //printf("at24 read %d %d\r\n", ReadAddr, lens);
+        ReadAddr=ReadAddr+lens;//下一页的地址
+    }
+    //IIC_WRITE_PROTECT_ON(); // 写保护打开
+    // __set_PRIMASK(0);//开总中断
+
+}
+/*---------------------------------------------------------
+ * 在AT24CXX里面的指定地址开始写入指定个数的数据
+ * WriteAddr :开始写入的地址 对24c02为0~255
+ * pBuffer   :数据数组首地址
+ * NumToWrite:要写入数据的个数
+ * 每64bytes为一个page,
+ * --------------------------------------------------------*/
+void epprom_write(uint32_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite)
+{
+    uint8_t addrH,addrL;
+    uint16_t lentmp,lentow,lens;
+    uint8_t tmp;
+//    rt_err_t err;
+
+    if(NumToWrite==0) return;
+ //   i2c_init();
+    IIC_WRITE_PROTECT_DISABLE(); // 写保护关闭
+    //__set_PRIMASK(1);//关总中断
+    delay_ms(10);//两次写操作,必须加间隔,否则写不进去
+    //fwdgt_feed();
+
+    lentmp=NumToWrite;
+    while(lentmp)
+    {
+        tmp=WriteAddr%PAGE_SIZE_EPPROM;
+        tmp=PAGE_SIZE_EPPROM-tmp;
+        if(tmp>=lentmp)//当页剩余空间大于要写入的长度
+        {
+            lentow=lentmp;
+        }
+        else
+        {
+            lentow=tmp;//写入长度只能是剩余空间长度
+        }
+        lentmp=lentmp-lentow;//计算要在下一页写入的长度
+        lens=lentow;
+
+        addrH=WriteAddr>>8;
+        addrL=WriteAddr&0xff;
+
+        i2c_start();
+
+        i2c_send_byte(0xa0);
+
+        i2c_wait_ack();
+        i2c_send_byte(addrH);   //发送高地址
+        i2c_wait_ack();
+        i2c_send_byte(addrL);   //发送低地址
+        i2c_wait_ack();
+
+        while(lentow--)
+        {
+            i2c_send_byte(*pBuffer);
+            i2c_wait_ack();
+            pBuffer++;
+        }
+        i2c_stop();//产生一个停止条件
+        delay_ms(10);
+        WriteAddr=WriteAddr+lens;//下一页的地址
+    }
+
+
+    delay_ms(10);//两次写操作,必须加间隔,否则写不进去
+    IIC_WRITE_PROTECT_ENABLE(); // 写保护使能打开
+    //__set_PRIMASK(0);//开总中断
+
+}
+void epprom_test(void)
+{
+    uint8_t i = 0,vale=0;
+    for(i=1;i<128;i++){
+        epprom_write(12800+i,&i,1);
+    }
+    for(i=1;i<128;i++){
+        vale = 0;
+        epprom_read(12800+i,&vale,1);
+        printf("i = %d,val = %d\r\n",i,vale);
+    }
+}
+
+

+ 19 - 0
src/agm_board/epprom.h

@@ -0,0 +1,19 @@
+#ifndef _EPPROM_H_
+#define _EPPROM_H_
+
+#include "board.h"
+
+#define PAGE_SIZE_EPPROM	64
+
+#define DEV_APP_VER (4*64) // 1页
+#define DEV_READ_MQTT_MSG (8*64) // mqtt信息
+#define DEV_RESET_NUM (5*64) // 1 页
+#define CONFIGTABLE_ADDR (25*64) // 配置路由表的首地址,3页
+#define COMM_CONFIG_ADDR (28*64) // com端的配置文件  2页
+#define PIN_CONFIG_ADDR  (30*64) // 针脚的配置文件   10页
+
+extern void epprom_read(uint32_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead);
+extern void epprom_write(uint32_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite);
+
+extern void epprom_test(void);
+#endif

+ 84 - 0
src/agm_board/fifo.c

@@ -0,0 +1,84 @@
+#include "fifo.h"
+//#include "Uart.h"
+
+FIFO_T g_rxfifo;
+FIFO_T g_txfifo;
+/*-----------------------------------------------------------------
+ *  初始化fifo
+ * ----------------------------------------------------------------*/
+void init_fifo(FIFO_T *fifo)
+{
+    uint8_t i = 0;
+    for(i=0;i<8;i++){
+        memset(fifo->memory[i].da,0,256);
+        fifo->memory[i].len = 0;
+    }
+    fifo->flag = false;
+    fifo->front = fifo->rear = 0;
+    printf("循环队列已经创建完毕\n");
+    return ;
+}
+/*-----------------------------------------------------------------
+ *  判断fifo是否已满
+ *  满返回1 否则返回0
+ * -----------------------------------------------------------------*/
+bool fifo_is_full(FIFO_T *fifo)
+{
+    if ((fifo->front == fifo->rear) && fifo->flag)
+    {
+        printf("循环队列已满!-fifo\n");
+        return true;
+    }
+    return false;
+}
+/*------------------------------------------------------------------
+ * 判断fio是否已空
+ *  空返回 1: 否则返回0
+ * -----------------------------------------------------------------*/
+bool fifo_is_empty(FIFO_T *fifo)
+{
+    if ((fifo->front == fifo->rear) && !(fifo->flag))  // 判断队空 flag 为false
+        return true;
+    return false;
+}
+/*------------------------------------------------------------------
+ *  写入数据到fifo
+ *  1:写入 0: 操作失败
+ * -----------------------------------------------------------------*/
+uint8_t fifo_write(FIFO_T *fifo,uint8_t *data,uint8_t len)
+{
+    if ((fifo->front == fifo->rear) && fifo->flag)
+    {
+        printf("循环队列已满!-write front=%d,flag = %d\n",fifo->front,fifo->flag);
+        return 0;
+    }
+
+    memcpy(fifo->memory[fifo->rear].da,data,len);
+    fifo->memory[fifo->rear].len = len;
+    ++(fifo->rear);
+    fifo->rear %= MAXSIZE;
+    if (fifo->rear == fifo->front) // 设置队列已满
+        fifo->flag = true;
+    return 1;
+}
+/*------------------------------------------------------------------
+ *  从fifo中读取数据
+ * -----------------------------------------------------------------*/
+uint8_t fifo_read(FIFO_T *fifo,uint8_t *data)
+{
+    uint8_t len;
+    if ((fifo->front == fifo->rear) && !(fifo->flag))  // 判断队空
+    {
+        printf("队列为空!不能进行删除操作\n");
+        return 0;
+    }
+    len = fifo->memory[fifo->front].len;
+    memcpy(data,fifo->memory[fifo->front].da,len);
+    //memset(fifo->memory[fifo->front].da,0,256);
+    fifo->memory[fifo->front].len = 0;
+    fifo->front++;
+    fifo->front %= MAXSIZE;
+    if (fifo->front == fifo->rear) // 设置队列为空
+        fifo->flag = false;
+    return len;
+}

+ 26 - 0
src/agm_board/fifo.h

@@ -0,0 +1,26 @@
+#ifndef _FIFO_H_
+#define _FIFO_H_
+
+#include "board.h"
+
+#define MAXSIZE 8
+typedef struct _fifo_data_{
+    uint8_t da[256];
+    uint8_t len;
+}__attribute__((packed))fifoDa;
+
+typedef struct _fifo_{
+    fifoDa memory[8];
+    uint8_t front;
+    uint8_t rear;
+    bool flag;
+}__attribute__((packed)) FIFO_T;
+extern FIFO_T g_rxfifo;
+extern FIFO_T g_txfifo;
+
+extern void init_fifo(FIFO_T *fifo);
+extern bool fifo_is_full(FIFO_T *fifo);
+extern bool fifo_is_empty(FIFO_T *fifo);
+extern uint8_t fifo_write(FIFO_T *fifo,uint8_t *data,uint8_t len);
+extern uint8_t fifo_read(FIFO_T *fifo,uint8_t *data);
+#endif

+ 124 - 0
src/agm_board/flash.c

@@ -0,0 +1,124 @@
+/*
+ * @Description:
+ * @Version: 2.0
+ * @Author: Seven
+ * @Date: 2023-08-24 15:03:24
+ * @LastEditors: Seven
+ * @LastEditTime: 2023-09-06 09:50:03
+ */
+#include "flash.h"
+#include "uart_agm.h"
+
+//flash擦除
+void Flash_RangeErase(uint32_t FlashAddress, uint32_t Size)
+{
+    FLASH_Unlock();
+    FLASH_Erase(FlashAddress, Size);
+    FLASH_Lock();
+}
+
+//flash写指定长度数据
+void Flash_BufferWrite(uint32_t address, uint32_t *p_buffer, uint32_t len)
+{
+	uint32_t EndAddr = 0;
+
+	if(address%4||len%4) {
+		return ;
+	}
+
+    FLASH_Unlock();
+    FLASH_FastProgram(address, (uint32_t)p_buffer, len);
+
+    // EndAddr = address + len;
+    // while (address < EndAddr) {
+	// 	FLASH_ProgramWord(address, *p_buffer);
+	// 	p_buffer++;
+	// 	address += 4;
+	// }
+    FLASH_Lock();
+}
+
+//flash读指定长度的数据
+void Flash_BufferRead(uint32_t address, uint32_t *buffer, uint32_t len)
+{
+    uint32_t EndAddr = 0;
+	uint32_t *p_buffer = (uint32_t *)buffer;
+    if(address%4||len%4) {
+		return ;
+	}
+    EndAddr = address + len;
+    FLASH_Unlock();
+    while (address < EndAddr) {
+		*p_buffer++ = RD_REG(address);
+		address += 4;
+	}
+    FLASH_Lock();
+}
+
+//读取flash中有效数据的长度
+uint32_t Flash_DatalenRead(uint32_t address,uint32_t len)
+{
+    uint32_t BeginAddr = 0;
+	uint32_t addrlen = 0;
+	uint32_t data;
+	if(address%4||len%4) {
+		return addrlen;
+	}
+    BeginAddr = address + len - 4;
+    FLASH_Unlock();
+    while(address < BeginAddr)
+	{
+		data = RD_REG(BeginAddr);
+		if(data != 0xFFFFFFFF)
+			break;
+		BeginAddr -= 4;
+	}
+    FLASH_Lock();
+
+    if(address <= BeginAddr)
+	{
+		addrlen = (BeginAddr+4) - address;
+	}
+	return addrlen;
+}
+
+#define FLASH_TEST_ADDR 0x80010000
+#define FLASH_TEST_LEN  2048 //0x800
+//flash测试
+void flash_test(void)
+{
+    static uint32_t flash_buf[FLASH_TEST_LEN/4],flash_len;
+    static uint32_t flash_read_buf[FLASH_TEST_LEN/4];
+    uint32_t i,num=0;
+    uint32_t crc;
+
+    // num = Flash_DatalenRead(FLASH_TEST_ADDR,FLASH_TEST_LEN);
+
+    Flash_BufferRead(FLASH_TEST_ADDR,flash_buf,FLASH_TEST_LEN);
+    data_dump("flash read",(uint8_t *)flash_buf,FLASH_TEST_LEN);
+    for(i = 0; i < FLASH_TEST_LEN/4; i++)
+    {
+        flash_buf[i] = 0x12345678+i;
+    }
+    data_dump("flash write",(uint8_t *)flash_buf,FLASH_TEST_LEN);
+    Flash_RangeErase(FLASH_TEST_ADDR,FLASH_TEST_LEN);
+    Flash_BufferWrite(FLASH_TEST_ADDR,flash_buf,FLASH_TEST_LEN);
+
+    // //计算crc32
+    // SYS_EnableAHBClock(AHB_MASK_CRC0);
+    // CRC_Reset(CRC0);
+    // crc = crc_block_data_calculate((uint32_t *)FLASH_TEST_ADDR,FLASH_TEST_LEN/4);
+    // printf("crc = %08x\n",crc);
+
+    memset(flash_read_buf,0,FLASH_TEST_LEN);
+    Flash_BufferRead(FLASH_TEST_ADDR,flash_read_buf,FLASH_TEST_LEN);
+    data_dump("flash read",(uint8_t *)flash_read_buf,FLASH_TEST_LEN);
+
+    for(i = 0; i < FLASH_TEST_LEN/4-1; i++)
+    {
+        if(flash_buf[i] != flash_read_buf[i])
+            num++;
+    }
+    printf("error num = %u\n",num);
+
+}

+ 18 - 0
src/agm_board/flash.h

@@ -0,0 +1,18 @@
+/*
+ * @Description: 
+ * @Version: 2.0
+ * @Author: Seven
+ * @Date: 2023-08-24 15:02:40
+ * @LastEditors: Seven
+ * @LastEditTime: 2023-08-24 16:42:48
+ */
+#ifndef __FLASH_H__
+#define __FLASH_H__
+#include "board.h"
+
+void Flash_RangeErase(uint32_t FlashAddress, uint32_t Size);
+void Flash_BufferWrite(uint32_t address, uint32_t *p_buffer, uint32_t len);
+void Flash_BufferRead(uint32_t address, uint32_t *buffer, uint32_t len);
+uint32_t Flash_DatalenRead(uint32_t address,uint32_t len);
+void flash_test(void);
+#endif // !

+ 448 - 0
src/agm_board/i2c.c

@@ -0,0 +1,448 @@
+#include "i2c.h"
+#include "delay.h"
+//#include "uart.h"
+
+
+#define PAGE_SIZE	64
+
+//引脚初始化
+void i2c_init(void)
+{
+    SYS_EnableAPBClock(APB_MASK_GPIO2);
+	// SYS_DisableNJTRST();
+    GPIO_SetHigh(IIC_SCL_PORT,IIC_SCL_PIN);
+    GPIO_SetHigh(IIC_SDA_PORT,IIC_SDA_PIN);
+
+    GPIO_SetOutput(IIC_WP_PORT,IIC_WP_PIN);
+    GPIO_SetOutput(IIC_SCL_PORT,IIC_SCL_PIN);
+    GPIO_SetOutput(IIC_SDA_PORT,IIC_SDA_PIN);
+
+    //打开写保护
+	IIC_WRITE_PROTECT_ENABLE();
+}
+
+/***********************iic**************************/
+
+//产生IIC起始信号
+void i2c_start(void)
+{
+	SDA_OUT();
+    IIC_SDA(1);//IIC_SDA = 1;
+    IIC_SCL(1);//IIC_SCL = 1;
+    delay_us(4);
+    IIC_SDA(0);//IIC_SDA = 0;//START:when CLK is high,DATA change form high to low
+    delay_us(4);
+    IIC_SCL(0);//IIC_SCL = 0;
+}
+
+
+//产生IIC停止信号
+void i2c_stop(void)
+{
+	SDA_OUT();
+    IIC_SDA(0);//IIC_SDA = 0;
+    IIC_SCL(0);//IIC_SCL = 0;
+    delay_us(4);
+    IIC_SCL(1);//IIC_SCL = 1;
+    delay_us(4);
+    IIC_SDA(1);//IIC_SDA = 1;
+    delay_us(4);
+}
+//等待应答信号到来
+//返回值:
+//		1,接收应答失败
+//    0,接收应答成功
+uint8_t i2c_wait_ack(void)
+{
+	volatile uint8_t ucErrTime=0;
+    SDA_IN();  // SDA 配置成输入
+    // IIC_SDA(1);//IIC_SDA=1;
+    delay_us(1);
+    IIC_SCL(1);//IIC_SCL=1;
+    delay_us(1);
+    while(READ_SDA)
+    {
+        ucErrTime++;
+        if(ucErrTime>250)
+        {
+        i2c_stop();
+        return 1;
+        }
+    }
+    IIC_SCL(0);//IIC_SCL=0;
+    return 0;
+
+}
+//产生ACK应答
+void IIC_Ack(void)
+{
+	IIC_SCL(0);//IIC_SCL = 0;
+    SDA_OUT();
+    IIC_SDA(0);//IIC_SDA = 0;
+    delay_us(4);
+    IIC_SCL(1);//IIC_SCL = 1;
+    delay_us(2);
+    IIC_SCL(0);//IIC_SCL = 0;
+}
+//不产生ACK应答
+void IIC_NAck(void)
+{
+	IIC_SCL(0);//IIC_SCL = 0;
+    SDA_OUT();
+    IIC_SDA(1);//IIC_SDA = 1;
+    delay_us(4);
+    IIC_SCL(1);//IIC_SCL = 1;
+    delay_us(2);
+    IIC_SCL(0);//IIC_SCL = 0;
+}
+//IIC发送一个字节
+//返回从机有无应答
+//1,有应答
+//0,无应答
+void i2c_send_byte(uint8_t txd)
+{
+	uint8_t t;
+    SDA_OUT();
+	IIC_SCL(0);//IIC_SCL=0;// 电平置低,开始传输数据
+	for(t=0;t<8;t++)
+	{
+		// IIC_SDA=(txd&0x80)>>7;
+		if((txd&0x80)>>7) IIC_SDA(1);
+		else IIC_SDA(0);
+		txd<<=1;
+		delay_us(4);   //
+		IIC_SCL(1);//IIC_SCL=1;
+		delay_us(2);
+		IIC_SCL(0);//IIC_SCL=0;
+        if(t==7)
+            SDA_IN();
+		delay_us(2);
+	}
+}
+//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
+uint8_t i2c_read_byte(uint8_t ack)
+{
+	uint8_t i,receive=0;
+    SDA_IN();//SDA设置为输入
+    for(i=0;i<8;i++ )
+    {
+        IIC_SCL(0);//IIC_SCL=0;
+        delay_us(4);
+        IIC_SCL(1);//IIC_SCL=1;
+        receive<<=1;
+        if(READ_SDA)receive++;
+        delay_us(1);
+    }
+    if(!ack)
+        IIC_NAck();//发送nACK
+    else
+        IIC_Ack(); //发送ACK
+    return receive;
+}
+
+
+/***********************以上为IIC驱动**************************/
+
+
+
+
+
+
+
+
+
+
+
+
+/***********************iic**************************/
+//在AT24CXX指定地址读出一个数据
+//ReadAddr:开始读数的地址
+//返回值  :读到的数据
+uint8_t at24cxx_readOneByte(uint32_t ReadAddr)
+{
+	uint8_t temp;
+	uint8_t addrH,addrL;
+
+	addrH=ReadAddr>>8;
+	addrL=ReadAddr&0xff;
+
+	i2c_start();
+
+	i2c_send_byte(0xa0);
+
+	i2c_wait_ack();
+	i2c_send_byte(addrH);   //发送高地址
+	i2c_wait_ack();
+   	i2c_send_byte(addrL);   //发送低地址
+	i2c_wait_ack();
+	i2c_start();
+	i2c_send_byte(0xa1);         //进入接收模式
+
+	i2c_wait_ack();
+	temp=	i2c_read_byte(0);
+	i2c_stop();//产生一个停止条件
+
+	delay_us(4);
+	return temp;
+}
+//在AT24CXX指定地址写入一个数据
+//WriteAddr  :写入数据的目的地址
+//DataToWrite:要写入的数据
+void at24cxx_writeOneByte(uint32_t WriteAddr,uint8_t DataToWrite)
+{
+	uint8_t addrH,addrL;
+
+	addrH=WriteAddr>>8;
+	addrL=WriteAddr&0xff;
+
+	i2c_start();
+
+	i2c_send_byte(0xa0);
+
+	i2c_wait_ack();
+	i2c_send_byte(addrH);   //发送高地址
+	i2c_wait_ack();
+	i2c_send_byte(addrL);   //发送低地址
+	i2c_wait_ack();
+	i2c_send_byte(DataToWrite);     //发送字节
+	i2c_wait_ack();
+	i2c_stop();//产生一个停止条件
+
+	delay_ms(10);//两次写操作,必须加间隔,否则写不进去
+}
+//在AT24CXX里面的指定地址开始读出指定个数的数据
+//ReadAddr :开始读出的地址 对24c02为0~255
+//pBuffer  :数据数组首地址
+//NumToRead:要读出数据的个数
+void at24cxx_read(uint32_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead)
+{
+	uint8_t addrH,addrL;
+	uint16_t lentmp,lentow,lens;
+	uint8_t tmp;
+
+	if(NumToRead==0)
+		return;
+
+
+//	I2C_init();
+//	OSTimeDlyHMSM(0, 0, 0, 40, OS_OPT_TIME_DLY, &err);
+//	delay_ms(1);//40
+	// delay_us(10);
+	lentmp=NumToRead;
+	while(lentmp)
+	{
+		tmp=ReadAddr%PAGE_SIZE;
+		tmp=PAGE_SIZE-tmp;
+		if(tmp>=lentmp)//当页剩余空间大于要写入的长度
+		{
+			lentow=lentmp;
+		}
+		else
+		{
+			lentow=tmp;//写入长度只能是剩余空间长度
+		}
+		lentmp=lentmp-lentow;//计算要在下一页写入的长度
+		lens=lentow;
+		addrH=ReadAddr>>8;
+		addrL=ReadAddr&0xff;
+
+		i2c_start();
+
+		i2c_send_byte(0xa0);//写
+		i2c_wait_ack();
+
+		i2c_send_byte(addrH);   //发送高地址
+		i2c_wait_ack();
+	   	i2c_send_byte(addrL);   //发送低地址
+		i2c_wait_ack();
+
+		delay_us(4);
+		i2c_start();
+		i2c_send_byte(0xa1);  //读       //进入接收模式
+		i2c_wait_ack();
+
+		while(lentow)
+		{
+			*pBuffer=i2c_read_byte(1);
+			pBuffer++;
+			//ReadAddr++;
+			lentow--;
+
+		}
+		i2c_read_byte(0);
+		i2c_stop();//产生一个停止条件
+
+		delay_us(4);
+		//printf("at24 read %d %d\r\n", ReadAddr, lens);
+		ReadAddr=ReadAddr+lens;//下一页的地址
+	}
+	//打开写保护
+//	IIC_WRITE_PROTECT_ENABLE();
+}
+//在AT24CXX里面的指定地址开始写入指定个数的数据
+//WriteAddr :开始写入的地址 对24c02为0~255
+//pBuffer   :数据数组首地址
+//NumToWrite:要写入数据的个数
+// 每128bytes为一个page,写操作不能跨页
+void at24cxx_write(uint32_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite)
+{
+	uint8_t addrH,addrL;
+	uint16_t lentmp,lentow,lens;
+	uint8_t tmp;
+	if(NumToWrite==0)
+		return;
+
+
+
+	IIC_WRITE_PROTECT_DISABLE();//关闭写保护
+//	delay_ms(1);//10
+	delay_us(10);
+
+	lentmp=NumToWrite;
+	while(lentmp)
+	{
+		tmp=WriteAddr%PAGE_SIZE;
+		tmp=PAGE_SIZE-tmp;
+		if(tmp>=lentmp)//当页剩余空间大于要写入的长度
+		{
+			lentow=lentmp;
+		}
+		else
+		{
+			lentow=tmp;//写入长度只能是剩余空间长度
+		}
+		lentmp=lentmp-lentow;//计算要在下一页写入的长度
+		lens=lentow;
+
+		addrH=WriteAddr>>8;
+		addrL=WriteAddr&0xff;
+
+		i2c_start();
+
+		i2c_send_byte(0xa0);
+
+		i2c_wait_ack();
+		i2c_send_byte(addrH);   //发送高地址
+		i2c_wait_ack();
+		i2c_send_byte(addrL);   //发送低地址
+		i2c_wait_ack();
+
+		while(lentow--)
+		{
+			i2c_send_byte(*pBuffer);
+			i2c_wait_ack();
+			pBuffer++;
+		}
+		i2c_stop();//产生一个停止条件
+		// if(lentmp)//需要写下一页
+			delay_ms(6);
+		//printf("at24 write %d %d %d, %d\r\n", WriteAddr, lens, addrH, addrL);
+		WriteAddr=WriteAddr+lens;//下一页的地址
+	}
+
+//	delay_ms(10);//两次写操作,必须加间隔,否则写不进去,最小5ms
+	//打开写保护
+	IIC_WRITE_PROTECT_ENABLE();
+}
+void at24cxx_clr(uint32_t WriteAddr,uint32_t NumToWrite)
+{
+	uint8_t addrH,addrL;
+	uint16_t lentmp,lentow,lens;
+	uint8_t tmp;
+
+	//关闭写保护
+	IIC_WRITE_PROTECT_DISABLE();
+
+	lentmp=NumToWrite;
+	while(lentmp)
+	{
+		tmp=WriteAddr%PAGE_SIZE;
+		tmp=PAGE_SIZE-tmp;
+		if(tmp>=lentmp)
+		{
+			lentow=lentmp;
+		}
+		else
+		{
+			lentow=tmp;
+		}
+		lentmp=lentmp-lentow;
+		lens=lentow;
+
+		addrH=WriteAddr>>8;
+		addrL=WriteAddr&0xff;
+
+		i2c_start();
+
+		i2c_send_byte(0xa0);
+
+		i2c_wait_ack();
+		i2c_send_byte(addrH);   //发送高地址
+		i2c_wait_ack();
+		i2c_send_byte(addrL);   //发送低地址
+		i2c_wait_ack();
+
+		while(lentow--)
+		{
+			i2c_send_byte(0xff);
+			i2c_wait_ack();
+		}
+		i2c_stop();//产生一个停止条件
+		delay_ms(10);
+		WriteAddr=WriteAddr+lens;
+	}
+	//打开写保护
+	IIC_WRITE_PROTECT_ENABLE();
+	delay_ms(10);
+}
+//----------------------EEPROM---------------------------//
+//--------------------------------------------------------EEPROM DATA
+
+/*********************************************END OF FILE**********************/
+#define I2C_DATA_LEN	512
+uint8_t I2c_Buf_Write[I2C_DATA_LEN], I2c_Buf_Read[I2C_DATA_LEN];
+/**
+* @brief I2C(AT24C02)读写测试
+* @param 无
+* @retval 正常返回 1 ,不正常返回 0
+*/
+/*
+写1个字节用时336us
+写16个字节用时3.17ms
+写64个字节用时9.4ms
+读1个字节用时450us
+读16个字节用时2.12ms
+读64个字节用时6.44ms
+*/
+uint8_t I2C_Test(void)
+{
+	uint16_t i;
+
+	i2c_init();
+
+	EEPROM_INFO("\r\nI2C(AT24C128)字节读写测试\r\n");
+	memset(I2c_Buf_Write, 0, I2C_DATA_LEN);
+	memset(I2c_Buf_Read, 0, I2C_DATA_LEN);
+
+	EEPROM_INFO("\r\nI2C(AT24C128)连续地址读写测试\r\n");
+	// GPIO_SetLow(GPIO1,GPIO_BIT1);
+	memset(I2c_Buf_Write, 0, I2C_DATA_LEN);
+	memset(I2c_Buf_Read, 0, I2C_DATA_LEN);
+	for ( i=0; i< I2C_DATA_LEN; i++ ) //填充缓冲
+	{
+		I2c_Buf_Write[i] = i+8;
+	}
+
+	at24cxx_write(512, I2c_Buf_Write, 64);
+
+	delay_ms(10);
+	// GPIO_SetHigh(GPIO1,GPIO_BIT1);
+	at24cxx_read(512, I2c_Buf_Read, 64);
+	// GPIO_SetLow(GPIO1,GPIO_BIT1);
+	//data_dump("I2C Write", I2c_Buf_Write, I2C_DATA_LEN);
+	//data_dump("I2C Read", I2c_Buf_Read, I2C_DATA_LEN);
+
+	EEPROM_INFO("\r\nI2C(AT24C128)读写测试成功\r\n");
+
+	return 1;
+}

+ 48 - 0
src/agm_board/i2c.h

@@ -0,0 +1,48 @@
+#ifndef AT24C128_H__
+#define AT24C128_H__
+
+#include "board.h"
+
+
+#define IIC_WP_PORT     GPIO2
+#define IIC_WP_PIN		GPIO_BIT0
+
+#define IIC_SDA_PORT    GPIO2
+#define IIC_SDA_PIN		GPIO_BIT2
+
+#define IIC_SCL_PORT	GPIO2
+#define IIC_SCL_PIN     GPIO_BIT1
+
+#define SDA_IN()    GPIO_SetInput(IIC_SDA_PORT,IIC_SDA_PIN)
+#define SDA_OUT()   {GPIO_SetOutput(IIC_SDA_PORT,IIC_SDA_PIN);}
+
+#define IIC_SCL(n)  (n?GPIO_SetHigh(IIC_SCL_PORT,IIC_SCL_PIN) : GPIO_SetLow(IIC_SCL_PORT,IIC_SCL_PIN))
+#define IIC_SDA(n)  (n?GPIO_SetHigh(IIC_SDA_PORT,IIC_SDA_PIN) : GPIO_SetLow(IIC_SDA_PORT,IIC_SDA_PIN))
+
+#define READ_SDA GPIO_GetValue(IIC_SDA_PORT, IIC_SDA_PIN)
+
+//写保护,低电平关闭,可以写入;高电平打开,不能写入
+#define IIC_WRITE_PROTECT_ENABLE()   {GPIO_SetHigh(IIC_WP_PORT, IIC_WP_PIN);}
+#define IIC_WRITE_PROTECT_DISABLE()  {GPIO_SetLow(IIC_WP_PORT, IIC_WP_PIN);}
+
+
+extern void i2c_init(void);
+extern void i2c_start(void);
+extern void i2c_stop(void);
+extern uint8_t i2c_wait_ack(void);
+extern void IIC_Ack(void);
+extern void IIC_NAck(void);
+extern void i2c_send_byte(uint8_t txd);
+extern uint8_t i2c_read_byte(uint8_t ack);
+
+extern uint8_t at24cxx_readOneByte(uint32_t ReadAddr);
+extern void at24cxx_writeOneByte(uint32_t WriteAddr,uint8_t DataToWrite);
+extern void at24cxx_read(uint32_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead);
+extern void at24cxx_write(uint32_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite);
+extern void at24cxx_clr(uint32_t WriteAddr,uint32_t NumToWrite);
+
+extern uint8_t I2C_Test(void);
+
+#define EEPROM_INFO(fmt,arg...)           printf("<<-EEPROM-INFO->> "fmt"\n",##arg)
+
+#endif // !

+ 89 - 0
src/agm_board/led.c

@@ -0,0 +1,89 @@
+#include "led.h"
+#include "./app/public.h"
+
+void led_init(void)
+{
+    SYS_EnableAPBClock(LED_GPIO_MASK_01);
+    GPIO_SetOutput(LED_GPIO_RUN,LED_GPIO_RUN_BIT);
+    GPIO_SetOutput(LED_GPIO_MOD,LED_GPIO_MOD_BIT);
+    GPIO_SetOutput(LED_GPIO_PWR,LED_GPIO_PWR_BIT);
+    GPIO_SetLow(LED_GPIO_PWR,LED_GPIO_PWR_BIT);  // 电源灯上电常亮
+}
+
+void display_led_status(uint32_t tickt)
+{
+    static volatile uint8_t ledgreen = 0, ledred=0;
+    static volatile uint8_t num = 0;
+    if(0 == g_devMsg.ledgreen) { // 绿灯状态不亮
+        GPIO_SetHigh(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+    }
+    else if(1 == g_devMsg.ledgreen){ // 绿灯慢闪
+        if(tickt%500==0) {
+            if(ledgreen==0) GPIO_SetHigh(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+            else    GPIO_SetLow(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+            ledgreen = !ledgreen;
+        }
+    }
+    else if(2 == g_devMsg.ledgreen) { // 绿灯快闪
+        if(tickt%200==0) {
+            if(ledgreen==0) GPIO_SetHigh(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+            else    GPIO_SetLow(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+            ledgreen = !ledgreen;
+        }
+    }
+    else if(3 == g_devMsg.ledgreen) { // 绿灯常亮
+        GPIO_SetLow(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+    }
+    else if((4 == g_devMsg.ledgreen) ||(5 == g_devMsg.ledgreen)){
+        if( g_devMsg.ledgreen == 5){
+            if((tickt%300) == 0){
+                g_devMsg.ledgreen = 6;
+                return;
+            }
+        }
+        if(tickt%200==0) {
+            if(ledgreen==0) {
+                GPIO_SetHigh(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+                GPIO_SetHigh(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+            }
+            else    {
+                GPIO_SetLow(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+                GPIO_SetLow(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+                num++;
+                if(num>g_devMsg.ledred){
+                    g_devMsg.ledgreen = 5;// 上电显示灯已经结束
+                    GPIO_SetHigh(LED_GPIO_RUN, LED_GPIO_RUN_BIT);
+                    GPIO_SetHigh(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+                    ledgreen = 1;
+                }
+            }
+
+            ledgreen = !ledgreen;
+
+        }
+        return;
+    }
+
+
+    if(0 == g_devMsg.ledred) { // 红灯状态不亮
+        GPIO_SetHigh(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+    }
+    else if(1 == g_devMsg.ledred){ // 红灯慢闪
+        if(tickt%500==0) {
+            if(ledred==0) GPIO_SetHigh(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+            else    GPIO_SetLow(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+            ledred = !ledred;
+        }
+    }
+    else if(2 == g_devMsg.ledred) { // 红灯快闪
+        if(tickt%200==0) {
+            if(ledred==0) GPIO_SetHigh(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+            else    GPIO_SetLow(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+            ledred = !ledred;
+        }
+    }
+    else if(3 == g_devMsg.ledred) { // 红灯常亮
+        GPIO_SetLow(LED_GPIO_MOD, LED_GPIO_MOD_BIT);
+    }
+
+}

+ 24 - 0
src/agm_board/led.h

@@ -0,0 +1,24 @@
+#ifndef _LED_H_
+#define _LED_H_
+
+#include "board.h"
+
+#define LED_GPIO_MASK_01   APB_MASK_GPIO1
+
+#define LED_GPIO_RUN        GPIO1
+#define LED_GPIO_RUN_BIT    GPIO_BIT0
+
+#define LED_GPIO_MOD        GPIO1
+#define LED_GPIO_MOD_BIT    GPIO_BIT1
+
+#define LED_GPIO_PWR        GPIO1
+#define LED_GPIO_PWR_BIT    GPIO_BIT3
+
+
+
+
+extern void led_init(void);
+extern void display_led_status(uint32_t tickt);
+
+
+#endif

+ 116 - 0
src/agm_board/rtc.c

@@ -0,0 +1,116 @@
+#include "rtc.h"
+
+
+_calendar_obj calendar;	//日历结构体
+
+//rtc初始化
+void rtc_init(void)
+{
+    uint32_t times;
+    RTC_Init(board_rtc_source());
+    RTC_SetPrescaler(32768);
+    if(0x5AA5 != (RTC_ReadBackupRegister(0)))
+    {
+        times = RTC_GetEpochSeconds(2023, 8, 21, 11, 01, 00);
+        RTC_SetCounter(times);
+        RTC_WriteBackupRegister(0,0x5AA5);
+    }
+	RTC_Get();
+}
+
+//rtc时间显示
+#define  IS_LEAP_YEAR_m(year) (!((year) % 4) && (((year) % 100) || !((year) % 400)))
+const uint8_t mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
+//得到当前的时间
+//返回值:0,成功;其他:错误代码.
+uint8_t RTC_Get(void)
+{
+    // static uint16_t daycnt = 0;
+    // uint32_t timecount;
+    // uint32_t temp  = 0;
+    // uint16_t temp1 = 0;
+
+	time_t now;
+	now=RTC_GetCounter();
+	struct tm *tm = gmtime(&now);
+	printf("rtc time:%d:%02d:%02d-%02d:%02d:%02d\n", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+#if 0
+    timecount=RTC_GetCounter();
+    temp=timecount/86400;   //得到天数(秒钟数对应的)
+    if(timecount<86400)//不到1天
+    {
+        //从1970年1月1日开始
+        calendar.w_year  = 1970;
+        calendar.w_month = 1;
+        calendar.w_date  = 1;
+    }
+	if(daycnt!=temp)  //超过一天了
+	{
+		daycnt = temp;
+		temp1  = 1970;  //从1970年开始
+		while(temp>=365)  //计算出来的天数大于等于一年的天数
+		{
+			if(IS_LEAP_YEAR_m(temp1))  //是闰年
+			{
+				if(temp>=366)
+				{
+					temp -= 366;  //闰年的秒钟数
+				}
+				else
+				{
+					temp1++;
+					break;
+				}
+			}
+			else temp -= 365;  //平年
+			temp1++;
+		}
+		calendar.w_year = temp1;  //得到年份
+		temp1           = 0;
+		while(temp>=28)  //超过了一个月
+		{
+			if(IS_LEAP_YEAR_m(calendar.w_year)&&temp1==1)  //当年是不是闰年/2月份
+			{
+				if(temp>=29)  //如果天数超过29天
+				{
+					temp -= 29;  //闰年的秒钟数
+				}
+				else break;  //小于29天,不到闰年3月,直接跳出。
+			}
+			else
+			{
+				if(temp>=mon_table[temp1])
+				{
+					temp -= mon_table[temp1];  //平年
+				}
+				else break;
+			}
+			temp1++;
+		}
+		calendar.w_month = temp1+1;  //得到月份
+		calendar.w_date  = temp+1;   //得到日期
+	}
+
+	temp         =timecount%86400;  //得到秒钟数
+	calendar.hour=temp/3600;        //小时
+	calendar.min =(temp%3600)/60;   //分钟
+	calendar.sec =(temp%3600)%60;   //秒钟
+	                                // calendar.week=RTC_Get_Week(calendar.w_year,calendar.w_month,calendar.w_date);//获取星期
+
+	 printf("timecount:%u, current time %d-%d-%d %02d:%02d:%02d\r\n", timecount,
+		calendar.w_year,calendar.w_month,calendar.w_date,
+		calendar.hour, calendar.min, calendar.sec);
+#endif
+	return 0;
+}
+
+//设置时钟
+//以1970年1月1日为基准
+//1970~2099年为合法年份
+//参数:时间戳
+void set_time(uint32_t seccount)
+{
+	RTC_SetCounter(seccount);		//设置RTC计数器的值
+}
+

+ 44 - 0
src/agm_board/rtc.h

@@ -0,0 +1,44 @@
+/*
+ * @Description:
+ * @Version: 2.0
+ * @Author: Seven
+ * @Date: 2023-08-21 10:10:30
+ * @LastEditors: Seven
+ * @LastEditTime: 2023-09-19 17:47:28
+ */
+#ifndef __RTC_H__
+#define __RTC_H__
+#include "board.h"
+
+
+
+enum BKP_t {
+	BKP_DATA_0,
+    BKP_DATA_1,
+    BKP_DATA_2,
+    BKP_DATA_3,
+    BKP_DATA_4,
+    BKP_DATA_5,
+    BKP_DATA_6,
+    BKP_DATA_7,
+};
+
+
+//时间结构体
+typedef struct
+{
+	uint32_t hour;
+	uint32_t min;
+	uint32_t sec;
+	//公历日月年周
+	uint32_t w_year;
+	uint32_t  w_month;
+	uint32_t  w_date;
+	uint32_t  week;
+}_calendar_obj;
+extern _calendar_obj calendar;	//日历结构体
+
+extern void rtc_init(void);
+uint8_t RTC_Get(void);
+extern void set_time(uint32_t seccount);
+#endif // !

+ 54 - 0
src/agm_board/timeout.c

@@ -0,0 +1,54 @@
+#include "timeout.h"
+#include "Timer.h"
+
+
+/*----------------------------------------------------------------------------
+  * 设置定时器
+  * tt:定时器指针
+  * val,延时ms
+  *---------------------------------------------------------------------------*/
+void timeout_setValue(timeout_t *tt,uint32_t val){
+  tt->counter = Get_SysTick();
+  tt->timeout = val;
+}
+/*----------------------------------------------------------------------------
+ * 启动定时器
+ * tt :定时器指针
+ *---------------------------------------------------------------------------*/
+void timeout_start(timeout_t *tt){
+    tt->counter = Get_SysTick();
+    tt->flag = 1;
+    tt->endMode = 1;
+
+}
+/*----------------------------------------------------------------------------
+ * 停止定时器
+ * tt: 定时器指针
+ *---------------------------------------------------------------------------*/
+void timeout_stop(timeout_t *tt){
+  tt->flag = 0;
+  tt->endMode = 2;
+}
+/*----------------------------------------------------------------------------
+ * 返回定时器是否超时
+ * tt:定时器指针
+ * 返回值 1:超时 0:未超时
+ *---------------------------------------------------------------------------*/
+uint8_t timeout_isOut(timeout_t *tt){
+  if(tt->flag){
+    if((Get_SysTick() - tt->counter) > tt->timeout){
+      tt->counter = Get_SysTick();
+      if(tt->flag == 1){
+        tt->flag = 0;
+      }
+      tt->endMode = 0x03;
+      return 1;
+    }
+    else{
+      return 0;
+    }
+  }
+  else{
+    return 1;
+  }
+}

+ 19 - 0
src/agm_board/timeout.h

@@ -0,0 +1,19 @@
+#ifndef _TIMEOUT_H_
+#define _TIMEOUT_H_
+
+#include "board.h"
+
+typedef struct
+{
+  uint8_t flag;
+  uint8_t endMode; // 1:start 2: endNormal
+  uint32_t counter;
+  uint32_t timeout;
+}__attribute__((packed)) timeout_t;
+
+extern void timeout_setValue(timeout_t *tt,uint32_t val);
+extern void timeout_start(timeout_t *tt);
+extern void timeout_stop(timeout_t *tt);
+extern uint8_t timeout_isOut(timeout_t *tt);
+
+#endif

+ 295 - 0
src/agm_board/uart_agm.c

@@ -0,0 +1,295 @@
+#include "uart_agm.h"
+#include "delay.h"
+#include "app/public.h"
+#include "app/air780e.h"
+
+uint32_t uart_delay[UART_MAX];
+
+//根据波特率计算延时时间
+void uart_baud_delay(uint8_t uartid, uint32_t baud)
+{
+    uint32_t delay,temp;
+    if(uartid >= UART_MAX)
+        return;
+    temp = 1000000/baud;
+    delay = temp*10 + temp*1;
+    uart_delay[uartid] = delay;
+    // printf("uart%d,delay:%u\n",uartid,uart_delay[uartid]);
+}
+
+void uart_0_debug_init(void)
+{
+    GPIO_AF_ENABLE(GPIO_AF_PIN(UART, LOGGER_UART, UARTRXD));
+    GPIO_AF_ENABLE(GPIO_AF_PIN(UART, LOGGER_UART, UARTTXD));
+    SYS_EnableAPBClock(APB_MASK_UART0);
+    UART_Init(UART0, 115200, UART_LCR_DATABITS_8, UART_LCR_STOPBITS_1, UART_LCR_PARITY_NONE, UART_LCR_FIFO_1);
+
+    UART_EnableInt(UART0, UART_INT_RX);
+    UART_SetRxIntFifoLevel(UART0, UART_INT_FIFO_HALF);
+    INT_EnableIRQ(UART0_IRQn, UART_PRIORITY);
+}
+
+void data_dump(const char *name, uint8_t *data, uint16_t length)
+{
+    int index = 0;
+
+    printf("%s Data Info: \r\n    ", name);
+
+    for (index = 0; index < length; index++)
+    {
+        if ((index % 4 == 0) && index)
+        {
+            if ((index % 16 == 0) && index)
+            {
+                printf("\r\n    ");
+            }
+            else
+            {
+                printf(" ");
+            }
+        }
+        printf("%02x ", *(data + index));
+    }
+    printf("\r\n");
+}
+
+uint8_t uartDeal[1024] = {0};
+uart_rcv_info g_u4ginfo;
+uint8_t _tempstr[512],netrcvdata[512];
+void UART1_isr(void)
+{
+    char val;
+    volatile static uint16_t dalen = 0;
+    volatile static uint8_t flag = 0;
+    char *str = NULL, *str1 = NULL,*str2 = NULL;
+    char *msg = NULL;
+    int slen;
+    volatile uint32_t net_rcv_len;
+    if (UART_IsRawIntActive(UART1, UART_INT_RX))
+    {
+        UART_ClearInt(UART1, UART_INT_RX);
+        UART_ReceiveCh(UART1, &val, 0);
+        g_u4ginfo.rcvBuf[g_u4ginfo.tail] = val;
+        if(val == '+'){
+            dalen = 0;
+        }
+        if(dalen > 1023) dalen = 0;
+        uartDeal[dalen++] = val;
+        if((dalen>6) && (WORK_UPDATE != g_devMsg.workMode)){
+             if(strncmp((char*)uartDeal,"+MSUB:",6)==0){ //
+                if(uartDeal[dalen-2] =='\r' && uartDeal[dalen-1]=='\n'){
+                    flag = 1;
+                }
+            }
+        }
+        if((flag == 1) ) {
+            str = strstr(uartDeal,"+MSUB:");
+            if(str) {
+                str1 = strstr(uartDeal,"byte");
+                str2 = strstr(str1,"\r\n");
+                if(str1 && str2 ){//&&( ucnt-datalen>=(len+2))
+                    memset(_tempstr, 0, sizeof(_tempstr));
+                    slen = net_data_copy(str1+5,(uint8_t *)_tempstr);
+                    net_rcv_len = net_rcvdata_ch((char *)_tempstr,netrcvdata,slen);
+                    fifo_write(&g_4Grxfifo,netrcvdata,net_rcv_len);
+                    //data_dump("NET RECB", netrcvdata, net_rcv_len);
+                    memset(str,0xFF,str2-str1);
+                    g_u4ginfo.tail = 0;
+                    g_u4ginfo.head = 0;
+                }
+            }
+            dalen = 0;
+            flag = 0;
+        }
+        g_u4ginfo.tail = (g_u4ginfo.tail+1)%UART_RCV_PROCBUF_LEN;
+        if(g_u4ginfo.head == g_u4ginfo.tail){ // 前面的已经覆盖
+            g_u4ginfo.head = (g_u4ginfo.head+1)%UART_RCV_PROCBUF_LEN;
+        }
+        timeout_setValue(&g_u4ginfo.ttUart, UART_RCV_TIMEOUT);
+        timeout_start(&g_u4ginfo.ttUart);
+    }
+}
+
+/*--------------------------------------------------------------------------------
+ *  串口fifo 的初始化函数
+ *  uartid: 串口号 rcv: 信息接收函数
+ *--------------------------------------------------------------------------------*/
+int uart_rs232_fifo_init(void)
+{
+    g_u4ginfo.head = 0;
+    g_u4ginfo.tail = 0;
+    g_u4ginfo.readpos = 0;
+    memset(g_u4ginfo.rcvBuf,0,UART_RCV_PROCBUF_LEN);
+
+    return 0;
+}
+void uart1_4g_init(uint32_t baud)
+{
+    GPIO_AF_ENABLE(GPIO_AF_PIN(UART, 1, UARTRXD));
+    GPIO_AF_ENABLE(GPIO_AF_PIN(UART, 1, UARTTXD));
+    SYS_EnableAPBClock(APB_MASK_UART1);
+
+    UART_Init(UART1, baud, UART_LCR_DATABITS_8, UART_LCR_STOPBITS_1, UART_LCR_PARITY_NONE, UART_LCR_FIFO_1);
+
+    UART_EnableInt(UART1, UART_INT_RX);
+    //UART_SetRxIntFifoLevel(UART1, UART_INT_FIFO_HALF); //
+    INT_EnableIRQ(UART1_IRQn, UART_PRIORITY);
+    uart_baud_delay(1,baud);
+    uart_rs232_fifo_init();
+}
+
+uart485Info_t g_uart485;
+uart_com_rcv_info g_uComInfo[3];
+uint8_t usart485TX_Buffer[USART3_TX_SIZE];
+void read_485_data(void)
+{
+    static uint8_t tempbuf[256];
+    uint8_t strlen = 0;
+    static uint16_t len = 0;
+    //len = 0;
+
+
+    if(timeout_isOut(&g_uComInfo[0].ttUart)&& g_uComInfo[0].ttUart.endMode==3){
+        timeout_stop(&g_uComInfo[0].ttUart);
+        //printf("head = %d, tail=%d\n",g_uComInfo[0].head,g_uComInfo[0].tail);
+        while(g_uComInfo[0].head != g_uComInfo[0].tail){
+            tempbuf[len++] = g_uComInfo[0].rcvBuf[g_uComInfo[0].head];
+            g_uComInfo[0].head = (g_uComInfo[0].head+1)%UART_COM_RCVBUF_LEN;
+        }
+        if(strstr(tempbuf,"AT+PTMOD=ON\r\n") && (g_devMsg.workMode != WORK_UPDATE)){
+            //fifo_write(&g_rxfifo,tempbuf,len);// 数据加入到fifo中
+            printf("jum to pt\n");
+            len = 0;
+            memset(tempbuf,0,256);
+            run_app();
+
+        }
+        if(len >= 12)
+        {
+            //printf("head = %d, tail=%d\n",g_uComInfo[0].head,g_uComInfo[0].tail);
+            //data_dump("收到 ~~~~~~~~: ",tempbuf,len);
+            strlen = (tempbuf[11]<<8)| tempbuf[10];
+            if(len >= (strlen+12)) {
+                fifo_write(&g_rxfifo,tempbuf,len);// 数据加入到fifo中
+                len = 0;
+                memset(tempbuf,0,256);
+            }
+            if(len >= 256) len = 0;
+        }
+
+    }
+
+
+}
+void UART2_isr(void)
+{
+    char data;
+    uart_com_rcv_info *uinfo;
+
+    uinfo = &g_uComInfo[0];
+    if (UART_IsRawIntActive(UART2, UART_INT_RX))
+    {
+        UART_ReceiveCh(UART2, &data, 0);
+        uinfo->rcvBuf[uinfo->tail] = data;
+        uinfo->tail = (uinfo->tail + 1)%UART_COM_RCVBUF_LEN;
+        timeout_setValue(&uinfo->ttUart,UART_RCV_TIMEOUT);
+        timeout_start(&uinfo->ttUart);
+        UART_ClearInt(UART2, UART_INT_RX);
+    }
+}
+
+void uart2_485_init(uint32_t baud)
+{
+    GPIO_AF_ENABLE(GPIO_AF_PIN(UART, 2, UARTRXD));
+    GPIO_AF_ENABLE(GPIO_AF_PIN(UART, 2, UARTTXD));
+    SYS_EnableAPBClock(APB_MASK_UART2);
+    UART_Init(UART2, baud, UART_LCR_DATABITS_8, UART_LCR_STOPBITS_1, UART_LCR_PARITY_NONE, UART_LCR_FIFO_1);
+
+    UART_EnableInt(UART2, UART_INT_RX);
+    UART_SetRxIntFifoLevel(UART2, UART_INT_FIFO_HALF);
+    INT_EnableIRQ(UART2_IRQn, UART_PRIORITY);
+
+    // 485 CTL
+    SYS_EnableAPBClock(APB_MASK_GPIO1);
+    GPIO_SetOutput(GPIO1, GPIO_BIT2);
+    RS485_RX();
+
+    g_uComInfo[0].head = 0;
+    g_uComInfo[0].tail = 0;
+
+    uart_baud_delay(2,baud);
+}
+
+
+
+// 串口发送函数
+UART_TypeDef *uart_choice(uint8_t uartid)
+{
+    UART_TypeDef *USARTx;
+    switch (uartid)
+    {
+    case UART0_ID:
+        USARTx = UART0;
+        break;
+    case UART1_ID:
+        USARTx = UART1;
+        break;
+    case UART2_ID:
+        USARTx = UART2;
+        break;
+    case UART3_ID:
+        USARTx = UART3;
+        break;
+    case UART4_ID:
+        USARTx = UART4;
+        break;
+    default:
+        break;
+    }
+    return USARTx;
+}
+/*******************************************************************************
+ *uart1_msg_send 发送报文处理
+ *Input:
+ *	buf		--需要发送的数据指针
+ *	buflen	--发送的数据长度
+ *Output:
+ *	None
+ *Return:
+ *	OK/ERROR,表示执行成功和失败
+ */
+ReturnCodeTypedef UART_Send_t(uint8_t uartid, UART_TypeDef *uart, const unsigned char *p, unsigned int num)
+{
+    for (unsigned int i = 0; i < num; ++i)
+    {
+        // UART_SendCh(uart,*p);
+        // p++;
+        // delay_us(90);
+        while (UART_IsTxFifoFull(uart))
+            ;
+
+        uart->DR = *p++;
+
+        delay_us(uart_delay[uartid]);
+    }
+    return RET_OK;
+}
+int uart_msg_send(uint8_t uartid, const char *buf, uint32_t buflen)
+{
+    uint32_t t = 0;
+    UART_TypeDef *USARTx;
+
+    if (uartid >= UART_MAX)
+        return -1;
+    if (uartid == UART2_ID)
+        RS485_TX();
+    USARTx = uart_choice(uartid);
+    UART_Send_t(uartid, USARTx, buf, buflen);
+    // UART_Send(USARTx, buf, buflen);
+    if (uartid == UART2_ID)
+    {
+        // delay_us(60);
+        RS485_RX();
+    }
+    return 0;
+}

+ 82 - 0
src/agm_board/uart_agm.h

@@ -0,0 +1,82 @@
+#ifndef _UART_AGM_H_
+#define _UART_AGM_H_
+
+#include "board.h"
+#include "agmconfig.h"
+#include "timeout.h"
+#include "fifo.h"
+
+
+#define UART_RCV_TIMEOUT    (20)  // 串口接收超时时间 10ms
+
+/*端口号*/
+enum {
+	UART0_ID    = 0,
+	UART1_ID    = 1,
+	UART2_ID    = 2,
+    UART3_ID    = 3,
+    UART4_ID    = 4,
+
+	UART_DEBUG  = UART0_ID,
+    UART_4G     = UART1_ID,
+    UART_485    = UART2_ID,
+	UART_MAX = 5
+};
+
+#define RS485_RX() GPIO_SetLow(GPIO1, GPIO_BIT2)
+#define RS485_TX() GPIO_SetHigh(GPIO1, GPIO_BIT2)
+
+
+
+#define USART1_TX_SIZE  640
+
+#define UART_RCV_TEMPBUF_LEN	1024
+#define UART_RCV_PROCBUF_LEN	2048
+
+typedef struct _uart_rcv_da_{
+	uint8_t rcvBuf[UART_RCV_PROCBUF_LEN];
+	uint16_t head;
+	uint16_t tail;
+	timeout_t ttUart;
+	uint16_t readpos;
+}__attribute__((packed))uart_rcv_info;
+extern uart_rcv_info g_u4ginfo;
+
+
+#define UART_COM_RCVBUF_LEN 256
+
+typedef struct _uart_com_rcv_da_{
+	uint8_t rcvBuf[UART_COM_RCVBUF_LEN];
+	volatile uint16_t head;
+	volatile uint16_t tail;
+	timeout_t ttUart;
+	uint16_t readpos;
+}__attribute__((packed))uart_com_rcv_info;
+extern uart_com_rcv_info g_uComInfo[3];
+
+#define USART3_TX_SIZE	256
+//#define USART3_RX_SIZE	256
+extern uint8_t usart485TX_Buffer[USART3_TX_SIZE];
+//extern uint8_t usart485RX_Buffer[USART3_RX_SIZE];
+
+typedef struct _uart_485_info_{
+    uint8_t bSdFinish; //
+    uint8_t bRcv;
+    timeout_t time; // 发送的时候启动  收到数据时结束
+}__attribute__((packed))uart485Info_t;
+extern uart485Info_t g_uart485;
+
+
+
+extern void uart_0_debug_init(void);
+extern void data_dump(const char *name, uint8_t *data, uint16_t length);
+
+extern void read_485_data(void);
+extern void uart1_4g_init(uint32_t baud);
+extern void uart2_485_init(uint32_t baud);
+
+extern int uart_rs232_fifo_init(void);
+
+extern int uart_msg_send(uint8_t uartid, const char *buf, uint32_t buflen);
+
+#endif

+ 916 - 0
src/app/air780e.c

@@ -0,0 +1,916 @@
+#include "air780e.h"
+#include "public.h"
+#include "../agm_board/agmboard.h"
+
+
+FIFO_T g_4Grxfifo; // 4G的接收缓冲区
+FIFO_T g_4Gtxfifo; // 4G的发送缓冲区
+_4GMsgInfo g_4gMsg;
+MqttMsg g_mqttMsg;
+MqttCHmsg g_mqttCHmsg;
+uartInfo_t g_uart1Info;
+
+timeout_t g_uartTime;
+static uint8_t _tempbuff[256] = {'\0'};
+static uint8_t _temp4Gbuff[640];
+static uint8_t buff[256];
+
+uint8_t AT_GET_Data_2Param(char * buff1,uint8_t get_data[],char*head,char*tail)
+{
+    if(strstr(buff1,head)&&strstr(buff1,tail))
+	{
+		uint16_t i;
+		uint16_t len1,len2;
+		char *t = NULL;
+		char *h=strstr(buff1,head);
+		len1=strlen(h);				/*剩余长度*/
+		len2=strlen(head);		/*头子串长度*/
+		t=strstr(h+len2,tail);
+		if(len1>len2)
+		{
+					for(i=0;h+i+len2!=t;i++)
+					{
+						get_data[i]=h[i+len2];
+					}
+					get_data[i]='\0';//加上结束符
+		}else
+		{
+			printf("\r\n字串长度错误\r\n");
+			return 0;
+		}
+	}else
+	{
+		if(!strstr(buff1,head))printf("\r\n未能检索到头字串\r\n");
+		if(!strstr(buff1,tail))printf("\r\n未能检索到尾字串\r\n");
+
+		printf("\r\n请检查你的数据原文:\r\n");
+		printf("%s", buff1);
+		return 0;
+	}
+	return 1;
+}
+void send_cmd_to_mqtt(char *str,uint8_t cmd)
+{
+    g_uart1Info.cmd = cmd;
+    UART_Send(UART1,str,strlen(str));
+}
+void send_data_to_mqtt(uint8_t type, uint8_t *data, uint8_t len)
+{
+    uint16_t i,ret;
+    uint16_t send_len = 0;
+
+    //if(len > NET_SEND_DA_LEN) return;
+
+    if(! g_4gMsg.bconnect) return ;
+
+
+    memset(g_uart1Info.txfifo,0,USART1_TX_SIZE);
+    memset(_temp4Gbuff,0,640);
+    for(i=0;i<len;i++){
+        send_len += snprintf((char*)_temp4Gbuff+send_len,sizeof(_temp4Gbuff),"%02x",data[i]);
+    }
+    sprintf((char*)g_uart1Info.txfifo,"AT+MPUB=\"%s\",0,0,\"%s\"\r\n",g_4gMsg.upTopic,_temp4Gbuff);
+    UART_Send(UART1,g_uart1Info.txfifo,strlen((char*)g_uart1Info.txfifo));
+    ret = waiting_uart_return(300,"OK",NULL);
+    if(ret == 1){
+        g_4gMsg.noreturnNum = 0;
+    }
+    else {
+        g_4gMsg.noreturnNum++;
+    }
+    if(g_4gMsg.noreturnNum >5){
+        g_4gMsg.bconnect = 0;
+        g_4gMsg.noreturnNum = 0;
+    }
+    return;
+}
+void close_mqtt(void)
+{
+    //uint8_t val;
+    send_cmd_to_mqtt("AT+MDISCONNECT\r\n",AT_MDISCONNECT);
+    waiting_uart_return(500,"OK",NULL);
+    //if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("AT+MIPCLOSE\r\n",AT_MIPCLOSE);
+    waiting_uart_return(500,"OK",NULL);
+    //if(ret==0) goto MQTT_ERROR;
+}
+
+
+int net_data_copy(char *data, uint8_t *out_data)
+{
+    int len = 0;
+    while(1)
+    {
+        if(data[len] == '\r'||data[len] == '\n') break;
+        out_data[len] = data[len];
+        len++;
+    }
+    return len;
+}
+
+void read_uart_data(void)
+{
+    uint16_t i = 0;
+    timeout_setValue(&g_uartTime,10000);
+    timeout_start(&g_uartTime);
+    do{
+        if((g_u4ginfo.head != g_u4ginfo.tail) && timeout_isOut(&g_u4ginfo.ttUart)){
+            memcpy(buff,&g_u4ginfo.rcvBuf[g_u4ginfo.head],g_u4ginfo.tail-g_u4ginfo.head);
+            printf("收到:%s",&buff[1]);
+            if(strstr(buff,"+NITZ")) {
+                break;
+            }
+            g_u4ginfo.head = g_u4ginfo.tail;
+            memset(buff,0,256);
+        }
+        if(timeout_isOut(&g_uartTime)) {
+            printf("time out\n");
+            break;
+        }
+    }while(1);
+    timeout_stop(&g_uartTime);
+}
+unsigned char HexToChar(unsigned char bChar)
+{
+    if((bChar>=0x30)&&(bChar<=0x39))
+    {
+        bChar -= 0x30;
+    }
+    else if((bChar>=0x41)&&(bChar<=0x46)) // Capital
+    {
+        bChar -= 0x37;
+    }
+    else if((bChar>=0x61)&&(bChar<=0x66)) //littlecase
+    {
+        bChar -= 0x57;
+    }
+    else
+    {
+        bChar = 0xff;
+    }
+    return bChar;
+}
+//字符串转十六进制数
+uint32_t strtohex(char *data, uint8_t len)
+{
+	uint8_t i = 0;;
+	uint32_t p_data = 0;
+	uint8_t temp;
+	for(i = 0; i < len; i++)
+	{
+		temp = HexToChar(data[i]);
+		if(temp == 0xff)
+			break;
+		p_data = (p_data<<4)|temp;
+	}
+	return p_data;
+}
+int net_rcvdata_ch(char *data, uint8_t *out_data, int len)
+{
+    int i,slen=0;
+    uint8_t temp1,temp2;
+    for(i = 0; i < len; i+=2)
+    {
+        temp1 = HexToChar(data[i]);
+        temp2 = HexToChar(data[i+1]);
+        out_data[slen] = (temp1<<4) | temp2;
+        slen++;
+    }
+    return slen;
+}
+uint8_t  waiting_uart_return(uint32_t timeout,char*str,uint32_t *value)
+{
+    uint8_t ret = 0;
+    char *str1=NULL;
+    int dBm,dbvl;
+    uint8_t srclen,flag = 0;
+
+    memset(g_uart1Info.waitMsg,0,16);
+    strcpy((char*)g_uart1Info.waitMsg,str);
+
+    if(strcmp(str,"CONNECT OK") == 0){
+        flag = 1;
+    }
+
+    timeout_setValue(&g_uartTime,timeout);
+    timeout_start(&g_uartTime);
+    UTIL_IdleMs(50);
+    memset(buff,0,sizeof(buff));
+    do{
+        if((g_u4ginfo.head != g_u4ginfo.tail) && timeout_isOut(&g_u4ginfo.ttUart)){
+            strncat(buff,&g_u4ginfo.rcvBuf[g_u4ginfo.head],g_u4ginfo.tail-g_u4ginfo.head);
+            g_u4ginfo.head = g_u4ginfo.tail;
+            printf("收到:%s",buff);
+
+            if(flag == 0) {
+                if(strstr((char*)buff,(char*)g_uart1Info.waitMsg)){
+                    ret = 1;
+                    break;
+                }
+            }
+            else if(flag == 1){
+                if(strstr((char*)buff,(char*)g_uart1Info.waitMsg) || strstr((char*)buff,(char*)"ALREADY CONNECT")){
+                    ret = 1;
+                    break;
+                }
+            }
+
+        }
+
+        if(timeout_isOut(&g_uartTime)) {
+            printf("超时\n");
+            ret = 0;
+            break;
+        }
+    }while(1);
+    if(ret == 1)
+    {
+        memset((char*)_tempbuff,0,32);
+        switch(g_uart1Info.cmd){
+        case AT_MQTTSTATUS:
+            printf("收到:%s\r\n",buff);
+            str1 = strstr((char*)buff,"+MQTTSTATU :");
+            *value = atoi(str1+12);
+            break;
+        case AT_CPIN:
+            printf("收到:%s\r\n",buff);
+            AT_GET_Data_2Param((char*)buff,_tempbuff,"+CPIN: ","\r\nOK");
+            printf("---CPIN:%s\r\n",_tempbuff);
+            //if(strstr(_tempbuff,"READY")) ret = 1;
+            //else ret = 2;
+            break;
+        case AT_CGATT: // 查询是否附着上数据网络
+            printf("收到:%s\r\n",buff);
+            AT_GET_Data_2Param((char*)buff,_tempbuff,"+CGATT: ","\r\nOK");
+            printf("---CGATT:%s\r\n",_tempbuff);
+            *value = atoi(_tempbuff);
+            break;
+        case AT_SAPRB_GPRS: //
+            printf("收到:%s\r\n",buff);
+            break;
+        case AT_SAPRB_APN: //
+            printf("收到:%s\r\n",buff);
+            break;
+        case AT_SAPRB_11: //
+            printf("收到:%s\r\n",buff);
+            break;
+        case AT_SAPRB_21: //
+            printf("收到:%s\r\n",buff);
+            break;
+        case AT_CREG:
+            printf("收到:%s\r\n",buff);
+            AT_GET_Data_2Param((char*)buff,_tempbuff,",","\r\nOK");
+            g_4gMsg.cregStatus = atoi((char*)_tempbuff);
+            printf("网络连接状态 cregStatus = :%d\r\n",g_4gMsg.cregStatus);
+            break;
+        case AT_ICCID:
+            printf("收到:%s\r\n",buff);
+            AT_GET_Data_2Param((char*)buff,_tempbuff,"+ICCID: ","\r\n");
+            //printf("ICCID: %s\r\n",_tempbuff);
+            memcpy(g_4gMsg.iccid,_tempbuff,20);
+            //printf("ICCID: %s\r\n",g_4gMsg.iccid);
+            break;
+        case AT_CGSN:
+            printf("收到:%s\r\n",buff);
+            AT_GET_Data_2Param((char*)buff,_tempbuff,"AT+CGSN\r\n","\r\nOK");
+            //printf("IMEI: %s\r\n",_tempbuff);
+            memcpy(g_4gMsg.imei,_tempbuff+2,15);
+            break;
+        case AT_ATI:
+            printf("收到:%s\r\n",buff);
+            break;
+        case AT_CSQ:
+            AT_GET_Data_2Param((char*)buff,_tempbuff,"+CSQ: ",",");
+            dbvl = (uint32_t)atoi((char*)_tempbuff);
+            if(dbvl==99) {dBm = 0; printf("signal intensity:there is no signal\r\n");}
+            else if(dbvl>=31&&dbvl<=99) {dBm = dbvl*2-113; printf("signal intensity:-51dBm or higher\r\n");}
+            else if(dbvl>=2&&dbvl<31) {dBm = dbvl*2-113; printf("signal intensity:-109dBm ~ -53dBm\r\n");}
+            else if(dbvl==1) {dBm = -111; printf("signal intensity:-111dBm\r\n");}
+            else {dBm = dbvl*2-113; printf("signal intensity:-111dBm or less\r\n");}
+            g_4gMsg.dBm = dBm;
+            printf("~~~~~~~~~~4g-rssi-dbm: %d\r\n",g_4gMsg.dBm);
+        case AT_MCONNECT:
+            printf("MQTT CONNECT SUCCESS\r\n");
+            g_4gMsg.bconnect = 1;
+            //g_devMsg.baskIdentity = 1;
+
+            break;
+        case AT_HTTPACTION:
+            str = strstr((char*)buff, "," );
+            if(str) {
+                printf("%s\r\n", str);
+                str += 1;
+                str = strstr(str, "," );
+                if(str) {
+                    printf("%s\r\n", str);
+                    str += 1;
+                    *value = atoi(str);//获取接收长度
+                }
+            }
+            break;
+        case AT_HTTPFILELEN:
+            AT_GET_Data_2Param((char*)buff,_tempbuff,"Content-Length: ","\r\n");
+            dbvl = (uint32_t)atoi((char*)_tempbuff);
+            *value = dbvl;
+            break;
+        default:
+            str = strstr((char*)buff,(char*)"byte");
+            if(str != NULL){
+                AT_GET_Data_2Param((char*)buff,_tempbuff,",","byte");
+                srclen = atoi((char*)_tempbuff);
+                memset(_tempbuff,0,256);
+                //srclen = net_rcvdata_ch(str+5,_tempbuff,srclen*2);
+                //data_dump("NET_RCB",_tempbuff,srclen);
+                //fifo_write(&g_4Grxfifo,_tempbuff,srclen); // 将数据写入到4G 接收fifo中
+            }
+            break;
+        }
+    }
+    else {
+        printf("超时,4G模块没有返回\r\n");
+        ret = 0;
+    }
+    return ret;
+}
+
+#if(0)
+void AIR_HTTP_GET(const char *url, uint32_t *pLen)
+{
+    char buff[128]={0};
+
+    waiting_uart_return(200,"CLOSE OK", NULL);
+
+    send_cmd_to_mqtt("AT+CIPCLOSE\r\n",AT_NULL);
+    waiting_uart_return(200,"CLOSE OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r\n",AT_NULL);
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=3,1,\"APN\",\"\"\r\n",AT_NULL);
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=1,1\r\n",AT_NULL);
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=2,1\r\n",AT_NULL);
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+HTTPINIT\r\n",AT_NULL);
+    waiting_uart_return(500,"OK", NULL);
+
+    memset(buff,0,128);
+    sprintf(buff,"AT+HTTPPARA=\"URL\",\"%s\"\r\n", url);
+    printf("send :%s",buff);
+    send_cmd_to_mqtt(buff,AT_NULL);
+    waiting_uart_return(800,"OK", NULL);
+
+    uart_rs232_fifo_init();
+    send_cmd_to_mqtt("AT+HTTPACTION=0\r\n",AT_HTTPACTION);
+    waiting_uart_return(8000,"+HTTPACTION:", pLen);
+
+    return;
+}
+
+#else
+void AIR_HTTP_GET(const char *url, uint32_t *pLen)
+{
+    char buff[128]={0};
+
+    waiting_uart_return(200,"CLOSE OK", NULL);
+
+    send_cmd_to_mqtt("AT+CIPCLOSE\r\n",AT_NULL);                       //
+    waiting_uart_return(500,"CLOSE OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r\n",AT_NULL); //
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=3,1,\"APN\",\"\"\r\n",AT_NULL);//
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=1,1\r\n",AT_NULL);//
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+SAPBR=2,1\r\n",AT_NULL);//
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+HTTPINIT\r\n",AT_NULL);//
+    waiting_uart_return(500,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+HTTPPARA=\"CID\",1\r\n",AT_NULL);//
+    waiting_uart_return(500,"OK", NULL);
+
+    memset(buff,0,128);
+    sprintf(buff,"AT+HTTPPARA=\"URL\",\"%s\"\r\n", url);
+    //printf("send :%s",buff);
+    send_cmd_to_mqtt(buff,AT_NULL);//
+    waiting_uart_return(800,"OK", NULL);
+
+    send_cmd_to_mqtt("AT+HTTPACTION=2\r\n",AT_HTTPACTION); //
+    waiting_uart_return(8000,"+HTTPACTION:", pLen);
+
+    send_cmd_to_mqtt("AT+HTTPHEAD\r\n",AT_HTTPFILELEN); // 查找文件长度
+    waiting_uart_return(8000,"OK\r\n", pLen);
+
+
+
+    return;
+}
+#endif
+#define RX_FIFO_FILE  2048
+uint8_t rxfifo[RX_FIFO_FILE];
+timeout_t g_updatetime;
+
+#if(0)
+uint8_t * AIR_HTTP_READ(uint32_t start_addr, uint32_t data_len)
+{
+    uint8_t *p_buf = NULL;
+    char *str=NULL;
+    uint32_t read_len;
+    uint8_t temp[32];
+    uint16_t rxlen = 0,len=0;
+
+    memset(temp,0,32);
+
+    sprintf((char*)temp,"AT+HTTPREAD=%d,%d\r\n", start_addr, data_len);
+    //printf("request : %s\r\n",temp);
+    send_cmd_to_mqtt((char*)temp,AT_NULL);//AT+HTTPREAD=<start_address>,<byte_size>
+    strcpy((char*)g_uart1Info.waitMsg,"+HTTPREAD: ");
+
+    memset(rxfifo,0,1024);
+    rxlen = 0;
+    timeout_setValue(&g_updatetime,300);
+    timeout_start(&g_updatetime);
+    delay_us(100);
+    do{
+        if((g_u4ginfo.head != g_u4ginfo.tail) && timeout_isOut(&g_u4ginfo.ttUart)){
+         //   break;
+        }
+        if(timeout_isOut(&g_updatetime)) {
+            printf("timeout \r\n");
+            timeout_stop(&g_updatetime);
+            break;
+        }
+
+    }while(1);
+    memcpy(rxfifo,&g_u4ginfo.rcvBuf[g_u4ginfo.head],g_u4ginfo.tail-g_u4ginfo.head);
+    //data_dump("aaaaaa",rxfifo,g_u4ginfo.tail-g_u4ginfo.head);
+    g_u4ginfo.tail = g_u4ginfo.head = 0;
+
+    memset(temp,0,32);
+    if(AT_GET_Data_2Param((char*)rxfifo,(uint8_t*)temp, "+HTTPREAD: ", "\r\n")) {
+        read_len = atoi((char*)temp);
+        if(data_len == read_len) {
+            p_buf = (uint8_t *)strstr((char*)rxfifo, "+HTTPREAD: ");
+            p_buf = (uint8_t *)strstr((char *)p_buf, "\r\n");
+            p_buf += 2;/* data position. */
+
+            g_u4ginfo.tail = 0;
+            g_u4ginfo.head = 0;
+            memset(g_u4ginfo.rcvBuf,0,1024);
+        }
+    }
+
+    return p_buf;
+}
+#else
+uint8_t * AIR_HTTP_READ(uint32_t start_addr, uint32_t data_len)
+{
+    uint8_t *p_buf = NULL;
+    char *str=NULL;
+    uint32_t read_len;
+    uint8_t temp[32];
+    uint16_t rxlen = 0,len=0,start = 0xFFFF;
+    uint32_t httplen = 0;
+
+    uart_rs232_fifo_init();
+
+    printf("break addr = %d, breakend addr = %d",start_addr,start_addr+data_len-1);
+    sprintf((char*)temp,"AT+HTTPPARA=\"BREAK\",%d\r\n", start_addr);
+    send_cmd_to_mqtt((char*)temp,AT_NULL);
+    waiting_uart_return(300,"OK\r\n", NULL);
+
+    sprintf((char*)temp,"AT+HTTPPARA=\"BREAKEND\",%d\r\n", start_addr+data_len-1);
+    send_cmd_to_mqtt((char*)temp,AT_NULL);
+    waiting_uart_return(300,"OK\r\n", NULL);
+
+    send_cmd_to_mqtt("AT+HTTPACTION=0\r\n",AT_HTTPACTION); // 查找文件长度
+    waiting_uart_return(5000,"+HTTPACTION:", &httplen);
+    printf("httplen = %d\r\n",httplen);
+
+    uart_rs232_fifo_init();
+    send_cmd_to_mqtt("AT+HTTPREAD\r\n",AT_HTTPFILELEN); // 查找文件长度
+    //waiting_uart_return(500,"OK\r\n", NULL);
+
+    // sprintf((char*)temp,"AT+HTTPREAD=%d,%d\r\n", 0, data_len);
+    // send_cmd_to_mqtt((char*)temp,AT_NULL);//AT+HTTPREAD=<start_address>,<byte_size>
+    // strcpy((char*)g_uart1Info.waitMsg,"+HTTPREAD: ");
+
+    memset(rxfifo,0,RX_FIFO_FILE);
+    rxlen = 0;
+    //start_delay_ms(300);
+    timeout_setValue(&g_updatetime,300);
+    timeout_start(&g_updatetime);
+    delay_us(100);
+
+    do{
+        if((g_u4ginfo.head != g_u4ginfo.tail) && timeout_isOut(&g_u4ginfo.ttUart)){
+            len =  g_u4ginfo.tail - g_u4ginfo.head;
+            printf("tail = %d, head = %d\r\n",g_u4ginfo.tail,g_u4ginfo.head);
+            if(start == 0xFFFF){
+                start = g_u4ginfo.head;
+            }
+            str = strstr((char*)&g_u4ginfo.rcvBuf[start],"+HTTPREAD: ");
+            if(str) {
+                memcpy(rxfifo+rxlen,&g_u4ginfo.rcvBuf[g_u4ginfo.head],len);
+                rxlen = rxlen + len;
+                g_u4ginfo.head +=len;
+
+                str = strstr((char*)rxfifo,"+HTTPREAD: ");
+                if(str && ((rxlen-(str-(char*)rxfifo))>=17)){
+                    memset(temp,0,32);
+                    if(AT_GET_Data_2Param((char*)rxfifo,(uint8_t*)temp, "+HTTPREAD: ", "\r\n")){
+                        read_len = atoi((char*)temp);
+                    }
+                    if(((char*)rxfifo+rxlen-str)>= (read_len+20))
+                        break;
+                }
+            }
+        }
+        if(timeout_isOut(&g_updatetime)) {
+            printf("timeout \r\n");
+            timeout_stop(&g_updatetime);
+            break;
+        }
+    }while(1);
+    memset(temp,0,32);
+    if(AT_GET_Data_2Param((char*)rxfifo,(uint8_t*)temp, "+HTTPREAD: ", "\r\n")) {	/*?·???á??·?·¨*/
+        read_len = atoi((char*)temp);
+        if(data_len == read_len) {
+
+            p_buf = (uint8_t *)strstr((char*)rxfifo, "+HTTPREAD: ");
+            p_buf = (uint8_t *)strstr((char *)p_buf, "\r\n");
+            p_buf += 2;/* data position. */
+            printf("rxfifo = %x, p_buff= %x\n",rxfifo,p_buf);
+            g_u4ginfo.tail = 0;
+            g_u4ginfo.head = 0;
+            memset(g_u4ginfo.rcvBuf,0,2048);
+        }
+        printf("data_len = %d, read_len = %d\n",data_len,read_len);
+    }
+    else {
+        printf("error,tail = %d, head = %d\r\n",g_u4ginfo.tail,g_u4ginfo.head);
+        data_dump("errr",&g_u4ginfo.rcvBuf[g_u4ginfo.head],g_u4ginfo.tail-g_u4ginfo.head);
+    }
+    return p_buf;
+}
+#endif
+/*----------------------------------------------------------------
+ *  激活pdp
+ * ---------------------------------------------------------------*/
+uint8_t activation_pdp(void)
+{
+    uint8_t ret;
+    uint8_t count = 0,repeat = 0;
+    uint32_t val;
+
+REPEAT_PDP:
+    send_cmd_to_mqtt("AT+CPIN?\r\n",AT_CPIN); // 查询SIM卡是否正常
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0){
+        count++;
+        printf("cpin repeat %d\r\n",count);
+        if(count <4) goto REPEAT_PDP;
+        else goto END_PDP;
+    }
+    count = 0;
+AT_CGATT:
+    send_cmd_to_mqtt("AT+CGATT?\r\n",AT_CGATT); // 查询是否附着上数据网络
+    ret = waiting_uart_return(500,"OK",&val);
+    if((ret==0) || (val==0)){
+        count++;
+        if(count <4) goto AT_CGATT;
+        else goto END_PDP;
+    }
+
+    count = 0;
+
+    send_cmd_to_mqtt("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r\n",AT_SAPRB_GPRS); // 设置PDP
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) {
+        send_cmd_to_mqtt("AT+SAPBR=0,1\r\n\r\n",AT_SAPRB_01); // 设置PDP
+        ret = waiting_uart_return(500,"OK",NULL);
+        UTIL_IdleMs(2000);
+        if(ret == 0){
+            if(repeat++ < 3)goto REPEAT_PDP;
+            else goto END_PDP;
+        }
+        else repeat = 0;
+    }
+
+    send_cmd_to_mqtt("AT+SAPBR=3,1,\"APN\",\"\"\r\n",AT_SAPRB_APN); // 设置PDP
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) {
+        send_cmd_to_mqtt("AT+SAPBR=0,1\r\n\r\n",AT_SAPRB_01); // 设置PDP
+        ret = waiting_uart_return(500,"OK",NULL);
+        UTIL_IdleMs(2000);
+        if(ret == 0){
+            if(repeat++ < 3)goto REPEAT_PDP;
+            else goto END_PDP;
+        }
+        else repeat = 0;
+    }
+
+    send_cmd_to_mqtt("AT+SAPBR=1,1\r\n",AT_SAPRB_11); // 设置PDP
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) {
+        send_cmd_to_mqtt("AT+SAPBR=0,1\r\n\r\n",AT_SAPRB_01); // 设置PDP
+        ret = waiting_uart_return(500,"OK",NULL);
+        UTIL_IdleMs(2000);
+        if(ret == 0){
+            if(repeat++ < 3)goto REPEAT_PDP;
+            else goto END_PDP;
+        }
+        else repeat = 0;
+    }
+
+    send_cmd_to_mqtt("AT+SAPBR=2,1\r\n",AT_SAPRB_21); // 设置PDP
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) {
+        send_cmd_to_mqtt("AT+SAPBR=0,1\r\n\r\n",AT_SAPRB_01); // 设置PDP
+        ret = waiting_uart_return(500,"OK",NULL);
+        UTIL_IdleMs(2000);
+        if(ret == 0){
+            if(repeat++ < 3)goto REPEAT_PDP;
+            else goto END_PDP;
+        }
+        else repeat = 0;
+    }
+
+    return 1;
+END_PDP:
+
+    return 0;
+}
+void init_4g_power_up(void)
+{
+    SYS_EnableAPBClock(APB_MASK_GPIO5);
+    GPIO_SetOutput(GPIO5,GPIO_BIT1);
+    GPIO_SetInput(GPIO5,GPIO_BIT0); // VDD
+
+    if(GPIO_GetValue(GPIO5,GPIO_BIT0) ==1) { // 如果当前是开机状态,则先关机,再开机
+        GPIO_SetHigh(GPIO5,GPIO_BIT1);
+        UTIL_IdleMs(2000);
+        printf("aaaaaaaaaaaaaaa\r\n");
+        GPIO_SetLow(GPIO5,GPIO_BIT1);
+        UTIL_IdleMs(2000);
+    }
+    GPIO_SetHigh(GPIO5,GPIO_BIT1); // 直接开机
+    UTIL_IdleMs(2000);
+    GPIO_SetLow(GPIO5,GPIO_BIT1);
+    uart_rs232_fifo_init();
+    printf("aaaaaaaaaaaaa,kai ji  \r\n");
+    //UTIL_IdleMs(12000);
+    UTIL_IdleMs(2000);
+    read_uart_data();
+    printf("wait finish   \r\n");
+    uart_rs232_fifo_init();
+
+}
+uint8_t init_mqtt_power_up(void)
+{
+    uint8_t ret,count = 0;
+    uint32_t val;
+    char topic[64],sub_topic[64];
+
+    if(g_4gMsg.delay == 0) g_4gMsg.delay = 1;
+    timeout_setValue(&g_4gMsg.timer,g_4gMsg.delay*TIMER_4G);
+    memset(g_4gMsg.upTopic,0,64);
+    sprintf(g_4gMsg.upTopic,"cpyypt/up/%04x/%010u",g_devMsg.devType, g_devMsg.devSn); // 上行主题
+    sprintf(g_4gMsg.upLogTopic,"%s%04x/%010u",(char*)MQTT_LOGUPLINK_TOPIC,g_devMsg.devType, g_devMsg.devSn);
+    eeprom_read_mqtt_msg();
+    if(1 == g_mqttMsg.flag){ // 产测时配置了mqtt
+        if(1 == g_mqttCHmsg.bChangeMqtt){ //切换mqtt服务器地址
+            memset(topic,0,64);
+            sprintf(topic,"AT+MCONFIG=%04x-%010u,%s,%s\r\n",g_devMsg.devType,g_devMsg.devSn,g_mqttCHmsg.mqttMsg.admin,g_mqttCHmsg.mqttMsg.password);
+            memset(sub_topic,0,64);
+            sprintf(sub_topic,"AT+MIPSTART=\"%s\",\"%s\"\r\n",g_mqttCHmsg.mqttMsg.ip,g_mqttCHmsg.mqttMsg.port);
+            printf("mqtt_change _normal \r\n");
+        }
+        else { // 不切换mqtt服务器地址
+            memset(topic,0,64);
+            sprintf(topic,"AT+MCONFIG=%04x-%010u,%s,%s\r\n",g_devMsg.devType,g_devMsg.devSn,g_mqttMsg.admin,g_mqttMsg.password);
+            memset(sub_topic,0,64);
+            sprintf(sub_topic,"AT+MIPSTART=\"%s\",\"%s\"\r\n",g_mqttMsg.ip,g_mqttMsg.port);
+            printf("mqtt_read _normal \r\n");
+            printf("ip:%s, admin:%s,   password:%s\n",g_mqttMsg.ip, g_mqttMsg.admin,g_mqttMsg.password);
+        }
+    }
+    else {// 未配置mqtt服务器地址
+        sprintf(g_mqttMsg.admin,"%s","admin");
+        sprintf(g_mqttMsg.port,"%s","9000");
+        sprintf(g_mqttMsg.ip,"%s","test-mqtt.cpyypt.cn");
+        sprintf(g_mqttMsg.password,"%s","houjianwei");
+        //eeprom_write_mqtt_msg((uint8_t*)&g_mqttMsg,sizeof(MqttMsg));
+
+        memset(topic,0,64);
+        sprintf(topic,"AT+MCONFIG=%04x-%010u,%s,%s\r\n",g_devMsg.devType,g_devMsg.devSn,"admin","houjianwei");
+        memset(sub_topic,0,64);
+        sprintf(sub_topic,"AT+MIPSTART=\"%s\",\"%s\"\r\n","test-mqtt.cpyypt.cn","9000");
+
+        printf("mqtt_default _normal \r\n");
+    }
+
+    printf("send at_mqttstatus \r\n");
+    send_cmd_to_mqtt("AT+MQTTSTATU\r\n",AT_MQTTSTATUS);
+    ret = waiting_uart_return(1500,"OK",&val);
+    if(ret==0) goto MQTT_ERROR;
+    if(val != 0){
+        send_cmd_to_mqtt("AT+MIPCLOSE\r\n",AT_MIPCLOSE);
+        ret = waiting_uart_return(500,"OK",NULL);
+        if(ret==0) goto MQTT_ERROR;
+    }
+    printf("send AT ++++++++++\r\n");
+    send_cmd_to_mqtt("AT\r\n",AT_AT);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("AT\r\n",AT_AT);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("AT\r\n",AT_AT);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+
+    ret = activation_pdp();
+    if(ret == 0) goto MQTT_ERROR;
+
+
+    send_cmd_to_mqtt("AT+CREG=1\r\n",AT_CREGSET);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("AT+CREG?\r\n",AT_CREG);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("ATI\r\n",AT_ATI); // 回显示模式关闭
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("AT+ICCID\r\n",AT_ICCID);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("AT+CGSN\r\n",AT_CGSN);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("AT+CSQ\r\n",AT_CSQ);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+REPEAT_MCONFIG:
+    send_cmd_to_mqtt(topic,AT_MCONFIG);//"AT+MCONFIG=123,admin,houjianwei\r\n"
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0){
+        count++;
+        if(count <4) goto REPEAT_MCONFIG;
+        else goto MQTT_ERROR;
+    }
+    count = 0;
+
+REPEAT_MIPSTART:
+    send_cmd_to_mqtt(sub_topic,AT_MIPSTART);//"AT+MIPSTART=\"test-mqtt.cpyypt.cn\",\"9000\"\r\n"
+    val == 0xAA;
+    ret = waiting_uart_return(500,"CONNECT OK",NULL);
+    if(ret==0){
+        count++;
+        if(count <4) goto REPEAT_MIPSTART;
+        else goto MQTT_ERROR;
+    }
+    count = 0;
+
+REPEAT_MCONNECT:
+    send_cmd_to_mqtt("AT+MCONNECT=1,60\r\n",AT_MCONNECT);
+    ret = waiting_uart_return(500,"CONNACK OK",NULL);
+    if(ret==0){
+        count++;
+        if(count <4) goto REPEAT_MCONNECT;
+        else goto MQTT_ERROR;
+    }
+    count = 0;
+
+    send_cmd_to_mqtt("AT+MQTTMODE=1\r\n",AT_MQTTMODE);
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+    send_cmd_to_mqtt("ATE0\r\n",AT_ATE); // 回显示模式关闭
+    ret = waiting_uart_return(500,"OK",NULL);
+    if(ret==0) goto MQTT_ERROR;
+
+REPEAT_MSUB_01:
+    memset(topic,0,sizeof(topic));
+    sprintf((char*)topic,"%s%04x/%s",(char*)MQTT_DNLINK_TOPIC_CASE,g_devMsg.devType, (char*)"broadcast");
+    printf("topic_01:%s\r\n",topic);
+    memset(sub_topic,0,sizeof(sub_topic));
+    sprintf((char*)sub_topic,"AT+MSUB=\"%s\", 0\r\n",(char*)topic);
+    send_cmd_to_mqtt((char*)sub_topic,AT_SUB); // 订阅主题
+    ret = waiting_uart_return(500,"SUBACK",NULL);
+    if(ret==0){
+        count++;
+        if(count <4) goto REPEAT_MSUB_01;
+        else goto MQTT_ERROR;
+    }
+    else printf("MQTT SUB01 SUCCESS\r\n");
+    count = 0;
+
+REPEAT_MSUB_02:
+    memset(topic,0,sizeof(topic));
+    sprintf((char*)topic,"%s%04x/%010u",(char*)MQTT_DNLINK_TOPIC,g_devMsg.devType, g_devMsg.devSn);
+    printf("topic_02:%s\r\n",topic);
+    memset(sub_topic,0,sizeof(sub_topic));
+    sprintf((char*)sub_topic,"AT+MSUB=\"%s\", 0\r\n",(char*)topic);
+    send_cmd_to_mqtt((char*)sub_topic,AT_SUB); // 订阅主题
+    ret = waiting_uart_return(500,"SUBACK",NULL);
+    if(ret==0){
+        count++;
+        if(count <4) goto REPEAT_MSUB_02;
+        else goto MQTT_ERROR;
+    }
+    else printf("MQTT SUB02 SUCCESS\r\n");
+
+    //sprintf((char*)sub_topic,"AT+SLEDS=\"%s\", 0\r\n",(char*)topic);
+    send_cmd_to_mqtt("AT+SLEDS=2,125,125\r\n",AT_AT);
+    waiting_uart_return(500,"OK",NULL);
+
+    count = 0;
+
+    strcpy((char*)g_uart1Info.waitMsg,"+MSUB");
+    timeout_stop(&g_4gMsg.timer);
+    g_4gMsg.delay = 1;
+    if(1 == g_mqttCHmsg.bChangeMqtt){
+        eeprom_write_mqtt_msg((uint8_t*)&g_mqttCHmsg.mqttMsg,sizeof(MqttMsg));
+        g_mqttCHmsg.bChangeMqtt = 0;
+    }
+    //dma_config_mode_work();
+
+    return ret;
+MQTT_ERROR:
+    g_4gMsg.bconnect = 0;
+
+    if(g_4gMsg.delay == 61){ // 一个小时没有连接上网络,则重新启动
+        SYS_SoftwareReset();
+    }
+
+    timeout_start(&g_4gMsg.timer);
+    if(1 == g_4gMsg.delay) g_4gMsg.delay = 3;
+    else if(3 == g_4gMsg.delay) g_4gMsg.delay = 5;
+    else if(5 == g_4gMsg.delay) g_4gMsg.delay = 10;
+    else if(10 == g_4gMsg.delay) g_4gMsg.delay = 60;
+    else g_4gMsg.delay = 61;
+    printf("--------------mqtt error,delay = %d\r\n",g_4gMsg.delay);
+    if(g_4gMsg.delay == 10){
+        if(1 == g_mqttCHmsg.bChangeMqtt){ // 切换到原来的服务器上
+            g_mqttCHmsg.bChangeMqtt = 0;
+            g_4gMsg.delay = 1;
+            timeout_stop(&g_4gMsg.timer);
+            timeout_setValue(&g_4gMsg.timer,g_4gMsg.delay*TIMER_4G);
+            printf("切换服务器失败,切换到原来的服务器\r\n");
+        }
+    }
+    return ret;
+
+}
+/*----------------------------------------------------------------------------------
+ *  将需要发送的数据放到4G的发送fifo中
+ *  1: 操作成功  0:操作失败
+ * ---------------------------------------------------------------------------------*/
+uint8_t add_data_to_4G_txfifo(uint8_t *txdata,uint8_t len,uint8_t msgType1,uint16_t msgType2)
+{
+    //uint8_t buff[256]= {0};
+    static uint32_t seq_num = 0;
+    uint16_t crc;
+    netMsgFormat *p_msg = (netMsgFormat*)buff;
+
+    if(len > 256-12) return 0;
+
+    memset(buff,0,256);
+    p_msg->start = 0xfefe;
+    p_msg->proVer = 0x02;
+    p_msg->msgId = (seq_num++)%0xFFFFFFFF;
+
+    p_msg->msgType1 = msgType1;
+    p_msg->msgType2 = msgType2;
+    p_msg->palen = len + 2;
+
+    memcpy(p_msg->info, txdata, len);
+    crc = _crc16_get((uint8_t *)p_msg,len+12);
+    p_msg->info[len] = crc&0xff;
+    p_msg->info[len+1] = (crc>>8)&0xff;
+
+    return (fifo_write(&g_4Gtxfifo,buff,len+NET_HEAD_LEN+2));
+}
+

+ 132 - 0
src/app/air780e.h

@@ -0,0 +1,132 @@
+#ifndef _AIR780E_H_
+#define _AIR780E_H_
+
+#include "board.h"
+#include "./agm_board/agmboard.h"
+
+
+#define MQTT_SERVER_IP      "test-mqtt.cpyypt.cn"
+#define MQTT_SERVER_PORT    "9000"
+
+#define MQTT_UPLINK_TOPIC       "cpyypt/up/"
+#define MQTT_DNLINK_TOPIC       "cpyypt/down/"
+#define MQTT_DNLINK_TOPIC_CASE  "cpyypt/down/"
+#define MQTT_LOGUPLINK_TOPIC    "cpyypt/logup/"
+
+
+#define TIMER_4G  60000 // 1分钟
+
+extern FIFO_T g_4Grxfifo; // 4G的接收缓冲区
+extern FIFO_T g_4Gtxfifo; // 4G的发送缓冲区
+
+
+#define TIMER_4G  60000 // 1分钟
+
+typedef struct _uart_info_{
+    uint8_t txfifo[USART1_TX_SIZE];
+    uint8_t waitMsg[16]; // 等待接收的字符串
+    uint8_t cmd;
+    uint8_t bSdFinish; // 发送完成
+}uartInfo_t;
+extern uartInfo_t g_uart1Info;
+
+
+typedef struct _4G_MSG_{
+    uint8_t bconnect; // mqtt是否连接
+    uint8_t breturn;  /*发送数据时有返回*/
+    uint8_t noreturnNum; /* 发送数据时,没有返回的次数*/
+    uint8_t cregStatus; // 附着网络的状态 1:已附着
+    int     dBm;    /*精确的网络信号强度*/
+
+    uint8_t delay; // 时间 1:代表1分钟 3: 代表3分钟
+    uint8_t bHaveSim;
+    uint8_t imei[15];   // imei
+    uint8_t iccid[20];  // iccid
+    timeout_t timer; // 4G 连接时间
+    char upTopic[64];
+    char upLogTopic[64];
+}__attribute__((packed))_4GMsgInfo;
+extern _4GMsgInfo g_4gMsg;
+/* mqtt IP地址 端口号*/
+typedef struct _MQTT_IP_PORT_{
+    uint8_t flag;
+    char port[8]; // 端口号
+    char ip[32]; //IP地址
+    char admin[16]; // 用户名
+    char password[24]; // 密码
+}__attribute__((packed)) MqttMsg;
+extern MqttMsg g_mqttMsg;
+
+typedef struct _change_mqtt_msg_{
+    uint8_t bChangeMqtt; // 1:为切换mqtt 服务器
+    uint8_t bChangeSuc; // 0:初始值 1: 切换成功 2: 切换连接失败
+    uint8_t connectNum;  // 连接次数
+    uint8_t mqttIdlen;
+    uint8_t mqttPortlen;
+    uint8_t mqttUserlen;
+    uint8_t mqttPwdlen;
+    MqttMsg mqttMsg; // mqtt的IP地址和端口
+}__attribute__((packed))MqttCHmsg;
+extern MqttCHmsg g_mqttCHmsg;
+//extern uint8_t rxfifo[1024];
+enum {
+    AT_NULL         = 0x00,
+    AT_MQTTSTATUS   = 0x01,
+    AT_AT           = 0x02,
+    AT_MIPCLOSE     = 0x03,
+    AT_CGREG        = 0x04,
+    AT_CGATT        = 0x05,// 查询是否附着上数据网络
+    AT_MCONFIG      = 0x06,
+    AT_MIPSTART     = 0x07,
+    AT_MCONNECT     = 0x08,
+    AT_MQTTMODE     = 0x09,
+    AT_ATE          = 0x0A,
+    AT_CREGSET      = 0x0B,
+    AT_CREG         = 0x0C, // 检测网络状态
+    AT_ICCID        = 0x0D,
+    AT_CGSN         = 0x0E,
+    AT_CSQ          = 0x0F, //
+    AT_SUB          = 0x010,
+    AT_MDISCONNECT  = 0x11,
+    AT_HTTPACTION   = 0x12,
+    AT_ATI          = 0x13,
+    AT_CPIN         = 0x14, // 查询SIM卡是否正常
+    AT_SAPRB_GPRS   = 0x15,
+    AT_SAPRB_APN    = 0x16,
+    AT_SAPRB_11     = 0x17,
+    AT_SAPRB_21     = 0x18,
+    AT_SAPRB_01     = 0x19,
+    AT_HTTPFILELEN  = 0x20,
+};
+
+#define NET_HEAD_LEN 12
+typedef struct _NET_HEAD_DATA_{
+    uint16_t start;
+    uint8_t proVer;
+    uint32_t msgId;
+    uint8_t msgType1;
+    uint16_t msgType2;
+    uint16_t palen;
+    uint8_t info[256-12];
+}__attribute__((packed))netMsgFormat;
+
+
+extern uint8_t AT_GET_Data_2Param(char * buff1,uint8_t get_data[],char*head,char*tail);
+
+extern void send_cmd_to_mqtt(char *str,uint8_t cmd);
+extern void send_data_to_mqtt(uint8_t type, uint8_t *data, uint8_t len);
+extern void close_mqtt(void);
+extern uint8_t  waiting_uart_return(uint32_t timeout,char*str,uint32_t *value);
+extern uint8_t add_data_to_4G_txfifo(uint8_t *txdata,uint8_t len,uint8_t msgType1,uint16_t msgType2);
+
+extern void init_4g_power_up(void);
+extern uint8_t init_mqtt_power_up(void);
+
+extern void AIR_HTTP_GET(const char *url, uint32_t *pLen);
+extern uint8_t * AIR_HTTP_READ(uint32_t start_addr, uint32_t data_len);
+extern int net_data_copy(char *data, uint8_t *out_data);
+extern int net_rcvdata_ch(char *data, uint8_t *out_data, int len);
+extern uint32_t strtohex(char *data, uint8_t len);
+
+
+#endif

+ 449 - 0
src/app/dn_4g.c

@@ -0,0 +1,449 @@
+#include "dn_4g.h"
+#include "air780e.h"
+#include "masterslave.h"
+#include "up_4g.h"
+#include "ota_update.h"
+#include "taskOpt.h"
+#include "./agm_board/epprom.h"
+#include "public.h"
+/*--------------------------------------------------------------------------
+ *  升级类  获取设备版本 0x1001
+ * --------------------------------------------------------------------------*/
+static void dn_4g_update_cmd_0x1001(uint8_t *data, uint8_t len)
+{
+    uint8_t sendbuff[128], sendlen,i,flag,slaveflag;
+    dnUpdateCmd0x1001 *msg = (dnUpdateCmd0x1001*)(data + NET_HEAD_LEN);
+
+    flag = 0;
+    slaveflag = 0;
+
+    if(msg->devType == g_devMsg.devType){ // 本设备的设备类型
+        if(msg->devSn == g_devMsg.devSn){ // 本设备
+            flag = 1;
+        }
+        else return;
+    }
+    else { // 从设备的设备类型
+        if(g_devMsg.devSn == msg->devSn){ // 固定一个从设备
+            slaveflag = 1;
+        }
+        else if(BROADCAST_SN == msg->devSn){// 广播从设备
+            for(i=0;i<g_runNode.slaveNum;i++){
+                msg->devType = g_runNode.nodMsg[i].devType;
+                msg->devSn   = g_runNode.nodMsg[i].devSn;
+                fifo_write(&g_txfifo,data,len);
+            }
+            slaveflag = 0;
+        }
+        else return;
+    }
+    if(1 == flag){
+        up_update_cmd_0x2001(sendbuff,&sendlen,msg->taskId);
+        add_data_to_4G_txfifo(sendbuff,sendlen,0x04,0x2001);
+    }
+    if(1 == slaveflag) fifo_write(&g_txfifo,data,len);
+}
+/*--------------------------------------------------------------------------
+ *  升级类 升级下行0x1002
+ * -------------------------------------------------------------------------*/
+void dn_4g_update_cmd_0x1002(uint8_t *data, uint8_t len)
+{
+    ota_master_update_task(0x1002,data+NET_HEAD_LEN);
+}
+/*---------------------------------------------------------------------------
+ *  升级类 未安装升级 0x1004
+ * --------------------------------------------------------------------------*/
+void dn_4g_update_cmd_0x1004(uint8_t *data, uint8_t len)
+{
+    ota_master_update_task(0x1004,data+NET_HEAD_LEN);
+}
+
+/*--------------------------------------------------------------------------
+ *  mqtt 服务器切换
+ * -------------------------------------------------------------------------*/
+static void dn_4g_system_cmd_0x1003(uint8_t *data, uint8_t len)
+{
+    dnSysCmd0x1003 *msg = (dnSysCmd0x1003*)(data + NET_HEAD_LEN);
+
+    //if(0== check_dev_type_sn(msg->devTypeM,msg->devSnM)) return;
+    if(DEV_TYPE != msg->devTypeM) return;
+    if(msg->devSnM != g_devMsg.devSn) return;
+    close_mqtt();
+    printf("收到mqtt切换指令 \r\n");
+    init_mqtt_power_up();
+    memset(&(g_mqttCHmsg.mqttMsg),0,sizeof(MqttMsg));
+
+    memcpy(g_mqttCHmsg.mqttMsg.ip,msg->str,msg->iplen);
+    len = msg->iplen;
+    memcpy(g_mqttCHmsg.mqttMsg.port,msg->str+len,msg->portlen);
+    len += msg->portlen;
+    memcpy(g_mqttCHmsg.mqttMsg.admin,msg->str+len,msg->userlen);
+    len += msg->userlen;
+    memcpy(g_mqttCHmsg.mqttMsg.password,msg->str+len,msg->pwdlen);
+
+    g_mqttCHmsg.mqttIdlen = msg->iplen;
+    g_mqttCHmsg.mqttPortlen = msg->portlen;
+    g_mqttCHmsg.mqttUserlen = msg->userlen;
+    g_mqttCHmsg.mqttPwdlen = msg->pwdlen;
+
+    g_mqttCHmsg.bChangeMqtt = 1;
+    g_4gMsg.bconnect= 0;
+    g_devMsg.baskIdentity = 0x00;
+    g_mqttCHmsg.connectNum = 0;
+    g_4gMsg.cregStatus = 0;
+    timeout_stop(&g_4gMsg.timer);
+
+}
+/*----------------------------------------------------------------------------
+ *  设备重启 0x1021
+ * ---------------------------------------------------------------------------*/
+static void dn_4g_system_cmd_0x1021(uint8_t *data,uint8_t len)
+{
+    dnSysCmd0x1021 *msg = (dnSysCmd0x1021*)(data+NET_HEAD_LEN);
+
+    if(DEV_TYPE == msg->devTypeS){// 本设备的设备类型
+        if(msg->devSnS == g_devMsg.devSn){// 本设备
+            if(2 == msg->object)SYS_SoftwareReset();
+        }
+    }
+    else {// 从设备, 直接透传
+        fifo_write(&g_txfifo,data,len);
+    }
+
+}
+/*--------------------------------------------------------------------------------
+ *  时间同步 0x1015
+ * -------------------------------------------------------------------------------*/
+static void dn_4g_system_cmd_0x1015(uint8_t *data,uint8_t len)
+{
+    dnSysCmd0x1015 *msg = (dnSysCmd0x1015*)(data+NET_HEAD_LEN);
+
+    set_time(msg->timer);
+    fifo_write(&g_txfifo,data,len);
+    g_taskRunDa.timetamp = msg->timer;
+    printf("收到时间同步, %d\r\n",g_taskRunDa.timetamp);
+}
+/*------------------------------------------------------------------------------------
+ *  身份应答  0x1041
+ * -----------------------------------------------------------------------------------*/
+static void dn_4g_system_cmd_0x1041(uint8_t *data, uint8_t len)
+{
+//    dnSysCmd0x1041 *msg = (dnSysCmd0x1041*)(data+NET_HEAD_LEN);
+
+//    if(0 == check_dev_type_sn(msg->devTypeM,msg->devSnM)) return;
+//    g_iDentity = (Identity)msg->relation;
+//    printf("收到服务的配置身份 = %d\r\n", g_iDentity);
+//    if(IDENTITY_MASTER == g_iDentity ){
+//        epprom_read_config_table(); // 接收到自己是主的指令,则读取路表
+//    }
+//    g_iDentity = IDENTITY_MASTER;
+    return;
+}
+/*------------------------------------------------------------------------------------
+ *  路由表初下发 0x1024
+ * -----------------------------------------------------------------------------------*/
+static void dn_4g_system_cmd_0x1024(uint8_t *data, uint8_t len)
+{
+    dnSysCmd0x1024 *msg = (dnSysCmd0x1024*)(data+NET_HEAD_LEN);
+
+    if((msg->devTypeM==g_devMsg.devType) &&(msg->devSnM==g_devMsg.devSn)){
+        epprom_init_config_table();
+        epprom_write_config_table(msg->buff,len-6);
+        epprom_read_config_table();
+    }
+}
+/*------------------------------------------------------------------------------------
+ *  路由表问询 0x1025
+ * -----------------------------------------------------------------------------------*/
+static void dn_4g_system_cmd_0x1025(uint8_t *data, uint8_t len)
+{
+    uint8_t buff[180] = {0},len1;
+
+    dnSysCmd0x1025 *msg = (dnSysCmd0x1025*)(data+NET_HEAD_LEN);
+
+    //if(0 == check_dev_type_sn(msg->targetType,msg->targetSn)) return;
+    if((msg->targetType != DEV_TYPE) || (msg->targetSn != g_devMsg.devSn)) return;
+    up_system_cmd_0x2025(buff,&len1,msg->targetType,msg->targetSn);
+    epprom_read((uint32_t)CONFIGTABLE_ADDR,&buff[len1],g_runNode.slaveNum*8+1);
+    add_data_to_4G_txfifo(buff,g_runNode.slaveNum*8+1+len1,0x01,0x2025);
+
+}
+static void dn_4g_system_cmd_0x1026(uint8_t *data, uint8_t len)
+{
+//    DnSysCmd0x1026 *msg = (DnSysCmd0x1026*)(data + NET_HEAD_LEN);
+//    uint8_t flag = 0; // 3:主从都有, 1:主 2:从
+//    if((msg->da1026.appointDevModel == g_devMsg.devType)) {
+//        if((0xFFFFFFFF == msg->devSnS) ){ //
+//            flag = 0x03;
+//        }
+//        else if(msg->devSnS == g_devMsg.devSn) {
+//            flag = 0x01;
+//        }
+//        else if(msg->devSnS != g_devMsg.devSn) {
+//                flag = 0x02;
+//        }
+//        if((0x03 == flag) || (0x02==flag)){ // 直接透传给从设备
+//            fifo_write(&g_txfifo,data,len);
+//        }
+//    }
+//    else { // 不是给主的,或许是给从的
+//        fifo_write(&g_txfifo,data,len);
+//    }
+    fifo_write(&g_txfifo,data,len);
+}
+void anlaysis_0x1027(uint8_t *data,uint8_t framNo,uint16_t time)
+{
+    static uint8_t groupId;
+    uint8_t flag = 0,i=0;
+    sysCmd1027 *msg = (sysCmd1027*)data;
+
+    if(0xFF == framNo){ // 单帧
+        groupId = 0;
+        memcpy((uint8_t*)&g_table1027,data,sizeof(sysCmd1027));
+        g_table1027.groupNum = msg->groupNum;
+        flag = 1;
+    }
+    else if((framNo&0x80) == 0x80){ // 多帧的第一帧
+        groupId = 0;
+        memcpy((uint8_t*)&g_temtable1027,data,sizeof(sysCmd1027));
+        groupId = msg->groupNum;
+
+    }
+    else if((framNo%0x0F) != 0x01) { // 多帧的中间帧
+        memcpy(g_temtable1027.table[groupId],msg->table,sizeof(sysCmd1027)-11);
+        groupId += msg->groupNum;
+    }
+    else if((framNo&0x01) == 0x01) { // 多帧的最后一帧
+        memcpy(g_temtable1027.table[groupId],msg->table,sizeof(sysCmd1027)-11);
+        groupId += msg->groupNum;
+        g_temtable1027.groupNum = groupId;
+        flag = 1;
+        memcpy(&g_table1027,&g_temtable1027,sizeof(sysCmd1027));// 将临时表中的数据放入到用到的表中
+    }
+
+    if( (1 == flag) ){
+        if((0==time)){
+            epprom_write_pin_config((uint8_t*)&g_table1027,(uint16_t)sizeof(sysCmd1027)); // 写入EEPROm中
+            g_taskRunDa.bcfgfiletime = 0;
+        }
+        else {
+            timeout_setValue(&g_taskRunDa.cfigFileTime,time*1000);
+            timeout_start(&g_taskRunDa.cfigFileTime);
+            g_taskRunDa.bcfgfiletime = 1;
+        }
+        for(i=0;i<g_table1027.groupNum;i++){
+            if(i%10 == 0) printf("\r\n");
+            printf("{%d,%2d},",g_table1027.table[i][0],g_table1027.table[i][1]);
+
+        }
+    }
+}
+
+static void dn_4g_system_cmd_0x1027(uint8_t *data, uint8_t len)
+{
+//     DnSysCmd0x1027 *msg = (DnSysCmd0x1027*)(data + NET_HEAD_LEN);
+//     uint8_t flag = 0; // 1: 主 2: 从 3: 主从
+//     if(msg->da1027.appointDevModel == g_devMsg.devType){
+//        if((0xFFFFFFFF == msg->devSnS)){
+//            flag = 3;
+//        }
+//        else if(msg->devSnS == g_devMsg.devSn){
+//            flag = 1;
+//        }
+//        else {
+//            flag = 2;
+//        }
+//        if((3==flag) || (2==flag)){
+//            fifo_write(&g_txfifo,data,len);
+//        }
+//    }
+//     else { // 不是给主的,或许是给从设备的
+//        fifo_write(&g_txfifo,data,len);
+//    }
+    fifo_write(&g_txfifo,data,len);
+}
+static void dn_4g_system_cmd_0x1028(uint8_t *data, uint8_t len)
+{
+    DnSysCmd0x1028 *msg = (DnSysCmd0x1028*)(data+NET_HEAD_LEN);
+    uint8_t flag = 0; // 1: 主 2: 从 3: 主从
+
+
+    if(msg->devTypeM != DEV_TYPE) return;
+    if(msg->devSnM != g_devMsg.devSn) return;
+
+    if(0xFFFFFFFF == msg->devSnS) flag = 3;
+    else flag = 2;
+
+    timeout_setValue(&g_up7segData.upTime,msg->time*1000);
+    g_up7segData.bOpen = 1;
+    timeout_start(&g_up7segData.upTime);
+
+    timeout_setValue(&g_logMsg.singTime,TIME_SING_N);
+    timeout_start(&g_logMsg.singTime);
+    timeout_stop(&g_logMsg.tsingTime);
+    g_logMsg.singOpen = 0;
+
+    if(3 == flag) g_up7segData.bAppointDev = 0; // 未指定设备主从都需要报
+
+    if((2==flag) || (3==flag)){
+        fifo_write(&g_txfifo,data,len);
+    }
+    if(2 == flag){
+        g_up7segData.bAppointDev = 2; // 指定设备为从设备
+        memcpy(g_up7segData.devMsg,(uint8_t*)msg,12);
+    }
+}
+static void dn_4g_system_cmd_0x1029(uint8_t *data, uint8_t len)
+{
+    DnSysCmd0x1029 *msg = (DnSysCmd0x1029*)(data + NET_HEAD_LEN);
+
+    if(msg->devTypeM != DEV_TYPE) return;
+    if(msg->devSnM != g_devMsg.devSn) return;
+
+    g_up7segData.bOpen = 0;
+    g_up7segData.bAppointDev = 0;
+    timeout_stop(&g_up7segData.upTime);
+
+    fifo_write(&g_txfifo,data,len);
+
+}
+
+void dn_4g_system_cmd(uint16_t cmd, uint8_t *data, uint8_t len)
+{
+    switch(cmd){
+    case 0x1003: // mqtt 配置
+        dn_4g_system_cmd_0x1003(data,len);
+        break;
+    case 0x1021: // 系统重启
+        dn_4g_system_cmd_0x1021(data,len);
+        break;
+    case 0x1015: // 时间同步
+        dn_4g_system_cmd_0x1015(data,len);
+        break;
+    case 0x1041: // 身份应答
+        dn_4g_system_cmd_0x1041(data, len);
+        break;
+    case 0x1024: // 路由表下 行
+        dn_4g_system_cmd_0x1024(data, len);
+        break;
+    case 0x1025: // 路由表问询
+        dn_4g_system_cmd_0x1025(data, len);
+        break;
+    case 0x1026: // com 端配置文件下发
+        dn_4g_system_cmd_0x1026(data,len);
+        break;
+    case 0x1027: // 探针板管脚配置文件下发
+        dn_4g_system_cmd_0x1027(data,len);
+        break;
+    case 0x1028: // 开启8段码测试
+        dn_4g_system_cmd_0x1028(data,len);
+        break;
+    case 0x1029: // 关闭8段码测试
+        dn_4g_system_cmd_0x1029(data,len);
+        break;
+    }
+}
+
+/*--------------------------------------------------------------------------
+ *  显示屏的数据读取
+ * -------------------------------------------------------------------------*/
+static void dn_4g_data_cmd_0x1061(uint8_t *data, uint8_t len)
+{
+    fifo_write(&g_txfifo,data,len);
+}
+
+/*--------------------------------------------------------------------------
+ *
+ * -------------------------------------------------------------------------*/
+void dn_4g_data_cmd(uint16_t cmd, uint8_t *data, uint8_t len)
+{
+    switch(cmd){
+    case 0x1061: // 显示屏数据
+        dn_4g_data_cmd_0x1061(data, len);
+        break;
+    }
+}
+
+void dn_4g_update_cmd(uint16_t cmd, uint8_t *data, uint8_t len)
+{
+    switch(cmd) {
+    case 0x1001: // 获取设备版本
+        dn_4g_update_cmd_0x1001(data,len);
+        break;
+    case 0x1002: // 升级下发指令
+        dn_4g_update_cmd_0x1002(data,len);
+        break;
+    case 0x1004: // 未安装升级
+        printf("收到未安装升级指令1004\r\n");
+        dn_4g_update_cmd_0x1004(data,len);
+        break;
+    }
+}
+
+/*------------------------------------异常类0x10的处理---------------------------*/
+
+/*--------------------------------------------------------------------------
+ *  日志0x1062
+ * -------------------------------------------------------------------------*/
+static void dn_4g_log_cmd_0x1062(uint8_t *data, uint8_t len)
+{
+    DnLogCmd0x1062 *msg = (DnLogCmd0x1062*)(data+NET_HEAD_LEN);
+
+    fifo_write(&g_txfifo,data,len);
+    printf("收到10----1062指令 delay = %d type=%d\r\n",msg->time,msg->logType);
+}
+
+/*--------------------------------------------------------------------------
+ *  日志0x1063
+ * -------------------------------------------------------------------------*/
+static void dn_4g_log_cmd_0x1063(uint8_t *data, uint8_t len)
+{
+    DnLogCmd0x1063 *msg = (DnLogCmd0x1063*)(data+NET_HEAD_LEN);
+
+    //fifo_write(&g_txfifo,data,len);
+    printf("收到10----1063指令 delay = %d interval = %d type=%d\r\n",msg->time,msg->interval, msg->logType);
+
+    if(msg->logType == 0x03){
+        if(msg->time == 0x00){
+            timeout_setValue(&g_logMsg.singTime,TIME_SING_N);
+            timeout_start(&g_logMsg.singTime);
+            g_logMsg.singOpen = 0;
+        }
+        else {
+            g_up7segData.bOpen = 0;
+            g_up7segData.bAppointDev = 0;
+            timeout_stop(&g_up7segData.upTime);
+
+            g_logMsg.devSn = msg->devSnS;
+            g_logMsg.devType = msg->devTypeS;
+
+            if(msg->interval <2) msg->interval = 2;
+            if(msg->time <5) msg->time = 5;
+            if(msg->time > 20*60*1000) msg->time = 20*60*1000;
+            if(msg->interval > msg->time) msg->interval = msg->time -2;
+            timeout_setValue(&g_logMsg.singTime,msg->interval*1000);
+            timeout_setValue(&g_logMsg.tsingTime,msg->time*1000);
+            timeout_start(&g_logMsg.tsingTime);
+            timeout_start(&g_logMsg.singTime);
+            timeout_stop(&g_logMsg.singTime);
+            g_logMsg.singOpen = 1;
+        }
+
+    }
+    return;
+}
+void dn_4g_log_cmd(uint16_t cmd, uint8_t *data, uint8_t len)
+{
+    switch(cmd) {
+    case 0x1062: // 日志开启
+        dn_4g_log_cmd_0x1062(data, len);
+        break;
+    case 0x1063:
+        dn_4g_log_cmd_0x1063(data, len);
+        break;
+    default: break;
+
+    }
+}
+
+

+ 176 - 0
src/app/dn_4g.h

@@ -0,0 +1,176 @@
+#ifndef _DN_4G_H_
+#define _DN_4G_H_
+
+#include "board.h"
+
+typedef struct _dn_update_cmd_0x1001_{ // 获取设备版本
+    uint16_t devType;
+    uint32_t devSn;
+    uint16_t taskId; // 任务号
+    uint32_t reserve; // 预留
+}__attribute__((packed))dnUpdateCmd0x1001;
+typedef struct _dn_update_cmd_0x1002_{
+    uint16_t devType;       // 升级目标设备类型
+    uint32_t devSn;         // 升级目标设备SN
+    uint8_t  firmType;      // 升级固件类型
+    uint16_t taskId;        // 升级任务号
+    uint16_t losePage;      // 最大丢包个数的百分比,最小为10%, 最大为60%
+    uint8_t  urllen;        // URL最大长度
+    uint8_t  url[256];      // URL地址
+}__attribute__((packed))dnUpdateCmd0x1002;
+typedef struct _dn_update_cmd_0x1004_{ //未安装升级
+    uint16_t devType;       // 设备类型
+    uint32_t devSn;         // 设备SN
+    uint16_t rcvDevType;    // 接收设备类型
+    uint32_t rcvDevSn;      // 接收设备 SN
+    uint16_t desDevType;    // 升级目标设备类型
+    uint32_t desDevSn;      // 升级目标设备 SN
+    uint16_t taskId;        // 任务号
+    uint8_t firmType;       // 升级固件类型
+    uint8_t  urllen;        // URL最大长度
+    uint8_t  url[256];      // URL地址
+}__attribute__((packed))dnUpdateCmd0x1004;
+
+typedef struct _dn_sys_cmd_0x1003_{ // mqtt服务器配置
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint32_t reserve;
+    uint8_t iplen;   // 服务器地址长度
+    uint8_t portlen; // 端口长度
+    uint8_t userlen; // 用户名长度
+    uint8_t pwdlen;  // 密码长度
+    uint8_t str[64]; // mqqtt的信息,顺序:ip port username pwd
+}__attribute__((packed))dnSysCmd0x1003;
+
+typedef struct _dn_sys_cmd_0x1021_{ // 系统重启
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t object; // 重启对象
+    uint32_t reserve;
+}__attribute__((packed))dnSysCmd0x1021;
+
+typedef struct _dn_sys_cmd_0x1015_{ // 时间同步
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint32_t timer; // 时间戳
+    uint32_t reserve;
+}__attribute__((packed))dnSysCmd0x1015;
+
+typedef struct _dn_sys_cmd_0x1041_{ // 身份应答
+    uint16_t devTypeM;  // 主设备类型
+    uint32_t devSnM;    // 从设备类型
+    uint8_t relation;   // 身份 1:从 2:主
+    uint32_t reserve;   // 预留
+}__attribute__((packed))dnSysCmd0x1041;
+
+typedef struct _dn_sys_cmd_0x1024_{ // 路由表下发
+    uint16_t devTypeM;     // 主设备类型
+    uint32_t devSnM;       // 主设备SN
+    uint8_t buff[128];      // 从设备数量  从设备类型 从设备SN 预留 总预留
+}__attribute__((packed))dnSysCmd0x1024;
+
+typedef struct _dn_sys_cmd_0x1025_{ // 路由表询问
+    uint16_t devTypeM;  // 主设备类型
+    uint32_t devSnM;    // 从设备类型
+    uint16_t targetType; // 询问目标设备类型
+    uint32_t targetSn;   // 询问目标设备SN
+    uint32_t reserve;    // 预留
+}__attribute__((packed))dnSysCmd0x1025;
+
+typedef struct _sys_cmd_1026_{
+    uint8_t priceInuseCout; // 对于单价屏是否探针板接线
+    uint8_t confFileNum[8]; //配置文件编号
+    uint16_t appointDevModel; // 配置文件适配设备类型
+    uint8_t portStatus;    // 端口是否启用
+    uint8_t portNum[4];    // 每个端口连接针脚的个数
+    uint8_t comGroup;      // com端的级数
+    uint8_t param[8][4];   //  一共4组,每组4个参数
+}__attribute__((packed))sysCmd1026;
+
+typedef struct _dn_sys_cmd_0x1026_{
+    uint16_t devTypeM;     // 主设备类型
+    uint32_t devSnM;       // 主设备SN
+    uint16_t devTypeS;     // 从设备类型
+    uint32_t devSnS;       // 从设备SN
+    uint32_t reserve;      // 预留
+    uint16_t expireTime;   // 过期时间
+    sysCmd1026 da1026;
+}__attribute__((packed))DnSysCmd0x1026;
+
+typedef struct _sys_cmd_1027_{
+    uint8_t confFileNum[8]; //配置文件编号
+    uint16_t appointDevModel; // 配置文件适配设备类型
+    uint8_t groupNum;         // 组数
+    uint8_t table[300][2];    // 表的说明
+}__attribute__((packed))sysCmd1027;
+
+typedef struct _dn_sys_cmd_0x1027_{
+    uint16_t devTypeM;     // 主设备类型
+    uint32_t devSnM;       // 主设备SN
+    uint16_t devTypeS;     // 从设备类型
+    uint32_t devSnS;       // 从设备SN
+    uint32_t reserve;      // 预留
+    uint16_t expireTime;   // 过期时间
+    uint8_t  framNo;       // 帧号
+    sysCmd1027 da1027;
+}__attribute__((packed))DnSysCmd0x1027;
+
+typedef struct _dn_sys_cmd_0x1028_{
+    uint16_t devTypeM;     // 主设备类型
+    uint32_t devSnM;       // 主设备SN
+    uint16_t devTypeS;     // 从设备类型
+    uint32_t devSnS;       // 从设备SN
+    uint32_t time;         // 开启时常
+}__attribute__((packed))DnSysCmd0x1028;
+typedef struct _dn_sys_cmd_0x1029_{
+    uint16_t devTypeM;     // 主设备类型
+    uint32_t devSnM;       // 主设备SN
+    uint16_t devTypeS;     // 从设备类型
+    uint32_t devSnS;       // 从设备SN
+    uint8_t status;        // 保存状态 1:保存 2:放弃
+}__attribute__((packed))DnSysCmd0x1029;
+
+
+typedef struct _dn_data_cmd_0x1061_{
+    uint16_t devTypeM;     // 主设备类型
+    uint32_t devSnM;       // 主设备SN
+    uint16_t devTypeS;     // 从设备类型
+    uint32_t devSnS;       // 从设备SN
+    uint32_t recordId;     // 记录ID
+    uint32_t reserve;      // 预留
+}__attribute__((packed))DnDataCmd0x1061;
+
+typedef struct _dn_log_cmd_0x1062_{
+    uint16_t devTypeM;     // 主设备类型
+    uint32_t devSnM;       // 主设备SN
+    uint16_t devTypeS;     // 从设备类型
+    uint32_t devSnS;       // 从设备SN
+    uint8_t  logType;      // 日志类型
+    uint32_t time;         // 开启日志的时间
+    uint32_t reserve;      // 预留
+}__attribute__((packed))DnLogCmd0x1062;
+
+typedef struct _dn_log_0x1063_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t  logType;      // 日志类型 1: 去重七段码上报 2:lg日志 3: 信号采集率调试
+    uint32_t time;         // 开启日志的时间(秒) 0: 关闭 非0:开始时长
+    uint8_t interval;     // 间隔上报 秒
+    uint32_t reserve;      // 预留
+}__attribute__((packed))DnLogCmd0x1063;
+
+
+extern void anlaysis_0x1027(uint8_t *data,uint8_t framNo,uint16_t time);
+
+extern void dn_4g_system_cmd(uint16_t cmd, uint8_t *data, uint8_t len);
+
+extern void dn_4g_data_cmd(uint16_t cmd, uint8_t *data, uint8_t len);
+extern void dn_4g_update_cmd(uint16_t cmd, uint8_t *data, uint8_t len);
+extern void dn_4g_log_cmd(uint16_t cmd, uint8_t *data, uint8_t len);
+#endif

+ 580 - 0
src/app/masterslave.c

@@ -0,0 +1,580 @@
+#include "masterslave.h"
+#include "up_4g.h"
+#include "air780e.h"
+#include "ota_update.h"
+#include "taskOpt.h"
+#include "./agm_board/agmboard.h"
+#include "public.h"
+
+
+uint32_t _msgid = 0;
+
+void slave_send_data_to_uart(uint8_t type1, uint16_t type2,uint8_t *data,uint8_t len)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc ;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = type1;
+    msg->msgType2 = type2;
+
+    memcpy(msg->comInfo.info,data,len);
+    sendlen =  COMM_HEAD_LEN + len;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.info[len] = crc &0xff;
+    msg->comInfo.info[len+1] = (crc>>8) &0xff;
+
+    data_dump("send to 485:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+
+
+}
+
+void master_read_status(uint16_t cmd,DevMsg *dev)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = 0x02;
+    msg->msgType2 = cmd;
+
+    msg->comInfo.statusMsg.devTypeM = dev->devType;
+    msg->comInfo.statusMsg.devSnM  = dev->devSn;
+    msg->comInfo.statusMsg.devTypeS = dev->devTypeS;
+    msg->comInfo.statusMsg.devSnS  = dev->devSnS;
+
+    sendlen = STATUS_COMM_LEN + COMM_HEAD_LEN;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.statusMsg.info[0] = crc &0xff;
+    msg->comInfo.statusMsg.info[1] = (crc>>8) &0xff;
+
+    data_dump("02-send to 485:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+    //fifo_write(&g_txfifo,usart485TX_Buffer,sendlen+2);
+}
+void master_read_data_0x1061(DevMsg *dev,uint32_t recordId)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = 0x03;
+    msg->msgType2 = 0x1061;
+
+    msg->comInfo.da1061.devTypeM = dev->devType;
+    msg->comInfo.da1061.devSnM  = dev->devSn;
+    msg->comInfo.da1061.devTypeS = dev->devTypeS;
+    msg->comInfo.da1061.devSnS = dev->devSnS;
+    msg->comInfo.da1061.recordId = recordId;
+    sendlen = DATA_1061_LEN + COMM_HEAD_LEN;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.da1061.info[0] = crc &0xff;
+    msg->comInfo.da1061.info[1] = (crc>>8) &0xff;
+
+    data_dump("03-1061-send to 485:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+}
+
+void master_read_data_0x1030(DevMsg *dev)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = 0x01;
+    msg->msgType2 = 0x1030;
+
+    msg->comInfo.sysMsg.devTypeM = dev->devType;
+    msg->comInfo.sysMsg.devSnM  = dev->devSn;
+    msg->comInfo.sysMsg.devTypeS = dev->devTypeS;
+    msg->comInfo.sysMsg.devSnS = dev->devSnS;
+    msg->comInfo.sysMsg.sDa.s0x1030.reserve = 0x00;
+
+    sendlen = SYSTEM_1030_LEN + COMM_HEAD_LEN;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.sysMsg.sDa.s0x1030.info[0] = crc &0xff;
+    msg->comInfo.sysMsg.sDa.s0x1030.info[1] = (crc>>8) &0xff;
+
+    data_dump("01-1030-send to 485:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+}
+//void master_get_self_0x2030(void)
+//{
+//   uint8_t sendbuff[128],len;
+
+//    memset(sendbuff,0,128);
+//    up_system_cmd_0x2030(sendbuff,&g_7egDa[1],(uint8_t*)&g_table1027.confFileNum[0],&len);
+//    add_data_to_4G_txfifo(sendbuff,len,0x01,0x2030);
+//}
+
+
+void master_read_log_0x1063(DevMsg *dev)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = 0x10;
+    msg->msgType2 = 0x1063;
+
+    msg->comInfo.lg1063.devTypeM = dev->devType;
+    msg->comInfo.lg1063.devSnM  = dev->devSn;
+    msg->comInfo.lg1063.devTypeS = dev->devTypeS;
+    msg->comInfo.lg1063.devSnS = dev->devSnS;
+    msg->comInfo.lg1063.logType = 0x03;
+    msg->comInfo.lg1063.time  = 0x00;
+    msg->comInfo.lg1063.interval  = 0x00;
+    msg->comInfo.lg1063.reserve = 0x00;
+    sendlen = LOG_1063_LEN + COMM_HEAD_LEN;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.lg1063.info[0] = crc &0xff;
+    msg->comInfo.lg1063.info[1] = (crc>>8) &0xff;
+
+    data_dump("send:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+}
+static void slave_get_status_0x1002(uint8_t *buf,uint8_t *len,uint16_t devtypeM,uint32_t devSnM,uint8_t bself)
+{
+    status0x2002 *msg = (status0x2002*)buf;
+
+
+    if(bself == SLAVE_OFFLINE){
+        msg->devTypeM = g_devMsg.devType;
+        msg->devSnM   = g_devMsg.devSn;
+        msg->devTypeS = devtypeM;
+        msg->devSnS   = devSnM;
+        msg->identity = IDENTITY_SLAVE;
+
+        msg->identity = g_iDentity;
+        if(IDENTITY_MASTER == g_iDentity){
+            memcpy(msg->cfgFileNo,g_table1027.confFileNum,8);
+            msg->bHave4G  = g_devMsg.bHave4G;
+        }
+        else{
+            memset(msg->cfgFileNo,0,8);
+            msg->bHave4G  = 0;
+        }
+        msg->status = 0;
+    }
+    else {
+        msg->devTypeM = devtypeM;
+        msg->devSnM   = devSnM;
+        msg->devTypeS = g_devMsg.devType;
+        msg->devSnS   = g_devMsg.devSn;
+        memcpy(msg->cfgFileNo,g_table1027.confFileNum,8);
+        msg->identity = g_iDentity;
+        msg->bHave4G  = g_devMsg.bHave4G;
+        msg->status = 1;
+        msg->lastResetType = g_devResetMsg.resetflag;
+        msg->resetNum = g_devResetMsg.resetNum;
+        msg->runTime  = Get_SysTick()/1000;
+        msg->voltage = 0x00;
+        msg->temperature = 0x00;
+        msg->rssi4G  =  g_4gMsg.dBm + 1000;
+        msg->snr4G   = 0x00;
+        msg->tempStamp = g_taskRunDa.timetamp;
+        msg->reserve = 0x00;
+    }
+
+    *len = sizeof(status0x2002);
+
+    return;
+}
+static void slave_get_status_0x1001(uint8_t *buf,uint8_t *len,uint16_t devtypeM,uint32_t devSnM)
+{
+    status0x2001 *msg = (status0x2001*)buf;
+
+    msg->devTypeM = devtypeM;
+    msg->devSnM   = devSnM;
+
+    msg->devTypeS = g_devMsg.devType;
+    msg->devSnS   = g_devMsg.devSn;
+
+    msg->upCode   = 0;
+    msg->bootVer  = g_devAppVer.bootVer;
+    msg->ptVer    = g_devAppVer.ptVer;
+    msg->appVer   = g_devAppVer.app1Ver;
+    memcpy(msg->uuid,g_devfirmMsg.uuid,12);
+    memcpy(msg->imei,g_4gMsg.imei,15);
+    memcpy(msg->iccid,g_4gMsg.iccid,20);
+    msg->reserve = 0x00;
+
+
+    *len = sizeof(status0x2001);
+
+    return;
+}
+void slave_get_update_0x1001(uint8_t *outdata, uint8_t *len,uint16_t taskId)
+{
+    update0x2001 *msg = (update0x2001*)outdata;
+
+    msg->devType = g_devMsg.devType;
+    msg->devSn = g_devMsg.devSn;
+    msg->appVer = 0x1001234;
+    msg->taskId = taskId;
+    msg->reserve = 0x00;
+
+    *len = sizeof(update0x2001);
+    return;
+}
+
+void master_add_status_to_4g_txfifo(uint8_t type1,uint16_t type2,uint16_t devType,uint32_t devSn, uint8_t bself)
+{
+    uint8_t sendbuff[128],sendlen;
+
+    memset(sendbuff,0,128);
+    if(0x2002 == type2) slave_get_status_0x1002(sendbuff,&sendlen,devType,devSn,bself);
+    else slave_get_status_0x1001(sendbuff,&sendlen,devType,devSn);
+    add_data_to_4G_txfifo(sendbuff,sendlen,type1,type2);
+}
+
+void slave_send_status_comm(uint16_t cmd,uint8_t *data,uint8_t len)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc ;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = 0x02;
+    msg->msgType2 = cmd;
+
+    memcpy(msg->comInfo.info,data,len);
+    sendlen =  COMM_HEAD_LEN + len;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.info[len] = crc &0xff;
+    msg->comInfo.info[len+1] = (crc>>8) &0xff;
+
+    data_dump("send:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+}
+
+void slave_send_data_0x2061(uint16_t devType, uint32_t devSn,uint8_t *data, uint8_t len,uint8_t bnew)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc ;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = 0x03;
+    msg->msgType2 = 0x2061;
+
+    msg->comInfo.da2061.devTypeM = devType;
+    msg->comInfo.da2061.devSnM  = devSn;
+    msg->comInfo.da2061.devTypeS = g_devMsg.devType;
+    msg->comInfo.da2061.devSnS = g_devMsg.devSn;
+    msg->comInfo.da2061.bnewflag = bnew;
+    msg->comInfo.da2061.palen = len;
+
+    memcpy(msg->comInfo.da2061.info,data,len);
+    sendlen = DATA_2061_LEN + COMM_HEAD_LEN + len;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.da2061.info[len] = crc &0xff;
+    msg->comInfo.da2061.info[len+1] = (crc>>8) &0xff;
+
+    data_dump("send:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+}
+void slave_send_data_0x2030(uint16_t devType, uint32_t devSn,uint8_t *data,uint8_t *cfigNo, uint8_t len)
+{
+    MasterSlave *msg = NULL;
+    uint16_t crc ;
+    uint8_t sendlen;
+
+    msg = (MasterSlave*)usart485TX_Buffer;
+    memset(usart485TX_Buffer,0,sizeof(usart485TX_Buffer));
+
+    msg->start = 0xFEFE;
+    msg->msgId = _msgid++;
+    msg->proVer = 2;
+    msg->msgType1 = 0x01;
+    msg->msgType2 = 0x2030;
+
+    msg->comInfo.sysMsg.devTypeM = devType;
+    msg->comInfo.sysMsg.devSnM  = devSn;
+    msg->comInfo.sysMsg.devTypeS = g_devMsg.devType;
+    msg->comInfo.sysMsg.devSnS = g_devMsg.devSn;
+    memcpy(msg->comInfo.sysMsg.sDa.s0x2030.configfileNo,cfigNo,8);// = bnew;
+    msg->comInfo.sysMsg.sDa.s0x2030.reserve = 0;
+
+    memcpy(msg->comInfo.info+SYSTEM_2030_LEN,data,len); // 24为2030的头
+    sendlen = SYSTEM_2030_LEN + COMM_HEAD_LEN + len;
+    msg->palen  = sendlen + 2 - COMM_HEAD_LEN;
+
+
+    crc = _crc16_get(usart485TX_Buffer,sendlen);
+    msg->comInfo.info[len+SYSTEM_2030_LEN] = crc &0xff;
+    msg->comInfo.info[len+1+SYSTEM_2030_LEN] = (crc>>8) &0xff;
+
+    data_dump("send:",usart485TX_Buffer,sendlen+2);
+    uart_msg_send(UART2_ID,usart485TX_Buffer,sendlen+2);
+}
+/*------------------------------------------- 主解析从的指令 并存储到4G 的发送fifo中---------------*/
+/*----------------------------------------------------------------------
+ *  直接透传 状态指令 0x2002 0x2001
+ * --------------------------------------------------------------------*/
+void master_analysis_status_cmd(uint8_t *data, uint8_t size)
+{
+    fifo_write(&g_4Gtxfifo,data,size); // 直接透传
+
+//END_02_0x2002:
+    timeout_stop(&g_uart485.time);
+    return;
+}
+
+
+uint8_t master_check_dev_table(uint16_t devType, uint32_t devSn)
+{
+    volatile uint8_t i = 0;
+    uint8_t flag;
+    flag = 0;
+    g_runNode.slaveNum = (g_runNode.slaveNum>NODE_MAX_SIZE ? NODE_MAX_SIZE:g_runNode.slaveNum);
+    for(i=0;i<g_runNode.slaveNum;i++){
+        if((devType== g_runNode.nodMsg[i].devType) \
+            && (devSn == g_runNode.nodMsg[i].devSn)) {
+            flag = 1;
+            break;
+        }
+    }
+    if(flag == 1){
+        g_runNode.nodMsg[i].readCount = 0;
+        g_runNode.nodMsg[i].status = 1;
+        return i;
+    }
+    else
+        return 0xFF;
+}
+
+
+/*----------------------------------------------------------------------------------
+ *   解析系统类 0x01
+ * ---------------------------------------------------------------------------------*/
+void analysis_cmd_system(uint16_t cmd, uint8_t *data,uint8_t len)
+{
+    MasterSlave * pmsg = (MasterSlave*)data;
+    commInfo_t *msg = &(pmsg->comInfo);
+
+    if(0x2000 == (cmd&0x2000)){
+        data_dump("收到数据",data,len);
+        switch(cmd){
+        case 0x2030: // 8段码数据上报
+            if((msg->sysMsg.devSnM == g_devMsg.devSn) && (msg->sysMsg.devTypeM== g_devMsg.devType)) {
+                fifo_write(&g_4Gtxfifo,data,len); // 直接透传
+                timeout_stop(&g_uart485.time);
+                break;
+            }
+        }
+    }
+
+}
+/*----------------------------------------------------------------------------------
+ *   解析状态类 0x02
+ * ---------------------------------------------------------------------------------*/
+void analysis_cmd_status(uint16_t cmd, uint8_t *data,uint8_t len)
+{
+    uint8_t sendbuff[128], sendlen,sIndex;
+    MasterSlave *msg = (MasterSlave*)data;
+
+    if(0x2000 == (cmd&0x2000)){
+        data_dump("收到数据",data,len);
+        sIndex = master_check_dev_table(msg->comInfo.statusMsg.devTypeS,msg->comInfo.statusMsg.devSnS);
+        if(sIndex == 0xFF) return;
+        switch(cmd){
+        case 0x2002:case 0x2001: // 实时状态信息 // 固件信息
+            master_analysis_status_cmd(data,len);
+            break;
+        }
+    }
+    // else if(0x1000 == (cmd&0x1000)) { // 从设备处理
+    //     if(0==check_dev_type_sn(msg->comInfo.statusMsg.devTypeS,msg->comInfo.statusMsg.devSnS)) return;
+    //     data_dump("收到数据",data,len);
+    //     memset(sendbuff,0,128);
+    //     switch(cmd){
+    //     case 0x1002: // 实时状态
+    //         slave_get_status_0x1002(sendbuff,&sendlen,msg->comInfo.statusMsg.devTypeM,msg->comInfo.statusMsg.devSnM,SELF_STATUS);
+    //         slave_send_status_comm(0x2002,sendbuff,sendlen);
+    //         break;
+    //     case 0x1001: // 固件信息
+    //         slave_get_status_0x1001(sendbuff,&sendlen,msg->comInfo.statusMsg.devTypeM,msg->comInfo.statusMsg.devSnM);
+    //         slave_send_status_comm(0x2001,sendbuff,sendlen);
+    //         break;
+    //     }
+    // }
+}
+
+/*----------------------------------------------------------------------------------
+ *   解析数据类 0x03
+ * ---------------------------------------------------------------------------------*/
+void analysis_cmd_data(uint16_t cmd,uint8_t *data,uint8_t len)
+{
+    MasterSlave *msg = (MasterSlave*)data;
+    uint16_t sIndex = 0xFF;
+    uint8_t ret;
+    switch (cmd) {
+    case 0x1061:
+//        if(0==check_dev_type_sn(msg->comInfo.da1061.devTypeS,msg->comInfo.da1061.devSnS)) break;
+//        data_dump("收到数据",data,len);
+//        if(0 == msg->comInfo.da1061.recordId) {
+////            slave_read_flash_data_to485(msg->comInfo.da1061.devTypeM,msg->comInfo.da1061.devSnM);
+//        }
+//        else if(0xFFFFFFFF == msg->comInfo.da1061.recordId){ // 主设备按键读取
+////            save_display_data_to_flash();
+////            slave_read_flash_data_to485(msg->comInfo.da1061.devTypeM,msg->comInfo.da1061.devSnM);
+//        }
+//        else { // 服务器读取
+//            ret = xsp_check_point_record(msg->comInfo.da1061.recordId,g_xspReDa.data);
+//            if(1 == ret ){ // 说明已经找到的记录
+//                slave_send_data_0x2061(msg->comInfo.da1061.devTypeM,msg->comInfo.da1061.devSnM,g_xspReDa.data,64,2);
+//            }
+//        }
+        break;
+    case 0x2061:
+        //if(g_iDentity == IDENTITY_SLAVE) break; // 从设备退出
+        data_dump("收到数据",data,len);
+        sIndex = master_check_dev_table(msg->comInfo.da2061.devTypeS,msg->comInfo.da2061.devSnS);
+        if(sIndex == 0xFF) return;
+        if(msg->comInfo.da2061.bnewflag != 0)
+            fifo_write(&g_4Gtxfifo,data,len); // 直接透传
+        timeout_stop(&g_uart485.time);
+        break;
+    default:
+        break;
+    }
+}
+/*----------------------------------------------------------------------------------
+ *   解析升级类 0x04
+ * ---------------------------------------------------------------------------------*/
+void analysis_cmd_update(uint16_t cmd,uint8_t *data,uint8_t len)
+{
+    uint8_t sendbuff[128], sendlen;
+    MasterSlave *msg = (MasterSlave*)data;
+
+    if(0x2000 == (cmd&0x2000)){
+        if((g_devMsg.workMode==WORK_UPDATE && g_updateDa.iDentity==IDENTITY_SLAVE)||0x01 ==g_updateDa.bResetUpdate) return;//被升级时,不处理
+        data_dump("收到数据",data,len);
+        switch(cmd){
+        case 0x2001: // 获取设备版本上行
+            fifo_write(&g_4Gtxfifo,data,len); // 直接透传
+            break;
+        case 0x2007: //  收到从设备上报的升级状态
+            set_start_ota_timer(&g_otaTimer.upstatusTmr,10*1000);
+            master_update_status_rcv(msg->comInfo.info,msg->palen-2);
+            printf("收到从设备上报的升级状态\r\n");
+            break;
+        case 0x2005: // 收到从设备的重传指令
+            ota_update_master_retransmit(msg->comInfo.info);
+            break;
+        }
+    }
+    // else if(0x1000 == (cmd&0x1000)) { // 从设备处理
+
+    //     memset(sendbuff,0,128);
+    //     switch(cmd){
+    //     case 0x1001: // 获取设备版本
+    //         if(0==check_dev_type_sn(msg->comInfo.upMsg.up0x1001.devType,msg->comInfo.upMsg.up0x1001.devSn)) return;
+    //         data_dump("收到数据",data,len);
+    //         slave_get_update_0x1001(sendbuff,&sendlen,msg->comInfo.upMsg.up0x1001.taskId);
+    //         slave_send_data_to_uart(0x04,0x2001,sendbuff,sendlen);
+    //         break;
+    //     case 0x1003: case 0x1004: case 0x1005: case 0x1007: // 需要在升级时处理
+    //         if(0==check_dev_type_sn(msg->comInfo.upMsg.up0x1001.devType,msg->comInfo.upMsg.up0x1001.devSn)) return;
+    //         ota_timer_stop(&g_otaTimer.randomTmr);
+    //         if(0x1005 == cmd) g_updateDa.bRetransmit = 0;
+    //         data_dump("收到升级指令",data,len);
+    //         ota_update_slave_task(cmd,msg->comInfo.info,msg->palen-2);
+    //         break;
+    //     case 0x1006: // 离线升级
+    //         ota_update_slave_offline(msg->comInfo.info,msg->palen-2);
+    //         break;
+
+
+    //     }
+    // }
+}
+/*----------------------------------------------------------------------------------
+ *   解析日志类 0x10
+ * ---------------------------------------------------------------------------------*/
+void analysis_cmd_log(uint16_t cmd,uint8_t *data,uint8_t len)
+{
+    MasterSlave *msg = (MasterSlave*)data;
+    uint16_t sIndex = 0xFF;
+
+    switch(cmd){
+    case 0x2062: // 错误数据
+        sIndex = master_check_dev_table(msg->comInfo.lg2062.devTypeS,msg->comInfo.lg2062.devSnS);
+        if(sIndex == 0xFF) {
+            timeout_stop(&g_uart485.time);
+            return;
+        }
+        fifo_write(&g_4Gtxfifo,data,len);// 直接透传
+        timeout_stop(&g_uart485.time);
+        break;
+    case 0x2063: // 信号采样率上传
+        // sIndex = master_check_dev_table(msg->comInfo.lg2063.devTypeS,msg->comInfo.lg2063.devSnS);
+        // if(sIndex == 0xFF) {
+        //     timeout_stop(&g_uart485.time);
+        //     return;
+        // }
+        fifo_write(&g_4Gtxfifo,data,len);// 直接透传
+        timeout_stop(&g_uart485.time);
+        break;
+    default: break;
+    }
+}

+ 265 - 0
src/app/masterslave.h

@@ -0,0 +1,265 @@
+#ifndef _DN_485_H_
+#define _DN_485_H_
+
+#include "board.h"
+#include "public.h"
+//#include "xspDataOpt.h"
+/*-------------------------------------系统指令 --------------------*/
+#define SYSTEM_1001_LEN 13
+#define SYSTEM_2030_LEN 24
+#define SYSTEM_1030_LEN 16
+typedef struct _system_0x1021_{ // 系统类指令 重启
+    uint8_t  object; // 重启对象
+    uint8_t  info[2]; // 用于存储crc 校验码
+}__attribute__((packed))system0x1021;
+typedef struct _system_0x1015_{ // 系统类指令  时间同步
+    uint32_t timer;   // 时间戳
+    uint32_t reserve; // 预留
+}__attribute__((packed))system0x1015;
+
+typedef struct _system_0x1026_{ // 系统类指令 com端文件配置
+    uint32_t reserve;      // 预留 不需要存储EPPROM -4
+    uint16_t expireTime;   // 过期时间  不需要存储EPPROM -2
+    uint8_t priceInuseCout; // 对于单价屏是否探针板接线
+    uint8_t confFileNum[8]; //配置文件编号
+    uint16_t appointDevModel; // 配置文件适配设备类型
+    uint8_t portStatus;    // 端口是否启用
+    uint8_t portNum[4];    // 每个端口连接针脚的个数
+    uint8_t comGroup;      // com端的级数
+    uint8_t param[4][4];   //  一共4组,每组4个参数
+}__attribute__((packed))system0x1026;
+
+typedef struct _sys_0x1027_{
+    uint32_t reserve;      // 预留
+    uint16_t expireTime;   // 过期时间
+    uint8_t  framNo;       // 帧号
+    sysCmd1027 da1027;
+}__attribute__((packed))system0x1027;
+
+typedef struct _sys_0x1028_{
+    uint32_t time;         // 开启时常
+}__attribute__((packed))system0x1028;
+
+typedef struct _sys_0x1029_{
+    uint8_t status;        // 保存状态 1:保存 2:放弃
+}__attribute__((packed))system0x1029;
+typedef struct _sys_0x1030_{
+    uint32_t reserve;
+    uint8_t info[2];//用于校验位
+}__attribute__((packed))system0x1030;
+
+typedef struct _sys_0x2030_{
+    uint8_t configfileNo[8];        //配置文件编号
+    uint32_t reserve;               //预留
+}__attribute__((packed))system0x2030;
+
+typedef union _system_cmd_table_{
+    system0x1021 s0x1021;
+    system0x1015 s0x1015;
+    system0x1026 s0x1026; // com端配置文件
+    system0x1027 s0x1027; // 探针脚配置文件
+    system0x1028 s0x1028; // 开启8段码上报
+    system0x1029 s0x1029; // 关闭8段码上报
+    system0x1030 s0x1030; // 读取8段数据
+    system0x2030 s0x2030;  // 上报8段码数据
+}__attribute__((packed))systemCmdTable;
+
+typedef struct _system_cmd_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    systemCmdTable sDa;
+}__attribute__((packed))systemCmd;
+
+
+/*-------------------------------------状态指令 --------------------*/
+enum {
+    SELF_STATUS = 0x02,
+    SLAVE_OFFLINE = 0x03,
+};
+
+typedef struct _status_0x2002_{
+    uint16_t devTypeM;      //主设备类型
+    uint32_t devSnM;        //主设备SN
+    uint16_t devTypeS;      //从设备类型
+    uint32_t devSnS;        //从设备SN
+    uint8_t  cfgFileNo[8];  //配置文件编号
+    uint8_t identity;       //主从身份 1:从 2:主
+    uint8_t  bHave4G;       //是否有4G模块 0:无 1:有
+    uint8_t status;         //在线状态 0:离线 1:在线
+    uint8_t lastResetType;  // 最后一次复位类型
+    uint32_t resetNum;      // 复位次数
+    uint32_t runTime;       // 运行时常
+    uint32_t voltage;       // 电压
+    uint32_t temperature;   // 温度
+    uint16_t rssi4G;        // 4G强度
+    uint16_t snr4G;         // 4G信噪比
+    uint32_t tempStamp;     // 时间戳
+    uint32_t reserve;
+}__attribute__((packed))status0x2002;
+
+typedef struct _status_0x2001_{
+    uint16_t devTypeM;  // 主设备类型
+    uint32_t devSnM;    // 主设备SN
+    uint16_t devTypeS;  // 从设备类型
+    uint32_t devSnS;    // 从设备SN
+    uint8_t upCode;     // 升级状态码
+    uint32_t bootVer;   // bootloader版本
+    uint32_t ptVer;     // pt版本
+    uint32_t appVer;    // app版本
+    uint8_t uuid[12];   // UUID
+    uint8_t imei[15];   // imei
+    uint8_t iccid[20];  // iccid
+    uint32_t reserve;   // 预留
+}__attribute__((packed))status0x2001;
+
+#define STATUS_COMM_LEN 12
+typedef struct _status_comm_msg_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t info[2];
+}__attribute__((packed))statCom;
+
+/*-------------------------------------数据指令 --------------------*/
+#define DATA_1061_LEN 20
+typedef struct _data_0x1061_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint32_t recordId;
+    uint32_t reserve;
+    uint8_t info[2];
+}__attribute__((packed))data0x1061;
+
+#define DATA_2061_LEN 18
+typedef struct _data_0x2061_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint32_t reserve;
+    uint8_t bnewflag; // 新交易标识
+    uint8_t palen;    // 参数长度
+    uint8_t info[160];
+}__attribute__((packed))data0x2061;
+#define LOG_2062_LEN 17
+typedef struct _log_0x2062_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint32_t reserve;
+    uint8_t palen;    // 参数长度
+    uint8_t info[160];
+}__attribute__((packed))log0x2062;
+
+#define LOG_1062_LEN 21
+typedef struct _log_0x1062_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t  logType;      // 日志类型
+    uint32_t time;         // 开启日志的时间
+    uint32_t reserve;      // 预留
+    uint8_t info[160];
+}__attribute__((packed))log0x1062;
+
+#define LOG_2063_LEN 18
+typedef struct _log_0x2063_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t logtype; // 1:错误七段码上 2:log 日志 3:信号错误率
+    uint32_t reserve;
+    uint8_t palen;    // 参数长度
+    uint8_t info[256];
+}__attribute__((packed))log0x2063;
+
+#define LOG_1063_LEN 22
+typedef struct _log_0x1063_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t  logType;      // 日志类型 1: 去重七段码上报 2:lg日志 3: 信号采集率调试
+    uint32_t time;         // 开启日志的时间(秒) 0: 关闭 非0:开始时长
+    uint8_t interval;     // 间隔上报 秒
+    uint32_t reserve;      // 预留
+    uint8_t info[160];
+}__attribute__((packed))log0x1063;
+
+
+
+/*----------------------------------升级指令-------------------------*/
+typedef struct _update_0x1001_{
+    uint16_t devType;
+    uint32_t devSn;
+    uint16_t taskId; // 任务号
+    uint32_t reserve; // 预留
+}__attribute__((packed))update0x1001;
+
+typedef struct _update_0x2001_{
+    uint16_t devType;
+    uint32_t devSn;
+    uint32_t appVer;
+    uint16_t taskId;
+    uint32_t reserve;
+}__attribute__((packed))update0x2001;
+
+typedef union _update_info_{
+    update0x1001 up0x1001;
+    update0x2001 up0x2001;
+}__attribute__((packed))updateCmd;
+
+/*------------------------------------------------------------------*/
+typedef union _comm_info_{
+    //system0x1021 sys1021;
+    systemCmd sysMsg;
+    statCom statusMsg;
+    updateCmd upMsg;
+    data0x1061 da1061;
+    data0x2061 da2061;
+    log0x1062  lg1062;
+    log0x2062  lg2062;
+    log0x1063  lg1063;
+    log0x2063  lg2063;
+    uint8_t info[256];
+}__attribute__((packed))commInfo_t;
+
+#define COMM_HEAD_LEN 12
+typedef struct _HEAD_DATA_{
+    uint16_t start;
+    uint8_t proVer;
+    uint32_t msgId;
+    uint8_t msgType1;
+    uint16_t msgType2;
+    uint16_t palen;
+    commInfo_t comInfo;
+}__attribute__((packed))MasterSlave;
+
+extern void master_get_self_0x2030(void);
+
+extern void slave_send_data_to_uart(uint8_t type1, uint16_t type2,uint8_t *data,uint8_t len);
+//extern void master_read_system_0x1001(DevMsg *dev);
+extern void master_read_flash_data_to_4gtx(void);
+extern void master_read_status(uint16_t cmd, DevMsg *dev);
+extern void master_add_status_to_4g_txfifo(uint8_t type1, uint16_t type2, uint16_t devType, uint32_t devSn, uint8_t bself);
+extern void master_read_data_0x1061(DevMsg *dev, uint32_t recordId);
+extern void master_read_data_0x1030(DevMsg *dev);
+
+extern void master_read_log_0x1063(DevMsg *dev);
+
+extern void slave_send_data_0x2030(uint16_t devType, uint32_t devSn,uint8_t *data,uint8_t *cfigNo, uint8_t len);
+
+extern void analysis_cmd_system(uint16_t cmd, uint8_t *data,uint8_t len);
+extern void analysis_cmd_status(uint16_t cmd, uint8_t *data,uint8_t len);
+extern void analysis_cmd_data(uint16_t cmd,uint8_t *data,uint8_t len);
+extern void analysis_cmd_update(uint16_t cmd,uint8_t *data,uint8_t len);
+extern void analysis_cmd_log(uint16_t cmd,uint8_t *data,uint8_t len);
+#endif

+ 1095 - 0
src/app/ota_update.c

@@ -0,0 +1,1095 @@
+/*----------------------------------------------------------------------------------
+ *  备份寄存器的说明
+ *  BKP_DR0: 写入的RTC标志
+ *  BKP_DR1: 写入升级标志码
+ *  BKP_DR2: 写入升级状态码
+ *  BKP_DR3: 写入升级任务号
+ *  BKP_DR4: 升级的来源: 0x22:来源于服务器下发的 0x44:来源于网关的离线升级
+ *  BKP_DR5: 上电后升级从设备
+ *  BKP_DR6: 升级的固件类型
+ * ---------------------------------------------------------------------------------*/
+#include "ota_update.h"
+#include "dn_4g.h"
+#include "up_4g.h"
+#include "air780e.h"
+#include "masterslave.h"
+#include "./agm_board/rtc.h"
+#include "public.h"
+
+static uint8_t _buff[256];
+
+UpdateDa g_updateDa;
+OtaUpdateTime g_otaTimer;
+static otaUpdatMsg ota_devMsg;
+static uint16_t updata_state,updata_state_save;
+
+static void send_update_code_to_serve(uint16_t devtype, uint32_t devsn,uint16_t taskId,uint8_t upcode,uint8_t firmType)
+{
+    uint8_t  bufflen;
+
+    memset(_buff,0,256);
+    up_update_cmd_0x2002(_buff,&bufflen,devtype,devsn,taskId,firmType,upcode);
+    add_data_to_4G_txfifo(_buff,bufflen,0x04,0x2002);
+}
+static void waiting_4g_tx_fifo_empty(void)
+{
+    uint8_t len;
+    g_uart1Info.cmd = AT_NULL;
+    do{
+        if(fifo_is_empty(&g_4Gtxfifo) == true) break ;// 发送fifo为空
+
+        printf("发送4G数据到服务器\n");
+        len = fifo_read(&g_4Gtxfifo,_buff);
+        data_dump("4g-data-to-server",_buff,len);
+        send_data_to_mqtt(0x00,_buff,len);
+    }while(1);
+}
+
+/*--------------------------------------------------------------------------
+ *  上电读取升级的状态
+ * --------------------------------------------------------------------------*/
+void ota_power_up_read_update_status(void)
+{
+    uint16_t data;
+
+    data = RTC_ReadBackupRegister(BKP_DATA_1); // 读取入标志码
+    if(data != 0){
+        if(updata_state_cmp(data)){
+            if((data&0x00ff) == 0x82){ // 升级成功
+                data = set_updata_state(UPDATE_SUCCESS);
+                RTC_WriteBackupRegister(BKP_DATA_2, data);
+                printf("\n send to net update sucess\n");
+            }
+            else if((data&0x00ff) == 0x83) { // 回退成功
+                data = set_updata_state(UPDATE_RETURN_SUCESS);
+                RTC_WriteBackupRegister(BKP_DATA_2, data);
+                printf("\n send to net return sucess\n");
+            }
+            // else if((data&0x00ff) == 0x84) { // 升级失败
+            //     data = RTC_ReadBackupRegister(BKP_DATA_2);
+            // }
+            printf("\n update status1 = %x\n",data);
+            data = RTC_ReadBackupRegister(BKP_DATA_2);
+            RTC_WriteBackupRegister(BKP_DATA_1, 0);
+            g_updateDa.updateCode = data&0xFF;
+
+            data = RTC_ReadBackupRegister(BKP_DATA_4);//升级任务号
+            g_updateDa.taskNo = data;
+
+            data = RTC_ReadBackupRegister(BKP_DATA_5);
+            //if(data == UP_PROG_FROM_NET) g_updateDa.bResetUpdate = 1;
+            //else g_updateDa.bResetUpdate = 2;
+            if(data == UP_PROG_FROM_GAT)
+            {
+                set_start_ota_timer(&g_otaTimer.randomTmr,(rand()%150+200));
+            }
+            g_updateDa.Update_Source = data;
+            g_updateDa.bResetUpdate = 1;
+            printf("g_updateDa.bResetUpdate = %d\n",g_updateDa.bResetUpdate);
+            RTC_WriteBackupRegister(BKP_DATA_5, 0);
+
+            data = RTC_ReadBackupRegister(BKP_DATA_3);//固件类型
+            g_updateDa.bfirmware_type = data;
+
+            data = RTC_ReadBackupRegister(BKP_DATA_6);
+            printf("bkp5=%04x\n",data);
+            if(data == UPDATE_SLAVE)//需要升级从设备
+            {
+                if(ota_offline_init(OTA_UPDATE_APP3_FLASH_START_ADDR,OTA_UPDATE_APP3_FLASH_SIZE))//升级包正确
+                {
+                    ota_master_init_update_msg_offline(g_devMsg.devType,0xffffffff,g_devMsg.devType,0xffffffff,g_updateDa.bfirmware_type);
+//					g_updateDa.bOffline_s = 1;//可以离线升级
+                    g_updateDa.bUpdate_slave = data;
+                    g_updateDa.bOffline_addr = OTA_UPDATE_APP3_FLASH_START_ADDR;
+                    g_devMsg.workMode = WORK_UPDATE;
+                    g_devMsg.ledgreen = 2;
+                    printf("升级从设备\n");
+                }
+            }
+            RTC_WriteBackupRegister(BKP_DATA_6, 0);
+        }
+    }
+    else{
+        g_updateDa.bResetUpdate = 0;
+        printf("\n no update program, data = %x\n",data);
+    }
+}
+
+
+/*------------------------------------------------------------------------------------------
+ *对app进行校验
+ *参数:addr:app首地址
+ *         len: app长度
+ *         checkdata:计算的crc值
+ *返回:0:校验正确,1:校验失败
+*-------------------------------------------------------------------------------------------*/
+void app_check_crc(uint32_t addr, uint32_t len, uint32_t *checkdata)
+{
+    uint32_t datalen,read_crc,get_crc;
+    datalen = Flash_DatalenRead(addr,len);
+    read_crc = *(uint32_t*)(addr + datalen-4); //CRC校验
+
+    SYS_EnableAHBClock(AHB_MASK_CRC0);
+    CRC_Reset(CRC0);
+    get_crc = crc_block_data_calculate((uint32_t*)addr,(datalen -4)/4);//计算crc数值
+
+    *checkdata = get_crc;
+    if(read_crc != get_crc)
+    {
+        return; //ret = 1;
+    }
+    return;// ret;
+}
+void set_start_ota_timer(otaTimeSet *timer, uint32_t delay)
+{
+    timeout_stop(&(timer->timer));
+    timeout_setValue(&(timer->timer),delay);
+    timeout_start(&(timer->timer));
+    timer->status = OTA_TIMER_START;
+}
+void ota_timer_stop(otaTimeSet *timer)
+{
+    timeout_stop(&timer->timer);
+    timer->status = OTA_TIMER_END;
+}
+
+/*----------------------------------------------------------------------
+ *  1: 超时 0: 未超时
+ * ---------------------------------------------------------------------*/
+uint8_t ota_timer_is_timeout(otaTimeSet * timer)
+{
+    if(timer->status == OTA_TIMER_NULL) return 0; // 定时器还未启动时
+    if((OTA_TIMER_START == timer->status) && timeout_isOut(&(timer->timer))){
+        timer->status = OTA_TIMER_END;
+        return 1;
+    }
+    else
+        return 0;
+}
+
+void ota_master_update_slave_continue(otaUpdatMsg *msg,uint32_t addr)
+{
+    updateCmd0x1004 *pmsg = NULL;
+   // uint8_t i;
+    uint32_t flash_buf[256];
+    pmsg = (updateCmd0x1004*)_buff;
+    memset(_buff,0,256);
+    pmsg->rcvDevType = msg->rcvDevType;
+    pmsg->rcvDevSn   = msg->rcvDevSn;
+    pmsg->desDevType = msg->rcvDevType;
+    pmsg->desDevSn   = msg->rcvDevSn;
+    pmsg->totalPage  = msg->totalPage;
+    pmsg->subPkgId   = msg->subPkgId;
+    pmsg->subPkgLen  = msg->subPkgLen;
+
+    while(ota_devMsg.subPkgId <= ota_devMsg.totalPage){
+		start_delay_ms(msg->sendInterval);
+        printf("lora_gw_ota_continues %d\r\n", msg->subPkgId);
+        pmsg->subPkgId = msg->subPkgId++;
+
+        Flash_BufferRead(addr + (pmsg->subPkgId - 1)*OTA_MASTER_SEND_PKG_SIZE,flash_buf, OTA_MASTER_SEND_PKG_SIZE);
+        memcpy(((uint8_t *)pmsg) + OTA_CONTINUES_INFO_LEN,flash_buf,OTA_MASTER_SEND_PKG_SIZE);
+//        if(pmsg->subPkgId%30)
+            slave_send_data_to_uart(0x04,0x1004,(uint8_t*)pmsg,sizeof(updateCmd0x1004)+OTA_MASTER_SEND_PKG_SIZE);
+//        for(i=0;i< sizeof(updateCmd0x1004)+OTA_MASTER_SEND_PKG_SIZE-OTA_CONTINUES_INFO_LEN;i++){
+//            printf("%02x ",_buff[i]);
+//        }
+//        printf("\r\n");
+//		printf("发送间隔:%u\n",msg->sendInterval);
+//        start_delay_ms(msg->sendInterval);
+        while(!g_iDelayfinish);
+    }
+    printf("continue finish, start repeat\r\n");
+
+}
+void ota_master_init_update_msg(dnUpdateCmd0x1004 *msg,uint32_t version,uint32_t totallen,uint16_t losepage)
+{
+    memset(&ota_devMsg,0,sizeof(otaUpdatMsg));
+    ota_devMsg.rcvDevType   = msg->rcvDevType;    // 接收设备类型
+    ota_devMsg.rcvDevSn     = msg->rcvDevSn;      // 接收设备SN
+    ota_devMsg.desDevType   = msg->desDevType;    // 升级目标设备类型
+    ota_devMsg.desDevSn     = msg->desDevSn;      // 升级目标设备SN
+    ota_devMsg.firmType     = msg->firmType;   // 升级的固件类型
+    ota_devMsg.version      = version;
+    ota_devMsg.totalByte    = totallen;         // 升级的总大小
+    ota_devMsg.losePage     = losepage;
+    ota_devMsg.sendInterval = 300;
+    ota_devMsg.totalPage    = totallen/OTA_MASTER_SEND_PKG_SIZE;
+    if(totallen%OTA_MASTER_SEND_PKG_SIZE) ota_devMsg.totalPage += 1;
+    ota_devMsg.subPkgLen    = OTA_MASTER_SEND_PKG_SIZE;
+    ota_devMsg.subPkgId = 1;
+    ota_devMsg.lastRightPkgNum = 1;
+    ota_devMsg.lossPkgIndex = 0;
+}
+/*-------------------------------------------------------------------------------
+ *  从设备初化
+ * ------------------------------------------------------------------------------*/
+void ota_slave_init_update_msg(updateCmd0x1003 *msg)
+{
+    memset(&ota_devMsg,0,sizeof(otaUpdatMsg));
+
+    ota_devMsg.rcvDevType   = msg->rcvDevType;    // 接收设备类型
+    ota_devMsg.rcvDevSn     = msg->rcvDevSn;      // 接收设备SN
+    ota_devMsg.desDevType   = msg->desDevType;    // 升级目标设备类型
+    ota_devMsg.desDevSn     = msg->desDevSn;      // 升级目标设备SN
+    ota_devMsg.firmType     = msg->firmType;      // 固件类型
+    ota_devMsg.totalByte    = msg->totalByte;     // 升级总总长度
+    ota_devMsg.eachMaxByte  = msg->eachMaxByte;   // 单包最大字节类
+    ota_devMsg.losePage     = msg->losePage;      // 最大丢包面分比 最小为10%,最大为60%
+    ota_devMsg.sendInterval = msg->sendInterval;  // 连续阶段发 送包的时间间隔(单位:ms)
+    ota_devMsg.totalPage    = msg->totalByte/OTA_MASTER_SEND_PKG_SIZE; //总包数
+    if(msg->totalByte%OTA_MASTER_SEND_PKG_SIZE) ota_devMsg.totalPage += 1;
+	ota_devMsg.loseTotalPage = (ota_devMsg.totalPage*ota_devMsg.losePage)/100;//计算最大丢包数
+	ota_devMsg.loseTotalPage = (ota_devMsg.loseTotalPage>250)?250:ota_devMsg.loseTotalPage;//最大丢包数不能超过250个
+	printf("losetotalpage=%d\n",ota_devMsg.loseTotalPage);
+    ota_devMsg.subPkgId     = 1;      // 升级包编号
+    ota_devMsg.subPkgLen    = 0;     // 本升级包的长度
+    ota_devMsg.lastRightPkgNum = 1;
+    ota_devMsg.lossPkgIndex = 0;
+}
+
+/*--------------------------------------------------------------------------
+ *  主设备升级从设备
+ * -------------------------------------------------------------------------*/
+void ota_master_update_salve(otaUpdatMsg*msg,uint32_t addr)
+{
+    uint8_t i;
+    updateCmd0x1003 pMsg;
+    pMsg.rcvDevType = msg->rcvDevType;
+    pMsg.rcvDevSn   = msg->rcvDevSn;
+    pMsg.desDevType = msg->desDevType;
+    pMsg.desDevSn   = msg->desDevSn;
+    pMsg.firmType   = msg->firmType;
+    pMsg.updateVer  = msg->version;
+    pMsg.totalByte  = msg->totalByte;
+    pMsg.eachMaxByte= OTA_MASTER_SEND_PKG_SIZE;
+    pMsg.losePage   = msg->losePage;
+    pMsg.sendInterval = msg->sendInterval;
+    for(i=0;i<3;i++){ // 下发启动升级指令
+        slave_send_data_to_uart(0x04,0x1003,(uint8_t*)&pMsg,sizeof(updateCmd0x1003));
+        start_delay_ms(2000);
+        while(!g_iDelayfinish);
+    }
+
+    set_start_ota_timer(&g_otaTimer.totalTmr,OTA_TIM_TOTALTMR); // 升级的总时间
+    printf("启动升级总定时时间\r\n");
+    ota_master_update_slave_continue(msg,addr);// 处理连续升级指令
+    set_start_ota_timer(&g_otaTimer.repeatTmr,OTA_TIM_REPEAT); //启动重传定时器
+    printf("启动升级重传时间\r\n");
+}
+#define UPDATE_ONE_SIZE 1024
+/*--------------------------------------------------------------------------
+ *  主设备升级
+ *  updateType: 1: 升级主设备  2:升级从设备
+ * -------------------------------------------------------------------------*/
+void ota_master_update_task(uint16_t cmd,uint8_t *data)
+{
+    uint32_t Version;
+    char *binPos = NULL;
+    uint8_t updateCode,sendbuff[200] = {0};
+    uint8_t *p_content = NULL;
+    uint32_t flashbuff[256];
+    uint16_t pages = 0,send_data_dr2 = 0,losepage = 10;
+    uint32_t fileVer,addr,filelen,crcVl,fixChar,getcrc;
+    uint32_t start_addr = 0, total_len = 0, remain_len, read_len;
+
+    dnUpdateCmd0x1002 *msg1002 = NULL;
+    dnUpdateCmd0x1004 *msg = NULL;
+
+    if(cmd == 0x1002){
+        msg = (dnUpdateCmd0x1004*)sendbuff;
+        msg1002 = (dnUpdateCmd0x1002*)data;
+        msg->devType    = g_devMsg.devType;
+        msg->devSn      = g_devMsg.devSn;
+        msg->rcvDevType = msg1002->devType;
+        msg->rcvDevSn   = msg1002->devSn;
+        msg->desDevType = msg1002->devType;
+        msg->desDevSn   = msg1002->devSn;
+        msg->firmType   = msg1002->firmType;
+        msg->taskId     = msg1002->taskId;
+        msg->urllen     = msg1002->urllen;
+        memcpy(msg->url,msg1002->url,msg->urllen);
+        losepage = msg1002->losePage;
+    }
+    else {
+        msg = (dnUpdateCmd0x1004*)data;
+        losepage = 10;
+    }
+
+
+    printf("主设备收到升级指令\r\n");
+    g_devMsg.workMode = WORK_UPDATE;
+    g_devMsg.ledgreen = 2;
+
+    send_update_code_to_serve(msg->desDevType,msg->desDevSn,msg->taskId,UPDATE_RECEIVE_UPDATEFLAG,0x03);
+    waiting_4g_tx_fifo_empty();
+
+    start_delay_ms(1000);
+    while(!g_iDelayfinish);
+
+    RTC_WriteBackupRegister(BKP_DATA_4, msg->taskId);// 升级任务号  BKP_DATA_4
+    g_updateDa.taskNo = msg->taskId;
+
+    binPos = strstr((char*)msg->url,".bin") - 8;
+    memset(_buff,0,sizeof(_buff));
+    memcpy(_buff,binPos,8);
+    //sscanf((char*)_buff,"%x",&Version);
+    Version = strtohex(_buff,8);//
+    printf("version = %08x\n",Version);
+
+    memcpy(_buff,msg->url,msg->urllen);
+    _buff[msg->urllen] = '\0';
+    AIR_HTTP_GET((char*)_buff,&total_len); // 得到文件总大小
+
+    if(total_len<=2){
+        updateCode = UPDATE_DOWNLOADFILE_FAILED;// 文件下载失败
+        goto UPDATE_END;
+    }
+    else if(total_len>262144){ // 96K的文件
+        updateCode = UPdATE_FILE_LEN_ERROR;
+        goto UPDATE_END;
+    }
+
+    Flash_RangeErase(OTA_UPDATE_APP3_FLASH_START_ADDR, OTA_UPDATE_APP3_FLASH_SIZE); // 擦除APP3区
+
+    printf("total len=%d\n",total_len);
+    while(start_addr < total_len) {//每次读取512字节,写入到flash中
+        remain_len = total_len - start_addr;
+        read_len = (remain_len > UPDATE_ONE_SIZE)?UPDATE_ONE_SIZE:remain_len;
+        p_content = AIR_HTTP_READ(start_addr, read_len);
+        printf("update recive page = %d\r\n",pages++);
+        //data_dump("Update Data", p_content+read_len-16,16);// read_len);
+        memcpy(flashbuff,p_content,read_len);
+        Flash_BufferWrite(OTA_UPDATE_APP3_FLASH_START_ADDR + start_addr, (uint32_t *)flashbuff, read_len);
+        start_addr += read_len;
+    }
+    crcVl = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+total_len-4); //CRC校验
+    fixChar = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+total_len-8); // 固定字符 WBJW
+    fileVer = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+total_len-12); // 固件信息
+    filelen =  *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+total_len-20); // 文件总长度
+    addr = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+total_len-16); // 文件写入的地址
+
+    app_check_crc(OTA_UPDATE_APP3_FLASH_START_ADDR,OTA_UPDATE_APP3_FLASH_SIZE,&getcrc);
+    printf("crcVl=%08x, getcrc=%08x\n",crcVl,getcrc);
+    if(getcrc!=crcVl) {
+        updateCode = UPDATE_CRCERROR;
+        printf("update file crc error\r\n");// 升级文件crc校验错误
+        goto UPDATE_END;
+    }
+    // if(Version!=fileVer){
+    //     updateCode = UPDATE_URL_FILE_TYPE_ERROR;
+    //     goto UPDATE_END;
+    // }
+    printf("~~~~~~~~update file download sucess~~~~~~~~~~\r\n");
+    send_update_code_to_serve(msg->desDevType,msg->desDevSn,msg->taskId,UPDATE_DOWNLOADFILE_SUCCESS,0x03); // 文件下载成功并写入到APP3中
+    waiting_4g_tx_fifo_empty();
+    RTC_WriteBackupRegister(BKP_DATA_4, msg->taskId); // 升级任务号
+
+    if(cmd == 0x1004){
+        if(msg->desDevSn != g_devMsg.devSn){
+            g_updateDa.iDentity = IDENTITY_MASTER;//标记为下发升级设备
+            ota_master_init_update_msg(msg,Version,total_len,losepage);
+            ota_master_update_salve(&ota_devMsg,OTA_UPDATE_APP3_FLASH_START_ADDR);
+            return;
+        }
+    }
+    if(msg->desDevType == DEV_TYPE){
+        // if(fixChar != 0x57424A57) {//固定字符错误
+        //     goto UPDATE_END;
+        // }
+        // if((fileVer&0xfffff000) != (APP_VERSION&0xFFFFF000)){ //固件信息错误
+        //     updateCode = UPDATE_DEVICETYPEERROR;
+        //     goto UPDATE_END;
+        // }
+        if(msg->desDevSn == g_devMsg.devSn || (0xFFFFFFFF == msg->desDevSn)){//|| (0xFFFFFFFF == msg->devSn)
+            //if(0xFFFFFFFF == msg->desDevSn) RTC_WriteBackupRegister(BKP_DATA_6,(uint16_t)UPDATE_SLAVE);// 记录升级的设备,如果是广播升级,则需要重新启动后,升级从设备
+            //else RTC_WriteBackupRegister(BKP_DATA_6,0);
+            g_updateDa.bfirmware_type = msg->firmType;
+            send_data_dr2 = set_updata_state(g_updateDa.bfirmware_type);
+            RTC_WriteBackupRegister(BKP_DATA_3,send_data_dr2);//记录固件类型
+            printf("1\n");
+            send_data_dr2 = set_updata_state(UPDATE_DOWNLOADFILE_SUCCESS);
+            RTC_WriteBackupRegister(BKP_DATA_2, send_data_dr2); // 写入状态码
+            send_data_dr2 = set_updata_state(UPDATE_FLAG); // 升级标志0x81,bootloader可以根据此标志进行升级
+            RTC_WriteBackupRegister(BKP_DATA_1, send_data_dr2); // 写入标志码
+            g_updateDa.Update_Source = UP_PROG_FROM_NET;
+            RTC_WriteBackupRegister(BKP_DATA_5, UP_PROG_FROM_NET); // 升级的来源 0x22 来源来网络服务下发的
+            start_delay_ms(2000);
+            while(!g_iDelayfinish);
+            printf("\r\n gateway update ======================\r\n");
+            SYS_SoftwareReset();//复位//设备重新启动//写升级标志位,然后复位,进入bootloader程序中
+        }
+    }
+    else { // 从设备升级
+        g_updateDa.iDentity = IDENTITY_MASTER;//标记为下发升级设备
+        ota_master_init_update_msg(msg,Version,total_len,losepage);
+        ota_master_update_salve(&ota_devMsg,OTA_UPDATE_APP3_FLASH_START_ADDR);
+    }
+
+
+    return;
+UPDATE_END:
+    send_update_code_to_serve(msg->desDevType,msg->desDevSn,msg->taskId,updateCode,0x03);
+    waiting_4g_tx_fifo_empty();
+    g_devMsg.workMode = WORK_NORMAL;
+    return;
+}
+
+//重传随机延时
+void ota_repeat_rand_timer(uint8_t status)
+{
+	static uint32_t randDa;
+
+//	srand(randDa+g_devMsg.devSn);
+	if(status == 0)
+		randDa = rand()%150 + 200;
+	else
+		randDa = rand()%150 + 500;
+	printf("重传随机时间 = %d\r\n",randDa);
+	set_start_ota_timer(&g_otaTimer.repeatRandomTmr,randDa);
+}
+
+void ota_check_update_timer(void)
+{
+	int i;
+	uint32_t randDa;
+    //if(g_updateDa.Work_State == OTA_UPDATE_CONTINUE_END){
+        ota_update_slave_continue_end(g_updateDa.Work_State);
+    //}
+
+    if(ota_timer_is_timeout(&g_otaTimer.totalTmr)){ // 总定时器超时
+        g_updateDa.Work_State = OTA_UPDATE_NULL;
+        //g_devMsg.workMode = WORK_NORMAL;
+        reset_work_mode();
+
+        printf("启动升级总定时时间--超时\r\n");
+    }
+    if(ota_timer_is_timeout(&g_otaTimer.onlookerTmr)){ // 旁观都定时器超时
+        if(g_updateDa.iDentity == IDENTITY_SLAVE)
+        {
+            if(g_updateDa.ResetUpdate_s)
+            {
+                g_updateDa.ResetUpdate_s = 0;
+                g_updateDa.bResetUpdate = 1;
+
+                randDa = rand()%150+200;
+                set_start_ota_timer(&g_otaTimer.randomTmr,randDa);
+                printf("上报升级状态\n");
+            }
+        }
+
+        //g_devMsg.workMode = WORK_NORMAL;
+        reset_work_mode();
+        ota_timer_stop(&g_otaTimer.continueTmr);
+        ota_timer_stop(&g_otaTimer.repeatTmr);
+        ota_timer_stop(&g_otaTimer.totalTmr);
+        printf("旁观者时间到\r\n");
+    }
+    if(ota_timer_is_timeout(&g_otaTimer.continueTmr)) {
+        printf("连续发包超时\n");
+        if(IDENTITY_MASTER != g_updateDa.iDentity)//被升级设备
+        {
+            for(i=ota_devMsg.lastRightPkgNum;i<ota_devMsg.totalPage;i++){
+                ota_devMsg.losePkgNum++;
+                ota_devMsg.lossPkgId[ota_devMsg.lossPkgIndex++] = i;
+                if(ota_devMsg.losePkgNum == ota_devMsg.loseTotalPage) {// 丢10条
+                    set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);
+                    updata_state_save = set_updata_state(PACKET_LOSS_MORE);// 丢包太多
+                    RTC_WriteBackupRegister(BKP_DATA_2,updata_state_save);
+                    return;
+                }
+            }
+            if(ota_devMsg.losePkgNum)//有丢包,开始重传
+            {
+                g_updateDa.Work_State = OTA_UPDATE_REPEAT;
+                set_start_ota_timer(&g_otaTimer.repeatTmr,OTA_TIM_REPEAT);
+                ota_repeat_rand_timer(0);//重传随机延时
+            }
+        }
+    }
+    if(ota_timer_is_timeout(&g_otaTimer.repeatTmr)){
+        printf("启动升级重传时间--超时\r\n");
+        if(IDENTITY_MASTER != g_updateDa.iDentity)//被升级设备
+        {
+            updata_state = RETRANSMIT_TIMEOUT;
+            updata_state_save = set_updata_state(updata_state);
+            RTC_WriteBackupRegister(BKP_DATA_2, updata_state_save);
+            g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+            ota_timer_stop(&g_otaTimer.repeatRandomTmr);
+            ota_timer_stop(&g_otaTimer.repeatTmr);
+        }
+        else//下发升级的设备
+        {
+            ota_timer_stop(&g_otaTimer.repeatRandomTmr);
+            ota_timer_stop(&g_otaTimer.repeatTmr);
+            set_start_ota_timer(&g_otaTimer.upstatusTmr,10*1000);
+        }
+    }
+    if(ota_timer_is_timeout(&g_otaTimer.upstatusTmr)){ // 读取状态时间
+        ota_timer_stop(&g_otaTimer.totalTmr);
+        ota_timer_stop(&g_otaTimer.repeatTmr);
+        //g_devMsg.workMode = WORK_NORMAL;
+        reset_work_mode();
+        g_updateDa.Work_State = OTA_UPDATE_NULL;
+        memset(&g_updateDa,0,sizeof(UpdateDa));//
+        printf("状态已经上报,升级结束\r\n");
+    }
+}
+
+/*---------------------------------------------------------------------------
+ *  从设备运行的升级任务
+ * ---------------------------------------------------------------------------*/
+void ota_update_slave_task(uint16_t cmd,uint8_t *data,uint8_t len)
+{
+    uint16_t totalPkg,i,send_data_dr2;
+    uint32_t otaContinueTmr;
+    updateCmd0x1003 *msg1003 = NULL;
+    updateCmd0x1004 *msg1004 = NULL;
+    updateCmd0x1005 *msg1005 = NULL;
+    uint32_t flash_buff[256];
+    if(OTA_UPDATE_ONLOOKER == g_updateDa.Work_State) { //旁观者身份
+        set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);
+        printf("cur mode outlooker \r\n");
+    }
+    else {
+        switch(cmd){
+        case 0x1003:
+            msg1003 = (updateCmd0x1003*)data;
+            g_devMsg.workMode = WORK_UPDATE;
+            g_devMsg.ledgreen = 2;
+            if(0 == check_dev_type_sn(msg1003->desDevType,msg1003->desDevSn)){
+                g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+                set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);// 打开旁观者定时器
+                printf("cur mode outlooker \r\n");
+                break;
+            }
+            if(OTA_UPDATE_NULL == g_updateDa.Work_State){
+                Flash_RangeErase(OTA_UPDATE_APP3_FLASH_START_ADDR, OTA_UPDATE_APP3_FLASH_SIZE); //擦除app3
+            }
+			g_updateDa.iDentity = IDENTITY_SLAVE;//标记为被升级状态
+			g_updateDa.ResetUpdate_s = 1;//需要上报升级状态
+			g_updateDa.Update_Source = UP_PROG_FROM_GAT;
+			RTC_WriteBackupRegister(BKP_DATA_5, UP_PROG_FROM_GAT); // 升级的来源 0x44 来源来网关下发的
+			g_updateDa.bfirmware_type = msg1003->firmType;
+
+            //send_data_dr2 = set_updata_state(g_updateDa.bfirmware_type);
+            RTC_WriteBackupRegister(BKP_DATA_3,g_updateDa.bfirmware_type);//记录固件类型
+
+            set_start_ota_timer(&g_otaTimer.totalTmr,OTA_TIM_TOTALTMR); // 打开总定时器
+            //收到升级指令
+            updata_state = START_UPDATA;
+            updata_state_save = set_updata_state(updata_state);
+            RTC_WriteBackupRegister(BKP_DATA_2, updata_state_save);
+            g_updateDa.Work_State = OTA_UPDATE_BEGIN;
+            totalPkg = (msg1003->totalByte%msg1003->eachMaxByte) ? msg1003->totalByte/msg1003->eachMaxByte+1 : msg1003->totalByte/msg1003->eachMaxByte;
+            otaContinueTmr = totalPkg*msg1003->sendInterval + OTA_TIM_CONTINUE;
+            if(otaContinueTmr > 8*60*1000){
+                g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+                set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);
+                return;
+            }
+            ota_slave_init_update_msg(msg1003);
+            set_start_ota_timer(&g_otaTimer.continueTmr,otaContinueTmr); // 启用续传定时器
+            printf("ota_totle_byte:%d, ota_totle_pkg:%d\n",msg1003->totalByte,totalPkg);
+            printf("send interval:%d, continuous time:%d\n",msg1003->sendInterval,otaContinueTmr);
+            break;
+        case 0x1004:
+            msg1004 = (updateCmd0x1004*)data;
+            if((OTA_UPDATE_BEGIN == g_updateDa.Work_State) || (OTA_UPDATE_CONTINUE == g_updateDa.Work_State)){
+                if(0 == check_dev_type_sn(msg1004->desDevType,msg1004->desDevSn)){
+                    g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+                    set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);// 打开旁观者定时器
+                    ota_timer_stop(&g_otaTimer.continueTmr);// 关闭连续定时器
+                    break;
+                }
+                if(msg1004->subPkgLen > ota_devMsg.eachMaxByte) break; // 接收错误
+                if(OTA_UPDATE_BEGIN == g_updateDa.Work_State) g_updateDa.Work_State = OTA_UPDATE_CONTINUE;
+                if((msg1004->totalPage == ota_devMsg.totalPage) && (msg1004->subPkgId <= ota_devMsg.totalPage)){
+                    printf("update continue type=0x%x,sn=0x%x,{%d/%d/%d}\r\n",msg1004->rcvDevType,msg1004->rcvDevSn,
+                            msg1004->totalPage,msg1004->subPkgId,ota_devMsg.losePkgNum);
+                    memcpy(flash_buff,((data+OTA_CONTINUES_INFO_LEN)), msg1004->subPkgLen);
+                    Flash_BufferWrite(OTA_UPDATE_APP3_FLASH_START_ADDR + (msg1004->subPkgId - 1)*OTA_MASTER_SEND_PKG_SIZE,
+                        flash_buff, msg1004->subPkgLen);
+                    //data_dump("收到1004",(uint8_t*)data+OTA_CONTINUES_INFO_LEN,msg1004->subPkgLen);
+                    for(i=ota_devMsg.lastRightPkgNum;i<msg1004->subPkgId;i++){
+                        ota_devMsg.losePkgNum++;
+                        ota_devMsg.lossPkgId[ota_devMsg.lossPkgIndex++] = i;
+                        if(ota_devMsg.losePkgNum == ota_devMsg.loseTotalPage) {// 丢10条
+                            set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);
+                            updata_state_save = set_updata_state(PACKET_LOSS_MORE);// 丢包太多
+                            RTC_WriteBackupRegister(BKP_DATA_2,updata_state_save);
+                            return;
+                        }
+                    }
+                    ota_devMsg.lastRightPkgNum = msg1004->subPkgId +1;
+                    if(msg1004->subPkgId == msg1004->totalPage){ // 最后一包
+                        if(0 == ota_devMsg.losePkgNum){ // 没有丢包
+                            printf("传输完成,没有丢包\r\n");
+                            ota_timer_stop(&g_otaTimer.continueTmr);// 关闭连续定时器
+                            g_updateDa.Work_State = OTA_UPDATE_CONTINUE_END; // 接收完成
+                            printf("check program right\r\n");
+
+                        }
+                        else { // 有丢包
+                            printf("传输完成,有丢包,启动重传指令\r\n");
+                            g_updateDa.Work_State = OTA_UPDATE_REPEAT;
+                            set_start_ota_timer(&g_otaTimer.repeatTmr,OTA_TIM_REPEAT);
+
+							ota_repeat_rand_timer(0);//重传随机延时
+                        }
+						ota_timer_stop(&g_otaTimer.continueTmr);// 关闭连续定时器
+                    }
+                    else { // 不是最后一包
+
+                    }
+                }
+            }
+            else {
+                g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+                set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);
+                ota_timer_stop(&g_otaTimer.continueTmr);// 关闭连续定时器
+            }
+            break;
+        case 0x1005:
+            msg1005 = (updateCmd0x1005*)data;
+            if(g_updateDa.Work_State == OTA_UPDATE_REPEAT) {
+//                ota_timer_stop(&g_otaTimer.repeatTmr);
+                if(msg1005->totalPage == ota_devMsg.totalPage){
+                    if(msg1005->subPkgLen > OTA_MASTER_SEND_PKG_SIZE) return;
+                    //判定该包是否为本设备丢的那些包之中的子包
+                    for(i = 0;i < ota_devMsg.lossPkgIndex;i++) {
+                        if(ota_devMsg.lossPkgId[i] == msg1005->subPkgId) {
+                            ota_devMsg.losePkgNum--;
+                            ota_devMsg.lossPkgId[i] = 0;
+
+                            //接受本包并写入flash的对应位置
+                            memcpy(flash_buff,(data+OTA_CONTINUES_INFO_LEN ), msg1005->subPkgLen);
+                            Flash_BufferWrite(OTA_UPDATE_APP3_FLASH_START_ADDR + (msg1005->subPkgId - 1)*OTA_MASTER_SEND_PKG_SIZE,
+                            flash_buff, msg1005->subPkgLen);
+
+                            printf("rcv retransmit pkgid:%d\n",msg1005->subPkgId);
+                            break;
+                        }
+                    }
+                    if(ota_devMsg.losePkgNum == 0) //丢包已收完
+                    {
+                        //ota_continuous_end_flag = OTA_CONTINUOUS_DIRECT;
+                        //g_updateDa.Work_State = DEV_WORK_STATE_OTA_UPGRADE_RCV_END;
+                        g_updateDa.Work_State = OTA_UPDATE_REPEAT_END;
+						ota_timer_stop(&g_otaTimer.repeatRandomTmr);
+                    }
+                    printf("ota_info.lossPkgCounter = %d, lossPkgId:%d\r\n", ota_devMsg.losePkgNum,msg1005->subPkgId);
+                    //指示灯显示
+                    //remain_pkg = ota_info.lossPkgCounter; //gch
+                }
+//                set_start_ota_timer(&g_otaTimer.repeatTmr,OTA_TIM_REPEAT);
+
+				g_updateDa.retransmit_s = 0;
+            }
+            else {
+                g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+                set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);
+                ota_timer_stop(&g_otaTimer.continueTmr);// 关闭连续定时器
+            }
+            break;
+        }
+
+
+    }
+
+}
+void ota_update_slave_retransmit(uint16_t index)
+{
+    updateCmd0x2005 *msg = (updateCmd0x2005*)_buff;
+
+    memset(_buff,0,256);
+
+    msg->slaveDevType = g_devMsg.devType;
+    msg->slaveDevSn   = g_devMsg.devSn;
+    msg->repDevType   = g_devMsg.devType;
+    msg->repDevSn     = g_devMsg.devSn;
+    msg->repPkgId     = index;
+
+    slave_send_data_to_uart(0x04,0x2005,(uint8_t*)msg,sizeof(updateCmd0x2005));
+
+
+}
+/*----------------------------------------------------------------------------
+ *  主设备收到重传指令
+ * ---------------------------------------------------------------------------*/
+void ota_update_master_retransmit(uint8_t *data)
+{
+    updateCmd0x2005 *msg = (updateCmd0x2005*)data;
+    updateCmd0x1005 *pmsg = (updateCmd0x1005*)_buff;
+    uint32_t flash_buff[256];
+    ota_timer_stop(&g_otaTimer.repeatTmr);
+    memset(_buff,0,256);
+    pmsg->rcvDevSn   = ota_devMsg.rcvDevSn;       //msg->slaveDevSn;    ota_devMsg.rcvDevSn;
+    pmsg->rcvDevType = ota_devMsg.rcvDevType;     //msg->slaveDevType;  ota_devMsg.rcvDevType;
+    pmsg->desDevSn   = ota_devMsg.desDevSn;       //msg->repDevSn;      ota_devMsg.desDevSn;
+    pmsg->desDevType = ota_devMsg.desDevType;     //msg->repDevType;    ota_devMsg.desDevType;
+    pmsg->subPkgId   = msg->repPkgId;
+    pmsg->subPkgLen  = OTA_MASTER_SEND_PKG_SIZE;
+    pmsg->totalPage  = ota_devMsg.totalPage;
+
+    Flash_BufferRead(OTA_UPDATE_APP3_FLASH_START_ADDR + (pmsg->subPkgId - 1)*OTA_MASTER_SEND_PKG_SIZE,
+        flash_buff, OTA_MASTER_SEND_PKG_SIZE);
+        memcpy(((uint8_t *)pmsg) + OTA_CONTINUES_INFO_LEN,flash_buff, OTA_MASTER_SEND_PKG_SIZE);
+    slave_send_data_to_uart(0x04,0x1005,(uint8_t*)pmsg,sizeof(updateCmd0x1005)+OTA_MASTER_SEND_PKG_SIZE);
+
+    set_start_ota_timer(&g_otaTimer.repeatTmr,OTA_TIM_REPEAT);
+}
+
+void ota_update_slave_continue_end(uint8_t workMode)
+{
+    uint32_t crcVl,fixChar,fileVer,filelen,i;
+    uint32_t getcrc;
+
+    switch(workMode){
+    case OTA_UPDATE_CONTINUE_END: case OTA_UPDATE_REPEAT_END:
+        crcVl = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_devMsg.totalByte-4); //CRC校验
+        fixChar = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_devMsg.totalByte-8); // 固定字符 WBJW
+        fileVer = *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_devMsg.totalByte-12); // 固件信息
+        filelen =  *(uint32_t*)(OTA_UPDATE_APP3_FLASH_START_ADDR+ota_devMsg.totalByte-20); // 文件总长度
+
+        printf("read_fixchar:%08x, fixchar:%08x\n",fixChar,0x57424A57);
+        if(fixChar != 0x57424A57) //固定字符错误
+        {
+            g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+            set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);  //打开旁观者定时器
+            updata_state = FIXED_CHARACTER_ERROR;
+            updata_state_save = set_updata_state(updata_state);
+            RTC_WriteBackupRegister(BKP_DATA_2, updata_state_save);
+            printf("fixChar error\r\n");// 升级文件固定字符校验错误
+            return;
+        }
+        printf("read_filever:%08x, device_type:%08x\n",fileVer,0x09043000);
+        if((fileVer&0xfffff000) != (APP_VERSION&0xFFFFF000)) //固件信息错误
+        {
+            g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+            set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);   //打开旁观者定时器
+            updata_state = DEVICE_TYPE_ERROR;
+            updata_state_save = set_updata_state(updata_state);
+            RTC_WriteBackupRegister(BKP_DATA_2, updata_state_save);
+            printf("fileVer error\r\n");// 升级文件固件信息校验错误
+            return;
+        }
+
+        printf("read_filelen:%08x, total_bytes:%08x\n",filelen,(ota_devMsg.totalByte-20));
+        if(ota_devMsg.totalByte != (filelen+20))//长度错误
+        {
+            g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+            set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);   //打开旁观者定时器
+            updata_state = UPDATA_PACKAGE_LENGTH_ERROR;
+            updata_state_save = set_updata_state(updata_state);
+            RTC_WriteBackupRegister(BKP_DATA_2, updata_state_save);
+            printf("filelen error\r\n");// 升级文件长度校验错误
+            return;
+        }
+        app_check_crc(OTA_UPDATE_APP3_FLASH_START_ADDR,OTA_UPDATE_APP3_FLASH_SIZE,&getcrc);
+        printf("read_crc:%x, get_crc:%x\n",crcVl,getcrc);
+        if(getcrc!=crcVl) { //校验错误
+            printf("update file crc error\r\n");// 升级文件crc校验错误
+            g_updateDa.Work_State = OTA_UPDATE_ONLOOKER;
+            set_start_ota_timer(&g_otaTimer.onlookerTmr,OTA_TIM_ONLOOKER);   //打开旁观者定时器
+            updata_state = UPDATA_CRC_ERROR;
+            updata_state_save = set_updata_state(updata_state);
+            RTC_WriteBackupRegister(BKP_DATA_2, updata_state_save);
+
+            return;
+        }
+
+        printf("收包正确\n");
+        updata_state = UPDATA_DATA_SUCCESS;
+        updata_state_save = set_updata_state(updata_state);
+        RTC_WriteBackupRegister(BKP_DATA_2, updata_state_save);
+
+        updata_state = set_updata_state(UPDATE_FLAG);//置升级标志
+        RTC_WriteBackupRegister(BKP_DATA_1, updata_state);
+        SYS_SoftwareReset();
+        break;
+    case OTA_UPDATE_REPEAT:
+		// if(!timeout_isOut(&g_otaTimer.repeatRandomTmr.timer)) break;
+		// dma_channel_disable(DMA1, DMA_CH2);
+        // if(USART3_RX_SIZE - dma_transfer_number_get(DMA1,DMA_CH2))
+        // {
+		// 	dma_channel_enable(DMA1, DMA_CH2);/* enable USART1_RX DMA_Channel */
+		// 	ota_repeat_rand_timer(1);//重传随机延时
+		// 	break;
+		// }
+		// dma_channel_enable(DMA1, DMA_CH2);/* enable USART1_RX DMA_Channel */
+        // for(i = 0;i < ota_devMsg.lossPkgIndex;i++) {
+        //     if(ota_devMsg.lossPkgId[i])
+        //     {
+        //         ota_update_slave_retransmit(ota_devMsg.lossPkgId[i]);
+        //         printf("send retransmit pkgid:%d\n",ota_devMsg.lossPkgId[i]);
+        //         g_updateDa.bRetransmit = 1;
+		// 		g_updateDa.retransmit_s = 1;
+        //         break;
+        //     }
+        // }
+		// ota_repeat_rand_timer(0);//重传随机延时
+        break;
+    }
+}
+void ota_update_send_update_status(uint16_t desDevType,uint32_t desDevSn)
+{
+    updateCmd0x2007 *msg = (updateCmd0x2007*)_buff;
+
+    memset(_buff,0,256);
+
+    msg->slaveDevType   = g_devMsg.devType;
+    msg->slaveDevSn     = g_devMsg.devSn;
+    msg->desDevType     = desDevType;
+    msg->desDevSn       = desDevSn;
+    msg->ptVer          = g_devAppVer.ptVer;
+    msg->appVer         = APP_VERSION;
+    msg->updateCode     = g_updateDa.updateCode;
+    msg->reserve        = 0x00;
+    slave_send_data_to_uart(0x04,0x2007,(uint8_t*)_buff,sizeof(updateCmd0x2007));
+}
+
+void ota_update_deal_upstatus(void)
+{
+    static uint8_t flag = 0;
+    if((0x01 ==g_updateDa.bResetUpdate) ) { // 连接网络且有升级
+        if(g_updateDa.Update_Source == UP_PROG_FROM_NET){//升级来源于网络
+            if(0x01 == g_4gMsg.bconnect){
+                send_update_code_to_serve(g_devMsg.devType,g_devMsg.devSn,g_updateDa.taskNo,g_updateDa.updateCode,0x03);
+                printf("上传升级标志到服务器\r\n");
+                g_updateDa.bResetUpdate = 0;
+                if(g_updateDa.bUpdate_slave==UPDATE_SLAVE)
+                {
+                    g_updateDa.bOffline_s = 1;//可以离线升级
+                    g_devMsg.workMode = WORK_UPDATE;
+                    g_devMsg.ledgreen = 2;
+                }
+            }
+        }
+        else {
+            if(timeout_isOut(&(g_otaTimer.randomTmr.timer))){ //超时,可以发送
+                printf("发送升级标志 %d\r\n",g_updateDa.updateCode);
+                ota_update_send_update_status(g_devMsg.devType,g_devMsg.devSn);
+                flag++;
+                if(flag >=3 ){
+                    RTC_WriteBackupRegister(BKP_DATA_2,0);//清除标志备份寄存器
+                    g_updateDa.bResetUpdate = 0x00;
+                    memset(&g_updateDa,0,sizeof(UpdateDa));
+                    flag = 0;
+                }
+                set_start_ota_timer(&g_otaTimer.randomTmr,(rand()%150+200));
+            }
+        }
+    }
+
+
+}
+
+///////////////////////离线升级////////////////////////////
+//读取app程序包的大小并校验
+uint32_t Read_APP_datalen_check(uint32_t addr, uint32_t len)
+{
+    uint32_t datalen = 0;
+	uint32_t crcVl,fixChar,fileVer,filelen,getcrc,t_addr;
+	uint32_t bin_data[6] = {0};
+	uint8_t flag = 0;
+    uint8_t check_flag = 0;
+
+	printf("addr=%08x\n",addr);
+	datalen = Flash_DatalenRead(addr,len);
+	if((datalen > (96*1024)) || (datalen < (20)))
+	{
+		printf("升级包长度超过128K: %d\n",datalen);
+		datalen = 0;
+		return datalen;
+	}
+
+	filelen =  *(uint32_t*)(addr+datalen-20); // 文件总长度
+	printf("datalen=%08x,%u; filelen=%08x,%u\n",datalen,datalen,filelen,filelen);
+
+	printf("addr=%08x\n",addr);
+	crcVl = *(uint32_t*)(addr + datalen-4); //CRC校验
+	fixChar = *(uint32_t*)(addr + datalen-8); // 固定字符 WBJW
+	fileVer = *(uint32_t*)(addr + datalen-12); // 固件信息
+	filelen =  *(uint32_t*)(addr + datalen-20); // 文件总长度
+	t_addr = *(uint32_t*)(addr + datalen-16); // 文件写入的地址
+
+	printf("crcVl=%08x,fixChar=%08x,fileVer=%08x,filelen=%08x,t_addr=%08x\n",crcVl,fixChar,fileVer,filelen,t_addr);
+
+	//判断后20字节是否正确
+	if((fixChar == 0x57424A57) && (t_addr == 0x08018000))//升级包中包含了后20字节
+	{
+		printf("升级包包含了后20字节\n");
+		if(datalen != (filelen+20))
+		{
+			printf("升级包长度校验错误\n");
+			check_flag = 1;
+		}
+//			else if(fileVer != device_fixed_info.Soft_ver_app)
+//			{
+//				printf("固件信息错误\n");
+//				printf("filever=%08x,app=%08x\n",fileVer,device_fixed_info.Soft_ver_app);
+//                check_flag = 1;
+//			}
+		else
+		{
+			app_check_crc(addr,datalen,&getcrc);
+			printf("read_crc:%08x, get_crc:%08x\n",crcVl,getcrc);
+			if(crcVl != getcrc)
+			{
+				printf("crc 错误\n");
+				check_flag = 1;
+			}
+		}
+	}
+	else
+	{
+		check_flag = 1;
+	}
+
+	if(check_flag)//后20字节错误
+	{
+		if(addr==OTA_UPDATE_APP1_FLASH_START_ADDR)//app1需要计算后20个字节
+		{
+			bin_data[0] = datalen;  //原始bin文件字节长度
+			bin_data[1] = OTA_UPDATE_APP1_FLASH_START_ADDR; //存储地址
+                        bin_data[2] = APP_VERSION; //固件版本
+			bin_data[3] = 0x57424A57; //固定标记,"WBJW"
+
+			fileVer = bin_data[2];
+
+			Flash_BufferWrite(addr+datalen,bin_data,16);
+
+			datalen += 20;
+			printf("datalen1=%08x\n",datalen);
+			SYS_EnableAHBClock(AHB_MASK_CRC0);
+            CRC_Reset(CRC0);
+            getcrc = crc_block_data_calculate((uint32_t*)addr,(datalen -4)/4);//计算crc数值
+
+			bin_data[0] = getcrc;
+			printf("crc=%08x\n",bin_data[0]);
+			Flash_BufferWrite(addr+datalen-4,bin_data,4); //crc校验
+		}
+		else
+		{
+			datalen = 0;
+		}
+
+	}
+
+    if(datalen)
+    {
+        memset(&ota_devMsg,0,sizeof(otaUpdatMsg));
+        ota_devMsg.version      = fileVer;     // 升级的软件版本号
+        ota_devMsg.totalByte    = datalen;    // 升级的总大小
+    }
+	return datalen;
+}
+
+void ota_master_init_update_msg_offline(uint16_t rcvdevtype,uint32_t rcvdevsn,uint16_t desdevtype,uint32_t desdevsn,uint8_t firmtype)
+{
+    // memset(&ota_devMsg,0,sizeof(otaUpdatMsg));
+    ota_devMsg.rcvDevType   = rcvdevtype;  // 接收设备类型
+    ota_devMsg.rcvDevSn     = rcvdevsn;    // 接收设备SN
+    ota_devMsg.desDevType   = desdevtype;  // 升级目标设备类型
+    ota_devMsg.desDevSn     = desdevsn;    // 升级目标设备SN
+	ota_devMsg.firmType     = firmtype;    // 升级固件类型
+    // ota_devMsg.version      = version;     // 升级的软件版本号
+    // ota_devMsg.totalByte    = totallen;    // 升级的总大小
+    ota_devMsg.losePage     = 20;
+    ota_devMsg.sendInterval = 300;
+    ota_devMsg.totalPage    = ota_devMsg.totalByte/OTA_MASTER_SEND_PKG_SIZE;
+    if(ota_devMsg.totalByte%OTA_MASTER_SEND_PKG_SIZE) ota_devMsg.totalPage += 1;
+    ota_devMsg.subPkgLen    = OTA_MASTER_SEND_PKG_SIZE;
+    ota_devMsg.subPkgId = 1;
+    ota_devMsg.lastRightPkgNum = 1;
+    ota_devMsg.lossPkgIndex = 0;
+}
+
+
+//离线升级初始化
+uint8_t ota_offline_init(uint32_t addr,uint32_t len)
+{
+    uint32_t total_bytes = 0;
+    total_bytes = Read_APP_datalen_check(addr,len);
+    if(total_bytes==0) //升级包长度错误,升级结束
+    {
+        printf("升级包长度错误 ");
+        return 0;
+    }
+    return 1;
+}
+
+//离线升级过程
+void ota_offline_proc(void)
+{
+    g_updateDa.iDentity = IDENTITY_MASTER;//标记为下发升级设备
+    g_devMsg.workMode = WORK_UPDATE;
+    g_devMsg.ledgreen = 2;
+    ota_master_update_salve(&ota_devMsg,g_updateDa.bOffline_addr);
+}
+
+//离线升级处理函数
+void ota_offline_handle(void)
+{
+    //离线升级
+    if(g_updateDa.bOffline_s)
+    {
+        g_updateDa.bOffline_s = 0;
+        printf("开始离线升级\n");
+        ota_offline_proc();
+    }
+}
+
+//从设备收到离线升级指令
+void ota_update_slave_offline(uint8_t *data,uint8_t len)
+{
+    updateCmd0x1006* msg1006 = (updateCmd0x1006*)data;
+    if(g_devMsg.workMode == WORK_UPDATE) return;
+
+    if((msg1006->masterDevType==g_devMsg.devType) && (msg1006->masterDevSn==g_devMsg.devSn))
+    {
+        if(msg1006->firmType != 0x03) return; //不是升级app
+        if(ota_offline_init(OTA_UPDATE_APP1_FLASH_START_ADDR,OTA_UPDATE_APP1_FLASH_SIZE))//升级包正确
+        {
+            ota_master_init_update_msg_offline(msg1006->slaveDevType,msg1006->slaveDevSn,msg1006->desDevType,msg1006->desDevSn,msg1006->firmType);
+            g_updateDa.bOffline_s = 1;//可以离线升级
+            g_updateDa.bOffline_addr = OTA_UPDATE_APP1_FLASH_START_ADDR;
+            g_devMsg.workMode = WORK_UPDATE;
+            g_devMsg.ledgreen = 2;
+            printf("升级从设备\n");
+        }
+    }
+}
+/*-------------------------------------------------------------------------------
+ *  按键启动离线升级
+ * -----------------------------------------------------------------------------*/
+void ota_start_offline_update(void)
+{
+    if(g_devMsg.workMode != WORK_UPDATE)//非升级模式
+    {
+        if(ota_offline_init(OTA_UPDATE_APP1_FLASH_START_ADDR,OTA_UPDATE_APP1_FLASH_SIZE))//升级包正确
+        {
+            ota_master_init_update_msg_offline(DEV_TYPE,0xffffffff,DEV_TYPE,0xffffffff,0x03);//升级app
+            g_updateDa.bOffline_s = 1;//可以离线升级
+            g_updateDa.bOffline_addr = OTA_UPDATE_APP1_FLASH_START_ADDR;
+            printf("升级从设备\n");
+        }
+        g_devMsg.workMode = WORK_UPDATE;
+        g_devMsg.ledgreen = 2;
+    }
+}
+
+/*-------------------------------------------------------------------------------
+ *  升级成功后,主设备 接收升级的状态
+ * --------------------------------------------------------------------------------*/
+void master_update_status_rcv(uint8_t *data, uint32_t len)
+{
+	updateCmd0x2007 *msg = (updateCmd0x2007*)data;
+
+	printf("^^^^^^^rcv type = %04x  sn = %08x app = %08x, status = %d\r\n",msg->desDevType, msg->desDevSn,msg->appVer,msg->updateCode);
+        if((IDENTITY_MASTER == g_updateDa.iDentity) || (IDENTITY_MASTER == g_iDentity))
+	{
+		send_update_code_to_serve(msg->desDevType,msg->desDevSn,g_updateDa.taskNo,msg->updateCode,0x03);
+	}
+}

+ 250 - 0
src/app/ota_update.h

@@ -0,0 +1,250 @@
+#ifndef _OTA_UPDATE_H_
+#define _OTA_UPDATE_H_
+
+#include "board.h"
+#include "./agm_board/timeout.h"
+
+enum { // 升级结果类型
+    UPDATE_RECEIVE_UPDATEFLAG = 0x11, // 收到服务器的升级指令
+    UPDATE_SAMEVERSION, // 和当前版本相同
+    UPDATE_FAILE_NOCOLLECT, // 此采集器不在本网关下
+    UPDATE_HTTP_ERROR,  //HTTP返回错误码
+    UPDATE_DOWNLOADFILE_FAILED, //文件下载失败,即文件大小小于2个字节
+    UPDATE_DOWNLOADFILE_SUCCESS, // 文件下载成功
+    UPDATE_CRCERROR, // 文件包中的CRC与实际不符
+    UPDATE_URL_FILE_TYPE_ERROR, // URL中的文件信息与文件包中的信息不一致
+    UPDATE_DEVICETYPEERROR, // 升级设备类型不匹配
+    UPdATE_FILE_LEN_ERROR,  // 升级文件长度超过128个字节
+    UPDATE_SUCCESS, // 升级成功
+    UPDATE_RETURN_SUCESS, // 回退
+};
+
+//升级状态
+#define START_UPDATA                  0x21  //已收到正确的升级指令
+#define PACKET_LOSS_MORE              0x22  //丢包超标,升级结束
+#define RETRANSMIT_TIMEOUT            0x23  //重传阶段超时,升级失败
+#define UPDATA_CRC_ERROR              0x24  //升级包CRC校验失败
+#define DEVICE_TYPE_ERROR             0x25  //目标设备类型不匹配
+#define UPDATA_PACKAGE_LENGTH_ERROR   0x26  //长度不符
+#define FIXED_CHARACTER_ERROR         0x27  //固定字符错误
+#define UPDATA_DATA_SUCCESS           0x28  //升级包接收正确
+#define UPDATA_TOTAL_TIMEOUT          0x29  //升级总时间超时
+#define UPDATA_SUCCESS                0x2A  //升级成功
+#define UPDATA_BACK                   0x2B  //回退
+
+
+#define UPDATE_SLAVE 0x5AA5
+enum {
+    UP_PROG_FROM_NET = 0x22, // 来源来网络
+	UP_PROG_FROM_GAT = 0x44, //来源来网关
+};
+
+#define OTA_UPDATE_BOOTROM_FLASH_START_ADDR  (0x08000000)                                                          //
+
+#define OTA_UPDATE_PT_FLASH_SIZE        (0x10000)                                                             //
+#define OTA_UPDATE_PT_FLASH_START_ADDR  (0x80010000)                                                          //
+#define OTA_UPDATE_PT_FLASH_END_ADDR    (OTA_UPDATE_PT_FLASH_START_ADDR+OTA_UPDATE_PT_FLASH_SIZE-1)
+
+
+#define OTA_UPDATE_APP1_FLASH_SIZE        (0x40000)                                                             //
+#define OTA_UPDATE_APP1_FLASH_START_ADDR  (0x80020000)                                                          //
+#define OTA_UPDATE_APP1_FLASH_END_ADDR    (OTA_UPDATE_APP1_FLASH_START_ADDR+OTA_UPDATE_APP1_FLASH_SIZE-1)       //
+
+#define OTA_UPDATE_APP2_FLASH_SIZE        (0x40000)                                                             //
+#define OTA_UPDATE_APP2_FLASH_START_ADDR  (0x80060000)                                                          //
+#define OTA_UPDATE_APP2_FLASH_END_ADDR    (OTA_UPDATE_APP2_FLASH_START_ADDR+OTA_UPDATE_APP2_FLASH_SIZE-1)       //
+
+#define OTA_UPDATE_APP3_FLASH_SIZE        (0x40000)                                                             //
+#define OTA_UPDATE_APP3_FLASH_START_ADDR  (0x800A0000)                                                          //
+#define OTA_UPDATE_APP3_FLASH_END_ADDR    (OTA_UPDATE_APP3_FLASH_START_ADDR+OTA_UPDATE_APP3_FLASH_SIZE-1)       //
+
+#define OTA_UPDATE_FPGA_FLASH_SIZE            (0x19000)                                                             //
+#define OTA_UPDATE_FPGA_FLASH_START_ADDR      (0x800E7000)                                                          //
+#define OTA_UPDATE_FPGA_FLASH_END_ADDR        (OTA_UPDATE_FPGA_FLASH_START_ADDR+OTA_UPDATE_FPGA_FLASH_SIZE-1)       //
+
+#define OTA_UPDATE_APP_FLASH_SIZE             (0x40000)
+
+typedef struct _UPDATE_DATA_{
+    uint16_t updateCode; // 升级状态码,
+    uint8_t bResetUpdate;  // 升级完成后,需要上报升级的状态(包含从设备通过485上报,或是主设备通过4G上报)
+    uint8_t bReadUpdateCode; // 可以允许读取升级状态码了
+    uint16_t taskNo;         // 升级任务号
+    uint8_t bupdateFinish; // 升级是否完成
+    uint8_t brcvCmd0x16; // 收到16指令
+    uint8_t Work_State; // 当前升级状态
+    uint8_t bRetransmit;  // 是否允许重传 1:不允许, 0:允许
+	uint8_t iDentity; //升级时的身份(下发设备或被升级设备)
+	uint8_t retransmit_s;//是否发送了重传指令
+	uint8_t ResetUpdate_s;//是否需要上报升级状态
+	uint8_t Update_Source;//升级来源
+	uint16_t bUpdate_slave;//是否需要升级从设备
+	uint8_t bOffline_s;	//是否开始离线升级
+	uint32_t bOffline_addr; //离线升级首地址
+	uint8_t bfirmware_type;//升级的固件类型
+}__attribute__((packed))UpdateDa;
+extern UpdateDa g_updateDa;
+
+#define OTA_TIM_ONLOOKER 5000 // 旁观都 5S
+#define OTA_TIM_TOTALTMR (60000*5) // 升级总定时器
+#define OTA_TIM_REPEAT   (60*1000) // 重传定时器10S
+#define OTA_TIM_REPEAR_MASTER (10*1000) //重传定时器(主设备)
+//#define OTA_TIM_REPEAR_SLAVE_FAST (rand()%100+300) //重传定时器快(从设备)
+//#define OTA_TIM_REPEAR_SLAVE_SLOW (rand()%100+500) //重传定时器慢
+#define OTA_TIM_CONTINUE  3000   // 连续接收时间 3S
+enum {
+    OTA_TIMER_NULL = 0x00,
+    OTA_TIMER_START = 0x01,
+    OTA_TIMER_END   = 0x02,
+};
+typedef struct _ota_update_time_set_{
+    timeout_t timer;
+    uint8_t status;
+}__attribute__((packed))otaTimeSet;
+
+typedef struct _ota_update_time_{
+    otaTimeSet totalTmr;  // 升级总时间
+    otaTimeSet continueTmr; // 连续接收时间
+    otaTimeSet repeatTmr;  // 重传时间
+    otaTimeSet onlookerTmr; // 旁观者时间
+    otaTimeSet randomTmr;   // 随机定时器
+    otaTimeSet upstatusTmr; // 读取状态时间
+	otaTimeSet repeatRandomTmr;//重传随机时间
+}__attribute__((packed))OtaUpdateTime;
+extern OtaUpdateTime g_otaTimer;
+
+/*-----------------------------------------------升级标记----------------------------------*/
+#define UPDATE_FLAG  0x81   // 升级标志
+#define UPDATE_SUCCESS_FLAG 0x82   // 升级成功标志
+#define BACKOFF_OVER 0x83   // 回滚成功
+/*---------------------------------------------升级协议开始-------------------------------------*/
+
+enum {
+    OTA_UPDATE_NULL     = 0x00, // 默认状态
+    OTA_UPDATE_ONLOOKER = 0x01, // 旁观者模式
+    OTA_UPDATE_BEGIN = 0x02, // 启动升级
+    OTA_UPDATE_CONTINUE = 0x03, // 连续续传模式
+    OTA_UPDATE_REPEAT   = 0x04, // 重传模式
+    OTA_UPDATE_RCVEND   = 0x05, // 升级包接收完成
+    OTA_UPDATE_CONTINUE_END = 0x06, // 连续包结束
+    OTA_UPDATE_REPEAT_END  = 0x07, // 重传包结束
+};
+typedef struct _ota_update_msg_{
+    uint16_t rcvDevType;    // 接收设备类型
+    uint32_t rcvDevSn;      // 接收设备SN
+    uint16_t desDevType;    // 升级目标设备类型
+    uint32_t desDevSn;      // 升级目标设备SN
+    uint8_t  firmType;      // 固件类型
+    uint32_t version;       // 升级版本号
+    uint32_t totalByte;     // 升级总总长度
+    uint16_t eachMaxByte;   // 单包最大字节类
+    uint16_t losePage;      // 最大丢包百分比 最小为10%,最大为60%
+	uint16_t loseTotalPage;	// 最大丢包个数
+    uint16_t sendInterval;  // 连续阶段发 送包的时间间隔(单位:ms)
+    uint16_t totalPage;     // 升级包总个数
+    uint16_t subPkgId;      // 升级包编号
+    uint16_t subPkgLen;     // 本升级包的长度
+    uint8_t  losePkgNum;    // 丢包的个数
+    uint16_t lastRightPkgNum;
+    uint16_t lossPkgId[250];
+    uint8_t  retransLossPkts;  //重传丢包个数
+    uint8_t lossPkgIndex;
+}__attribute__((packed))otaUpdatMsg;
+
+typedef struct _update_cmd_0x1003_{ // 启动升级下行
+    uint16_t rcvDevType;    // 接收设备类型
+    uint32_t rcvDevSn;      // 接收设备SN
+    uint16_t desDevType;    // 升级目标设备类型
+    uint32_t desDevSn;      // 升级目标设备SN
+    uint8_t  firmType;      // 固件类型
+    uint32_t updateVer;     // 升级包版本
+    uint32_t totalByte;     // 升级总总长度
+    uint16_t eachMaxByte;   // 单包最大字节类
+    uint16_t losePage;      // 最大丢包面分比 最小为10%,最大为60%
+    uint16_t sendInterval;  // 连续阶段发 送包的时间间隔(单位:ms)
+}__attribute__((packed))updateCmd0x1003;
+
+typedef struct _update_cmd_0x1004_{ // 连续包下行
+    uint16_t rcvDevType;    // 接收设备类型
+    uint32_t rcvDevSn;      // 接收设备SN
+    uint16_t desDevType;    // 升级目标设备类型
+    uint32_t desDevSn;      // 升级目标设备SN
+    uint16_t totalPage;     // 升级包总个数
+    uint16_t subPkgId;      // 升级包编号
+    uint16_t subPkgLen;     // 本升级包的长度
+}__attribute__((packed))updateCmd0x1004;
+
+typedef struct _update_cmd_0x1005_{ // 重传包
+    uint16_t rcvDevType;    // 接收设备类型
+    uint32_t rcvDevSn;      // 接收设备SN
+    uint16_t desDevType;    // 升级目标设备类型
+    uint32_t desDevSn;      // 升级目标设备SN
+    uint16_t totalPage;     // 升级包总个数
+    uint16_t subPkgId;      // 升级包编号
+    uint16_t subPkgLen;     // 本升级包的长度
+}__attribute__((packed))updateCmd0x1005;
+
+typedef struct _update_cmd_0x2005_{ // 重传包请求上行
+    uint16_t slaveDevType;
+    uint32_t slaveDevSn;
+    uint16_t repDevType;    // 发起请求的设备类型
+    uint32_t repDevSn;      // 发起请求的设备SN
+    uint16_t repPkgId;      // 升级包编号
+}__attribute__((packed))updateCmd0x2005;
+
+typedef struct _update_cmd_0x1006_{ // 离线升级指令
+    uint16_t masterDevType;     // 主设备类型
+    uint32_t masterDevSn;       // 主设备SN
+    uint16_t slaveDevType;      // 从设备类型
+    uint32_t slaveDevSn;        // 从设备SN
+    uint16_t desDevType;        // 升级目标设备类型
+    uint32_t desDevSn;          // 升级目标设备SN
+    uint8_t  firmType;          // 固件类型
+    uint32_t reserve;           // 预留
+}__attribute__((packed))updateCmd0x1006;
+
+typedef struct _update_cmd_0x1007_{ // 升级状态读取下行
+    uint16_t rcvDevType;        // 接收设备类型
+    uint32_t rcvDevSn;          // 接收设备SN
+    uint16_t pointDevType;      // 指定读取的设备类型
+    uint32_t pointDevSn;        // 指定读取的设备SN
+    uint32_t reserve;           // 预留
+}__attribute__((packed))updateCmd0x1007;
+
+typedef struct _update_cmd_0x2007_{ // 升级状态读取上行
+    uint16_t slaveDevType;      // 从设备类型
+    uint32_t slaveDevSn;        // 从设备SN
+    uint16_t desDevType;        // 升级目标设备类型
+    uint32_t desDevSn;          // 升级目标设备SN
+    uint32_t bootVer;           // 升级目标bootloader版本
+    uint32_t ptVer;             // 升级目标的产测版本
+    uint32_t appVer;            // 升级目标的app版本
+    uint8_t updateCode;         // 升级状态码
+    uint32_t reserve;         // 预留
+}__attribute__((packed))updateCmd0x2007;
+
+#define OTA_START_INFO_LEN      sizeof(updateCmd0x1003)
+#define OTA_CONTINUES_INFO_LEN  sizeof(updateCmd0x1004)
+#define OTA_RETRNSMIT_INFO_LEN  sizeof(updateCmd0x1005)
+#define OTA_MASTER_SEND_PKG_SIZE 128 // 主下发每包的大小
+/*---------------------------------------------升级协议结束-------------------------------------*/
+
+extern void ota_repeat_rand_timer(uint8_t status);
+extern void ota_update_master_retransmit(uint8_t *data);
+extern void ota_timer_stop(otaTimeSet *timer);
+extern void set_start_ota_timer(otaTimeSet *timer, uint32_t delay);
+extern void ota_power_up_read_update_status(void);
+extern void ota_master_update_task(uint16_t cmd, uint8_t *data);
+extern void ota_update_slave_task(uint16_t cmd, uint8_t *data, uint8_t len);
+extern void ota_check_update_timer(void);
+extern void ota_update_deal_upstatus(void);
+extern void ota_update_slave_continue_end(uint8_t workMode);
+
+extern void ota_master_init_update_msg_offline(uint16_t rcvdevtype,uint32_t rcvdevsn,uint16_t desdevtype,uint32_t desdevsn,uint8_t firmtype);
+extern uint8_t ota_offline_init(uint32_t addr,uint32_t len);
+extern void ota_offline_proc(void);
+extern void ota_offline_handle(void);
+extern void ota_update_slave_offline(uint8_t *data,uint8_t len);
+extern void master_update_status_rcv(uint8_t *data, uint32_t len);
+extern void ota_start_offline_update(void);
+
+#endif

+ 412 - 0
src/app/public.c

@@ -0,0 +1,412 @@
+#include "public.h"
+#include <string.h>
+#include "public.h"
+#include "air780e.h"
+#include "ota_update.h"
+#include "./agm_board/epprom.h"
+#include "./agm_board/flash.h"
+#include "./agm_board/rtc.h"
+
+
+Up7segData g_up7segData;
+Identity g_iDentity; // 身份信息 主或从
+
+typedef  void (*otafun)(void);				//定义一个函数类型的参数.
+otafun jump2_pt_app;
+
+
+DevMsg g_devMsg;
+DevFirmMsg g_devfirmMsg;
+nodeRun_t g_runNode;
+DevAppVersion g_devAppVer;
+DevPtMsg g_devPtMsg;
+DevResetMsg g_devResetMsg;
+Up7segData g_up7segData;
+LogMsg g_logMsg;
+
+sysCmd1027 g_table1027;
+sysCmd1027 g_temtable1027; // 临时表
+
+void init_dev_msg(void)
+{
+    g_devMsg.devType = DEV_TYPE;
+    g_devMsg.devSn = 0x08;
+}
+
+/*---------------------------------------------------------------------------------
+ *  上电读取UUID
+ * ---------------------------------------------------------------------------------*/
+uint32_t mcuID[4];
+void power_up_read_uuid(void)
+{
+    //memcpy(g_devfirmMsg.uuid,(uint8_t*)(0x1FFFF7E8),12);
+    FLASH_Unlock();
+	FLASH_GetUniqueID(mcuID);
+	FLASH_Lock();
+	memcpy(g_devfirmMsg.uuid,(uint8_t *)mcuID,12);
+	//data_dump("uuid",g_devfirmMsg.uuid,16);
+}
+
+void printf_dev_msg(void)
+{
+    uint8_t i = 0;
+    g_devResetMsg.resetflag = power_up_system_resettype(); // 读取上电的复位类型
+    power_up_read_uuid();
+    printf("dev_type: %04x\r\n",g_devMsg.devType);
+    printf("dev_sn  : %010u\r\n",g_devMsg.devSn);
+    printf("app1Ver : %08x\r\n",g_devAppVer.app1Ver);
+    printf("app2Ver : %08x\r\n",g_devAppVer.app2Ver);
+    printf("app3Ver : %08x\r\n",g_devAppVer.app3Ver);
+    printf("bootVer : %08x\r\n",g_devAppVer.bootVer);
+    printf("ptVer   : %08x\r\n",g_devAppVer.ptVer);
+    printf("resetnum: %u\r\n",g_devResetMsg.resetNum);
+    printf("work_mod: %d\r\n",g_devMsg.workMode);
+    printf("timer   : %u\r\n",RTC_GetCounter());
+    printf("uuid    : ");
+    for(i=0;i<12;i++){
+        printf("%02x ",g_devfirmMsg.uuid[i]);
+    }
+    printf("\r\n");
+
+}
+
+/*-----------------------------------------------------------------------------
+ * 检查设备类型以及SN是否是设备本身的
+ *  返回值 1: 本设备  0: 错误
+ * ----------------------------------------------------------------------------*/
+uint8_t check_dev_type_sn(uint16_t devType, uint32_t devSn)
+{
+    if(devType == g_devMsg.devType){
+        if(devSn == g_devMsg.devSn) return 1;
+        else if(0xFFFFFFFF == devSn) return 1;
+        else return 0;
+    }
+    else return 0;
+}
+uint8_t check_dev_type_sn01(uint16_t devType, uint32_t devSn)
+{
+    if(devType==g_devMsg.devType && devSn==g_devMsg.devSn) return 1;
+    else if((0xFFFFFFFF == devSn) && (0xFFFF ==devType) ) return 1;
+    else if(0xFFFF == devType){
+        if(devSn==g_devMsg.devSn) return 1;
+        else return 0;
+    }
+    else if(0xFFFFFFFF == devSn) {
+        if(devType == g_devMsg.devType) return 1;
+        else return 0;
+    }
+    else return 0;
+
+}
+/*--------------------------------------------------------------------------------
+ *  crc_16 校验
+ * -------------------------------------------------------------------------------*/
+uint16_t crc16_get(uint8_t *data, uint8_t size)
+{
+    uint16_t crc=0;
+    int i;
+    for(i = 0; i < size; i++)
+    {
+        crc += data[i];
+    }
+    return crc;
+}
+uint16_t _crc16_get(uint8_t *_buff,uint32_t _len)
+{
+    uint32_t i,j;
+    uint16_t crc;
+    uint16_t temp;
+
+    crc=(uint16_t)CRC_INIT_VALUE;
+    for(i=0;i<_len;i++) {
+        temp=_buff[i];
+        temp &=0x00FF;
+        crc^=temp;
+
+        for(j=0;j<8;j++) {
+            if((crc&0x0001)!=0x00) {
+                crc>>=1;
+                crc^=0xA001;
+            } else {
+                crc>>=1;
+            }
+        }
+    }
+    return crc;
+}
+
+/*--------------------------------------------------------------------------------
+ *  转义
+ * 帧中除了帧头为 BB 外,不再出现 BB,如果出现 BB 则转义为
+    BA 01;如果出现 BA 则转义为 BA 00;帧长度和校验码都按转义前
+    来计算。
+ * -------------------------------------------------------------------------------*/
+int _ytsf_data_code(uint8_t *buff, uint8_t *len)
+{
+    uint8_t buff_code[128];
+    uint8_t i, tlen = 0;
+
+    for(i = 0;i < *len; i ++){
+        if(buff[i] == 0xba){
+            buff_code[tlen++] = 0xba;
+            buff_code[tlen++] = 0x00;
+        } else if(i&&buff[i] == 0xbb){
+            buff_code[tlen++] = 0xba;
+            buff_code[tlen++] = 0x01;
+        }
+        else{
+            buff_code[tlen++] = buff[i];
+        }
+    }
+    memcpy(buff, buff_code, tlen);
+    *len = tlen;
+    return 0;
+}
+/*--------------------------------------------------------------------------------
+ *  反转义
+ * 帧中除了帧头为 BB 外,不再出现 BB,如果出现 BB 则转义为
+    BA 01;如果出现 BA 则转义为 BA 00;帧长度和校验码都按转义前
+    来计算。
+ * -------------------------------------------------------------------------------*/
+int _ytsf_data_decode(uint8_t *buff, uint8_t *len)
+{
+    uint8_t buff_code[128];
+    uint8_t i, tlen = 0;
+
+    for(i = 0;i < *len; i ++){
+        if((buff[i] == 0xba)&&(buff[i+1] == 0x00)) {
+            buff_code[tlen++] = 0xba;
+            i += 1;
+        } else if((buff[i] == 0xba)&&(buff[i+1] == 0x01)){
+            buff_code[tlen++] = 0xbb;
+            i += 1;
+        }
+        else{
+        buff_code[tlen++] = buff[i];
+        }
+    }
+    memcpy(buff, buff_code, tlen);
+    *len = tlen;
+
+    return 0;
+}
+/*---------------------------------------------------------------------------
+ * 设置升级标志(设置标记高位取反)
+ * 将一个数设置为高八位是第八位的取反
+ * --------------------------------------------------------------------------*/
+uint16_t set_updata_state(uint16_t data)
+{
+    uint16_t temp_data,ret_data = 0;
+    uint16_t temp_h,temp_l;
+    temp_data = data;
+    temp_h = ((~temp_data)<<8)&0xff00;
+    temp_l = temp_data&0x00ff;
+    ret_data = temp_h | temp_l;
+    return ret_data;
+}
+/*-------------------------------------------------------------------------------
+ * 判断升级标志的本体和掩码
+ * 标记高位取反判断
+ * ------------------------------------------------------------------------------*/
+uint8_t updata_state_cmp(uint16_t data)
+{
+    uint8_t ret = 0;
+    uint16_t temp_data;
+    uint8_t temp_h,temp_l;
+    temp_data = data;
+    temp_h = (uint8_t)((temp_data&0xff00)>>8);
+    temp_l = (uint8_t)(temp_data&0x00ff);
+    if((temp_h^temp_l) == 0xff)
+    {
+        ret = 1;
+    }
+    return ret;
+}
+
+//crc32校验
+uint32_t crc_block_data_calculate(uint32_t *buf, uint32_t len)
+{
+    uint32_t i,data;
+    for(i = 0; i < len; i++)
+    {
+        CRC_FeedData32(CRC0, buf[i]);
+    }
+    data = CRC_ReadData32(CRC0);
+    return data;
+}
+
+
+/*--------------------------------------------------------------------------
+ *  读取复位次数
+ * -------------------------------------------------------------------------*/
+void epprom_read_reset_num(void)
+{
+    uint32_t resetnum = 0;
+    epprom_read(DEV_RESET_NUM,(uint8_t*)&resetnum,4);
+    g_devResetMsg.resetNum = resetnum;
+}
+
+/*----------------------------------------------------------------------------
+ *  初始化、读取 、 写入 路由表到EPPROm中
+ * ---------------------------------------------------------------------------*/
+void epprom_init_config_table(void)
+{
+    uint8_t buff[128] = {0};
+
+    g_runNode.slaveNum = 0x00;
+    memset(g_runNode.nodMsg,0,sizeof(nodeMsg_t));
+    epprom_write((uint32_t)CONFIGTABLE_ADDR,buff,128);
+}
+void epprom_read_config_table(void)
+{
+    uint8_t buff[128] = {0},len,i;
+    uint8_t *pbuff = buff;
+    nodeMsg_t *pNode = NULL;
+    uint16_t devtype;
+    uint32_t devsn;
+    epprom_read((uint32_t)CONFIGTABLE_ADDR,&g_runNode.slaveNum,1); // 读取从设备的个数
+    printf("config_table_num = %d\n",g_runNode.slaveNum);
+    if(g_runNode.slaveNum >16) return;
+    len = g_runNode.slaveNum*8+1;
+
+    epprom_read((uint32_t)CONFIGTABLE_ADDR,buff,len);
+
+    pbuff++;
+    for(i=0;i<g_runNode.slaveNum;i++){
+        pNode = &g_runNode.nodMsg[i];
+        memcpy(&devtype,pbuff,2);
+        pNode->devType = devtype;
+        pbuff += 2;
+        memcpy(&devsn,pbuff,4);
+        pNode->devSn = devsn;
+        pbuff += 4;
+        pbuff += 2; // 预留
+        if((pNode->devType == g_devMsg.devType) &&(pNode->devSn == g_devMsg.devSn)){
+            pNode->bSelf = 1;
+				pNode->status = 1;
+			}
+        else {
+				pNode->bSelf = 0;
+				pNode->status = 0;
+			}
+        pNode->readCount = 0;
+        printf("slave_table type = %04x, sn = %010u bself=%d\r\n",pNode->devType,pNode->devSn,pNode->bSelf);
+    }
+}
+void epprom_write_config_table(uint8_t *data, uint8_t len)
+{
+    epprom_write((uint32_t)CONFIGTABLE_ADDR,data,len);
+}
+/*-----------------------------------------------------------------------------------------
+ *  com 端的配置文件的初始化 读取 写入
+ * ----------------------------------------------------------------------------------------*/
+void epprom_init_com_config(void)
+{
+
+}
+void epprom_read_com_config(void)
+{
+
+
+}
+void epprom_write_com_config(uint8_t *data, uint8_t len)
+{
+    epprom_write((uint32_t)COMM_CONFIG_ADDR,data,len);
+}
+/*-----------------------------------------------------------------------------------------
+ *  探针板的管脚的配置文件的初始化 读取 写入
+ * ----------------------------------------------------------------------------------------*/
+void epprom_init_pin_config(void)
+{
+    memset(&g_table1027,0,sizeof(sysCmd1027));
+}
+void epprom_read_pin_config(void)
+{
+    epprom_read((uint32_t)PIN_CONFIG_ADDR,(uint8_t*)&g_table1027,sizeof(sysCmd1027));
+    printf("table msg pointDev = 0x%04x,group = %d\n",g_table1027.appointDevModel,g_table1027.groupNum);
+}
+void epprom_write_pin_config(uint8_t *data, uint16_t len)
+{
+    epprom_write((uint32_t)PIN_CONFIG_ADDR,data,len);
+}
+/*-----------------------------------------------------------------
+ *  读取设备的基本信息
+ * ----------------------------------------------------------------*/
+void epprom_read_dev_app_version(void)
+{
+    epprom_read((uint32_t)DEV_APP_VER,(uint8_t*)&g_devAppVer,sizeof(DevAppVersion));
+    if(g_devAppVer.app1Ver != APP_VERSION){
+        g_devAppVer.app1Ver = APP_VERSION;
+        epprom_write((uint32_t)DEV_APP_VER,(uint8_t*)&g_devAppVer,sizeof(DevAppVersion));
+    }
+}
+void eeprom_read_mqtt_msg(void)
+{
+    epprom_read((uint32_t)DEV_READ_MQTT_MSG,(uint8_t*)&g_mqttMsg,sizeof(MqttMsg));
+
+}
+void eeprom_write_mqtt_msg(uint8_t *msg,uint16_t len)
+{
+    g_mqttCHmsg.mqttMsg.flag = 1;
+    epprom_write((uint32_t)DEV_READ_MQTT_MSG,(uint8_t*)msg,len);
+
+}
+/*----------------------------------------------------
+ *  工作模式
+ * ----------------------------------------------------*/
+void reset_work_mode(void)
+{
+    if(g_devPtMsg.binit == 0x01){
+        g_devMsg.workMode = WORK_NORMAL;
+        g_devMsg.ledgreen = 1;
+        g_devMsg.ledred = 0;
+    }
+    else{
+        g_devMsg.ledgreen = 3;
+        g_devMsg.ledred = 1;
+        g_devMsg.workMode = WORK_NOINIT;
+    }
+}
+
+/*------------------------------------------------------------------------------------------
+ *  上电读取设备类型
+ * -----------------------------------------------------------------------------------------*/
+void epprom_power_up_deal(void)
+{
+    uint8_t num = 0;
+    epprom_read_dev_app_version();
+
+    num = (g_devAppVer.app1Ver&0x03);
+    g_devMsg.ledred = (num == 0) ? 4: num;
+    g_devMsg.ledgreen = 4;
+
+	epprom_read(0,(uint8_t*)&g_devPtMsg,sizeof(DevPtMsg));
+
+	g_devMsg.devType = DEV_TYPE;//g_devPtMsg.devType1;
+	g_devMsg.devSn   = g_devPtMsg.devSn;
+
+
+    epprom_read_reset_num();
+    epprom_read_config_table(); // 上电时不需要读取路由表,收到是主的身份时再读取
+   // epprom_read_pin_config();
+
+    start_delay_ms(3000);
+    do{
+        if((g_devMsg.ledgreen == 0x06)) break;
+    }while(!g_iDelayfinish);
+    stop_delay_ms();
+
+    if(g_devPtMsg.binit == 0x01){
+        g_devMsg.workMode = WORK_NORMAL;
+        g_devMsg.ledgreen = 1;
+        g_devMsg.ledred = 0;
+    }
+    else{
+        g_devMsg.ledgreen = 3;
+        g_devMsg.ledred = 1;
+        g_devMsg.workMode = WORK_NOINIT;
+    }
+}
+
+
+

+ 180 - 0
src/app/public.h

@@ -0,0 +1,180 @@
+#ifndef _PUBLIC_H_
+#define _PUBLIC_H_
+#include "board.h"
+#include "dn_4g.h"
+#include "./agm_board/timeout.h"
+
+extern sysCmd1027 g_table1027;
+extern sysCmd1027 g_temtable1027; // 临时表
+
+#define DEV_TYPE 0x0104
+#define APP_VERSION 0x01043004
+
+
+#define BROADCAST_SN   0xFFFFFFFF // 广播地址
+#define BROADCAST_TYPE 0xFFFF     // 广播设备类型
+
+#define CRC_INIT_VALUE 0x0000
+
+enum { // workMode
+    WORK_NOINIT = 0x01,  // 未初始化模式
+    WORK_NORMAL = 0x02,  // 正常模式
+    WORK_UPDATE = 0x03,  // 升级模式
+
+};
+enum {
+    B4G_NOHAVE = 0x00, // 无4G模块
+    B4G_HAVE = 0x01,   // 有4G模块
+};
+typedef struct _dev_msg_{
+    uint16_t devType;   // 主设备类型
+    uint32_t devSn;     // 主设备SN
+    uint16_t devTypeS;  // 从设备类型
+    uint32_t devSnS;    // 从设备SN
+    uint8_t  bHave4G;   // 是否有4G模块
+    uint8_t  baskIdentity; // 是否询问自己的身份
+    uint8_t workMode;
+    uint8_t ledred; // 红灯状态
+    uint8_t ledgreen; //绿灯状态
+}__attribute__((packed))DevMsg;
+extern DevMsg g_devMsg;
+
+typedef struct _dev_firm_msg_{
+    uint32_t bootVer;   // bootloader版本
+    uint32_t ptVer;     // pt版本
+    uint32_t appVer;    // app版本
+    uint8_t uuid[12];   // UUID
+
+}__attribute__((packed))DevFirmMsg;
+extern DevFirmMsg g_devfirmMsg;
+
+
+
+#define NODE_MAX_SIZE 8
+#define OFF_LINE_COUNT  5 // 5次读取不到,则判断为离线
+typedef struct _node_msg_{
+    uint16_t devType;
+    uint32_t devSn;
+    uint8_t status;
+    uint8_t readCount; // 读取次数
+    uint8_t bSelf;     // 是自己的设备类型和SN
+}__attribute__((packed))nodeMsg_t;
+
+typedef struct _node_run_info_{
+    nodeMsg_t nodMsg[NODE_MAX_SIZE];
+    uint8_t nIndex;
+    uint8_t slaveNum; // 从的个数
+}__attribute__((packed))nodeRun_t;
+extern nodeRun_t g_runNode;
+
+#define TIME_SING_N 10*60*1000 // 信号采样率的时候 10分钟读取一次
+
+typedef struct _log_msg_{
+    uint8_t blogOpen;
+    timeout_t logtime;
+    timeout_t singTime; //信号采样率的间隔时间
+    timeout_t tsingTime; // 信号采样率的总时间
+    uint8_t singOpen;   // 信号采样率是否开起
+    uint16_t devType;
+    uint32_t devSn;
+}__attribute__((packed))LogMsg;
+extern LogMsg g_logMsg;
+
+typedef struct _up_7seg_src_data_{
+    uint8_t bOpen;    // 是否开启 1:开启
+    uint8_t bAppointDev; // 是否指定的一个设备 0:否, 1:指令的设备为主 2:指定的设备为从
+    uint8_t bofflineTest; // 离线调试,主动上报
+    timeout_t upTime; // 上报的时长
+    uint8_t devMsg[17]; // 读取指令的从设备的8段数据,用于主设备问询从设备
+}__attribute__((packed))Up7segData;
+extern Up7segData g_up7segData;
+
+typedef enum {
+    IDENTITY_SLAVE  = 0x01, // 从设备
+    IDENTITY_MASTER = 0x02, // 主设备
+}Identity;
+extern Identity g_iDentity; // 身份信息 主或从
+
+typedef struct _dev_reset_msg_{
+    uint8_t resetflag;
+    uint32_t resetNum;
+}__attribute__((packed))DevResetMsg;
+extern DevResetMsg g_devResetMsg;
+typedef struct _dev_pt_msg_{
+    uint16_t firstPowerUp;      // 是否为第一次上电 0x5A5A 说明已经上过电
+    uint8_t  eepromVer;         // eeprom 的版本
+    uint8_t  binit;             // 是否初始化
+    uint32_t devSn;             // 设备SN
+    uint16_t devType1;          // 设备类型
+    uint16_t  devfactory;        // 设备厂家信息
+    uint16_t seqNo ; // 生产批次号
+    uint32_t data; // 生产日期
+    uint8_t pcbVersion; // 硬件(PCB)版本
+    uint32_t sqare; //备用
+}__attribute__((packed))DevPtMsg;
+extern DevPtMsg g_devPtMsg;
+typedef struct _dev_app_version_{
+    uint32_t bootVer;
+    uint32_t ptVer;
+    uint32_t app1Ver;
+    uint32_t app2Ver;
+    uint32_t app3Ver;
+}__attribute__((packed))DevAppVersion;
+extern DevAppVersion g_devAppVer;
+
+typedef uint32_t  u32;
+typedef uint16_t u16;
+typedef uint8_t  u8;
+
+typedef const uint32_t uc32;  /*!< Read Only */
+typedef const uint16_t uc16;  /*!< Read Only */
+typedef const uint8_t uc8;   /*!< Read Only */
+
+typedef __IO uint32_t  vu32;
+typedef __IO uint16_t vu16;
+typedef __IO uint8_t  vu8;
+
+typedef __I uint32_t vuc32;  /*!< Read Only */
+typedef __I uint16_t vuc16;  /*!< Read Only */
+typedef __I uint8_t vuc8;   /*!< Read Only */
+
+
+
+extern void init_dev_msg(void);
+extern uint8_t check_dev_type_sn(uint16_t devType, uint32_t devSn);
+extern uint8_t check_dev_type_sn01(uint16_t devType, uint32_t devSn);
+extern uint16_t crc16_get(uint8_t *data, uint8_t size);
+extern uint16_t _crc16_get(uint8_t *_buff,uint32_t _len);
+extern int _ytsf_data_code(uint8_t *buff, uint8_t *len);
+extern int _ytsf_data_decode(uint8_t *buff, uint8_t *len);
+extern void printf_dev_msg(void);
+
+extern uint16_t set_updata_state(uint16_t data);
+extern uint8_t updata_state_cmp(uint16_t data);
+
+extern void epprom_read_reset_num(void);
+
+extern void epprom_init_config_table(void);
+extern void epprom_read_config_table(void);
+extern void epprom_write_config_table(uint8_t *data, uint8_t len);
+
+
+extern void epprom_init_com_config(void);
+extern void epprom_read_com_config(void);
+extern void epprom_write_com_config(uint8_t *data, uint8_t len);
+
+
+extern void epprom_init_pin_config(void);
+extern void epprom_read_pin_config(void);
+extern void epprom_write_pin_config(uint8_t *data, uint16_t len);
+
+extern void eeprom_read_mqtt_msg(void);
+extern void eeprom_write_mqtt_msg(uint8_t *msg, uint16_t len);
+
+extern void epprom_power_up_deal(void);
+
+
+extern void reset_work_mode(void);
+extern uint32_t crc_block_data_calculate(uint32_t *buf, uint32_t len);
+
+#endif

+ 471 - 0
src/app/taskOpt.c

@@ -0,0 +1,471 @@
+#include "taskOpt.h"
+//#include "xspDataOpt.h"
+#include "masterslave.h"
+#include "up_4g.h"
+timeout_t g_upstatusTime; // 上报状态的时间
+timeout_t g_upfirmTime;  // 上报固件信息的时间
+
+taskRunData g_taskRunDa;
+
+void init_run_data(void)
+{
+    //uint8_t i;
+    if(g_iDentity == IDENTITY_SLAVE) return;
+    timeout_setValue(&g_uart485.time,2000); // 发送延时
+    timeout_setValue(&g_upstatusTime,READ_STATUS_TIME); // 读取状态的时间
+    timeout_setValue(&g_upfirmTime,READ_FIRME_TIME); // 读取固件的时间
+    timeout_setValue(&g_logMsg.singTime,TIME_SING_N); // 读取信号采样率 10 分钟读取一次
+    timeout_setValue(&g_taskRunDa.delayRead,300);
+    g_taskRunDa.breadstatus = 1;
+    g_taskRunDa.breadfirmmsg = 1;
+}
+/*------------------------------------------------------------------------------
+ *  有4G模块的设备,且连接网络的状态下,上电要询问自己的身份
+ * -----------------------------------------------------------------------------*/
+void ask_oneself_for_identity(void)
+{
+    uint8_t sendbuff[128],len,ret;
+    if((0x01 == g_devMsg.baskIdentity)&&(B4G_HAVE == g_devMsg.bHave4G) && (1 == g_4gMsg.bconnect)){
+        memset(sendbuff,0,sizeof(sendbuff));
+        up_system_cmd_0x2041(sendbuff,&len);
+        ret = add_data_to_4G_txfifo(sendbuff,len,0x01,0x2041);
+        if(1 == ret) g_devMsg.baskIdentity = 0x00;
+        printf("4g mode ask own identity\r\n");
+    }
+
+    return;
+}
+
+/*-----------------------------------------------------------------------
+ * 主读取自己的加油数据,存入到4G的发送fifo中
+ * -----------------------------------------------------------------------*/
+//void master_deal_flash_data_to_4Grxfifo(void)
+//{
+//    uint8_t ret;
+//    XspDataInfo xspda;
+
+//    ret = read_flash(xspda.data,1);
+//    if(ret==1){
+//        printf("发送数据到服务器:recordId=%d,amount=%d,oil=%d,tamout=%lld,toil=%lld\r\n",\
+//               xspda.reDa.recordId,xspda.reDa.amount,xspda.reDa.oil,\
+//               xspda.reDa.tamount,xspda.reDa.toil);
+//    }
+//}
+
+/*------------------------------------------------------------------------
+ *  读取从的数据
+ * -----------------------------------------------------------------------*/
+void master_read_slave_data(void)
+{
+
+}
+/*-------------------------------------------------------------------------
+ *  读取从的状态
+ * -------------------------------------------------------------------------*/
+uint8_t master_read_slave_status(void)
+{
+    static uint8_t index = 0,bsendMaster = 0;
+    nodeMsg_t *nodeMsg = NULL;
+
+    if(0 == bsendMaster){
+        master_add_status_to_4g_txfifo(0x02,0x2002,g_devMsg.devType,g_devMsg.devSn, SELF_STATUS);
+        bsendMaster = 1;
+    }
+
+    if(1 == g_runNode.nodMsg[index].bSelf) {
+        index++;
+    }
+    if(((index != 0) && ((index%g_runNode.slaveNum)==0))||(g_runNode.slaveNum==0)){ // 一圈的状态读取完成
+        g_taskRunDa.breadstatus = 0;
+        timeout_start(&g_upstatusTime);
+        printf("读取状态信息 0x1002 完成\r\n");
+        index = 0;
+        bsendMaster = 0;
+        return 1;
+    }
+
+    if((0 == g_runNode.nodMsg[index].status) ){//||(3 == g_uart485.time.endMode)
+        g_devMsg.devTypeS = g_runNode.nodMsg[index].devType;
+        g_devMsg.devSnS   = g_runNode.nodMsg[index].devSn;
+        if(g_runNode.nodMsg[index].bSelf !=1)master_add_status_to_4g_txfifo(0x02,0x2002,g_devMsg.devTypeS,g_devMsg.devSnS, SLAVE_OFFLINE);
+        index++;
+    }
+    else {
+        printf("读取状态信息 0x1002\r\n");
+        nodeMsg = &g_runNode.nodMsg[index];
+        g_devMsg.devTypeS = nodeMsg->devType;
+        g_devMsg.devSnS   = nodeMsg->devSn;
+        master_read_status(0x1002,&g_devMsg);
+        timeout_start(&g_uart485.time);
+        index++;
+    }
+    return 0;
+
+
+}
+/*--------------------------------------------------------------------------
+ *  读取从的固件信息
+ * -------------------------------------------------------------------------*/
+void master_read_slave_firmmsg(void)
+{
+    static uint8_t index = 0,bsendMaster=0;
+    nodeMsg_t *nodeMsg = NULL;
+
+    if(0 == bsendMaster){
+        master_add_status_to_4g_txfifo(0x02,0x2001,g_devMsg.devType,g_devMsg.devSn,SELF_STATUS);
+        bsendMaster = 1;
+    }
+    if(1 == g_runNode.nodMsg[index].bSelf) {
+        index++;
+    }
+    if((index != 0 && index%g_runNode.slaveNum==0)||(g_runNode.slaveNum==0)){ // 一圈的状态读取完成
+        g_taskRunDa.breadfirmmsg = 0;
+        timeout_start(&g_upfirmTime);
+        printf("读取状态信息 0x1001 完成\r\n");
+        index = 0;
+        bsendMaster = 0;
+        return ;
+    }
+    printf("读取状态信息 0x1001\r\n");
+    nodeMsg = &g_runNode.nodMsg[index];
+    g_devMsg.devTypeS = nodeMsg->devType;
+    g_devMsg.devSnS   = nodeMsg->devSn;
+    master_read_status(0x1001,&g_devMsg);
+    timeout_start(&g_uart485.time);
+    index++;
+
+    return ;
+}
+
+/*------------------------------------------------------------------------
+ *  读取信号采样率
+ *-------------------------------------------------------------------------*/
+void read_sing_ratio(void)
+{
+    static uint8_t index = 0;
+    nodeMsg_t *nodeMsg = NULL;
+
+    if(1 == g_runNode.nodMsg[index].bSelf) {
+        index++;
+    }
+
+    if(g_logMsg.singOpen == 0x00) {
+
+        if((index != 0 && index%g_runNode.slaveNum==0)||(g_runNode.slaveNum==0)){ // 一圈的状态读取完成
+            timeout_start(&g_logMsg.singTime);
+            printf("自动读取 读取信号采样率 1063 完成\n");
+            index = 0;
+            return ;
+        }
+        printf("自动 读取信号采样率 1063  index = %d\n",index);
+        nodeMsg = &g_runNode.nodMsg[index];
+        g_devMsg.devTypeS = nodeMsg->devType;
+        g_devMsg.devSnS   = nodeMsg->devSn;
+        master_read_log_0x1063(&g_devMsg);
+        timeout_start(&g_uart485.time);
+        index++;
+
+    }
+    else if(g_logMsg.singOpen == 1 ){
+        if(!timeout_isOut(&g_logMsg.tsingTime)) {
+            if(timeout_isOut(&g_logMsg.singTime)){
+                printf("指令读取 1063 指令\n");
+                g_devMsg.devTypeS =g_logMsg.devType;
+                g_devMsg.devSnS   = g_logMsg.devSn;
+                master_read_log_0x1063(&g_devMsg);
+                timeout_start(&g_uart485.time);
+                timeout_start(&g_logMsg.singTime);
+            }
+        }
+        else {
+            g_logMsg.singOpen = 0;
+            timeout_setValue(&g_logMsg.singTime,TIME_SING_N);
+            timeout_start(&g_logMsg.singTime);
+        }
+    }
+
+
+}
+/*-----------------------------------------------------------------------------------
+ *  主处理4G的接收数据
+ *  先解析 计算校验,再根据type1的类型处理数据
+ * ----------------------------------------------------------------------------------*/
+void master_deal_4g_rx_data(void)
+{
+    uint8_t buff[256], bufflen;
+    uint16_t crc,fcrc;
+    netMsgFormat * msg = (netMsgFormat*)buff;
+
+
+    if(fifo_is_empty(&g_4Grxfifo)== true) return; // 4G fifo为空
+
+    bufflen = fifo_read(&g_4Grxfifo,buff);
+
+    if(msg->palen > 256) return;
+    if(msg->start != 0xFEFE) return;
+    crc = _crc16_get(buff,msg->palen+NET_HEAD_LEN-2);
+    fcrc = msg->info[msg->palen-1];
+    fcrc = (fcrc<<8) | msg->info[msg->palen-2];
+    if(crc != fcrc) {printf("dn_4g crc error\r\n"); return;}
+    printf("收到 4G 类型:0x%x, 指令: 0x%x\r\n",msg->msgType1,msg->msgType2);
+    switch (msg->msgType1) {
+    case 0x01: // 系统类
+        dn_4g_system_cmd(msg->msgType2,buff,bufflen);
+        break;
+    case 0x02: // 状态类
+
+        break;
+    case 0x03: // 数据类
+        dn_4g_data_cmd(msg->msgType2,buff,bufflen);
+        break;
+    case 0x04: // 升级类
+        dn_4g_update_cmd(msg->msgType2,buff,bufflen);
+        break;
+    case 0x10: // 异常类
+        dn_4g_log_cmd(msg->msgType2,buff,bufflen);
+        break;
+    default:
+        break;
+    }
+}
+/*-----------------------------------------------------------------------------------
+ *  主处理4G的发送fifo
+ * ----------------------------------------------------------------------------------*/
+void master_deal_4g_tx_data(void)
+{
+    uint8_t buff[256],len;
+
+    if(B4G_NOHAVE == g_devMsg.bHave4G) return;
+
+    if(fifo_is_empty(&g_4Gtxfifo) == true) return ;// 发送fifo为空
+    printf("发送4G数据到服务器\r\n");
+    len = fifo_read(&g_4Gtxfifo,buff);
+    data_dump("4g-data-to-server",buff,len);
+    send_data_to_mqtt(0x00,buff,len);
+}
+/*------------------------------------------------------------------------
+ *  主处理485的 发送fifo
+ *  用于服务器下发指令读取从的数据
+ *  没有数据发送时返回为1  有数据发送时,返回为0
+ * -----------------------------------------------------------------------*/
+uint8_t master_deal_485_tx_fifo(void)
+{
+    FIFO_T *fifo = &g_txfifo;
+    if(fifo_is_empty(fifo) == true) return 1; // fifo为空时,退出
+    printf("发送485 tx fifo 中的数据\r\n");
+    uart_msg_send(UART2_ID,fifo->memory[fifo->front].da,fifo->memory[fifo->front].len);
+    fifo->memory[fifo->front].len = 0;
+    fifo->front++;
+    fifo->front %= MAXSIZE;
+    if (fifo->front == fifo->rear) // 设置队列为空
+        fifo->flag = false;
+
+    return 0;
+}
+/*-------------------------------------------------------------------------
+ *  设备有4G模块,不管主设备或从设备都要上报自己的状态信息
+ * ------------------------------------------------------------------------*/
+void dev_4g_up_status_to_server(void)
+{
+    if(IDENTITY_MASTER == g_iDentity) return;
+    if((B4G_HAVE == g_devMsg.bHave4G)&& timeout_isOut(&g_upstatusTime)){
+            master_add_status_to_4g_txfifo(0x02,0x2002,g_devMsg.devType,g_devMsg.devSn, SELF_STATUS);
+            //bsendMsg &= (~0x01);
+            //if(IDENTITY_SLAVE == g_iDentity)
+                timeout_start(&g_upstatusTime);
+    }
+    if((B4G_HAVE == g_devMsg.bHave4G) && timeout_isOut(&g_upfirmTime)){ // 有4G模块,不管是主从,都需要上报自己的状态
+        master_add_status_to_4g_txfifo(0x02,0x2001,g_devMsg.devType,g_devMsg.devSn,SELF_STATUS);
+        //bsendMsg &= (~0x02);
+        //if(IDENTITY_SLAVE == g_iDentity)
+            timeout_start(&g_upfirmTime);
+    }
+
+}
+/*------------------------------------------------------------
+ *  判断配置文件是否过期
+ * -----------------------------------------------------------*/
+void config_file_is_timeout(void)
+{
+    if(1 == g_taskRunDa.bcfgfiletime) {
+        if(timeout_isOut(&g_taskRunDa.cfigFileTime)){
+            epprom_read_pin_config();
+            g_taskRunDa.bcfgfiletime = 0;
+        }
+    }
+}
+
+/*-----------------------------------------------------------
+ * 8段码测试模式
+ * ----------------------------------------------------------*/
+void open_8seg_test_mode(void)
+{
+    uint8_t ret  = 0,index;
+    uint16_t devtypeS;
+    uint32_t devSnS;
+    if(!timeout_isOut(&g_uart485.time)) return;
+    if(!timeout_isOut(&g_taskRunDa.delayRead)) return;
+
+
+    ret = master_deal_485_tx_fifo();
+    if(ret == 0) { // 485发送fifo有发送数据
+        timeout_start(&g_uart485.time);
+        return;
+    }
+
+    if(!timeout_isOut(&g_up7segData.upTime)){
+        if(g_up7segData.bAppointDev == 2){
+            memcpy(&devtypeS,&g_up7segData.devMsg[6],2);
+            memcpy(&devSnS,&g_up7segData.devMsg[8],4);
+            g_devMsg.devTypeS = devtypeS;
+            g_devMsg.devSnS = devSnS;
+            master_read_data_0x1030(&g_devMsg);
+        }
+        else { // 主从都有
+            index = g_runNode.nIndex;
+            if(1 == g_runNode.nodMsg[index].bSelf){
+                g_runNode.nIndex = (++g_runNode.nIndex)%g_runNode.slaveNum;
+                return;
+            }
+        }
+        timeout_start(&g_uart485.time);
+    }
+    else {
+        g_up7segData.bOpen = 0;
+        g_up7segData.bAppointDev = 0;
+    }
+}
+
+/*-----------------------------------------------------------------------
+ *  如果为主,则循环读取从的数据
+ * -----------------------------------------------------------------------*/
+void master_work_loop(void)
+{
+    uint8_t index;
+    uint8_t ret = 0;
+    if(!timeout_isOut(&g_uart485.time)) return;
+    if(!timeout_isOut(&g_taskRunDa.delayRead)) return;
+    ret = master_deal_485_tx_fifo();
+    if(ret == 0) { // 485发送fifo有发送数据
+        timeout_start(&g_uart485.time);
+        return;
+    }
+    if(IDENTITY_MASTER != g_iDentity) return;
+    if(g_taskRunDa.breadstatus == 1 || timeout_isOut(&g_upstatusTime)){ // 读取状态
+        master_read_slave_status();
+    }
+    else if(g_taskRunDa.breadfirmmsg == 1 || timeout_isOut(&g_upfirmTime)){ // 读取固件
+        master_read_slave_firmmsg();
+    }
+    else if(timeout_isOut(&g_logMsg.singTime)){
+        read_sing_ratio();
+    }
+    else { // 读取交易数据
+
+        if(1 == g_up7segData.bOpen) return;
+        if(g_4gMsg.bconnect == 0) return; // 4G 没有连接上网络则不读取交易数据
+
+        if(g_runNode.slaveNum == 0 ) return;
+
+        index = g_runNode.nIndex;
+        if(1 == g_runNode.nodMsg[index].bSelf){
+            g_runNode.nIndex = (++g_runNode.nIndex)%g_runNode.slaveNum;
+            return;
+        }
+        g_devMsg.devTypeS = g_runNode.nodMsg[index].devType;
+        g_devMsg.devSnS   = g_runNode.nodMsg[index].devSn;
+        g_runNode.nodMsg[index].readCount++;
+        if(g_runNode.nodMsg[index].readCount>5){
+            g_runNode.nodMsg[index].status = 0;
+            g_runNode.nodMsg[index].readCount = 0;
+        }
+        printf("读取 0x03-1061,index = %d\r\n",index);
+        /*if(1 == g_taskRunDa.keyReadcurData) master_read_data_0x1061(&g_devMsg,0xFFFFFFFF);
+        else */
+        master_read_data_0x1061(&g_devMsg,0);
+        timeout_start(&g_uart485.time);
+        g_runNode.nIndex = (++g_runNode.nIndex)%g_runNode.slaveNum;
+        if(g_runNode.nIndex == 0) {
+            g_taskRunDa.keyReadcurData = 0;
+        }
+    }
+}
+
+
+/*------------------------------------------------------------------------
+ *  主 从  解析485的接收fifo
+ * -----------------------------------------------------------------------*/
+void analysis_485_rx_fifo(void)
+{
+    uint8_t readBuf[256],readlen;
+    uint16_t crc,fcrc,randDa,devtype;
+    uint32_t devsn;
+
+    MasterSlave *msg = (MasterSlave*)readBuf;
+
+    if(fifo_is_empty(&g_rxfifo) == true) return;
+    readlen = fifo_read(&g_rxfifo,readBuf);
+
+    if(0x01 == g_updateDa.bResetUpdate){
+        randDa = rand()%100 + 200;
+        printf("随机时间 = %d\r\n",randDa);
+        set_start_ota_timer(&g_otaTimer.randomTmr,randDa);
+    }
+    if(g_updateDa.Work_State == OTA_UPDATE_REPEAT && g_updateDa.retransmit_s == 0)//重传阶段
+    {
+        ota_repeat_rand_timer(1);//重传随机延时
+    }
+
+    // if(msg->start != 0xfefe) {
+    //     if(strstr(readBuf,"AT+PTMOD=ON\r\n")){
+    //         run_app(); // 判断是否进入产测执行
+    //         return;
+    //     }
+
+    // }
+    crc = _crc16_get(readBuf,msg->palen+COMM_HEAD_LEN-2);
+    fcrc = msg->comInfo.info[msg->palen-1];
+    fcrc = (fcrc<<8) | msg->comInfo.info[msg->palen-2];
+    if(fcrc != crc ) return;
+    if((0x2000 == (msg->msgType2&0x2000))) { // 要考虑离线升级和升级的指令????
+        if(WORK_UPDATE == g_devMsg.workMode){ // 升级模式
+            if(IDENTITY_SLAVE == g_iDentity) return; //
+        }
+        else {
+            if(B4G_NOHAVE== g_devMsg.bHave4G) {
+                return;
+            }
+            else {
+                memcpy(&devsn,&msg->comInfo.info[2],4);
+                memcpy(&devtype,&msg->comInfo.info[0],2);
+                if((g_devMsg.devSn != devsn) \
+                    && (g_devMsg.devType != devtype)){
+                    printf("收到2000指令,设备类型和SN不匹配\r\n");
+                    return;
+                }
+            }
+        }
+    }
+    //data_dump("收到数据",readBuf,readlen);
+    printf("收到指令 %0d-%0x\r\n",msg->msgType1,msg->msgType2);
+    switch(msg->msgType1){
+    case 0x01: // 系统指令
+        analysis_cmd_system(msg->msgType2,readBuf,readlen);
+        break;
+    case 0x02: // 状态指令
+        analysis_cmd_status(msg->msgType2,readBuf,readlen); // 直接透传
+        break;
+    case 0x03: // 数据指令
+        analysis_cmd_data(msg->msgType2,readBuf,readlen);
+        break;
+    case 0x04: // 升级指令
+        analysis_cmd_update(msg->msgType2,readBuf,readlen);
+        break;
+    case 0x10: // 日志指令
+        analysis_cmd_log(msg->msgType2,readBuf,readlen);
+        break;
+    }
+    if(msg->msgType1 != 0x04){
+        timeout_start(&g_taskRunDa.delayRead);
+    }
+}

+ 41 - 0
src/app/taskOpt.h

@@ -0,0 +1,41 @@
+#ifndef _TASK_H_
+#define _TASK_H_
+
+#include "board.h"
+#include "public.h"
+#include "air780e.h"
+#include "dn_4g.h"
+#include "ota_update.h"
+
+#define READ_STATUS_TIME 1000*60  // 状态读取时间,1分钟
+#define READ_FIRME_TIME  1000*60*3 // 读取固件信息的时间 3分钟
+typedef struct task_run_data_{
+    uint8_t workMode; // 当前的工作模式 初始化4G 正常工作  升级
+    uint8_t breadstatus; // 读取 状态
+    uint8_t breadfirmmsg; // 读取固件信息
+    uint8_t bcfgfiletime;  // 配置文件的时间是否已经过期
+    uint8_t bcomfiletime;  //com文件的时间是否已经过期
+    timeout_t cfigFileTime; // 配置文件的过期时间
+    timeout_t comFileTime;  // com 文件的过期时间
+    uint32_t timetamp;       // 时间戳
+    uint8_t keyReadcurData;  // 按键读取当前显示屏的值
+    uint8_t keySaveMasterDa;  // 主存储显示数据到flash中
+    timeout_t delayRead;       // 延时读取
+}__attribute__((packed))taskRunData;
+extern taskRunData g_taskRunDa;
+
+
+extern void power_up_read_comm_min_time(void);
+extern void ask_oneself_for_identity(void);
+extern void dev_4g_up_status_to_server(void);
+extern void open_8seg_test_mode(void);
+extern void config_file_is_timeout(void);
+
+extern void init_run_data(void);
+extern void master_work_loop(void);
+
+extern void master_deal_4g_rx_data(void);
+extern void master_deal_4g_tx_data(void);
+extern void analysis_485_rx_fifo(void);
+
+#endif

+ 108 - 0
src/app/up_4G.c

@@ -0,0 +1,108 @@
+#include "up_4g.h"
+#include "public.h"
+
+void up_system_cmd_0x2041(uint8_t *outdata, uint8_t *len)
+{
+    systemCmd0x2041 *msg = (systemCmd0x2041*)outdata;
+
+    msg->devType = g_devMsg.devType;
+    msg->devSn   = g_devMsg.devSn;
+    msg->reserve = 0x00;
+    *len = sizeof(systemCmd0x2041);
+    return;
+}
+
+
+void up_system_cmd_0x2025(uint8_t *data, uint8_t *len, uint16_t devType, uint32_t devSn)
+{
+    systemCmd0x2025 *msg = (systemCmd0x2025*)data;
+
+    msg->devSn = g_devMsg.devSn;
+    msg->devType = g_devMsg.devType;
+    msg->targetSn = devSn;
+    msg->targetType = devType;
+    msg->reserve = 0x00;
+    *len = sizeof(systemCmd0x2025);
+
+    return;
+}
+void up_system_cmd_0x2030(uint8_t *data,uint8_t *seg8data,uint8_t *cfgfile, uint8_t *len)
+{
+    systemCmd0x2030 *msg = (systemCmd0x2030*)data;
+
+
+    msg->devTypeM = g_devMsg.devType;
+    msg->devSnM  = g_devMsg.devSn;
+    msg->devTypeS = g_devMsg.devType;
+    msg->devSnS = g_devMsg.devSn;
+    memcpy(msg->cfgfileNo,cfgfile,8);// = bnew;
+    msg->reserve = 0;
+
+    memcpy(msg->para,seg8data,28);
+
+    *len = sizeof(systemCmd0x2030);
+
+    return;
+}
+
+void up_update_cmd_0x2001(uint8_t *outdata, uint8_t *len,uint16_t taskId)
+{
+    updateCmd0x2001 *msg = (updateCmd0x2001*)outdata;
+
+    msg->devType = g_devMsg.devType;
+    msg->devSn   = g_devMsg.devSn;
+    msg->appVer  = APP_VERSION;
+    msg->taskId  = taskId;
+    msg->reserve = 0x00;
+    *len = sizeof(updateCmd0x2001);
+    return;
+}
+void up_update_cmd_0x2002(uint8_t *outdata, uint8_t *len,uint16_t devType, uint32_t devSn,uint16_t taskId,uint8_t firmType,uint8_t updateCode)
+{
+    updateCmd0x2002 *msg = (updateCmd0x2002*)outdata;
+
+    msg->devSnM = g_devMsg.devSn;
+    msg->devTypeM = g_devMsg.devType;
+    msg->devSnS = devSn;
+    msg->devTypeS = devType;
+    msg->firmType  = firmType;
+    msg->taskId    = taskId;
+    msg->reserve   = 0x00;
+    msg->updateCode = updateCode;
+
+    *len = sizeof(updateCmd0x2002);
+}
+
+
+
+void up_data_cmd_0x2061(uint8_t *outdata, uint8_t *len,uint32_t devSn,uint16_t devType,uint8_t bnewflag,uint8_t *da,uint8_t dalen)
+{
+    dataCmd0x2061 *msg = (dataCmd0x2061*)outdata;
+
+    msg->devTypeM = g_devMsg.devType;
+    msg->devSnM   = g_devMsg.devSn;
+    msg->devTypeS = devType;
+    msg->devSnS   = devSn;
+    msg->reserve  = 0;
+    msg->bnewflag = bnewflag;
+    msg->palen    = dalen;
+    memcpy(msg->para,da,dalen);
+
+    *len = dalen + 18;
+    return;
+}
+void up_data_cmd_0x2062(uint8_t *outdata, uint8_t *len,uint32_t devSn,uint16_t devType,uint8_t *da,uint8_t dalen)
+{
+    dataCmd0x2062 *msg = (dataCmd0x2062*)outdata;
+
+    msg->devTypeM = g_devMsg.devType;
+    msg->devSnM   = g_devMsg.devSn;
+    msg->devTypeS = devType;
+    msg->devSnS   = devSn;
+    msg->reserve  = 0;
+    msg->palen    = dalen;
+    memcpy(msg->para,da,dalen);
+
+    *len = dalen + 17;
+    return;
+}

+ 79 - 0
src/app/up_4g.h

@@ -0,0 +1,79 @@
+#ifndef _DEAL_DATA_4G_H_
+#define _DEAL_DATA_4G_H_
+
+#include "board.h"
+
+typedef struct _system_cmd_0x2041_{
+    uint16_t  devType;  //设备类型
+    uint32_t  devSn;    //设备SN
+    uint32_t  reserve;  //预留
+}__attribute__((packed))systemCmd0x2041;
+typedef struct _system_cmd_0x2025_{ // 路由表上报
+    uint16_t devType;
+    uint32_t devSn;
+    uint16_t targetType;
+    uint32_t targetSn;
+    uint32_t reserve;
+}__attribute__((packed))systemCmd0x2025;
+
+typedef struct _sytem_cmd_0x2030_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t cfgfileNo[8];
+    uint32_t reserve;
+    uint8_t  para[28];
+}__attribute__((packed))systemCmd0x2030;
+
+extern void up_system_cmd_0x2041(uint8_t *outdata, uint8_t *len);
+extern void up_system_cmd_0x2025(uint8_t *data, uint8_t *len, uint16_t devType, uint32_t devSn);
+extern void up_system_cmd_0x2030(uint8_t *data, uint8_t *seg8data, uint8_t *cfgfile, uint8_t *len);
+typedef struct _update_cmd_0x2001_{
+    uint16_t devType;
+    uint32_t devSn;
+    uint32_t appVer;
+    uint16_t taskId;
+    uint32_t reserve;
+}__attribute__((packed))updateCmd0x2001;
+
+typedef struct _update_cmd_0x2002_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint8_t firmType; // 固件类型
+    uint16_t taskId;
+    uint8_t updateCode;
+    uint32_t reserve;
+}__attribute__((packed))updateCmd0x2002;
+
+extern void up_update_cmd_0x2001(uint8_t *outdata, uint8_t *len,uint16_t taskId);
+extern void up_update_cmd_0x2002(uint8_t *outdata, uint8_t *len,uint16_t devType, uint32_t devSn,uint16_t taskId,uint8_t firmType,uint8_t updateCode);
+
+
+typedef struct _data_cmd_0x2061_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint32_t reserve;
+    uint8_t  bnewflag; // 新交易标识
+    uint8_t  palen;
+    uint8_t  para[128];
+}__attribute__((packed))dataCmd0x2061;
+extern void up_data_cmd_0x2061(uint8_t *outdata, uint8_t *len, uint32_t devSn, uint16_t devType, uint8_t bnewflag, uint8_t *da, uint8_t dalen);
+
+
+typedef struct _data_cmd_0x2062_{
+    uint16_t devTypeM;
+    uint32_t devSnM;
+    uint16_t devTypeS;
+    uint32_t devSnS;
+    uint32_t reserve;
+    uint8_t  palen;
+    uint8_t  para[128];
+}__attribute__((packed))dataCmd0x2062;
+extern void up_data_cmd_0x2062(uint8_t *outdata, uint8_t *len, uint32_t devSn, uint16_t devType, uint8_t *da, uint8_t dalen);
+
+#endif

+ 71 - 0
src/main.c

@@ -0,0 +1,71 @@
+#include  "main.h"
+#include "./agm_board/agmboard.h"
+#include "./app/public.h"
+#include "./app/ota_update.h"
+#include "./app/air780e.h"
+#include "./app/taskOpt.h"
+
+void test_485(void)
+{
+    uint8_t readBuf[256],readlen;
+    uint16_t crc,fcrc,randDa;
+
+    if(fifo_is_empty(&g_rxfifo) == true) return;
+    readlen = fifo_read(&g_rxfifo,readBuf);
+    data_dump("485 rcv",readBuf,readlen);
+
+}
+int main(void)
+{
+
+    agm_board_init();
+
+    g_iDentity = IDENTITY_MASTER;
+    g_devMsg.bHave4G = B4G_HAVE;
+    device_board_init();
+    led_init();
+    uart_0_debug_init();
+    printf("app is start\n");
+
+    rtc_init();
+    epprom_power_up_deal();
+    ota_power_up_read_update_status();
+    printf_dev_msg();
+
+    if(g_devPtMsg.binit == 0x01){ // 未产测则不连网
+        init_4g_power_up();
+        init_mqtt_power_up(); //连接4G
+    }
+
+
+    init_run_data();
+
+    while(1){
+
+       //if((B4G_HAVE == g_devMsg.bHave4G)){ // 有4G模块
+            if((0==g_4gMsg.bconnect) && (WORK_UPDATE != g_devMsg.workMode)){ // 重连4G模块
+                g_devMsg.baskIdentity = 0x00;
+                if(timeout_isOut(&g_4gMsg.timer)){ // 上次时间超时
+                    init_4g_power_up();
+                    init_mqtt_power_up();
+                }
+            }
+            dev_4g_up_status_to_server(); // 有4G的从设备上发状态信息
+            master_deal_4g_rx_data(); // 处理4G的接收fifo
+            if(WORK_UPDATE != g_devMsg.workMode) {
+                master_work_loop();
+            }
+            if(1 == g_up7segData.bOpen) open_8seg_test_mode();// 调试模式
+        //}
+        read_485_data();
+        analysis_485_rx_fifo(); // 读取485的接收fifo
+        master_deal_4g_tx_data(); // 读取 4G的发送fifo,并发送数据到服务器
+        if(WORK_UPDATE == g_devMsg.workMode){
+            ota_check_update_timer();
+            ota_offline_handle();//离线升级
+        }
+        ota_update_deal_upstatus();//处理升级的状态上报
+
+
+    }
+}

+ 7 - 0
src/main.h

@@ -0,0 +1,7 @@
+#ifndef _MAIN_H_
+#define _MAIN_H_
+
+#include "board.h"
+
+
+#endif