spi_demo.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. /*================================================================
  2. Copyright (c) 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
  3. Quectel Wireless Solution Proprietary and Confidential.
  4. =================================================================*/
  5. /*=================================================================
  6. EDIT HISTORY FOR MODULE
  7. This section contains comments describing changes made to the module.
  8. Notice that changes are listed in reverse chronological order.
  9. WHEN WHO WHAT, WHERE, WHY
  10. ------------ ------- -------------------------------------------------------------------------------
  11. =================================================================*/
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include "ql_api_osi.h"
  16. #include "ql_api_spi.h"
  17. #include "ql_log.h"
  18. #include "spi_demo.h"
  19. #include "ql_gpio.h"
  20. #include "ql_power.h"
  21. #define QL_SPI_DEMO_LOG_LEVEL QL_LOG_LEVEL_INFO
  22. #define QL_SPI_DEMO_LOG(msg, ...) QL_LOG(QL_SPI_DEMO_LOG_LEVEL, "ql_SPI_DEMO", msg, ##__VA_ARGS__)
  23. #define QL_SPI_DEMO_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_SPI_DEMO", msg, ##__VA_ARGS__)
  24. /**
  25. * 使用SPI DMA注意事项:
  26. * 8910:
  27. * 1. SPI DMA POLLING和SPI DMA IRQ只支持8bit和16bit的数据传输,不支持32bit数据传输
  28. * 2. 在使用16bit传输数据时,DMA实际使用的是32bit位宽,需要对输出数据插入一些无效数据,对输入数据去除无效数据,
  29. * 因此新增16bit dma api用于16bit情况下的读写,api包含ql_spi_write_16bit_dma、ql_spi_read_16bit_dma、
  30. * ql_spi_write_read_16bit_dma,这部分代码在demo中开源,客户可自行优化,或直接使用
  31. * 3. QL_SPI_16BIT_DMA置为1表示使用16bit DMA demo
  32. * 8850:
  33. * 1. SPI DMA POLLING和SPI DMA IRQ支持8bits、16bits和32bits的数据传输,但是传输的数据大小需要framesize对齐。
  34. */
  35. #define QL_SPI_16BIT_DMA 0 //16bit DMA demo
  36. #define QL_SPI_DEMO_LOW_POWER_USE 0 //0-not run in lower power mode;1-run in lower power mode
  37. ql_task_t spi_demo_task = NULL;
  38. ql_sem_t spi_demo_write;
  39. ql_sem_t spi_demo_read;
  40. int spi_power_lock = 0;
  41. #define QL_SPI_DEMO_WAIT_NONE 0
  42. #define QL_SPI_DEMO_WAIT_WRITE 1
  43. #define QL_SPI_DEMO_WAIT_READ 2
  44. unsigned char spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
  45. #if 1
  46. #define QL_CUR_SPI_PORT QL_SPI_PORT1
  47. #define QL_CUR_SPI_CS_PIN QL_CUR_SPI1_CS_PIN
  48. #define QL_CUR_SPI_CS_FUNC QL_CUR_SPI1_CS_FUNC
  49. #define QL_CUR_SPI_CLK_PIN QL_CUR_SPI1_CLK_PIN
  50. #define QL_CUR_SPI_CLK_FUNC QL_CUR_SPI1_CLK_FUNC
  51. #define QL_CUR_SPI_DO_PIN QL_CUR_SPI1_DO_PIN
  52. #define QL_CUR_SPI_DO_FUNC QL_CUR_SPI1_DO_FUNC
  53. #define QL_CUR_SPI_DI_PIN QL_CUR_SPI1_DI_PIN
  54. #define QL_CUR_SPI_DI_FUNC QL_CUR_SPI1_DI_FUNC
  55. #else
  56. #define QL_CUR_SPI_PORT QL_SPI_PORT2
  57. #define QL_CUR_SPI_CS_PIN QL_CUR_SPI2_CS_PIN
  58. #define QL_CUR_SPI_CS_FUNC QL_CUR_SPI2_CS_FUNC
  59. #define QL_CUR_SPI_CLK_PIN QL_CUR_SPI2_CLK_PIN
  60. #define QL_CUR_SPI_CLK_FUNC QL_CUR_SPI2_CLK_FUNC
  61. #define QL_CUR_SPI_DO_PIN QL_CUR_SPI2_DO_PIN
  62. #define QL_CUR_SPI_DO_FUNC QL_CUR_SPI2_DO_FUNC
  63. #define QL_CUR_SPI_DI_PIN QL_CUR_SPI2_DI_PIN
  64. #define QL_CUR_SPI_DI_FUNC QL_CUR_SPI2_DI_FUNC
  65. #endif
  66. #define QL_TYPE_SHIFT_8 8
  67. uint32_t g_inbuf[QL_SPI_DMA_IRQ_SIZE/4] OSI_CACHE_LINE_ALIGNED;
  68. uint32_t g_outbuf[QL_SPI_DMA_IRQ_SIZE/4] OSI_CACHE_LINE_ALIGNED;
  69. void ql_spi_read_data_transform(unsigned char *buf, unsigned int len)
  70. {
  71. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  72. {
  73. QL_SPI_DEMO_LOG("invalid parm");
  74. return;
  75. }
  76. for(int i = 0; i < len/2; i++)
  77. {
  78. buf[i*2] = (g_inbuf[i] >> QL_TYPE_SHIFT_8) & 0xFF;
  79. buf[i*2+1] = g_inbuf[i] & 0xFF;
  80. }
  81. }
  82. ql_errcode_spi_e ql_spi_write_16bit_dma(ql_spi_port_e port, unsigned char *buf, unsigned int len)
  83. {
  84. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  85. {
  86. QL_SPI_DEMO_LOG("invalid parm");
  87. return QL_SPI_PARAM_DATA_ERROR;
  88. }
  89. unsigned short out_temp = 0;
  90. for(int i = 0; i < len/2; i++)
  91. {
  92. out_temp = buf[i*2];
  93. g_outbuf[i] = (out_temp << QL_TYPE_SHIFT_8) + buf[i*2+1];
  94. }
  95. return ql_spi_write(port, (unsigned char*)g_outbuf, len*2);
  96. }
  97. ql_errcode_spi_e ql_spi_read_16bit_dma(ql_spi_port_e port, unsigned char *buf, unsigned int len)
  98. {
  99. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  100. {
  101. QL_SPI_DEMO_LOG("invalid parm");
  102. return QL_SPI_PARAM_DATA_ERROR;
  103. }
  104. return ql_spi_read(port, (unsigned char*)g_inbuf, len*2);
  105. }
  106. ql_errcode_spi_e ql_spi_write_read_16bit_dma(ql_spi_port_e port, unsigned char *inbuf, unsigned char *outbuf, unsigned int len)
  107. {
  108. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  109. {
  110. QL_SPI_DEMO_LOG("invalid parm");
  111. return QL_SPI_PARAM_DATA_ERROR;
  112. }
  113. unsigned short out_temp = 0;
  114. for(int i = 0; i < len/2; i++)
  115. {
  116. out_temp = outbuf[i*2];
  117. g_outbuf[i] = (out_temp << QL_TYPE_SHIFT_8) + outbuf[i*2+1];
  118. }
  119. return ql_spi_write_read(port, (unsigned char*)g_inbuf, (unsigned char*)g_outbuf, len*2);
  120. }
  121. void ql_spi_flash_data_printf(unsigned char *data, int len)
  122. {
  123. int i = 0;
  124. int count_len = 256;
  125. int count = 0;
  126. int exit = 0;
  127. int write_len = 0;
  128. int pos = 0;
  129. unsigned char *str_data = (unsigned char *)malloc(len*2+64);
  130. if (str_data == NULL)
  131. {
  132. QL_SPI_DEMO_LOG("malloc err");
  133. return ;
  134. }
  135. QL_SPI_DEMO_LOG("read len=%d", len);
  136. while ((exit == 0))
  137. {
  138. if (len - count > 256)
  139. {
  140. count_len = 256;
  141. }
  142. else
  143. {
  144. count_len = len - count;
  145. exit = 1;
  146. }
  147. memset(str_data, 0, len*2+64);
  148. for (i=count; i<count+count_len; i++)
  149. {
  150. //sprintf((char *)str_data,"%s%02x", str_data, data[i]);
  151. write_len += snprintf((char *)(str_data + write_len),(len*2+64 - write_len), "%02x", data[i]);
  152. }
  153. QL_SPI_DEMO_LOG("data[%d-%d]=%s", count, count+count_len, (char *)(str_data+pos));
  154. pos += write_len;
  155. count += count_len;
  156. }
  157. free(str_data);
  158. }
  159. void ql_spi_demo_cb_handler(ql_spi_irq_s cause)
  160. {
  161. if (cause.tx_dma_done == 1 && spi_demo_wait_write_read == QL_SPI_DEMO_WAIT_WRITE)
  162. {
  163. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
  164. ql_rtos_semaphore_release(spi_demo_write);
  165. }
  166. if (cause.rx_dma_done == 1 && spi_demo_wait_write_read == QL_SPI_DEMO_WAIT_READ)
  167. {
  168. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
  169. ql_rtos_semaphore_release(spi_demo_read);
  170. }
  171. QL_SPI_DEMO_LOG("cause.tx_dma_done=%d", cause.tx_dma_done);
  172. QL_SPI_DEMO_LOG("cause.rx_dma_done=%d", cause.rx_dma_done);
  173. }
  174. static void ql_spi_demo_task_pthread(void *ctx)
  175. {
  176. QlOSStatus err = 0;
  177. unsigned char *outdata = NULL;
  178. unsigned short outlen;
  179. unsigned char *indata = NULL;
  180. unsigned short inlen;
  181. unsigned char *out_mal_data = NULL;
  182. unsigned char *in_mal_data = NULL;
  183. ql_errcode_gpio ret;
  184. ql_spi_clk_e spiclk;
  185. ql_spi_transfer_mode_e transmode;
  186. unsigned int framesize;
  187. unsigned int tx_free = 0;
  188. ql_spi_config_s spi_config = {0};
  189. if (QL_CUR_SPI_CS_PIN == QUEC_PIN_NONE || QL_CUR_SPI_CS_PIN == QUEC_PIN_NONE || \
  190. QL_CUR_SPI_DO_PIN == QUEC_PIN_NONE || QL_CUR_SPI_DI_PIN == QUEC_PIN_NONE)
  191. {
  192. QL_SPI_DEMO_LOG("pin err");
  193. goto QL_SPI_EXIT;
  194. }
  195. ret = ql_pin_set_func(QL_CUR_SPI_CS_PIN, QL_CUR_SPI_CS_FUNC);
  196. if (ret != QL_GPIO_SUCCESS)
  197. {
  198. QL_SPI_DEMO_LOG("set pin err");
  199. goto QL_SPI_EXIT;
  200. }
  201. ret = ql_pin_set_func(QL_CUR_SPI_CLK_PIN, QL_CUR_SPI_CLK_FUNC);
  202. if (ret != QL_GPIO_SUCCESS)
  203. {
  204. QL_SPI_DEMO_LOG("set pin err");
  205. goto QL_SPI_EXIT;
  206. }
  207. ret = ql_pin_set_func(QL_CUR_SPI_DO_PIN, QL_CUR_SPI_DO_FUNC);
  208. if (ret != QL_GPIO_SUCCESS)
  209. {
  210. QL_SPI_DEMO_LOG("set pin err");
  211. goto QL_SPI_EXIT;
  212. }
  213. ret = ql_pin_set_func(QL_CUR_SPI_DI_PIN, QL_CUR_SPI_DI_FUNC);
  214. if (ret != QL_GPIO_SUCCESS)
  215. {
  216. QL_SPI_DEMO_LOG("set pin err");
  217. goto QL_SPI_EXIT;
  218. }
  219. //If you use the default parameters, you can initialize it with ql_spi_init
  220. /*transmode = QL_SPI_DMA_IRQ;
  221. spiclk = QL_SPI_CLK_25MHZ;
  222. framesize = 8;
  223. ql_spi_init(QL_CUR_SPI_PORT, transmode, spiclk);
  224. */
  225. spi_config.input_mode = QL_SPI_INPUT_TRUE;
  226. spi_config.port = QL_CUR_SPI_PORT;
  227. #if QL_SPI_16BIT_DMA
  228. framesize = 16;
  229. #else
  230. framesize = 8;
  231. #endif
  232. transmode = QL_SPI_DMA_IRQ; //使用QL_SPI_DMA_IRQ模式,传输一次最大的数据量为512个字节
  233. spiclk = QL_SPI_CLK_2MHZ;
  234. spi_config.spiclk = spiclk;
  235. spi_config.framesize = framesize;
  236. spi_config.cs_polarity0 = QL_SPI_CS_ACTIVE_LOW;
  237. spi_config.cs_polarity1 = QL_SPI_CS_ACTIVE_LOW;
  238. spi_config.cpol = QL_SPI_CPOL_LOW;
  239. spi_config.cpha = QL_SPI_CPHA_1Edge;
  240. spi_config.input_sel = QL_SPI_DI_1;
  241. spi_config.transmode = transmode;
  242. spi_config.cs = QL_SPI_CS0;
  243. spi_config.clk_delay = QL_SPI_CLK_DELAY_0;
  244. ql_spi_init_ext(spi_config);
  245. //使用QL_SPI_DMA_IRQ模式才会使用到信号量
  246. if(transmode == QL_SPI_DMA_IRQ)
  247. {
  248. ql_spi_irq_s mask = {0};
  249. mask.rx_dma_done = 1;
  250. mask.tx_dma_done = 1;
  251. //mask.tx_threshold = QL_SPI_TRIGGER_4_DATA;
  252. //mask.rx_threshold = QL_SPI_TRIGGER_4_DATA;
  253. ql_rtos_semaphore_create(&spi_demo_write, 0);
  254. ql_rtos_semaphore_create(&spi_demo_read, 0);
  255. ql_spi_set_irq(QL_CUR_SPI_PORT, mask, ql_spi_demo_cb_handler);
  256. }
  257. //用来测试SPI CS脚可以强制拉低,CS脚恢复成系统控制后,不需要强制拉高拉低
  258. ql_spi_cs_low(QL_CUR_SPI_PORT);
  259. ql_rtos_task_sleep_s(3);
  260. ql_spi_cs_auto(QL_CUR_SPI_PORT);
  261. //使用QL_SPI_DMA_IRQ模式,传输一次最大的数据量为512个字节,如果采用16bit传输数据,需要填充256字节无效数据用于DMA对齐,实际有效最大数据量为256字节
  262. #if QL_SPI_16BIT_DMA
  263. outlen = QL_SPI_DMA_IRQ_SIZE/2;
  264. inlen = QL_SPI_DMA_IRQ_SIZE/2;
  265. #else
  266. outlen = QL_SPI_DMA_IRQ_SIZE;
  267. inlen = QL_SPI_DMA_IRQ_SIZE;
  268. #endif
  269. out_mal_data = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN+outlen);
  270. in_mal_data = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN+outlen);
  271. if (out_mal_data == NULL || in_mal_data == NULL)
  272. {
  273. QL_SPI_DEMO_LOG("malloc err");
  274. goto QL_SPI_EXIT;
  275. }
  276. //使用QL_SPI_DMA_POLLING和QL_SPI_DMA_IRQ模式,使用的地址必须4字节对齐
  277. if(transmode == QL_SPI_DMA_POLLING || transmode == QL_SPI_DMA_IRQ)
  278. {
  279. outdata = (unsigned char *)OSI_ALIGN_UP(out_mal_data, QL_SPI_DMA_ADDR_ALIN);
  280. indata = (unsigned char *)OSI_ALIGN_UP(in_mal_data, QL_SPI_DMA_ADDR_ALIN);
  281. }
  282. else
  283. {
  284. outdata = out_mal_data;
  285. indata = in_mal_data;
  286. }
  287. memset(outdata, 0x00, outlen);
  288. memset(indata, 0x00, inlen);
  289. ql_spi_flash_data_printf(outdata, outlen);
  290. #if QL_SPI_DEMO_LOW_POWER_USE
  291. ql_autosleep_enable(QL_ALLOW_SLEEP);
  292. ql_rtos_task_sleep_s(2);
  293. #endif
  294. static uint8_t cmd_type = 0;
  295. while(1)
  296. {
  297. #if QL_SPI_DEMO_LOW_POWER_USE
  298. ql_lpm_wakelock_lock(spi_power_lock);
  299. #endif
  300. ql_spi_cs_low(QL_CUR_SPI_PORT);
  301. #if 1
  302. memset(outdata, 0x00, outlen);
  303. memset(indata, 0x00, inlen);
  304. if(transmode == QL_SPI_DMA_IRQ)
  305. {
  306. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_WRITE;
  307. //不允许进入慢时钟
  308. ql_spi_request_sys_clk(QL_CUR_SPI_PORT);
  309. }
  310. cmd_type = cmd_type + 1 > 4 ? 1 : cmd_type + 1;
  311. data_mpu_pack(outdata, &outlen, 0X50, cmd_type);
  312. ql_spi_write(QL_CUR_SPI_PORT, outdata, 256);
  313. if(transmode == QL_SPI_DMA_IRQ)
  314. {
  315. ql_rtos_semaphore_wait(spi_demo_write, QL_WAIT_FOREVER);
  316. //tx_dma_done只是DMA完成了,但是SPI的FIFO还可能存在数据未发送,在进入慢时钟或clk频率较低时出现
  317. ql_spi_get_tx_fifo_free(QL_CUR_SPI_PORT, &tx_free);
  318. QL_SPI_DEMO_LOG("tx_free=%d",tx_free);
  319. ql_delay_us((framesize+2)*(QL_SPI_FIFO_SIZE - tx_free)*1000000/spiclk);
  320. //恢复允许进入慢时钟
  321. ql_spi_release_sys_clk(QL_CUR_SPI_PORT);
  322. ql_spi_flash_data_printf(outdata, outlen);
  323. }
  324. //ql_rtos_task_sleep_ms(10);
  325. //ql_spi_write_read(QL_CUR_SPI_PORT, outdata, indata, 256);
  326. /////////////////////////////////////
  327. /////////////READ////////////////////
  328. /////////////////////////////////////
  329. if(transmode == QL_SPI_DMA_IRQ)
  330. {
  331. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_READ;
  332. //不允许进入慢时钟
  333. ql_spi_request_sys_clk(QL_CUR_SPI_PORT);
  334. }
  335. ql_spi_read(QL_CUR_SPI_PORT, indata, 512);
  336. if(transmode == QL_SPI_DMA_IRQ)
  337. {
  338. ql_rtos_semaphore_wait(spi_demo_read, QL_WAIT_FOREVER);
  339. //恢复允许进入慢时钟
  340. ql_spi_release_sys_clk(QL_CUR_SPI_PORT);
  341. ql_spi_flash_data_printf(indata, inlen);
  342. unsigned short sendLen = 0;
  343. data_decode_mpu(indata, 256, outdata, &sendLen);
  344. }
  345. #endif
  346. ql_rtos_task_sleep_ms(500);
  347. }
  348. ql_spi_release(QL_CUR_SPI_PORT);
  349. free(out_mal_data);
  350. free(in_mal_data);
  351. QL_SPI_EXIT:
  352. QL_SPI_DEMO_LOG("ql_rtos_task_delete");
  353. err = ql_rtos_task_delete(NULL);
  354. if(err != QL_OSI_SUCCESS)
  355. {
  356. QL_SPI_DEMO_LOG("task deleted failed");
  357. }
  358. }
  359. QlOSStatus ql_spi_demo_init(void)
  360. {
  361. QlOSStatus err = QL_OSI_SUCCESS;
  362. #if QL_SPI_DEMO_LOW_POWER_USE
  363. spi_power_lock = ql_lpm_wakelock_create("spi_irq", strlen("spi_irq"));
  364. #endif
  365. err = ql_rtos_task_create(&spi_demo_task, SPI_DEMO_TASK_STACK_SIZE, SPI_DEMO_TASK_PRIO, "ql_spi_demo", ql_spi_demo_task_pthread, NULL, SPI_DEMO_TASK_EVENT_CNT);
  366. if(err != QL_OSI_SUCCESS)
  367. {
  368. QL_SPI_DEMO_LOG("demo_task created failed");
  369. return err;
  370. }
  371. return err;
  372. }
  373. uint16_t Full_Frame_Verifi(uint8_t *srcdata, uint16_t srcLen, uint16_t* frame_start)
  374. {
  375. uint16_t frame_len = 0; // 获取帧长度
  376. uint8_t frame_flag = 0; //找到帧起始位
  377. for(uint32_t i = 0; i < (srcLen - sizeof(frame_pack_t)) && 0 == frame_flag; i++)
  378. {
  379. if(0X5A == srcdata[i])
  380. {
  381. frame_len = srcdata[i + FRAME_LEN_INDEX] + (srcdata[i + FRAME_LEN_INDEX + 1] << 8);
  382. if((i + frame_len + 1) < srcLen &&
  383. (srcdata[i + frame_len - 2] + (srcdata[i + frame_len - 1] << 8) == crc16_modbus(srcdata + i, frame_len -2)))
  384. {
  385. frame_flag = 1;
  386. (*frame_start) = i;
  387. //QL_SPI_DEMO_LOG("cmd :%d %d %dxxxxxx len %d", frame_flag, *frame_start, i, frame_len);
  388. return frame_len;
  389. }
  390. }
  391. }
  392. return 0;
  393. }
  394. uint8_t data_mpu_pack(uint8_t* output, uint16_t* output_data_len, uint8_t cmd, uint8_t cmd_type)
  395. {
  396. frame_pack_t frame_tmp = {0};
  397. frame_tmp.destination_addr = MCU_ADDR;
  398. frame_tmp.source_addr = MPU_ADDR;
  399. frame_tmp.frame_head = 0X5A;
  400. switch (cmd)
  401. {
  402. case 0X50:
  403. /* code */
  404. frame_tmp.cmd = 0X50;
  405. switch (cmd_type)
  406. {
  407. case 0X01:
  408. frame_tmp.cmd_type = 0X01;
  409. break;
  410. case 0X02:
  411. frame_tmp.cmd_type = 0X02;
  412. break;
  413. case 0X03:
  414. frame_tmp.cmd_type = 0X03;
  415. break;
  416. default:
  417. break;
  418. }
  419. *output_data_len = sizeof(frame_pack_t);
  420. break;
  421. case 0X60:
  422. /* code */
  423. frame_tmp.cmd = 0X60;
  424. switch (cmd_type)
  425. {
  426. case 0X01:
  427. frame_tmp.cmd_type = 0X01;
  428. break;
  429. case 0X02:
  430. frame_tmp.cmd_type = 0X02;
  431. break;
  432. case 0X03:
  433. frame_tmp.cmd_type = 0X03;
  434. break;
  435. default:
  436. break;
  437. }
  438. break;
  439. default:
  440. break;
  441. }
  442. frame_tmp.data_lenth = 2 + *output_data_len;
  443. memcpy(output, &frame_tmp, sizeof(frame_pack_t));
  444. uint16_t crc16 = crc16_modbus(output, *output_data_len);
  445. output[(*output_data_len)++] = crc16 & 0XFF;
  446. output[(*output_data_len)++] = (crc16 >> 8) & 0XFF;
  447. return 0;
  448. }
  449. uint8_t data_decode_mpu(uint8_t *input_data, uint16_t input_data_len, uint8_t* output, uint16_t* output_data_len)
  450. {
  451. uint16_t frame_start = 0; // 帧起始位
  452. uint16_t frame_len = 0;
  453. *output_data_len = 0;
  454. static frame_pack_t frame_tmp = {0};
  455. frame_tmp.frame_head = 0X5A;
  456. frame_tmp.destination_addr = MPU_ADDR;
  457. frame_tmp.source_addr = MCU_ADDR;
  458. //frame_pack_t* frame_read_tmp;
  459. frame_len = Full_Frame_Verifi(input_data, input_data_len, &frame_start);
  460. //QL_SPI_DEMO_LOG("cmd :%d %dxxxxxx",frame_len, frame_start);
  461. if(0 == frame_len)
  462. return 1;
  463. else
  464. {}
  465. *output_data_len += sizeof(frame_pack_t);
  466. //QL_SPI_DEMO_LOG("cmd :%d %dxxxxxx",input_data[frame_start + FRAME_CMD_INDEX], frame_start);
  467. switch(input_data[frame_start + FRAME_CMD_INDEX])
  468. {
  469. case 0X50:
  470. frame_tmp.cmd = 0X50;
  471. switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
  472. {
  473. case 0X01:
  474. QL_SPI_DEMO_LOG("cmd :0X01----");
  475. break;
  476. case 0X02:
  477. QL_SPI_DEMO_LOG("cmd :0X02----");
  478. break;
  479. case 0X03:
  480. QL_SPI_DEMO_LOG("cmd :0X03----");
  481. break;
  482. default:
  483. break;
  484. }
  485. break;
  486. case 0X60:
  487. //
  488. switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
  489. {
  490. case 0X01:
  491. ///
  492. *output_data_len = 0;
  493. break;
  494. case 0X02:
  495. ///
  496. break;
  497. case 0X03:
  498. //
  499. break;
  500. case 0X04:
  501. //
  502. break;
  503. default:
  504. break;
  505. }
  506. *output_data_len = 0;
  507. return 0;
  508. break;
  509. default:
  510. break;
  511. }
  512. memcpy(output, &frame_tmp, sizeof(frame_pack_t)); //帧固定帧在此复制
  513. uint16_t crc16 = crc16_modbus(output, *output_data_len);
  514. output[(*output_data_len)++] = crc16 & 0XFF;
  515. output[(*output_data_len)++] = (crc16 << 8) & 0XFF;
  516. return 0;
  517. }
  518. unsigned short crc16_modbus(unsigned char *pdata, int len)
  519. {
  520. int j = 0;
  521. int i = 0;
  522. uint16_t reg_crc = 0xffff;
  523. while (i < len )
  524. {
  525. reg_crc ^= pdata[i];
  526. i++;
  527. for (j = 0; j < 8; j++)
  528. {
  529. if ((reg_crc & 0x01) == 1)
  530. {
  531. reg_crc = (uint16_t)((reg_crc >> 1) ^ 0xa001);
  532. }
  533. else
  534. {
  535. reg_crc = (uint16_t)( reg_crc >> 1);
  536. }
  537. }
  538. }
  539. return reg_crc;
  540. }