MCU 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. /**
  2. * @file mcu_api.c
  3. * @brief this file contains basic fuctions and DP data report fucntion which is base on DP type
  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 "./mcu_sdk/zigbee.h"//directory by ddw
  12. #include "gd32f30x.h"
  13. /**
  14. * @brief hex translate to bcd
  15. * @param[in] {Value_H} higher bits data
  16. * @param[in] {Value_L} lower bits data
  17. * @return bcd type data
  18. */
  19. unsigned char hex_to_bcd(unsigned char Value_H,unsigned char Value_L)
  20. {
  21. unsigned char bcd_value;
  22. if((Value_H >= '0') && (Value_H <= '9')){
  23. Value_H -= '0';
  24. }
  25. else if((Value_H >= 'A') && (Value_H <= 'F')){
  26. Value_H = Value_H - 'A' + 10;
  27. }
  28. else if((Value_H >= 'a') && (Value_H <= 'f')){
  29. Value_H = Value_H - 'a' + 10;
  30. }
  31. bcd_value = Value_H & 0x0f;
  32. bcd_value <<= 4;
  33. if((Value_L >= '0') && (Value_L <= '9')){
  34. Value_L -= '0';
  35. }
  36. else if((Value_L >= 'A') && (Value_L <= 'F')){
  37. Value_L = Value_L - 'a' + 10;
  38. }
  39. else if((Value_L >= 'a') && (Value_L <= 'f')){
  40. Value_L = Value_L - 'a' + 10;
  41. }
  42. bcd_value |= Value_L & 0x0f;
  43. return bcd_value;
  44. }
  45. /**
  46. * @brief get string len
  47. * @param[in] {str} higher bits data
  48. * @return string len
  49. */
  50. unsigned long my_strlen(unsigned char *str)
  51. {
  52. unsigned long len = 0;
  53. if(str == NULL){
  54. return 0;
  55. }
  56. for(len = 0; *str ++ != '\0'; ){
  57. len ++;
  58. }
  59. return len;
  60. }
  61. /**
  62. * @brief assign ch to the first count bytes of the memory address src
  63. * @param[in] {src} srouce address
  64. * @param[in] {ch} set value
  65. * @param[in] {count} length of set address
  66. * @return void
  67. */
  68. void *my_memset(void *src,unsigned char ch,unsigned short count)
  69. {
  70. unsigned char *tmp = (unsigned char *)src;
  71. if(src == NULL){
  72. return NULL;
  73. }
  74. while(count --){
  75. *tmp ++ = ch;
  76. }
  77. return src;
  78. }
  79. /**
  80. * @brief copy count bytes data from src to dest
  81. * @param[in] {src} srouce address
  82. * @param[in] {dest} destination address
  83. * @param[in] {count} length of copy data
  84. * @return void
  85. */
  86. void *my_memcpy(void *dest, const void *src, unsigned short count)
  87. {
  88. unsigned char *pdest = (unsigned char *)dest;
  89. const unsigned char *psrc = (const unsigned char *)src;
  90. unsigned short i;
  91. if(dest == NULL || src == NULL){
  92. return NULL;
  93. }
  94. if((pdest <= psrc) || (pdest > psrc + count)){
  95. for(i = 0; i < count; i ++){
  96. pdest[i] = psrc[i];
  97. }
  98. }
  99. else{
  100. for(i = count; i > 0; i --){
  101. pdest[i - 1] = psrc[i - 1];
  102. }
  103. }
  104. return dest;
  105. }
  106. /**
  107. * @brief copy string src to string dest
  108. * @param[in] {src} srouce address
  109. * @param[in] {dest} destination address
  110. * @return the tail of destination
  111. */
  112. char *my_strcpy(char *dest, const char *src)
  113. {
  114. char *p = dest;
  115. while(*src!='\0'){
  116. *dest++ = *src++;
  117. }
  118. *dest = '\0';
  119. return p;
  120. }
  121. /**
  122. * @brief compare string s1 with string s2
  123. * @param[in] {s1} srouce address
  124. * @param[in] {s2} destination address
  125. * @return compare result
  126. */
  127. int my_strcmp(char *s1 , char *s2)
  128. {
  129. while( *s1 && *s2 && *s1 == *s2 ){
  130. s1++;
  131. s2++;
  132. }
  133. return *s1 - *s2;
  134. }
  135. /**
  136. * @brief int translate to byte
  137. * @param[in] {number} int data
  138. * @param[out] {value} the result array
  139. * @return void
  140. */
  141. void int_to_byte(unsigned long number,unsigned char value[4])
  142. {
  143. value[0] = number >> 24;
  144. value[1] = number >> 16;
  145. value[2] = number >> 8;
  146. value[3] = number & 0xff;
  147. }
  148. /**
  149. * @brief byte data translate to int
  150. * @param[in] {value} the byte array
  151. * @return result of int data
  152. */
  153. unsigned long byte_to_int(const unsigned char value[4])
  154. {
  155. unsigned long nubmer = 0;
  156. nubmer = (unsigned long)value[0];
  157. nubmer <<= 8;
  158. nubmer |= (unsigned long)value[1];
  159. nubmer <<= 8;
  160. nubmer |= (unsigned long)value[2];
  161. nubmer <<= 8;
  162. nubmer |= (unsigned long)value[3];
  163. return nubmer;
  164. }
  165. /**
  166. * @brief report bool type DP data to zigbee module
  167. * @param[in] {dpid} dp id
  168. * @param[in] {value} Data contents of dp
  169. * @return send result
  170. */
  171. unsigned char mcu_dp_bool_update(unsigned char dpid,unsigned char value)
  172. {
  173. unsigned short length = 0;
  174. length = set_zigbee_uart_byte(length,dpid);
  175. length = set_zigbee_uart_byte(length,DP_TYPE_BOOL);
  176. length = set_zigbee_uart_byte(length,0);
  177. length = set_zigbee_uart_byte(length,1);
  178. if(value == FALSE){
  179. length = set_zigbee_uart_byte(length,FALSE);
  180. }
  181. else{
  182. length = set_zigbee_uart_byte(length,1);
  183. }
  184. zigbee_uart_write_frame(DATA_REPORT_CMD,length);
  185. return SUCCESS;
  186. }
  187. /**
  188. * @brief report enum type DP data to zigbee module
  189. * @param[in] {dpid} dp id
  190. * @param[in] {value} Data contents of dp
  191. * @return send result
  192. */
  193. unsigned char mcu_dp_enum_update(unsigned char dpid,unsigned char value)
  194. {
  195. unsigned short length = 0;
  196. length = set_zigbee_uart_byte(length,dpid);
  197. length = set_zigbee_uart_byte(length,DP_TYPE_ENUM);
  198. //
  199. length = set_zigbee_uart_byte(length,0);
  200. length = set_zigbee_uart_byte(length,1);
  201. //
  202. length = set_zigbee_uart_byte(length,value);
  203. zigbee_uart_write_frame(DATA_REPORT_CMD,length);
  204. return SUCCESS;
  205. }
  206. /**
  207. * @brief report bitmap type DP data to zigbee module
  208. * @param[in] {dpid} dp id
  209. * @param[in] {value} Data contents of dp
  210. * @return send result
  211. */
  212. unsigned char mcu_dp_bitmap_update(unsigned char dpid,unsigned long value)
  213. {
  214. unsigned short length = 0;
  215. length = set_zigbee_uart_byte(length,dpid);
  216. length = set_zigbee_uart_byte(length,DP_TYPE_BITMAP);
  217. //
  218. length = set_zigbee_uart_byte(length,0);
  219. if((value | 0xff) == 0xff){
  220. length = set_zigbee_uart_byte(length,1);
  221. length = set_zigbee_uart_byte(length,value);
  222. }
  223. else if((value | 0xffff) == 0xffff){
  224. length = set_zigbee_uart_byte(length,2);
  225. length = set_zigbee_uart_byte(length,value >> 8);
  226. length = set_zigbee_uart_byte(length,value & 0xff);
  227. }
  228. else{
  229. length = set_zigbee_uart_byte(length,4);
  230. length = set_zigbee_uart_byte(length,value >> 24);
  231. length = set_zigbee_uart_byte(length,value >> 16);
  232. length = set_zigbee_uart_byte(length,value >> 8);
  233. length = set_zigbee_uart_byte(length,value & 0xff);
  234. }
  235. zigbee_uart_write_frame(DATA_REPORT_CMD,length);
  236. return SUCCESS;
  237. }
  238. /**
  239. * @brief report fault type DP data to zigbee module
  240. * @param[in] {dpid} dp id
  241. * @param[in] {value} Data contents of dp
  242. * @return send result
  243. */
  244. unsigned char mcu_dp_fault_update(unsigned char dpid,unsigned long value)
  245. {
  246. unsigned short length = 0;
  247. length = set_zigbee_uart_byte(length,dpid);
  248. length = set_zigbee_uart_byte(length,DP_TYPE_BITMAP);
  249. //
  250. length = set_zigbee_uart_byte(length,0);
  251. if((value | 0xff) == 0xff){
  252. length = set_zigbee_uart_byte(length,1);
  253. length = set_zigbee_uart_byte(length,value);
  254. }
  255. else if((value | 0xffff) == 0xffff){
  256. length = set_zigbee_uart_byte(length,2);
  257. length = set_zigbee_uart_byte(length,value >> 8);
  258. length = set_zigbee_uart_byte(length,value & 0xff);
  259. }
  260. else{
  261. length = set_zigbee_uart_byte(length,4);
  262. length = set_zigbee_uart_byte(length,value >> 24);
  263. length = set_zigbee_uart_byte(length,value >> 16);
  264. length = set_zigbee_uart_byte(length,value >> 8);
  265. length = set_zigbee_uart_byte(length,value & 0xff);
  266. }
  267. zigbee_uart_write_frame(DATA_REPORT_CMD,length);
  268. return SUCCESS;
  269. }
  270. /**
  271. * @brief report raw type DP data to zigbee module
  272. * @param[in] {dpid} dp id
  273. * @param[in] {value} Data contents of dp
  274. * @param[in] {len} length of Data contents
  275. * @return send result
  276. */
  277. unsigned char mcu_dp_raw_update(unsigned char dpid,const unsigned char value[],unsigned short len)
  278. {
  279. unsigned short length = 0;
  280. length = set_zigbee_uart_byte(length,dpid);
  281. length = set_zigbee_uart_byte(length,DP_TYPE_RAW);
  282. //
  283. length = set_zigbee_uart_byte(length,len / 0x100);
  284. length = set_zigbee_uart_byte(length,len % 0x100);
  285. //
  286. length = set_zigbee_uart_buffer(length,(unsigned char *)value,len);
  287. zigbee_uart_write_frame(DATA_REPORT_CMD,length);
  288. return SUCCESS;
  289. }
  290. /**
  291. * @brief report string type DP data to zigbee module
  292. * @param[in] {dpid} dp id
  293. * @param[in] {value} Data contents of dp
  294. * @param[in] {len} length of Data contents
  295. * @return send result
  296. */
  297. unsigned char mcu_dp_string_update(unsigned char dpid,const unsigned char value[],unsigned short len)
  298. {
  299. unsigned short length = 0;
  300. length = set_zigbee_uart_byte(length,dpid);
  301. length = set_zigbee_uart_byte(length,DP_TYPE_STRING);
  302. //
  303. length = set_zigbee_uart_byte(length,len / 0x100);
  304. length = set_zigbee_uart_byte(length,len % 0x100);
  305. //
  306. length = set_zigbee_uart_buffer(length,(unsigned char *)value,len);
  307. zigbee_uart_write_frame(DATA_REPORT_CMD,length);
  308. return SUCCESS;
  309. }
  310. /**
  311. * @brief report raw type DP data to zigbee module
  312. * @param[in] {dpid} dp id
  313. * @param[in] {value} Data contents of dp
  314. * @return send result
  315. */
  316. unsigned char mcu_dp_value_update(unsigned char dpid,unsigned long value)
  317. {
  318. unsigned short length = 0;
  319. length = set_zigbee_uart_byte(length,dpid);
  320. length = set_zigbee_uart_byte(length,DP_TYPE_VALUE);
  321. //
  322. length = set_zigbee_uart_byte(length,0);
  323. length = set_zigbee_uart_byte(length,4);
  324. //
  325. length = set_zigbee_uart_byte(length,value >> 24);
  326. length = set_zigbee_uart_byte(length,value >> 16);
  327. length = set_zigbee_uart_byte(length,value >> 8);
  328. length = set_zigbee_uart_byte(length,value & 0xff);
  329. zigbee_uart_write_frame(DATA_REPORT_CMD,length);
  330. return SUCCESS;
  331. }
  332. /**
  333. * @brief mcu get bool type value from zigbee translate
  334. * @param[in] {value} data of dp
  335. * @param[in] {len} Data length
  336. * @return true or false
  337. */
  338. unsigned char mcu_get_dp_download_bool(const unsigned char value[],unsigned short len)
  339. {
  340. return(value[0]);
  341. }
  342. /**
  343. * @brief mcu get enum type value from zigbee translate
  344. * @param[in] {value} data of dp
  345. * @param[in] {len} Data length
  346. * @return enum data
  347. */
  348. unsigned char mcu_get_dp_download_enum(const unsigned char value[],unsigned short len)
  349. {
  350. return(value[0]);
  351. }
  352. /**
  353. * @brief mcu get value type value from zigbee translate
  354. * @param[in] {value} data of dp
  355. * @param[in] {len} Data length
  356. * @return value data
  357. */
  358. unsigned long mcu_get_dp_download_value(const unsigned char value[],unsigned short len)
  359. {
  360. return(byte_to_int(value));
  361. }
  362. /**
  363. * @brief mcu start zigbee module test
  364. * @param[in] {channel} test channel usually 11
  365. * @return void
  366. */
  367. void mcu_start_zigbee_test(unsigned char channel)
  368. {
  369. zigbee_uart_tx_buf[DATA_START] = channel;
  370. zigbee_uart_write_frame(ZIGBEE_RF_TEST_CMD,1);
  371. }
  372. /**
  373. * @brief mcu reset zigbee module
  374. * @param[in] {void}
  375. * @return void
  376. */
  377. void mcu_reset_zigbee(void)
  378. {
  379. unsigned short length = 0;
  380. length = set_zigbee_uart_byte(length,0);
  381. zigbee_uart_write_frame(ZIGBEE_CFG_CMD, length);
  382. }
  383. /**
  384. * @brief mcu start zigbee module
  385. * this commond must be call after reveived checking proudect info, or after get zigbee network info
  386. * @param[in] {void}
  387. * @return void
  388. */
  389. void mcu_network_start(void)
  390. {
  391. unsigned short length = 0;
  392. length = set_zigbee_uart_byte(length,1);
  393. zigbee_uart_write_frame(ZIGBEE_CFG_CMD, length);
  394. }
  395. /**
  396. * @brief copy receive data from uart receive interrupt
  397. * @param[in] {value} Data received from interrupt
  398. * @return void
  399. */
  400. void uart_receive_input(unsigned char value)
  401. {
  402. // #error "please call this fuction in the interrupt fuction of serial receive, and delete this line"
  403. if(1 == queue_out - queue_in) {
  404. //queue full
  405. }else if((queue_in > queue_out) && ((queue_in - queue_out) >= sizeof(zigbee_queue_buf))) {
  406. //queue full
  407. }else {
  408. //queue not full
  409. if(queue_in >= (unsigned char *)(zigbee_queue_buf + sizeof(zigbee_queue_buf))){
  410. queue_in = (unsigned char *)(zigbee_queue_buf);
  411. }
  412. *queue_in ++ = value;
  413. }
  414. }
  415. /**
  416. * @brief init paramter and set rx_buf with zero
  417. * @param[in] {void}
  418. * @return void
  419. */
  420. void zigbee_protocol_init(void)
  421. {
  422. // #error "please call this fuction in main init"
  423. queue_in = (unsigned char *)zigbee_queue_buf;
  424. queue_out = (unsigned char *)zigbee_queue_buf;
  425. }
  426. /**
  427. * @brief read byte from zigbee_queue_buf array
  428. * @param[in] {void}
  429. * @return read byte value
  430. */
  431. unsigned char Queue_Read_Byte(void)
  432. {
  433. unsigned char value;
  434. if(queue_out != queue_in) {
  435. //have data in queue
  436. if(queue_out >= (unsigned char *)(zigbee_queue_buf + sizeof(zigbee_queue_buf))) {
  437. queue_out = (unsigned char *)(zigbee_queue_buf);
  438. }
  439. value = *queue_out ++;
  440. }
  441. return value;
  442. }
  443. /**
  444. * @brief check rx buffer is empty or not
  445. * @param Null
  446. * @return the queue state
  447. */
  448. unsigned char with_data_rxbuff(void)
  449. {
  450. if(queue_out != queue_in)
  451. return 1;
  452. else
  453. return 0;
  454. }
  455. /**
  456. * @brief uart receive data handle, call this function at mian loop
  457. * @param[in] {void}
  458. * @return void
  459. */
  460. void zigbee_uart_service(void)
  461. {
  462. // #error "please call this fucntion in main while(1){}, and delete this line"
  463. static unsigned short rx_in = 0;
  464. unsigned short offset = 0;
  465. unsigned short rx_value_len = 0;
  466. unsigned short protocol_version = 0, protocol_head_len = PROTOCOL_HEAD;
  467. while((rx_in < sizeof(zigbee_uart_rx_buf)) && (with_data_rxbuff() > 0)){
  468. zigbee_uart_rx_buf[rx_in++] = Queue_Read_Byte();
  469. }
  470. if(rx_in < PROTOCOL_HEAD){
  471. return;
  472. }
  473. while((rx_in - offset) >= PROTOCOL_HEAD){
  474. if(zigbee_uart_rx_buf[offset + HEAD_FIRST] != FIRST_FRAME_HEAD){
  475. offset++;
  476. continue;
  477. }
  478. if(zigbee_uart_rx_buf[offset + HEAD_SECOND] != SECOND_FRAME_HEAD){
  479. offset++;
  480. continue;
  481. }
  482. protocol_version = zigbee_uart_rx_buf[offset + PROTOCOL_VERSION];
  483. if(protocol_version != SERIAL_PROTOCOL_VER) /*version 2 is more than two byte sequence number than version 1*/
  484. {
  485. offset += 2;
  486. continue;
  487. }
  488. rx_value_len = zigbee_uart_rx_buf[offset + LENGTH_HIGH ] * 0x100;
  489. rx_value_len += (zigbee_uart_rx_buf[offset + LENGTH_LOW] + PROTOCOL_HEAD);
  490. if(rx_value_len > sizeof(zigbee_uart_rx_buf)){
  491. offset += 3;
  492. continue;
  493. }
  494. if((rx_in - offset) < rx_value_len){
  495. break;
  496. }
  497. if( get_check_sum((unsigned char *)zigbee_uart_rx_buf + offset, rx_value_len - 1) != zigbee_uart_rx_buf[offset + rx_value_len - 1]){
  498. offset += 3;
  499. continue;
  500. }
  501. data_handle(offset); //数据处理
  502. offset += rx_value_len;
  503. }
  504. rx_in -= offset;
  505. if(rx_in > 0){
  506. if((offset == 0) && (rx_in >= sizeof(zigbee_uart_rx_buf))){
  507. offset++;
  508. rx_in -= offset;
  509. }
  510. my_memcpy((char*)zigbee_uart_rx_buf, (const char *)zigbee_uart_rx_buf + offset, rx_in);
  511. }
  512. }