protocol.c 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959
  1. /**
  2. * @file protocol.c
  3. * @brief this file contains protocol analysis and construct response function when received zigbee module send message
  4. * @author qinlang
  5. * @date 2022.05.06
  6. * @par email:qinlang.chen@tuya.com
  7. * @copyright HANGZHOU TUYA INFORMATION TECHNOLOGY CO.,LTD
  8. * @par company
  9. * http://www.tuya.com
  10. */
  11. #include "zigbee.h"
  12. #include "uart.h"
  13. #include "GLOBAL.h"
  14. #include "gpio_ctrl.h"
  15. #include "EEPROM.h"
  16. #include <string.h>
  17. /******************************************************************************
  18. 移植须知:
  19. 1:MCU必须在while中直接调用mcu_api.c内的zigbee_uart_service()函数
  20. 2:程序正常初始化完成后,建议不进行关串口中断,如必须关中断,关中断时间必须短,关中断会引起串口数据包丢失
  21. 3:请勿在中断/定时器中断内调用上报函数
  22. ******************************************************************************/
  23. /******************************************************************************
  24. 第一步:初始化
  25. 1:在需要使用到zigbee相关文件的文件中include "zigbee.h"
  26. 2:在MCU初始化中调用mcu_api.c文件中的zigbee_protocol_init()函数
  27. 3:将MCU串口单字节发送函数填入protocol.c文件中uart_transmit_output函数内,并删除#error
  28. 4:在MCU串口接收函数中调用mcu_api.c文件内的uart_receive_input函数,并将接收到的字节作为参数传入
  29. 5:单片机进入while循环后调用mcu_api.c文件内的zigbee_uart_service()函数
  30. 6:mcu何时开启zigbee模块配网,当zigbee模块查询到mcu的产品信息之后,或者zigbee模块发送了当前网络状态
  31. 给到mcu,查询pid信息会在上电5秒之后发送,对接部分zigbee老版本通用对接固件低功耗版本尤其需要注意不要
  32. 在第一次确认波特率的时候提前唤醒或者发送串口给zigbee模组,有概率导致zigbee模组波特率存储失败。
  33. 7:上电之后,mcu何时上报数据给网关合适,在收到网络状态为已配网,或者接收到读取dp数据的时候。
  34. 8: 在mcu ota过程中发送固件内容请求未收到zigbee模块的应答时,需要mcu端做好超时重新请求的处理,和存储image
  35. 处理,校验和可以自行设计或者使用参考。
  36. ******************************************************************************/
  37. /******************************************************************************
  38. 1:dp数据点序列类型对照表
  39. **此为自动生成代码,如在开发平台有相关修改请重新下载MCU_SDK**
  40. ******************************************************************************/
  41. ///> dp data list, this will be generated by cloud platform
  42. #ifdef ZIGBEE_ZTU_T3_SW
  43. const DOWNLOAD_CMD_S download_cmd[] =
  44. {
  45. {DPID_SWITCH_1, DP_TYPE_BOOL},
  46. {DPID_SWITCH_2, DP_TYPE_BOOL},
  47. {DPID_SWITCH_3, DP_TYPE_BOOL},
  48. {DPID_RELAY_STATUS, DP_TYPE_ENUM},
  49. {DPID_LIGHT_MODE, DP_TYPE_ENUM},
  50. {DPID_BACKLIGHT_SWITCH, DP_TYPE_BOOL},
  51. {DPID_SWITCH_INCHING, DP_TYPE_STRING},
  52. {DPID_RELAY_STATUS_1, DP_TYPE_ENUM},
  53. {DPID_RELAY_STATUS_2, DP_TYPE_ENUM},
  54. {DPID_RELAY_STATUS_3, DP_TYPE_ENUM},
  55. };
  56. #endif
  57. #ifdef ZIGBEE_ZTU_T2_SW
  58. const DOWNLOAD_CMD_S download_cmd[] =
  59. {
  60. {DPID_SWITCH_1, DP_TYPE_BOOL},
  61. {DPID_SWITCH_3, DP_TYPE_BOOL},
  62. {DPID_RELAY_STATUS, DP_TYPE_ENUM},
  63. {DPID_LIGHT_MODE, DP_TYPE_ENUM},
  64. {DPID_BACKLIGHT_SWITCH, DP_TYPE_BOOL},
  65. {DPID_SWITCH_INCHING, DP_TYPE_STRING},
  66. {DPID_RELAY_STATUS_1, DP_TYPE_ENUM},
  67. {DPID_RELAY_STATUS_3, DP_TYPE_ENUM},
  68. };
  69. #endif
  70. #ifdef ZIGBEE_ZTU_T1_SW
  71. const DOWNLOAD_CMD_S download_cmd[] =
  72. {
  73. {DPID_SWITCH_2, DP_TYPE_BOOL},
  74. {DPID_RELAY_STATUS, DP_TYPE_ENUM},
  75. {DPID_LIGHT_MODE, DP_TYPE_ENUM},
  76. {DPID_BACKLIGHT_SWITCH, DP_TYPE_BOOL},
  77. {DPID_SWITCH_INCHING, DP_TYPE_STRING},
  78. {DPID_RELAY_STATUS_2, DP_TYPE_ENUM},
  79. };
  80. #endif
  81. #ifdef ZIGBEE_ZTU_T6_SCENCE_SW
  82. const DOWNLOAD_CMD_S download_cmd[] =
  83. {
  84. {DPID_SCENE_1, DP_TYPE_ENUM},
  85. {DPID_SCENE_2, DP_TYPE_ENUM},
  86. {DPID_SCENE_3, DP_TYPE_ENUM},
  87. {DPID_SCENE_4, DP_TYPE_ENUM},
  88. {DPID_SCENE_5, DP_TYPE_ENUM},
  89. {DPID_SCENE_6, DP_TYPE_ENUM},
  90. {DPID_MODE_1, DP_TYPE_ENUM},
  91. {DPID_MODE_2, DP_TYPE_ENUM},
  92. {DPID_MODE_3, DP_TYPE_ENUM},
  93. {DPID_SWITCH_1, DP_TYPE_BOOL},
  94. {DPID_SWITCH_2, DP_TYPE_BOOL},
  95. {DPID_SWITCH_3, DP_TYPE_BOOL},
  96. {DPID_BACKLIGHT_SWITCH, DP_TYPE_BOOL},
  97. {DPID_LIGHT_MODE, DP_TYPE_ENUM},
  98. {DPID_RELAY_STATUS, DP_TYPE_ENUM},
  99. {DPID_RELAY_STATUS_1, DP_TYPE_ENUM},
  100. {DPID_RELAY_STATUS_2, DP_TYPE_ENUM},
  101. {DPID_RELAY_STATUS_3, DP_TYPE_ENUM},
  102. {DPID_SWITCH_INCHING, DP_TYPE_STRING},
  103. };
  104. #endif
  105. /******************************************************************************
  106. 2:串口单字节发送函数
  107. 请将MCU串口发送函数填入该函数内,并将接收到的数据作为参数传入串口发送函数
  108. ******************************************************************************/
  109. static void report_mcu_ota_result(unsigned char res);
  110. /**
  111. * @brief encapsulates a generic send function, developer should use their own function to completing this fuction
  112. * @param[in] {value} send signle data
  113. * @return void
  114. */
  115. ////must modify
  116. void uart_transmit_output(unsigned char value)
  117. {
  118. // static unsigned char buf;
  119. // buf = value;
  120. // #error "please use your own uart send fuction complete this fuction, exmaple"
  121. /*
  122. * //demo:
  123. * extern void Uart_PutChar(unsigned char value);
  124. * Uart_PutChar(value);
  125. */
  126. UART1_send(value);
  127. }
  128. /******************************************************************************
  129. 第二步:实现具体用户函数
  130. 1:APP下发数据处理
  131. 2:数据上报处理
  132. ******************************************************************************/
  133. /******************************************************************************
  134. 1:所有数据上报处理
  135. 当前函数处理全部数据上报(包括可下发/可上报和只上报)
  136. 需要用户按照实际情况实现:
  137. 1:需要实现可下发/可上报数据点上报
  138. 2:需要实现只上报数据点上报
  139. 此函数为MCU内部必须调用
  140. 用户也可调用此函数实现全部数据上报
  141. ******************************************************************************/
  142. // 自动化生成数据上报函数
  143. /**
  144. * @brief Upload all dp information of the system, and realize the synchronization of APP and muc data
  145. * @param[in] {void}
  146. * @return void
  147. */
  148. #if (defined ZIGBEE_ZTU_T3_SW) || (defined ZIGBEE_ZTU_T2_SW) || (defined ZIGBEE_ZTU_T1_SW)
  149. //#ifdef ZIGBEE_ZTU_T3_SW
  150. void all_data_update(void)
  151. {
  152. // #error "mcu must realize function internal function"
  153. /*
  154. * these fucntion will be generated by cloud platform, but when use these function must reference the function in mcu_api.c
  155. */
  156. mcu_dp_bool_update(DPID_SWITCH_3, switchState.SWITCH[2]); // BOOL型数据上报;
  157. mcu_dp_bool_update(DPID_SWITCH_2, switchState.SWITCH[1]); // BOOL型数据上报;
  158. mcu_dp_bool_update(DPID_SWITCH_1, switchState.SWITCH[0]); // BOOL型数据上报;
  159. mcu_dp_bool_update(DPID_BACKLIGHT_SWITCH, switchState.human); // BOOL型数据上报;
  160. mcu_dp_enum_update(DPID_RELAY_STATUS_1, switchState.relay_status[0]); // 枚举型数据上报;
  161. mcu_dp_enum_update(DPID_RELAY_STATUS_2, switchState.relay_status[1]); // 枚举型数据上报;
  162. mcu_dp_enum_update(DPID_RELAY_STATUS_3, switchState.relay_status[2]); // 枚举型数据上报;
  163. mcu_dp_enum_update(DPID_LIGHT_MODE, switchState.led_level); // 枚举型数据上报;
  164. mcu_dp_enum_update(DPID_RELAY_STATUS, switchState.relay_allstatus); // 枚举型数据上报;
  165. /*
  166. mcu_dp_string_update(DPID_SWITCH_INCHING,当前点动开关(延时关)指针,当前点动开关(延时关)数据长度); //STRING型数据上报;
  167. */
  168. }
  169. #endif
  170. #ifdef ZIGBEE_ZTU_T6_SCENCE_SW
  171. void all_data_update(void)
  172. {
  173. // #error "mcu must realize function internal function"
  174. /*
  175. * these fucntion will be generated by cloud platform, but when use these function must reference the function in mcu_api.c
  176. */
  177. mcu_dp_bool_update(DPID_BACKLIGHT_SWITCH, switchState.human); // BOOL型数据上报;
  178. mcu_dp_enum_update(DPID_RELAY_STATUS_1, switchState.relay_status[0]); // 枚举型数据上报;
  179. mcu_dp_enum_update(DPID_RELAY_STATUS_2, switchState.relay_status[1]); // 枚举型数据上报;
  180. mcu_dp_enum_update(DPID_RELAY_STATUS_3, switchState.relay_status[2]); // 枚举型数据上报;
  181. mcu_dp_enum_update(DPID_LIGHT_MODE, switchState.led_level); // 枚举型数据上报;
  182. mcu_dp_enum_update(DPID_RELAY_STATUS, switchState.relay_allstatus); // 枚举型数据上报;
  183. mcu_dp_enum_update(DPID_MODE_1, switchState.mod[0]); // 枚举型数据上报;
  184. mcu_dp_enum_update(DPID_MODE_2, switchState.mod[1]); // 枚举型数据上报;
  185. mcu_dp_enum_update(DPID_MODE_3, switchState.mod[2]); // 枚举型数据上报;
  186. if (switchState.mod[2] == 0)
  187. mcu_dp_bool_update(DPID_SWITCH_3, switchState.SWITCH[2]); // BOOL型数据上报;
  188. if (switchState.mod[1] == 0)
  189. mcu_dp_bool_update(DPID_SWITCH_2, switchState.SWITCH[1]); // BOOL型数据上报;
  190. if (switchState.mod[0] == 0)
  191. mcu_dp_bool_update(DPID_SWITCH_1, switchState.SWITCH[0]); // BOOL型数据上报;
  192. // 场景不需要主动上报,APP不需要查询状态
  193. /*
  194. mcu_dp_enum_update(DPID_SCENE_1,当前场景1); //枚举型数据上报;
  195. mcu_dp_enum_update(DPID_SCENE_2,当前场景2); //枚举型数据上报;
  196. mcu_dp_enum_update(DPID_SCENE_3,当前场景3); //枚举型数据上报;
  197. mcu_dp_enum_update(DPID_SCENE_4,当前场景4); //枚举型数据上报;
  198. mcu_dp_enum_update(DPID_SCENE_5,当前场景5); //枚举型数据上报;
  199. mcu_dp_enum_update(DPID_SCENE_6,当前场景6); //枚举型数据上报;
  200. */
  201. /*
  202. mcu_dp_string_update(DPID_SWITCH_INCHING,当前点动开关(延时关)指针,当前点动开关(延时关)数据长度); //STRING型数据上报;
  203. */
  204. }
  205. #endif
  206. /******************************************************************************
  207. WARNING!!!
  208. 2:所有数据上报处理
  209. 自动化代码模板函数,具体请用户自行实现数据处理
  210. ******************************************************************************/
  211. ///> this will realize by cloud platform
  212. #ifdef ZIGBEE_ZTU_T6_SCENCE_SW
  213. /*****************************************************************************
  214. 函数名称 : dp_download_scene_1_handle
  215. 功能描述 : 针对DPID_SCENE_1的处理函数
  216. 输入参数 : value:数据源数据
  217. : length:数据长度
  218. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  219. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  220. *****************************************************************************/
  221. static unsigned char dp_download_scene_1_handle(const unsigned char value[], unsigned short length)
  222. {
  223. // 示例:当前DP类型为ENUM
  224. unsigned char ret;
  225. unsigned char scene_1;
  226. scene_1 = mcu_get_dp_download_enum(value, length);
  227. switch (scene_1)
  228. {
  229. case 0:
  230. break;
  231. default:
  232. break;
  233. }
  234. // There should be a report after processing the DP
  235. ret = mcu_dp_enum_update(DPID_SCENE_1, scene_1);
  236. if (ret == SUCCESS)
  237. return SUCCESS;
  238. else
  239. return ERROR;
  240. }
  241. /*****************************************************************************
  242. 函数名称 : dp_download_scene_2_handle
  243. 功能描述 : 针对DPID_SCENE_2的处理函数
  244. 输入参数 : value:数据源数据
  245. : length:数据长度
  246. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  247. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  248. *****************************************************************************/
  249. static unsigned char dp_download_scene_2_handle(const unsigned char value[], unsigned short length)
  250. {
  251. // 示例:当前DP类型为ENUM
  252. unsigned char ret;
  253. unsigned char scene_2;
  254. scene_2 = mcu_get_dp_download_enum(value, length);
  255. switch (scene_2)
  256. {
  257. case 0:
  258. break;
  259. default:
  260. break;
  261. }
  262. // There should be a report after processing the DP
  263. ret = mcu_dp_enum_update(DPID_SCENE_2, scene_2);
  264. if (ret == SUCCESS)
  265. return SUCCESS;
  266. else
  267. return ERROR;
  268. }
  269. /*****************************************************************************
  270. 函数名称 : dp_download_scene_3_handle
  271. 功能描述 : 针对DPID_SCENE_3的处理函数
  272. 输入参数 : value:数据源数据
  273. : length:数据长度
  274. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  275. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  276. *****************************************************************************/
  277. static unsigned char dp_download_scene_3_handle(const unsigned char value[], unsigned short length)
  278. {
  279. // 示例:当前DP类型为ENUM
  280. unsigned char ret;
  281. unsigned char scene_3;
  282. scene_3 = mcu_get_dp_download_enum(value, length);
  283. switch (scene_3)
  284. {
  285. case 0:
  286. break;
  287. default:
  288. break;
  289. }
  290. // There should be a report after processing the DP
  291. ret = mcu_dp_enum_update(DPID_SCENE_3, scene_3);
  292. if (ret == SUCCESS)
  293. return SUCCESS;
  294. else
  295. return ERROR;
  296. }
  297. /*****************************************************************************
  298. 函数名称 : dp_download_scene_4_handle
  299. 功能描述 : 针对DPID_SCENE_4的处理函数
  300. 输入参数 : value:数据源数据
  301. : length:数据长度
  302. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  303. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  304. *****************************************************************************/
  305. static unsigned char dp_download_scene_4_handle(const unsigned char value[], unsigned short length)
  306. {
  307. // 示例:当前DP类型为ENUM
  308. unsigned char ret;
  309. unsigned char scene_4;
  310. scene_4 = mcu_get_dp_download_enum(value, length);
  311. switch (scene_4)
  312. {
  313. case 0:
  314. break;
  315. default:
  316. break;
  317. }
  318. // There should be a report after processing the DP
  319. ret = mcu_dp_enum_update(DPID_SCENE_4, scene_4);
  320. if (ret == SUCCESS)
  321. return SUCCESS;
  322. else
  323. return ERROR;
  324. }
  325. /*****************************************************************************
  326. 函数名称 : dp_download_scene_5_handle
  327. 功能描述 : 针对DPID_SCENE_5的处理函数
  328. 输入参数 : value:数据源数据
  329. : length:数据长度
  330. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  331. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  332. *****************************************************************************/
  333. static unsigned char dp_download_scene_5_handle(const unsigned char value[], unsigned short length)
  334. {
  335. // 示例:当前DP类型为ENUM
  336. unsigned char ret;
  337. unsigned char scene_5;
  338. scene_5 = mcu_get_dp_download_enum(value, length);
  339. switch (scene_5)
  340. {
  341. case 0:
  342. break;
  343. default:
  344. break;
  345. }
  346. // There should be a report after processing the DP
  347. ret = mcu_dp_enum_update(DPID_SCENE_5, scene_5);
  348. if (ret == SUCCESS)
  349. return SUCCESS;
  350. else
  351. return ERROR;
  352. }
  353. /*****************************************************************************
  354. 函数名称 : dp_download_scene_6_handle
  355. 功能描述 : 针对DPID_SCENE_6的处理函数
  356. 输入参数 : value:数据源数据
  357. : length:数据长度
  358. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  359. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  360. *****************************************************************************/
  361. static unsigned char dp_download_scene_6_handle(const unsigned char value[], unsigned short length)
  362. {
  363. // 示例:当前DP类型为ENUM
  364. unsigned char ret;
  365. unsigned char scene_6;
  366. scene_6 = mcu_get_dp_download_enum(value, length);
  367. switch (scene_6)
  368. {
  369. case 0:
  370. break;
  371. default:
  372. break;
  373. }
  374. // There should be a report after processing the DP
  375. ret = mcu_dp_enum_update(DPID_SCENE_6, scene_6);
  376. if (ret == SUCCESS)
  377. return SUCCESS;
  378. else
  379. return ERROR;
  380. }
  381. /*****************************************************************************
  382. 函数名称 : dp_download_mode_1_handle
  383. 功能描述 : 针对DPID_MODE_1的处理函数
  384. 输入参数 : value:数据源数据
  385. : length:数据长度
  386. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  387. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  388. *****************************************************************************/
  389. static unsigned char dp_download_mode_1_handle(const unsigned char value[], unsigned short length)
  390. {
  391. // 示例:当前DP类型为ENUM
  392. unsigned char ret;
  393. unsigned char mode_1;
  394. mode_1 = mcu_get_dp_download_enum(value, length);
  395. switch (mode_1)
  396. {
  397. case 0:
  398. break;
  399. case 1:
  400. break;
  401. default:
  402. break;
  403. }
  404. // add by zzw 20240304
  405. switchState.mod[0] = mode_1; // 开关、场景设置
  406. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  407. write_mileage[6] = switchState.mod[0];
  408. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  409. // add by zzw 20240304
  410. // add by zzw 20240312 增加eeprom参数配置区
  411. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  412. write_mileage_backup[6] = switchState.mod[0];
  413. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  414. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  415. if (read_mileage_backup[6] != switchState.mod[0]) // 再次读取不相等,则再次写入
  416. {
  417. read_mileage_backup[6] = switchState.mod[0];
  418. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  419. }
  420. // add by zzw 20240312 增加eeprom参数配置区
  421. // There should be a report after processing the DP
  422. ret = mcu_dp_enum_update(DPID_MODE_1, mode_1);
  423. if (ret == SUCCESS)
  424. return SUCCESS;
  425. else
  426. return ERROR;
  427. }
  428. /*****************************************************************************
  429. 函数名称 : dp_download_mode_2_handle
  430. 功能描述 : 针对DPID_MODE_2的处理函数
  431. 输入参数 : value:数据源数据
  432. : length:数据长度
  433. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  434. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  435. *****************************************************************************/
  436. static unsigned char dp_download_mode_2_handle(const unsigned char value[], unsigned short length)
  437. {
  438. // 示例:当前DP类型为ENUM
  439. unsigned char ret;
  440. unsigned char mode_2;
  441. mode_2 = mcu_get_dp_download_enum(value, length);
  442. switch (mode_2)
  443. {
  444. case 0:
  445. break;
  446. case 1:
  447. break;
  448. default:
  449. break;
  450. }
  451. // add by zzw 20240304
  452. switchState.mod[1] = mode_2; // 开关、场景设置
  453. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  454. write_mileage[7] = switchState.mod[1];
  455. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  456. // add by zzw 20240304
  457. // add by zzw 20240312 增加eeprom参数配置区
  458. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  459. write_mileage_backup[7] = switchState.mod[1];
  460. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  461. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  462. if (read_mileage_backup[7] != switchState.mod[1]) // 再次读取不相等,则再次写入
  463. {
  464. read_mileage_backup[7] = switchState.mod[1];
  465. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  466. }
  467. // add by zzw 20240312 增加eeprom参数配置区
  468. // There should be a report after processing the DP
  469. ret = mcu_dp_enum_update(DPID_MODE_2, mode_2);
  470. if (ret == SUCCESS)
  471. return SUCCESS;
  472. else
  473. return ERROR;
  474. }
  475. /*****************************************************************************
  476. 函数名称 : dp_download_mode_3_handle
  477. 功能描述 : 针对DPID_MODE_3的处理函数
  478. 输入参数 : value:数据源数据
  479. : length:数据长度
  480. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  481. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  482. *****************************************************************************/
  483. static unsigned char dp_download_mode_3_handle(const unsigned char value[], unsigned short length)
  484. {
  485. // 示例:当前DP类型为ENUM
  486. unsigned char ret;
  487. unsigned char mode_3;
  488. mode_3 = mcu_get_dp_download_enum(value, length);
  489. switch (mode_3)
  490. {
  491. case 0:
  492. break;
  493. case 1:
  494. break;
  495. default:
  496. break;
  497. }
  498. // add by zzw 20240304
  499. switchState.mod[2] = mode_3; // 开关、场景设置
  500. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  501. write_mileage[8] = switchState.mod[2];
  502. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  503. // add by zzw 20240304
  504. // add by zzw 20240312 增加eeprom参数配置区
  505. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  506. write_mileage_backup[8] = switchState.mod[2];
  507. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  508. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  509. if (read_mileage_backup[8] != switchState.mod[2]) // 再次读取不相等,则再次写入
  510. {
  511. read_mileage_backup[8] = switchState.mod[2];
  512. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  513. }
  514. // add by zzw 20240312 增加eeprom参数配置区
  515. // There should be a report after processing the DP
  516. ret = mcu_dp_enum_update(DPID_MODE_3, mode_3);
  517. if (ret == SUCCESS)
  518. return SUCCESS;
  519. else
  520. return ERROR;
  521. }
  522. #endif
  523. /*****************************************************************************
  524. 函数名称 : dp_download_switch_1_handle
  525. 功能描述 : 针对DPID_SWITCH_1的处理函数
  526. 输入参数 : value:数据源数据
  527. : length:数据长度
  528. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  529. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  530. *****************************************************************************/
  531. static unsigned char dp_download_switch_1_handle(const unsigned char value[], unsigned short length)
  532. {
  533. // 示例:当前DP类型为BOOL
  534. unsigned char ret;
  535. // 0:off/1:on
  536. unsigned char switch_1;
  537. switch_1 = mcu_get_dp_download_bool(value, length);
  538. if (switch_1 == 0)
  539. {
  540. // bool off
  541. gRelayOnOff &= (~0x01);
  542. gLedState = gLedState & (~0x01); // 按键1清除
  543. }
  544. else
  545. {
  546. // bool on
  547. gRelayOnOff |= (0x01);
  548. gLedState = gLedState | 0x01; // 按键1设置
  549. if (appControlLedEnable) // add by zzw 开灯点亮按键背光10秒
  550. {
  551. gRadarKeepTimer = 100; // 10s
  552. }
  553. if (switchState.plus_mod[0] == 0x01) // 点动开启
  554. {
  555. switchState.plus_en[0] = 0x01;
  556. switchState.plus_counter[0] = switchState.plus_auto_time[0];
  557. // write_mileage[0] = switchState.plus_en;
  558. // iap_eeprom_write(14, write_mileage, 1); // 写入1字节
  559. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  560. write_mileage[14] = switchState.plus_en[0];
  561. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  562. }
  563. }
  564. // There should be a report after processing the DP
  565. ret = mcu_dp_bool_update(DPID_SWITCH_1, switch_1);
  566. if (ret == SUCCESS)
  567. return SUCCESS;
  568. else
  569. return ERROR;
  570. }
  571. /*****************************************************************************
  572. 函数名称 : dp_download_switch_2_handle
  573. 功能描述 : 针对DPID_SWITCH_2的处理函数
  574. 输入参数 : value:数据源数据
  575. : length:数据长度
  576. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  577. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  578. *****************************************************************************/
  579. static unsigned char dp_download_switch_2_handle(const unsigned char value[], unsigned short length)
  580. {
  581. // 示例:当前DP类型为BOOL
  582. unsigned char ret;
  583. // 0:off/1:on
  584. unsigned char switch_2;
  585. switch_2 = mcu_get_dp_download_bool(value, length);
  586. if (switch_2 == 0)
  587. {
  588. // bool off
  589. gRelayOnOff &= (~0x02);
  590. gLedState = gLedState & (~0x02); // 按键1清除
  591. }
  592. else
  593. {
  594. // bool on
  595. gRelayOnOff |= (0x02);
  596. gLedState = gLedState | 0x02; // 按键1设置
  597. if (appControlLedEnable) // add by zzw 开灯点亮按键背光10秒
  598. {
  599. gRadarKeepTimer = 100; // 10s
  600. }
  601. if (switchState.plus_mod[1] == 0x01) // 点动开启
  602. {
  603. switchState.plus_en[1] = 0x01;
  604. switchState.plus_counter[1] = switchState.plus_auto_time[1];
  605. // write_mileage[1] = switchState.plus_en;
  606. // iap_eeprom_write(15, write_mileage, 1); // 写入1字节
  607. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  608. write_mileage[15] = switchState.plus_en[1];
  609. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  610. }
  611. }
  612. // There should be a report after processing the DP
  613. ret = mcu_dp_bool_update(DPID_SWITCH_2, switch_2);
  614. if (ret == SUCCESS)
  615. return SUCCESS;
  616. else
  617. return ERROR;
  618. }
  619. /*****************************************************************************
  620. 函数名称 : dp_download_switch_3_handle
  621. 功能描述 : 针对DPID_SWITCH_3的处理函数
  622. 输入参数 : value:数据源数据
  623. : length:数据长度
  624. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  625. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  626. *****************************************************************************/
  627. static unsigned char dp_download_switch_3_handle(const unsigned char value[], unsigned short length)
  628. {
  629. // 示例:当前DP类型为BOOL
  630. unsigned char ret;
  631. // 0:off/1:on
  632. unsigned char switch_3;
  633. switch_3 = mcu_get_dp_download_bool(value, length);
  634. if (switch_3 == 0)
  635. {
  636. // bool off
  637. gRelayOnOff &= (~0x04);
  638. gLedState = gLedState & (~0x04); // 按键5清除
  639. }
  640. else
  641. {
  642. // bool on
  643. gRelayOnOff |= (0x04);
  644. gLedState = gLedState | 0x04; // 按键5设置
  645. if (appControlLedEnable) // add by zzw 开灯点亮按键背光10秒
  646. {
  647. gRadarKeepTimer = 100; // 10s
  648. }
  649. if (switchState.plus_mod[2] == 0x01) // 点动开启
  650. {
  651. switchState.plus_en[2] = 0x01;
  652. switchState.plus_counter[2] = switchState.plus_auto_time[2];
  653. // write_mileage[2] = switchState.plus_en;
  654. // iap_eeprom_write(16, write_mileage, 1); // 写入1字节
  655. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  656. write_mileage[16] = switchState.plus_en[2];
  657. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  658. }
  659. }
  660. // There should be a report after processing the DP
  661. ret = mcu_dp_bool_update(DPID_SWITCH_3, switch_3);
  662. if (ret == SUCCESS)
  663. return SUCCESS;
  664. else
  665. return ERROR;
  666. }
  667. /*****************************************************************************
  668. 函数名称 : dp_download_relay_status_handle
  669. 功能描述 : 针对DPID_RELAY_STATUS的处理函数
  670. 输入参数 : value:数据源数据
  671. : length:数据长度
  672. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  673. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  674. *****************************************************************************/
  675. static unsigned char dp_download_relay_status_handle(const unsigned char value[], unsigned short length)
  676. {
  677. // 示例:当前DP类型为ENUM
  678. unsigned char ret;
  679. unsigned char relay_status;
  680. relay_status = mcu_get_dp_download_enum(value, length);
  681. switch (relay_status) // 全局设置3路的状态
  682. {
  683. case 0:
  684. break;
  685. case 1:
  686. break;
  687. case 2:
  688. break;
  689. default:
  690. break;
  691. }
  692. // add by zzw 20240302
  693. switchState.relay_allstatus = relay_status;
  694. switchState.relay_status[0] = relay_status;
  695. switchState.relay_status[1] = relay_status;
  696. switchState.relay_status[2] = relay_status;
  697. // iap_eeprom_write(1, write_mileage, 4); // 写入4字节
  698. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  699. write_mileage[1] = relay_status;
  700. write_mileage[2] = relay_status;
  701. write_mileage[3] = relay_status;
  702. write_mileage[4] = relay_status;
  703. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  704. // add by zzw 20240302
  705. // add by zzw 20240312 增加eeprom参数配置区
  706. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  707. write_mileage_backup[1] = relay_status;
  708. write_mileage_backup[2] = relay_status;
  709. write_mileage_backup[3] = relay_status;
  710. write_mileage_backup[4] = relay_status;
  711. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  712. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  713. if (read_mileage_backup[1] != relay_status) // 再次读取不相等,则再次写入
  714. {
  715. read_mileage_backup[1] = relay_status;
  716. read_mileage_backup[2] = relay_status;
  717. read_mileage_backup[3] = relay_status;
  718. read_mileage_backup[4] = relay_status;
  719. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  720. }
  721. // add by zzw 20240312 增加eeprom参数配置区
  722. // There should be a report after processing the DP
  723. ret = mcu_dp_enum_update(DPID_RELAY_STATUS, relay_status);
  724. if (ret == SUCCESS)
  725. return SUCCESS;
  726. else
  727. return ERROR;
  728. }
  729. /*****************************************************************************
  730. 函数名称 : dp_download_light_mode_handle
  731. 功能描述 : 针对DPID_LIGHT_MODE的处理函数
  732. 输入参数 : value:数据源数据
  733. : length:数据长度
  734. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  735. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  736. *****************************************************************************/
  737. static unsigned char dp_download_light_mode_handle(const unsigned char value[], unsigned short length)
  738. {
  739. // 示例:当前DP类型为ENUM
  740. unsigned char ret;
  741. unsigned char light_mode;
  742. light_mode = mcu_get_dp_download_enum(value, length);
  743. switch (light_mode) // 枚举范围:Level1,Level2,Level3
  744. {
  745. case 0:
  746. switchState.led_level = 0;
  747. break;
  748. case 1:
  749. switchState.led_level = 1;
  750. break;
  751. case 2:
  752. switchState.led_level = 2;
  753. break;
  754. default:
  755. break;
  756. }
  757. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  758. write_mileage[5] = switchState.led_level;
  759. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  760. // add by zzw 20240312 增加eeprom参数配置区
  761. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  762. write_mileage_backup[5] = switchState.led_level;
  763. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  764. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  765. if (read_mileage_backup[5] != switchState.led_level) // 再次读取不相等,则再次写入
  766. {
  767. read_mileage_backup[5] = switchState.led_level;
  768. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  769. }
  770. // add by zzw 20240312 增加eeprom参数配置区
  771. // There should be a report after processing the DP
  772. ret = mcu_dp_enum_update(DPID_LIGHT_MODE, light_mode);
  773. if (ret == SUCCESS)
  774. return SUCCESS;
  775. else
  776. return ERROR;
  777. }
  778. /*****************************************************************************
  779. 函数名称 : dp_download_backlight_switch_handle
  780. 功能描述 : 针对DPID_BACKLIGHT_SWITCH的处理函数
  781. 输入参数 : value:数据源数据
  782. : length:数据长度
  783. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  784. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  785. *****************************************************************************/
  786. static unsigned char dp_download_backlight_switch_handle(const unsigned char value[], unsigned short length)
  787. {
  788. // 示例:当前DP类型为BOOL
  789. unsigned char ret;
  790. // 0:off/1:on
  791. unsigned char backlight_switch;
  792. backlight_switch = mcu_get_dp_download_bool(value, length);
  793. if (backlight_switch == 0)
  794. {
  795. // bool off
  796. // switchState.bluelight = 0;
  797. switchState.human = 0;
  798. }
  799. else
  800. {
  801. // bool on
  802. // switchState.bluelight = 1;
  803. switchState.human = 1;
  804. }
  805. // add by zzy 20240309
  806. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  807. // switchState.led_level = write_mileage[5];//重新读取刷新背光亮度值
  808. write_mileage[9] = switchState.human;
  809. iap_eeprom_write(0, write_mileage, 30); // 先读,在写入1字节
  810. // add by zzy 20240309
  811. // add by zzw 20240312 增加eeprom参数配置区
  812. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  813. switchState.led_level = write_mileage_backup[5]; // 重新读取刷新背光亮度值
  814. write_mileage_backup[9] = switchState.human;
  815. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  816. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  817. if (read_mileage_backup[9] != switchState.human) // 再次读取不相等,则再次写入
  818. {
  819. read_mileage_backup[9] = switchState.human;
  820. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  821. }
  822. // add by zzw 20240312 增加eeprom参数配置区
  823. // There should be a report after processing the DP
  824. ret = mcu_dp_bool_update(DPID_BACKLIGHT_SWITCH, backlight_switch);
  825. if (ret == SUCCESS)
  826. return SUCCESS;
  827. else
  828. return ERROR;
  829. }
  830. /*****************************************************************************
  831. 函数名称 : dp_download_switch_inching_handle
  832. 功能描述 : 针对DPID_SWITCH_INCHING的处理函数
  833. 输入参数 : value:数据源数据
  834. : length:数据长度
  835. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  836. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  837. *****************************************************************************/
  838. static unsigned char dp_download_switch_inching_handle(const unsigned char value[], unsigned short length)
  839. {
  840. // 示例:当前DP类型为STRING
  841. unsigned char ret;
  842. int i = 0;
  843. int j = 0;
  844. // 后面两位表示秒数,前面的1字节的0位表示开/关,1开,0关,bit7-bit1表示通道号
  845. // length=0,表示全部删除
  846. //"AQAF"的Base64解码结果是01,00,05
  847. //"AwAF"的Base64解码结果是03,00,05
  848. //"BQAF"的Base64解码结果是05, 00, 05
  849. // STRING type data processing
  850. unsigned char string_base64_data[32];
  851. unsigned char hex_data[32];
  852. // char source[32] = "abc";
  853. // char dest[32];
  854. /*将字符串abc进行base64编码*/
  855. // Base64Encode(dest, source, strlen(source));
  856. // printf("%s\n", dest);
  857. /*将字符串abc的编码字符串解码,还原成abc*/
  858. // Base64Decode(source, dest, strlen(dest));
  859. // printf("%s\n", source);
  860. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  861. write_mileage_backup[20] = 0;
  862. write_mileage_backup[21] = 0;
  863. write_mileage_backup[22] = 0;
  864. write_mileage_backup[23] = 0;
  865. write_mileage_backup[24] = 0;
  866. write_mileage_backup[25] = 0;
  867. write_mileage_backup[26] = 0;
  868. write_mileage_backup[27] = 0;
  869. write_mileage_backup[28] = 0;//每次清空数据,重新赋值
  870. switchState.plus_mod[0] = 0;
  871. switchState.plus_mod[1] = 0;
  872. switchState.plus_mod[2] = 0;
  873. if (length == 0) // 清空点动开关
  874. {
  875. switchState.plus_mod[0] = 0;
  876. switchState.plus_mod[1] = 0;
  877. switchState.plus_mod[2] = 0;
  878. }
  879. else
  880. {
  881. for (i = 0; i < (length / 4); i++) // 4字符一个数据集
  882. {
  883. for (j = 0; j < 4; j++) // 4个字符转换一次
  884. {
  885. string_base64_data[j] = value[i * 4 + j];
  886. }
  887. // base64_decode_three_bytes(string_base64_data, hex_data);
  888. Base64Decode(hex_data, string_base64_data, strlen(string_base64_data));
  889. if (hex_data[0] == 0x01) // 开关1使能
  890. {
  891. switchState.plus_mod[0] = 1;
  892. switchState.plus_auto_time[0] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数
  893. write_mileage_backup[20] = switchState.plus_mod[0];
  894. write_mileage_backup[21] = hex_data[1];
  895. write_mileage_backup[22] = hex_data[2];
  896. }
  897. else if (hex_data[0] == 0x00) // 开关1关闭
  898. {
  899. switchState.plus_mod[0] = 0;
  900. write_mileage_backup[20] = switchState.plus_mod[0];
  901. write_mileage_backup[21] = 0;
  902. write_mileage_backup[22] = 0;
  903. }
  904. else if (hex_data[0] == 0x03) // 开关2使能
  905. {
  906. switchState.plus_mod[1] = 1;
  907. switchState.plus_auto_time[1] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数
  908. write_mileage_backup[23] = switchState.plus_mod[1];
  909. write_mileage_backup[24] = hex_data[1];
  910. write_mileage_backup[25] = hex_data[2];
  911. }
  912. else if (hex_data[0] == 0x02) // 开关2关闭
  913. {
  914. switchState.plus_mod[1] = 0;
  915. write_mileage_backup[23] = switchState.plus_mod[1];
  916. write_mileage_backup[24] = 0;
  917. write_mileage_backup[25] = 0;
  918. }
  919. else if (hex_data[0] == 0x05) // 开关3使能
  920. {
  921. switchState.plus_mod[2] = 1;
  922. switchState.plus_auto_time[2] = (hex_data[1] * 256 + hex_data[2]) * 10; // 高字节在前,秒转100ms为基数
  923. write_mileage_backup[26] = switchState.plus_mod[2];
  924. write_mileage_backup[27] = hex_data[1];
  925. write_mileage_backup[28] = hex_data[2];
  926. }
  927. else if (hex_data[0] == 0x04) // 开关3关闭
  928. {
  929. switchState.plus_mod[2] = 0;
  930. write_mileage_backup[26] = switchState.plus_mod[2];
  931. write_mileage_backup[27] = 0;
  932. write_mileage_backup[28] = 0;
  933. }
  934. }
  935. }
  936. // add by zzw 20240313 增加eeprom参数配置区
  937. // 点动开关2个字节(使能1,时间2)-20-21-22,-23-24-25,-26-27-28
  938. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  939. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  940. if (read_mileage_backup[20] != switchState.plus_mod[0]) // 再次读取不相等,则再次写入
  941. {
  942. iap_eeprom_write_backup(0, write_mileage_backup, 30); //
  943. }
  944. // add by zzw 20240313 增加eeprom参数配置区
  945. /*string_data[0] = value[0];
  946. string_data[1] = value[1];
  947. string_data[2] = value[2];
  948. string_data[3] = value[3];
  949. string_data[4] = value[4];
  950. string_data[5] = value[5];
  951. string_data[6] = value[6];
  952. string_data[7] = value[7];*/
  953. // add by zzw 20240304 将实际参数解析为十六进制string_data数后存入flash
  954. /*
  955. //if ((switchState.plus_en[0] == 0x01) && (switchState.plus_mod[0] == 0x01)) // 点动开关触发
  956. switchState.plus_mod[0] = string_data[0];// 点动开启设置,开启需要string_data[0]转成0x01
  957. switchState.plus_auto_time[0] = (string_data[1] * 256 + string_data[2]) * 10; // 高字节在前,秒转100ms为基数
  958. switchState.plus_mod[1] = string_data[3];// 点动开启设置
  959. switchState.plus_auto_time[1] = (string_data[4] * 256 + string_data[5]) * 10; // 高字节在前,秒转100ms为基数
  960. switchState.plus_mod[2] = string_data[6];// 点动开启设置
  961. switchState.plus_auto_time[2] = (string_data[7] * 256 + string_data[8]) * 10; // 高字节在前,秒转100ms为基数
  962. */
  963. // There should be a report after processing the DP
  964. ret = mcu_dp_string_update(DPID_SWITCH_INCHING, value, length);
  965. if (ret == SUCCESS)
  966. return SUCCESS;
  967. else
  968. return ERROR;
  969. }
  970. /*****************************************************************************
  971. 函数名称 : dp_download_relay_status_1_handle
  972. 功能描述 : 针对DPID_RELAY_STATUS_1的处理函数
  973. 输入参数 : value:数据源数据
  974. : length:数据长度
  975. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  976. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  977. *****************************************************************************/
  978. static unsigned char dp_download_relay_status_1_handle(const unsigned char value[], unsigned short length)
  979. {
  980. // 示例:当前DP类型为ENUM
  981. unsigned char ret;
  982. unsigned char relay_status_1;
  983. relay_status_1 = mcu_get_dp_download_enum(value, length);
  984. switch (relay_status_1)
  985. {
  986. case 0: // 断电
  987. // switchState.relay_status[0]=0;
  988. break;
  989. case 1: // 通电
  990. // switchState.relay_status[0]=1;
  991. break;
  992. case 2: // 断电记忆
  993. // switchState.relay_status[0]=2;
  994. break;
  995. default:
  996. break;
  997. }
  998. // add by zzw 20240207
  999. switchState.relay_status[0] = relay_status_1;
  1000. // add by zzw 20240207
  1001. // add by zzy 20240309
  1002. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  1003. write_mileage[2] = switchState.relay_status[0];
  1004. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  1005. // add by zzy 20240309
  1006. // add by zzw 20240312 增加eeprom参数配置区
  1007. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  1008. write_mileage_backup[2] = switchState.relay_status[0];
  1009. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  1010. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  1011. if (read_mileage_backup[2] != switchState.relay_status[0]) // 再次读取不相等,则再次写入
  1012. {
  1013. read_mileage_backup[2] = switchState.relay_status[0];
  1014. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  1015. }
  1016. // add by zzw 20240312 增加eeprom参数配置区
  1017. // There should be a report after processing the DP
  1018. ret = mcu_dp_enum_update(DPID_RELAY_STATUS_1, relay_status_1);
  1019. if (ret == SUCCESS)
  1020. return SUCCESS;
  1021. else
  1022. return ERROR;
  1023. }
  1024. /*****************************************************************************
  1025. 函数名称 : dp_download_relay_status_2_handle
  1026. 功能描述 : 针对DPID_RELAY_STATUS_2的处理函数
  1027. 输入参数 : value:数据源数据
  1028. : length:数据长度
  1029. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  1030. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  1031. *****************************************************************************/
  1032. static unsigned char dp_download_relay_status_2_handle(const unsigned char value[], unsigned short length)
  1033. {
  1034. // 示例:当前DP类型为ENUM
  1035. unsigned char ret;
  1036. unsigned char relay_status_2;
  1037. relay_status_2 = mcu_get_dp_download_enum(value, length);
  1038. switch (relay_status_2)
  1039. {
  1040. case 0:
  1041. break;
  1042. case 1:
  1043. break;
  1044. case 2:
  1045. break;
  1046. default:
  1047. break;
  1048. }
  1049. // add by zzw 20240207
  1050. switchState.relay_status[1] = relay_status_2;
  1051. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  1052. write_mileage[3] = switchState.relay_status[1];
  1053. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  1054. // add by zzw 20240207
  1055. // add by zzw 20240312 增加eeprom参数配置区
  1056. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  1057. write_mileage_backup[3] = switchState.relay_status[1];
  1058. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  1059. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  1060. if (read_mileage_backup[3] != switchState.relay_status[1]) // 再次读取不相等,则再次写入
  1061. {
  1062. read_mileage_backup[3] = switchState.relay_status[1];
  1063. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  1064. }
  1065. // add by zzw 20240312 增加eeprom参数配置区
  1066. // There should be a report after processing the DP
  1067. ret = mcu_dp_enum_update(DPID_RELAY_STATUS_2, relay_status_2);
  1068. if (ret == SUCCESS)
  1069. return SUCCESS;
  1070. else
  1071. return ERROR;
  1072. }
  1073. /*****************************************************************************
  1074. 函数名称 : dp_download_relay_status_3_handle
  1075. 功能描述 : 针对DPID_RELAY_STATUS_3的处理函数
  1076. 输入参数 : value:数据源数据
  1077. : length:数据长度
  1078. 返回参数 : 成功返回:SUCCESS/失败返回:ERROR
  1079. 使用说明 : 可下发可上报类型,需要在处理完数据后上报处理结果至app
  1080. *****************************************************************************/
  1081. static unsigned char dp_download_relay_status_3_handle(const unsigned char value[], unsigned short length)
  1082. {
  1083. // 示例:当前DP类型为ENUM
  1084. unsigned char ret;
  1085. unsigned char relay_status_3;
  1086. relay_status_3 = mcu_get_dp_download_enum(value, length);
  1087. switch (relay_status_3)
  1088. {
  1089. case 0:
  1090. break;
  1091. case 1:
  1092. break;
  1093. case 2:
  1094. break;
  1095. default:
  1096. break;
  1097. }
  1098. // add by zzw 20240207
  1099. switchState.relay_status[2] = relay_status_3;
  1100. iap_eeprom_read(0, write_mileage, 30); // 读取30字节
  1101. write_mileage[4] = switchState.relay_status[2];
  1102. iap_eeprom_write(0, write_mileage, 30); // 写入1字节
  1103. // add by zzw 20240207
  1104. // add by zzw 20240312 增加eeprom参数配置区
  1105. iap_eeprom_read_backup(0, write_mileage_backup, 30); // 读取30字节
  1106. write_mileage_backup[4] = switchState.relay_status[2];
  1107. iap_eeprom_write_backup(0, write_mileage_backup, 30); // 写入1字节
  1108. iap_eeprom_read_backup(0, read_mileage_backup, 30); // 读取30字节
  1109. if (read_mileage_backup[4] != switchState.relay_status[2]) // 再次读取不相等,则再次写入
  1110. {
  1111. read_mileage_backup[4] = switchState.relay_status[2];
  1112. iap_eeprom_write_backup(0, read_mileage_backup, 30); // 写入1字节
  1113. }
  1114. // add by zzw 20240312 增加eeprom参数配置区
  1115. // There should be a report after processing the DP
  1116. ret = mcu_dp_enum_update(DPID_RELAY_STATUS_3, relay_status_3);
  1117. if (ret == SUCCESS)
  1118. return SUCCESS;
  1119. else
  1120. return ERROR;
  1121. }
  1122. #ifdef SUPPORT_MCU_RTC_CHECK
  1123. /**
  1124. * @brief mcu check local RTC time
  1125. * @param[in] {time} timestamp
  1126. * @return void
  1127. */
  1128. void mcu_write_rtctime(unsigned char time[])
  1129. {
  1130. // #error "mcu should realize RTC time wtriting fuction, and delete this line"
  1131. /*
  1132. time[0]~time[3]:standard time
  1133. time[4]~time[7]: Local time
  1134. */
  1135. my_memcpy((void *)timestamp, (const char *)time, 4); // get timestamp
  1136. zigbee_timestamp_to_time();
  1137. /*
  1138. year = _time.w_year; //year
  1139. month = _time.w_month; //month
  1140. date = _time.w_date; //date
  1141. hour = _time.hour + 8; //hour(8:BeiJing time)
  1142. min = _time.min; //minute
  1143. sec = _time.sec; //second
  1144. */
  1145. }
  1146. #endif
  1147. /**
  1148. * @brief Zigbee functional test feedback
  1149. * @param[in] {void}
  1150. * @return void
  1151. */
  1152. void zigbee_test_result(void)
  1153. {
  1154. // #error "this test is makesure the rf fuction of zigbee module, if test pass or not should do something, mcu should realize"
  1155. unsigned char rssi = zigbee_uart_rx_buf[DATA_START + 1];
  1156. if (zigbee_uart_rx_buf[DATA_START] == 0x01)
  1157. {
  1158. if (rssi > 0x3C)
  1159. {
  1160. // test sucess the range of rssi is 0% ~ 100%
  1161. }
  1162. else
  1163. {
  1164. // test failure
  1165. }
  1166. }
  1167. else
  1168. {
  1169. // test failure
  1170. }
  1171. }
  1172. /******************************************************************************
  1173. WARNING!!!
  1174. 以下函数用户请勿修改!!
  1175. ******************************************************************************/
  1176. /**
  1177. * @brief this function will handle uart received frame data
  1178. * @param[in] {dpid} dp id
  1179. * @param[in] {value} dp data
  1180. * @param[in] {length} lenght of dp data
  1181. * @return handle result
  1182. */
  1183. //#ifdef ZIGBEE_ZTU_T3_SW
  1184. #if (defined ZIGBEE_ZTU_T3_SW) || (defined ZIGBEE_ZTU_T2_SW) || (defined ZIGBEE_ZTU_T1_SW)
  1185. unsigned char dp_download_handle(unsigned char dpid, const unsigned char value[], unsigned short length)
  1186. {
  1187. /* only list of function, mcu need realize these fuction*/
  1188. unsigned char ret;
  1189. // 可收到控制信号,说明配网肯定成功
  1190. ZG_JoinCounter = 18000; // 入网成功,入网计数器置最大值,180秒
  1191. switchState.zigbee_work_state = 1;
  1192. // 可收到控制信号,说明配网肯定成功
  1193. switch (dpid)
  1194. {
  1195. case DPID_SWITCH_1:
  1196. // 开关 1处理函数
  1197. ret = dp_download_switch_1_handle(value, length);
  1198. break;
  1199. case DPID_SWITCH_2:
  1200. // 开关 2处理函数
  1201. ret = dp_download_switch_2_handle(value, length);
  1202. break;
  1203. case DPID_SWITCH_3:
  1204. // 开关 3处理函数
  1205. ret = dp_download_switch_3_handle(value, length);
  1206. break;
  1207. case DPID_RELAY_STATUS:
  1208. // 上电状态设置处理函数
  1209. ret = dp_download_relay_status_handle(value, length);
  1210. break;
  1211. case DPID_LIGHT_MODE:
  1212. // 指示灯状态设置处理函数
  1213. ret = dp_download_light_mode_handle(value, length);
  1214. break;
  1215. case DPID_BACKLIGHT_SWITCH:
  1216. // 背光开关处理函数
  1217. ret = dp_download_backlight_switch_handle(value, length);
  1218. break;
  1219. case DPID_SWITCH_INCHING:
  1220. // 点动开关(延时关)处理函数
  1221. ret = dp_download_switch_inching_handle(value, length);
  1222. break;
  1223. case DPID_RELAY_STATUS_1:
  1224. // 开关1上电状态设置处理函数
  1225. ret = dp_download_relay_status_1_handle(value, length);
  1226. break;
  1227. case DPID_RELAY_STATUS_2:
  1228. // 开关2上电状态设置处理函数
  1229. ret = dp_download_relay_status_2_handle(value, length);
  1230. break;
  1231. case DPID_RELAY_STATUS_3:
  1232. // 开关3上电状态设置处理函数
  1233. ret = dp_download_relay_status_3_handle(value, length);
  1234. break;
  1235. default:
  1236. break;
  1237. }
  1238. return ret;
  1239. }
  1240. #endif
  1241. #ifdef ZIGBEE_ZTU_T6_SCENCE_SW
  1242. unsigned char dp_download_handle(unsigned char dpid, const unsigned char value[], unsigned short length)
  1243. {
  1244. /* only list of function, mcu need realize these fuction*/
  1245. unsigned char ret;
  1246. switchState.zigbee_work_state = 1; // 有dp控制指令,说明设备肯定在线//add by zzw
  1247. switch (dpid)
  1248. {
  1249. case DPID_SCENE_1:
  1250. // 场景1处理函数
  1251. ret = dp_download_scene_1_handle(value, length);
  1252. break;
  1253. case DPID_SCENE_2:
  1254. // 场景2处理函数
  1255. ret = dp_download_scene_2_handle(value, length);
  1256. break;
  1257. case DPID_SCENE_3:
  1258. // 场景3处理函数
  1259. ret = dp_download_scene_3_handle(value, length);
  1260. break;
  1261. case DPID_SCENE_4:
  1262. // 场景4处理函数
  1263. ret = dp_download_scene_4_handle(value, length);
  1264. break;
  1265. case DPID_SCENE_5:
  1266. // 场景5处理函数
  1267. ret = dp_download_scene_5_handle(value, length);
  1268. break;
  1269. case DPID_SCENE_6:
  1270. // 场景6处理函数
  1271. ret = dp_download_scene_6_handle(value, length);
  1272. break;
  1273. case DPID_MODE_1:
  1274. // 模式1处理函数
  1275. ret = dp_download_mode_1_handle(value, length);
  1276. break;
  1277. case DPID_MODE_2:
  1278. // 模式2处理函数
  1279. ret = dp_download_mode_2_handle(value, length);
  1280. break;
  1281. case DPID_MODE_3:
  1282. // 模式3处理函数
  1283. ret = dp_download_mode_3_handle(value, length);
  1284. break;
  1285. case DPID_SWITCH_1:
  1286. // 开关1处理函数
  1287. ret = dp_download_switch_1_handle(value, length);
  1288. break;
  1289. case DPID_SWITCH_2:
  1290. // 开关2处理函数
  1291. ret = dp_download_switch_2_handle(value, length);
  1292. break;
  1293. case DPID_SWITCH_3:
  1294. // 开关3处理函数
  1295. ret = dp_download_switch_3_handle(value, length);
  1296. break;
  1297. case DPID_BACKLIGHT_SWITCH:
  1298. // 人感开关处理函数
  1299. ret = dp_download_backlight_switch_handle(value, length);
  1300. break;
  1301. case DPID_LIGHT_MODE:
  1302. // 指示灯亮度处理函数
  1303. ret = dp_download_light_mode_handle(value, length);
  1304. break;
  1305. case DPID_RELAY_STATUS:
  1306. // 上电状态设置处理函数
  1307. ret = dp_download_relay_status_handle(value, length);
  1308. break;
  1309. case DPID_RELAY_STATUS_1:
  1310. // 开关1上电状态设置处理函数
  1311. ret = dp_download_relay_status_1_handle(value, length);
  1312. break;
  1313. case DPID_RELAY_STATUS_2:
  1314. // 开关2上电状态设置处理函数
  1315. ret = dp_download_relay_status_2_handle(value, length);
  1316. break;
  1317. case DPID_RELAY_STATUS_3:
  1318. // 开关3上电状态设置处理函数
  1319. ret = dp_download_relay_status_3_handle(value, length);
  1320. break;
  1321. case DPID_SWITCH_INCHING:
  1322. // 点动开关(延时关)处理函数
  1323. ret = dp_download_switch_inching_handle(value, length);
  1324. break;
  1325. default:
  1326. break;
  1327. }
  1328. return ret;
  1329. }
  1330. #endif
  1331. /**
  1332. * @brief get received cmd total number
  1333. * @param[in] {void}
  1334. * @return received cmd total number
  1335. */
  1336. unsigned char get_download_cmd_total(void)
  1337. {
  1338. return (sizeof(download_cmd) / sizeof(download_cmd[0]));
  1339. }
  1340. /**
  1341. * @brief received zigbee net_work state handle
  1342. * @param[in] {zigbee_work_state} zigbee current network state
  1343. * @return void
  1344. */
  1345. void zigbee_work_state_event(unsigned char zigbee_work_state)
  1346. {
  1347. unsigned short length = 0;
  1348. zigbee_uart_write_frame(ZIGBEE_STATE_CMD, length);
  1349. switch (zigbee_work_state)
  1350. {
  1351. case ZIGBEE_NOT_JION: // 设备从在线切换到不在线则报警,脱网报警(离线状态) 慢闪60s 3s一闪烁
  1352. if (ZG_Joining == CONDITION_JOINGING_TO_NORMAL) // 入网前几入网阶段不进入报警闪烁,防止入网指令发送后的自动脱网导致闪烁混乱
  1353. {
  1354. switchState.zigbee_work_state = 2; // 脱网报警启动
  1355. switchState.time = 6000; // 60秒
  1356. ledSetParam(150, 300); // 3s一闪烁
  1357. }
  1358. break;
  1359. case ZIGBEE_JOIN_GATEWAY: // 新设备入网成功
  1360. ZG_JoinCounter = 18000; // 入网成功,入网计数器置最大值,180秒
  1361. switchState.zigbee_work_state = 1;
  1362. break;
  1363. case ZIGBEE_JOIN_ERROR: // 已经入网设备,发起再次入网,会进入这里
  1364. // 配网超时3分钟,触发误触重连,只要APP不操作添加设备确定按键,设备重新回连至上一个账号下
  1365. // ZG_JoinCounter = 18000; // 配网结束,入网计数器置最大值,180秒
  1366. // switchState.zigbee_work_state = 1;
  1367. break;
  1368. case ZIGBEE_JOINING:
  1369. break;
  1370. default:
  1371. break;
  1372. }
  1373. }
  1374. /**
  1375. * @brief received reset zigbee response
  1376. * @param[in] {state} response state
  1377. * @return void
  1378. */
  1379. void mcu_reset_zigbee_event(unsigned char state)
  1380. {
  1381. switch (state)
  1382. {
  1383. case RESET_ZIGBEE_OK:
  1384. break;
  1385. case RESET_ZIGBEE_ERROR:
  1386. break;
  1387. default:
  1388. break;
  1389. }
  1390. }
  1391. /**
  1392. * @brief check mcu version response
  1393. * @param[in] {void}
  1394. * @return void
  1395. */
  1396. void response_mcu_ota_version_event(void)
  1397. {
  1398. unsigned short length = 0;
  1399. length = set_zigbee_uart_byte(length, get_current_mcu_fw_ver()); // current fw version
  1400. zigbee_uart_write_frame(MCU_OTA_VERSION_CMD, length);
  1401. }
  1402. #ifdef SUPPORT_MCU_OTA
  1403. /**
  1404. * @brief mcu ota update notify response
  1405. * @param[in] {offset} data offset
  1406. * @return void
  1407. */
  1408. void response_mcu_ota_notify_event(unsigned char offset)
  1409. {
  1410. unsigned char i = 0;
  1411. unsigned short length = 0;
  1412. unsigned char update = 0;
  1413. unsigned long app_newcode_add = 0;
  1414. unsigned char j = 0;
  1415. current_mcu_fw_pid(); // current PID
  1416. while (i < 8)
  1417. {
  1418. ota_fw_info.mcu_ota_pid[i] = zigbee_uart_rx_buf[offset + DATA_START + i]; // ota fw PID
  1419. i++;
  1420. }
  1421. ota_fw_info.mcu_ota_ver = zigbee_uart_rx_buf[offset + DATA_START + 8]; // ota fw version
  1422. ota_fw_info.mcu_ota_fw_size = zigbee_uart_rx_buf[offset + DATA_START + 9] << 24 |
  1423. zigbee_uart_rx_buf[offset + DATA_START + 10] << 16 |
  1424. zigbee_uart_rx_buf[offset + DATA_START + 11] << 8 |
  1425. zigbee_uart_rx_buf[offset + DATA_START + 12]; // ota fw size
  1426. ota_fw_info.mcu_ota_checksum = zigbee_uart_rx_buf[offset + DATA_START + 13] << 24 |
  1427. zigbee_uart_rx_buf[offset + DATA_START + 14] << 16 |
  1428. zigbee_uart_rx_buf[offset + DATA_START + 15] << 8 |
  1429. zigbee_uart_rx_buf[offset + DATA_START + 16]; // ota fw checksum
  1430. if ((!strcmp_barry(&ota_fw_info.mcu_ota_pid[0], &current_mcu_pid[0], 8)) &&
  1431. (ota_fw_info.mcu_ota_ver > get_current_mcu_fw_ver() &&
  1432. ota_fw_info.mcu_ota_fw_size > 0))
  1433. { // check fw pid and fw version and fw size
  1434. length = set_zigbee_uart_byte(length, 0x00); // OK
  1435. update = 1; // 校验通过,可进行固件升级
  1436. }
  1437. else
  1438. {
  1439. length = set_zigbee_uart_byte(length, 0x01); // error
  1440. }
  1441. ota_fw_info.mcu_current_offset = 0;
  1442. zigbee_uart_write_frame(MCU_OTA_NOTIFY_CMD, length);
  1443. // add by zzw 升级通知接收成功,第一次调用接收固件命令
  1444. if (update)
  1445. {
  1446. // zzw ota must add
  1447. // 在读取数据之前先对FLASH进行擦除,从第38页开始
  1448. /* app_newcode_add = OTA_NEW_CODE_START_ADD;
  1449. fmc_unlock();
  1450. for (i = 0; i < 26; i++)
  1451. {
  1452. fmc_page_erase(app_newcode_add + i * 1024);
  1453. }
  1454. fmc_lock();*/
  1455. mcu_ota_fw_request(); // 固件升级
  1456. }
  1457. }
  1458. /**
  1459. * @brief received mcu ota data request response
  1460. * @param[in] {fw_offset} offset of file
  1461. * @param[in] {data} received data
  1462. * @return void
  1463. */
  1464. /*void reveived_mcu_ota_data_handle(unsigned int fw_offset, char *data)
  1465. {
  1466. //#error "received frame data, should save in flash, mcu should realize this fuction, and delete this line "
  1467. //未使用
  1468. }*/
  1469. /**
  1470. * @brief mcu send ota data request
  1471. * @param[in] {void}
  1472. * @return void
  1473. */
  1474. void mcu_ota_fw_request_event(unsigned char offset)
  1475. {
  1476. unsigned int fw_offset = 0;
  1477. char fw_data[FW_SINGLE_PACKET_SIZE] = {-1}; //
  1478. unsigned char i = 0;
  1479. unsigned char last_package_len = 0;
  1480. static unsigned int current_checksum = 0;
  1481. if (zigbee_uart_rx_buf[offset + DATA_START] == 0x01) // status check
  1482. return;
  1483. while (i < 8)
  1484. {
  1485. if (current_mcu_pid[i] != zigbee_uart_rx_buf[offset + DATA_START + 1 + i]) // pid check
  1486. return;
  1487. i++;
  1488. }
  1489. if (ota_fw_info.mcu_ota_ver != zigbee_uart_rx_buf[offset + DATA_START + 9]) // version check
  1490. return;
  1491. i = 0;
  1492. while (i < 4)
  1493. {
  1494. fw_offset |= (zigbee_uart_rx_buf[offset + DATA_START + 10 + i] << (24 - i * 8)); // offset
  1495. i++;
  1496. }
  1497. i = 0;
  1498. if (ota_fw_info.mcu_current_offset == fw_offset)
  1499. {
  1500. // if ((ota_fw_info.mcu_ota_fw_size - fw_offset) / FW_SINGLE_PACKET_SIZE != 0)
  1501. if (((ota_fw_info.mcu_ota_fw_size - fw_offset) / FW_SINGLE_PACKET_SIZE != 0) && (ota_fw_info.mcu_ota_fw_size != (fw_offset + FW_SINGLE_PACKET_SIZE)))
  1502. // if (((ota_fw_info.mcu_ota_fw_size - fw_offset) / FW_SINGLE_PACKET_SIZE != 0)&&((ota_fw_info.mcu_ota_fw_size - fw_offset) % FW_SINGLE_PACKET_SIZE != 0))
  1503. {
  1504. if (ota_fw_info.mcu_current_offset == 0)
  1505. {
  1506. current_checksum = 0;
  1507. }
  1508. while (i < FW_SINGLE_PACKET_SIZE)
  1509. {
  1510. fw_data[i] = zigbee_uart_rx_buf[offset + DATA_START + 14 + i]; // fw data
  1511. current_checksum += fw_data[i];
  1512. i++;
  1513. }
  1514. ota_fw_info.mcu_current_offset += FW_SINGLE_PACKET_SIZE;
  1515. ota_fw_data_handle(fw_offset, &fw_data[0], FW_SINGLE_PACKET_SIZE); // OTA paket data handle
  1516. }
  1517. else
  1518. {
  1519. i = 0;
  1520. // last_package_len = ota_fw_info.mcu_ota_fw_size - fw_offset;
  1521. if ((ota_fw_info.mcu_ota_fw_size - fw_offset) % FW_SINGLE_PACKET_SIZE != 0)
  1522. {
  1523. last_package_len = ota_fw_info.mcu_ota_fw_size - fw_offset;
  1524. }
  1525. else
  1526. {
  1527. last_package_len = FW_SINGLE_PACKET_SIZE;
  1528. }
  1529. while (i < last_package_len)
  1530. {
  1531. fw_data[i] = zigbee_uart_rx_buf[offset + DATA_START + 14 + i];
  1532. current_checksum += fw_data[i];
  1533. i++;
  1534. }
  1535. ota_fw_info.mcu_current_offset += last_package_len;
  1536. if (ota_fw_info.mcu_ota_checksum != current_checksum)
  1537. {
  1538. // ota failure report ota failure and clear ota struct
  1539. mcu_ota_result_report(1); // failed
  1540. }
  1541. else
  1542. {
  1543. // ota sucess
  1544. mcu_ota_result_report(0); // seccess
  1545. }
  1546. ota_fw_data_handle(fw_offset, &fw_data[0], last_package_len); // OTA paket data handle
  1547. current_checksum = 0;
  1548. }
  1549. }
  1550. else
  1551. {
  1552. // ota request timeout, then restart ota request from ota_fw_info.mcu_ota_fw_size
  1553. }
  1554. }
  1555. static void report_mcu_ota_result(unsigned char res)
  1556. {
  1557. unsigned short length;
  1558. if ((res == 0) || (res == 1))
  1559. {
  1560. length = set_zigbee_uart_byte(length, res);
  1561. zigbee_uart_write_frame(MCU_OTA_NOTIFY_CMD, length);
  1562. }
  1563. }
  1564. /**
  1565. * @brief mcu ota data result notify
  1566. * @param[in] {void}
  1567. * @return void
  1568. */
  1569. void mcu_ota_result_event(unsigned char offset)
  1570. {
  1571. unsigned short k, Ret;
  1572. u32 temp_buff[256];
  1573. unsigned char status = zigbee_uart_rx_buf[offset + DATA_START];
  1574. if (status == 0x00)
  1575. {
  1576. // 升级成功,用户提示
  1577. IAPUpdateFlag = 1;
  1578. // zzw ota must add
  1579. /* for (k = 0; k < 256; k++)
  1580. {
  1581. temp_buff[k] = flash_word_read(OTA_STATE_DATA_ADD + (4 * k)); // 1.取出程序运行区代码数据
  1582. }
  1583. temp_buff[0] = IAPUpdateFlag;
  1584. delay_1ms(10);
  1585. Ret = flash_page_write(OTA_STATE_DATA_ADD, temp_buff); // 2.将取出的运行区代码写入临时区
  1586. delay_1ms(20);
  1587. flash_word_write (OTA_STATE_DATA_ADD,IAPUpdateFlag);
  1588. delay_1ms(500);
  1589. NVIC_SystemReset(); // add by zzw 系统复位函数
  1590. */
  1591. }
  1592. else if (status == 0x01)
  1593. {
  1594. }
  1595. }
  1596. /**
  1597. * @brief mcu ota data handle
  1598. * @param[in] {fw_offset} frame offset
  1599. * @param[in] {data} received data
  1600. * @return void
  1601. */
  1602. void ota_fw_data_handle(unsigned int fw_offset, char *data1, unsigned char data_len)
  1603. {
  1604. unsigned short i = 0;
  1605. unsigned short update = 1;
  1606. unsigned long app_newcode_add = 0; // 读flash的时候的地址变量,新代码区
  1607. unsigned short temp = 0;
  1608. unsigned long write_data;
  1609. //"请在该函数处理固件包数据"
  1610. //"received frame data, should save in flash, mcu should realize this fuction, and delete this line "
  1611. // 取出数据存入falsh,建议延用‘ota_fw_info’全局变量,不需定义其他全局变量,可维护数据包长度等
  1612. if (fw_offset == 0)
  1613. {
  1614. // zzw ota must add
  1615. /*app_newcode_add = OTA_NEW_CODE_START_ADD;
  1616. fmc_unlock();
  1617. for (i = 0; i < 26; i++)
  1618. {
  1619. fmc_page_erase(app_newcode_add + i * 1024);
  1620. }
  1621. fmc_lock();*/
  1622. }
  1623. OTA_Reciv_Datalen = OTA_Reciv_Datalen + data_len;
  1624. // zzw ota must add
  1625. // app_newcode_add = OTA_NEW_CODE_START_ADD + fw_offset;
  1626. if (data_len == FW_SINGLE_PACKET_SIZE) // 整包数据
  1627. {
  1628. // zzw ota must add
  1629. /* for (i = 0; i < (FW_SINGLE_PACKET_SIZE / 4); i++)
  1630. {
  1631. write_data = 0;
  1632. write_data = data[i * 4 + 3];
  1633. write_data = (write_data << 8) + data[i * 4 + 2];
  1634. write_data = (write_data << 8) + data[i * 4 + 1];
  1635. write_data = (write_data << 8) + data[i * 4];
  1636. flash_word_write(app_newcode_add, write_data);
  1637. app_newcode_add = app_newcode_add + 4;
  1638. }*/
  1639. }
  1640. else // 最后一包非整包数据
  1641. {
  1642. temp = data_len % 4;
  1643. if (temp == 0)
  1644. {
  1645. // zzw ota must add
  1646. /*for (i = 0; i < (data_len / 4); i++)
  1647. {
  1648. write_data = 0;
  1649. write_data = data[i * 4 + 3];
  1650. write_data = (write_data << 8) + data[i * 4 + 2];
  1651. write_data = (write_data << 8) + data[i * 4 + 1];
  1652. write_data = (write_data << 8) + data[i * 4];
  1653. flash_word_write(app_newcode_add, write_data);
  1654. app_newcode_add = app_newcode_add + 4;
  1655. }*/
  1656. }
  1657. }
  1658. // if(OTA_Reciv_Datalen == ota_fw_info.mcu_ota_fw_size) //接收数据完成停止获取
  1659. // {
  1660. // update = 0;
  1661. // }
  1662. if (update) // 数据存储完毕,继续调用获取数据命令
  1663. {
  1664. mcu_ota_fw_request(); // 固件升级
  1665. }
  1666. // #error "请在该函数处理固件包数据,并删除该行"
  1667. }
  1668. #endif
  1669. #ifdef BEACON_TEST
  1670. /**
  1671. * @brief beacon test notify,which used in testing
  1672. * @param[in] {void}
  1673. * @return void
  1674. */
  1675. void mcu_received_beacon_test_handle(void)
  1676. {
  1677. unsigned short length = 0;
  1678. length = set_zigbee_uart_byte(length, 0x00);
  1679. zigbee_uart_write_frame(SEND_BEACON_NOTIFY_CMD, length);
  1680. // then start test
  1681. // add by zzw 产测
  1682. /*if(burn_in_test_timeout<=300)//开机30S内
  1683. {
  1684. burn_in_test_start=1;
  1685. //burn_in_test_counter=0;
  1686. }*/
  1687. }
  1688. #endif
  1689. #ifdef CHECK_ZIGBEE_NETWORK
  1690. /**
  1691. * @brief check zigbee nwkstate,before start join nwk, check nwk if state is not 0x02,can start jion,
  1692. * else delay 5s
  1693. *
  1694. * @param[in] {void}
  1695. * @return void
  1696. */
  1697. void mcu_check_zigbee_nwk_state(void)
  1698. {
  1699. unsigned short length = 0;
  1700. zigbee_uart_write_frame(CHECK_ZIGBEE_NETWORK_CMD, length);
  1701. // then start test
  1702. }
  1703. #endif
  1704. void zigbee_notify_factory_new_hanlde(void)
  1705. {
  1706. unsigned short length = 0;
  1707. length = set_zigbee_uart_byte(length, 0x01);
  1708. zigbee_uart_write_frame(ZIGBEE_FACTORY_NEW_CMD, length);
  1709. // then start test
  1710. // add by zzw 20240207 APP删除设备后自动入网开启
  1711. ZG_Joining = CONDITION_BEFOR_JOINING_TO_JOINING; // 配网倒计时
  1712. ZG_JoinCounter = 0;
  1713. ledSetParam(6, 12); // 高速闪烁,所有指示灯8Hz闪烁(表现为三位开关三个指示灯都闪烁)
  1714. // mcu_join_zigbee(); // 发送入网指令
  1715. switchState.zigbee_work_state = 0; // 设备被删除
  1716. }
  1717. #ifdef READ_DP_DATA_NOTIFY
  1718. /**
  1719. * @brief when gateway repower or relink clould, or zigbee module join sucess, repower, this commod will notify
  1720. * mcu, to sys dp data, mcu itself decide whether report.
  1721. *
  1722. * @param[in] {void}
  1723. * @return void
  1724. */
  1725. void read_dp_data_notify_hanlde(void)
  1726. {
  1727. unsigned short length = 0;
  1728. length = set_zigbee_uart_byte(length, 0x01);
  1729. zigbee_uart_write_frame(ZIGBEE_FACTORY_NEW_CMD, length);
  1730. // then start test
  1731. }
  1732. #endif
  1733. /*static const char decoding_table[] = {
  1734. 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, -1,
  1735. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
  1736. 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  1737. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
  1738. void base64_decode_three_bytes(const char input[4], u08 output[3])
  1739. {
  1740. u32 temp = 0;
  1741. int i = 0;
  1742. for (i = 0; i < 4; ++i)
  1743. {
  1744. if (input[i] >= 'A' && input[i] <= 'Z')
  1745. temp = (temp << 6) | decoding_table[input[i] - 'A'];
  1746. else if (input[i] >= 'a' && input[i] <= 'z')
  1747. temp = (temp << 6) | (decoding_table[input[i] - 'a'] + 26);
  1748. else if (input[i] >= '0' && input[i] <= '9')
  1749. temp = (temp << 6) | (decoding_table[input[i] - '0'] + 52);
  1750. else if (input[i] == '+')
  1751. temp = (temp << 6) | 62;
  1752. else if (input[i] == '/')
  1753. temp = (temp << 6) | 63;
  1754. }
  1755. for (i = 2; i >= 0; --i)
  1756. {
  1757. output[i] = temp & 0xFF;
  1758. temp >>= 8;
  1759. }
  1760. }*/