spi_demo.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  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. #include "ql_fs.h"
  22. #include "ql_api_dev.h"
  23. #define QL_SPI_DEMO_LOG_LEVEL QL_LOG_LEVEL_INFO
  24. #define QL_SPI_DEMO_LOG(msg, ...) QL_LOG(QL_SPI_DEMO_LOG_LEVEL, "ql_SPI_DEMO", msg, ##__VA_ARGS__)
  25. #define QL_SPI_DEMO_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_SPI_DEMO", msg, ##__VA_ARGS__)
  26. uint8_t OTA_FLAG = 1;
  27. output_control_t output_control_t_info = {0};
  28. sleep_control_t sleep_control_t_info = {0};
  29. communication_control_t communication_control_t_info = {0};
  30. /**
  31. * 使用SPI DMA注意事项:
  32. * 8910:
  33. * 1. SPI DMA POLLING和SPI DMA IRQ只支持8bit和16bit的数据传输,不支持32bit数据传输
  34. * 2. 在使用16bit传输数据时,DMA实际使用的是32bit位宽,需要对输出数据插入一些无效数据,对输入数据去除无效数据,
  35. * 因此新增16bit dma api用于16bit情况下的读写,api包含ql_spi_write_16bit_dma、ql_spi_read_16bit_dma、
  36. * ql_spi_write_read_16bit_dma,这部分代码在demo中开源,客户可自行优化,或直接使用
  37. * 3. QL_SPI_16BIT_DMA置为1表示使用16bit DMA demo
  38. * 8850:
  39. * 1. SPI DMA POLLING和SPI DMA IRQ支持8bits、16bits和32bits的数据传输,但是传输的数据大小需要framesize对齐。
  40. */
  41. #define QL_SPI_16BIT_DMA 0 //16bit DMA demo
  42. #define QL_SPI_DEMO_LOW_POWER_USE 0 //0-not run in lower power mode;1-run in lower power mode
  43. ql_task_t spi_demo_task = NULL;
  44. ql_sem_t spi_demo_write;
  45. ql_sem_t spi_demo_read;
  46. int spi_power_lock = 0;
  47. #define QL_SPI_DEMO_WAIT_NONE 0
  48. #define QL_SPI_DEMO_WAIT_WRITE 1
  49. #define QL_SPI_DEMO_WAIT_READ 2
  50. unsigned char spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
  51. #if 1
  52. #define QL_CUR_SPI_PORT QL_SPI_PORT1
  53. #define QL_CUR_SPI_CS_PIN QL_CUR_SPI1_CS_PIN
  54. #define QL_CUR_SPI_CS_FUNC QL_CUR_SPI1_CS_FUNC
  55. #define QL_CUR_SPI_CLK_PIN QL_CUR_SPI1_CLK_PIN
  56. #define QL_CUR_SPI_CLK_FUNC QL_CUR_SPI1_CLK_FUNC
  57. #define QL_CUR_SPI_DO_PIN QL_CUR_SPI1_DO_PIN
  58. #define QL_CUR_SPI_DO_FUNC QL_CUR_SPI1_DO_FUNC
  59. #define QL_CUR_SPI_DI_PIN QL_CUR_SPI1_DI_PIN
  60. #define QL_CUR_SPI_DI_FUNC QL_CUR_SPI1_DI_FUNC
  61. #else
  62. #define QL_CUR_SPI_PORT QL_SPI_PORT2
  63. #define QL_CUR_SPI_CS_PIN QL_CUR_SPI2_CS_PIN
  64. #define QL_CUR_SPI_CS_FUNC QL_CUR_SPI2_CS_FUNC
  65. #define QL_CUR_SPI_CLK_PIN QL_CUR_SPI2_CLK_PIN
  66. #define QL_CUR_SPI_CLK_FUNC QL_CUR_SPI2_CLK_FUNC
  67. #define QL_CUR_SPI_DO_PIN QL_CUR_SPI2_DO_PIN
  68. #define QL_CUR_SPI_DO_FUNC QL_CUR_SPI2_DO_FUNC
  69. #define QL_CUR_SPI_DI_PIN QL_CUR_SPI2_DI_PIN
  70. #define QL_CUR_SPI_DI_FUNC QL_CUR_SPI2_DI_FUNC
  71. #endif
  72. #define QL_TYPE_SHIFT_8 8
  73. uint32_t g_inbuf[QL_SPI_DMA_IRQ_SIZE/4] OSI_CACHE_LINE_ALIGNED;
  74. uint32_t g_outbuf[QL_SPI_DMA_IRQ_SIZE/4] OSI_CACHE_LINE_ALIGNED;
  75. void ql_spi_read_data_transform(unsigned char *buf, unsigned int len)
  76. {
  77. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  78. {
  79. QL_SPI_DEMO_LOG("invalid parm");
  80. return;
  81. }
  82. for(int i = 0; i < len/2; i++)
  83. {
  84. buf[i*2] = (g_inbuf[i] >> QL_TYPE_SHIFT_8) & 0xFF;
  85. buf[i*2+1] = g_inbuf[i] & 0xFF;
  86. }
  87. }
  88. ql_errcode_spi_e ql_spi_write_16bit_dma(ql_spi_port_e port, unsigned char *buf, unsigned int len)
  89. {
  90. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  91. {
  92. QL_SPI_DEMO_LOG("invalid parm");
  93. return QL_SPI_PARAM_DATA_ERROR;
  94. }
  95. unsigned short out_temp = 0;
  96. for(int i = 0; i < len/2; i++)
  97. {
  98. out_temp = buf[i*2];
  99. g_outbuf[i] = (out_temp << QL_TYPE_SHIFT_8) + buf[i*2+1];
  100. }
  101. return ql_spi_write(port, (unsigned char*)g_outbuf, len*2);
  102. }
  103. ql_errcode_spi_e ql_spi_read_16bit_dma(ql_spi_port_e port, unsigned char *buf, unsigned int len)
  104. {
  105. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  106. {
  107. QL_SPI_DEMO_LOG("invalid parm");
  108. return QL_SPI_PARAM_DATA_ERROR;
  109. }
  110. return ql_spi_read(port, (unsigned char*)g_inbuf, len*2);
  111. }
  112. ql_errcode_spi_e ql_spi_write_read_16bit_dma(ql_spi_port_e port, unsigned char *inbuf, unsigned char *outbuf, unsigned int len)
  113. {
  114. if(len%2 != 0 || len > QL_SPI_DMA_IRQ_SIZE/2)
  115. {
  116. QL_SPI_DEMO_LOG("invalid parm");
  117. return QL_SPI_PARAM_DATA_ERROR;
  118. }
  119. unsigned short out_temp = 0;
  120. for(int i = 0; i < len/2; i++)
  121. {
  122. out_temp = outbuf[i*2];
  123. g_outbuf[i] = (out_temp << QL_TYPE_SHIFT_8) + outbuf[i*2+1];
  124. }
  125. return ql_spi_write_read(port, (unsigned char*)g_inbuf, (unsigned char*)g_outbuf, len*2);
  126. }
  127. void ql_spi_flash_data_printf(unsigned char *data, int len)
  128. {
  129. int i = 0;
  130. int count_len = 256;
  131. int count = 0;
  132. int exit = 0;
  133. int write_len = 0;
  134. int pos = 0;
  135. unsigned char *str_data = (unsigned char *)malloc(len*2+64);
  136. if (str_data == NULL)
  137. {
  138. QL_SPI_DEMO_LOG("malloc err");
  139. return ;
  140. }
  141. QL_SPI_DEMO_LOG("read len=%d", len);
  142. while ((exit == 0))
  143. {
  144. if (len - count > 256)
  145. {
  146. count_len = 256;
  147. }
  148. else
  149. {
  150. count_len = len - count;
  151. exit = 1;
  152. }
  153. memset(str_data, 0, len*2+64);
  154. for (i=count; i<count+count_len; i++)
  155. {
  156. //sprintf((char *)str_data,"%s%02x", str_data, data[i]);
  157. if((i+1) % 128 == 0)
  158. write_len += snprintf((char *)(str_data + write_len),(len*2+64 - write_len), "%02x \n",data[i]);
  159. else
  160. write_len += snprintf((char *)(str_data + write_len),(len*2+64 - write_len), "%02x",data[i]);
  161. }
  162. QL_SPI_DEMO_LOG("data[%d-%d]=%s", count, count+count_len, (char *)(str_data+pos));
  163. pos += write_len;
  164. count += count_len;
  165. }
  166. free(str_data);
  167. }
  168. void ql_spi_demo_cb_handler(ql_spi_irq_s cause)
  169. {
  170. if (cause.tx_dma_done == 1 && spi_demo_wait_write_read == QL_SPI_DEMO_WAIT_WRITE)
  171. {
  172. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
  173. ql_rtos_semaphore_release(spi_demo_write);
  174. }
  175. if (cause.rx_dma_done == 1 && spi_demo_wait_write_read == QL_SPI_DEMO_WAIT_READ)
  176. {
  177. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_NONE;
  178. ql_rtos_semaphore_release(spi_demo_read);
  179. }
  180. QL_SPI_DEMO_LOG("cause.tx_dma_done=%d", cause.tx_dma_done);
  181. QL_SPI_DEMO_LOG("cause.rx_dma_done=%d", cause.rx_dma_done);
  182. }
  183. static void ql_spi_demo_task_pthread(void *ctx)
  184. {
  185. QlOSStatus err = 0;
  186. unsigned char *outdata = NULL;
  187. unsigned short outlen;
  188. unsigned char *indata = NULL;
  189. unsigned short inlen;
  190. unsigned char *out_mal_data = NULL;
  191. unsigned char *in_mal_data = NULL;
  192. ql_errcode_gpio ret;
  193. ql_spi_clk_e spiclk;
  194. ql_spi_transfer_mode_e transmode;
  195. unsigned int framesize;
  196. ql_spi_config_s spi_config = {0};
  197. if (QL_CUR_SPI_CS_PIN == QUEC_PIN_NONE || QL_CUR_SPI_CS_PIN == QUEC_PIN_NONE || \
  198. QL_CUR_SPI_DO_PIN == QUEC_PIN_NONE || QL_CUR_SPI_DI_PIN == QUEC_PIN_NONE)
  199. {
  200. QL_SPI_DEMO_LOG("pin err");
  201. goto QL_SPI_EXIT;
  202. }
  203. ret = ql_pin_set_func(QL_CUR_SPI_CS_PIN, QL_CUR_SPI_CS_FUNC);
  204. if (ret != QL_GPIO_SUCCESS)
  205. {
  206. QL_SPI_DEMO_LOG("set pin err");
  207. goto QL_SPI_EXIT;
  208. }
  209. ret = ql_pin_set_func(QL_CUR_SPI_CLK_PIN, QL_CUR_SPI_CLK_FUNC);
  210. if (ret != QL_GPIO_SUCCESS)
  211. {
  212. QL_SPI_DEMO_LOG("set pin err");
  213. goto QL_SPI_EXIT;
  214. }
  215. ret = ql_pin_set_func(QL_CUR_SPI_DO_PIN, QL_CUR_SPI_DO_FUNC);
  216. if (ret != QL_GPIO_SUCCESS)
  217. {
  218. QL_SPI_DEMO_LOG("set pin err");
  219. goto QL_SPI_EXIT;
  220. }
  221. ret = ql_pin_set_func(QL_CUR_SPI_DI_PIN, QL_CUR_SPI_DI_FUNC);
  222. if (ret != QL_GPIO_SUCCESS)
  223. {
  224. QL_SPI_DEMO_LOG("set pin err");
  225. goto QL_SPI_EXIT;
  226. }
  227. //If you use the default parameters, you can initialize it with ql_spi_init
  228. /*transmode = QL_SPI_DMA_IRQ;
  229. spiclk = QL_SPI_CLK_25MHZ;
  230. framesize = 8;
  231. ql_spi_init(QL_CUR_SPI_PORT, transmode, spiclk);
  232. */
  233. spi_config.input_mode = QL_SPI_INPUT_TRUE;
  234. spi_config.port = QL_CUR_SPI_PORT;
  235. #if QL_SPI_16BIT_DMA
  236. framesize = 16;
  237. #else
  238. framesize = 8;
  239. #endif
  240. transmode = QL_SPI_DMA_IRQ; //使用QL_SPI_DMA_IRQ模式,传输一次最大的数据量为512个字节
  241. spiclk = QL_SPI_CLK_1_3MHZ;
  242. spi_config.spiclk = spiclk;
  243. spi_config.framesize = framesize;
  244. spi_config.cs_polarity0 = QL_SPI_CS_ACTIVE_LOW;
  245. spi_config.cs_polarity1 = QL_SPI_CS_ACTIVE_LOW;
  246. spi_config.cpol = QL_SPI_CPOL_LOW;
  247. spi_config.cpha = QL_SPI_CPHA_1Edge;
  248. spi_config.input_sel = QL_SPI_DI_1;
  249. spi_config.transmode = transmode;
  250. spi_config.cs = QL_SPI_CS0;
  251. spi_config.clk_delay = QL_SPI_CLK_DELAY_0;
  252. ql_spi_init_ext(spi_config);
  253. //使用QL_SPI_DMA_IRQ模式才会使用到信号量
  254. if(transmode == QL_SPI_DMA_IRQ)
  255. {
  256. ql_spi_irq_s mask = {0};
  257. mask.rx_dma_done = 1;
  258. mask.tx_dma_done = 1;
  259. //mask.tx_threshold = QL_SPI_TRIGGER_4_DATA;
  260. //mask.rx_threshold = QL_SPI_TRIGGER_4_DATA;
  261. ql_rtos_semaphore_create(&spi_demo_write, 0);
  262. ql_rtos_semaphore_create(&spi_demo_read, 0);
  263. ql_spi_set_irq(QL_CUR_SPI_PORT, mask, ql_spi_demo_cb_handler);
  264. }
  265. //用来测试SPI CS脚可以强制拉低,CS脚恢复成系统控制后,不需要强制拉高拉低
  266. ql_spi_cs_low(QL_CUR_SPI_PORT);
  267. ql_rtos_task_sleep_s(3);
  268. ql_spi_cs_auto(QL_CUR_SPI_PORT);
  269. //使用QL_SPI_DMA_IRQ模式,传输一次最大的数据量为512个字节,如果采用16bit传输数据,需要填充256字节无效数据用于DMA对齐,实际有效最大数据量为256字节
  270. #if QL_SPI_16BIT_DMA
  271. outlen = QL_SPI_DMA_IRQ_SIZE/2;
  272. inlen = QL_SPI_DMA_IRQ_SIZE/2;
  273. #else
  274. outlen = QL_SPI_DMA_IRQ_SIZE;
  275. inlen = QL_SPI_DMA_IRQ_SIZE;
  276. #endif
  277. out_mal_data = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN+outlen);
  278. in_mal_data = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN+outlen);
  279. if (out_mal_data == NULL || in_mal_data == NULL)
  280. {
  281. QL_SPI_DEMO_LOG("malloc err");
  282. goto QL_SPI_EXIT;
  283. }
  284. //使用QL_SPI_DMA_POLLING和QL_SPI_DMA_IRQ模式,使用的地址必须4字节对齐
  285. if(transmode == QL_SPI_DMA_POLLING || transmode == QL_SPI_DMA_IRQ)
  286. {
  287. outdata = (unsigned char *)OSI_ALIGN_UP(out_mal_data, QL_SPI_DMA_ADDR_ALIN);
  288. indata = (unsigned char *)OSI_ALIGN_UP(in_mal_data, QL_SPI_DMA_ADDR_ALIN);
  289. }
  290. else
  291. {
  292. outdata = out_mal_data;
  293. indata = in_mal_data;
  294. }
  295. memset(outdata, 0x00, outlen);
  296. memset(indata, 0x00, inlen);
  297. ql_spi_flash_data_printf(outdata, outlen);
  298. #if QL_SPI_DEMO_LOW_POWER_USE
  299. ql_autosleep_enable(QL_ALLOW_SLEEP);
  300. ql_rtos_task_sleep_s(2);
  301. #endif
  302. //static uint8_t cmd_type = 0;
  303. OTA_FLAG = 1;
  304. while(1)
  305. {
  306. if(0)
  307. {
  308. OTA_FLAG = 1;
  309. QL_SPI_DEMO_LOG("ota test mode");
  310. data_mpu_pack(outdata, &outlen, 0X60, 0X03, spiclk);;
  311. }
  312. #if 0
  313. cmd_type = cmd_type + 1 > 4 ? 1 : cmd_type + 1;
  314. data_mpu_pack(outdata, &outlen, 0X50, cmd_type, spiclk);;
  315. spi_dma_write_hc(QL_CUR_SPI_PORT, outdata, 512, spiclk);
  316. ql_spi_flash_data_printf(outdata, 256);
  317. spi_dma_read_hc(QL_CUR_SPI_PORT, indata, 512, spiclk);
  318. unsigned short sendLen = 0;
  319. ql_spi_flash_data_printf(indata, 512);
  320. data_decode_mpu(indata, 512, outdata, &sendLen, spiclk);
  321. if(0X03 != cmd_type)
  322. {
  323. data_mpu_pack(outdata, &outlen, 0X60, cmd_type, spiclk);
  324. }
  325. spi_dma_write_hc(QL_CUR_SPI_PORT, outdata, 512, spiclk);
  326. spi_dma_read_hc(QL_CUR_SPI_PORT, indata, 512, spiclk);
  327. #endif
  328. ql_rtos_task_sleep_ms(500);
  329. }
  330. ql_spi_release(QL_CUR_SPI_PORT);
  331. free(out_mal_data);
  332. free(in_mal_data);
  333. QL_SPI_EXIT:
  334. QL_SPI_DEMO_LOG("ql_rtos_task_delete");
  335. err = ql_rtos_task_delete(NULL);
  336. if(err != QL_OSI_SUCCESS)
  337. {
  338. QL_SPI_DEMO_LOG("task deleted failed");
  339. }
  340. }
  341. QlOSStatus ql_spi_demo_init(void)
  342. {
  343. QlOSStatus err = QL_OSI_SUCCESS;
  344. #if QL_SPI_DEMO_LOW_POWER_USE
  345. spi_power_lock = ql_lpm_wakelock_create("spi_irq", strlen("spi_irq"));
  346. #endif
  347. 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);
  348. if(err != QL_OSI_SUCCESS)
  349. {
  350. QL_SPI_DEMO_LOG("demo_task created failed");
  351. return err;
  352. }
  353. return err;
  354. }
  355. uint16_t Full_Frame_Verifi(uint8_t *srcdata, uint16_t srcLen, uint16_t* frame_start)
  356. {
  357. uint16_t frame_len = 0; // 获取帧长度
  358. uint8_t frame_flag = 0; //找到帧起始位
  359. for(uint32_t i = 0; i < (srcLen - sizeof(frame_pack_t)) && 0 == frame_flag; i++)
  360. {
  361. if(0X5A == srcdata[i])
  362. {
  363. frame_len = srcdata[i + FRAME_LEN_INDEX] + (srcdata[i + FRAME_LEN_INDEX + 1] << 8);
  364. if((i + frame_len + 1) < srcLen &&
  365. (srcdata[i + frame_len - 2] + (srcdata[i + frame_len - 1] << 8) == crc16_modbus(srcdata + i, frame_len -2)))
  366. {
  367. frame_flag = 1;
  368. *frame_start = i;
  369. QL_SPI_DEMO_LOG("verfi successfully ");
  370. break;
  371. }
  372. }
  373. }
  374. if(0 == frame_flag)
  375. return 0;
  376. else
  377. return frame_len;
  378. }
  379. uint8_t data_mpu_pack(uint8_t* output, uint16_t* output_data_len, uint8_t cmd, uint8_t cmd_type, ql_spi_clk_e spiclk)
  380. {
  381. #define FLASH_SEND_DATA_LEN (256)
  382. #define FLASH_HEAD_0X6003 (0X03)
  383. #define FLASH_SEND_LEN_ALGINE (FLASH_SEND_DATA_LEN + sizeof(frame_pack_t) + 2 + 2 + FLASH_HEAD_0X6003)
  384. #define FLASH_SEND_LEN (512)
  385. #define FLASH_READ_LEN (512)
  386. frame_pack_t frame_tmp = {0};
  387. frame_tmp.destination_addr = MCU_ADDR;
  388. frame_tmp.source_addr = MPU_ADDR;
  389. frame_tmp.frame_head = 0X5A;
  390. (*output_data_len) = sizeof(frame_pack_t);
  391. switch (cmd)
  392. {
  393. case 0X50:
  394. /* code */
  395. frame_tmp.cmd = 0X50;
  396. switch (cmd_type)
  397. {
  398. case 0X01:
  399. frame_tmp.cmd_type = 0X01;
  400. break;
  401. case 0X02:
  402. frame_tmp.cmd_type = 0X02;
  403. break;
  404. case 0X03:
  405. frame_tmp.cmd_type = 0X03;
  406. break;
  407. default:
  408. break;
  409. }
  410. break;
  411. case 0X60:
  412. /* code */
  413. frame_tmp.cmd = 0X60;
  414. switch (cmd_type)
  415. {
  416. case 0X01:
  417. frame_tmp.cmd_type = 0X01;
  418. output_control_t_info.output_number = 6;
  419. output_control_t_info.pwm_number = 2;
  420. memcpy(output, &output_control_t_info, sizeof(output_control_t));
  421. *output_data_len += sizeof(output_control_t_info);
  422. break;
  423. case 0X02:
  424. frame_tmp.cmd_type = 0X02;
  425. sleep_control_t_info.control_type = 1;
  426. sleep_control_t_info.sleep_time = 256;
  427. memcpy(output, &sleep_control_t_info, sizeof(sleep_control_t));
  428. *output_data_len += sizeof(sleep_control_t_info);
  429. break;
  430. case 0X03:
  431. frame_tmp.cmd_type = 0X03;
  432. int fd_updata_file = 0;
  433. fd_updata_file = ql_fopen("UFS:/updata.bin", "r+");
  434. if(0 == fd_updata_file)
  435. {
  436. QL_SPI_DEMO_LOG("fd open failed");
  437. break;
  438. }
  439. else
  440. QL_SPI_DEMO_LOG("fd open succeeded");
  441. uint16_t crcFile = 0;
  442. creat_software_crc16(fd_updata_file, &crcFile);
  443. QL_SPI_DEMO_LOG("fd file %d", crcFile);
  444. ql_frewind(fd_updata_file);
  445. uint8_t pbuf[FLASH_SEND_DATA_LEN] = {0};
  446. int readLen = ql_fread(pbuf, FLASH_SEND_DATA_LEN, 1, fd_updata_file);
  447. uint16 crc16_tmp = 0;
  448. static uint16 frame_index = 0;
  449. uint8* indata_tmp = (unsigned char *)malloc(QL_SPI_DMA_ADDR_ALIN + FLASH_READ_LEN);
  450. uint8*indata = (unsigned char *)OSI_ALIGN_UP(indata_tmp, QL_SPI_DMA_ADDR_ALIN);
  451. #define DELAY_TIME_FLASH_TEST (150)
  452. while((readLen) > 0)
  453. {
  454. *output_data_len = sizeof(frame_pack_t);
  455. frame_tmp.data_lenth = sizeof(frame_pack_t) + FLASH_HEAD_0X6003 + readLen + 2 + 2;
  456. memcpy(output, &frame_tmp, sizeof(frame_pack_t));
  457. QL_SPI_DEMO_LOG("circle index %d head len %d send len %d", frame_index, *output_data_len, frame_tmp.data_lenth);
  458. output[(*output_data_len)++] = 0X01;
  459. output[(*output_data_len)++] = frame_index & 0XFF;
  460. output[(*output_data_len)++] = (frame_index >> 8) & 0XFF;
  461. memcpy(output + (*output_data_len), pbuf, readLen);
  462. (*output_data_len) += readLen;
  463. crc16_tmp = crc16_modbus(pbuf, readLen);
  464. output[(*output_data_len)++] = crc16_tmp & 0XFF;
  465. output[(*output_data_len)++] = (crc16_tmp >> 8) & 0XFF;
  466. crc16_tmp = crc16_modbus(output, *output_data_len);
  467. output[(*output_data_len)++] = crc16_tmp & 0XFF;
  468. output[(*output_data_len)++] = (crc16_tmp >> 8) & 0XFF;
  469. QL_SPI_DEMO_LOG("out data,frame_tmp.data_lenth %d readLen %d fdSize:%d", frame_tmp.data_lenth, readLen , ql_fsize(fd_updata_file));
  470. spi_dma_write_hc(QL_CUR_SPI_PORT, output, FLASH_SEND_LEN, spiclk);
  471. ql_rtos_task_sleep_ms(DELAY_TIME_FLASH_TEST);
  472. spi_dma_read_hc(QL_CUR_SPI_PORT, indata, FLASH_SEND_LEN, spiclk);
  473. QL_SPI_DEMO_LOG("out data,frame_tmp.data_lenth %d", frame_tmp.data_lenth);
  474. ql_spi_flash_data_printf(output, frame_tmp.data_lenth);
  475. QL_SPI_DEMO_LOG("in data");
  476. ql_spi_flash_data_printf(indata, FLASH_READ_LEN);
  477. uint8_t tmp[256];
  478. uint16_t len_tmp = 0;
  479. uint16 orIndex = data_decode_mpu(indata, FLASH_READ_LEN, tmp, &len_tmp, spiclk);
  480. static uint8_t errorNum = 0;
  481. while(frame_index != (orIndex - 1))
  482. {
  483. QL_SPI_DEMO_LOG("in data orindex %d", orIndex);
  484. ql_spi_flash_data_printf(indata, FLASH_READ_LEN);
  485. spi_dma_write_hc(QL_CUR_SPI_PORT, output, FLASH_SEND_LEN, spiclk);
  486. QL_SPI_DEMO_LOG("out data,frame_tmp.data_lenth %d", frame_tmp.data_lenth);
  487. ql_spi_flash_data_printf(output, frame_tmp.data_lenth);
  488. ql_rtos_task_sleep_ms(DELAY_TIME_FLASH_TEST);
  489. spi_dma_read_hc(QL_CUR_SPI_PORT, indata, FLASH_READ_LEN, spiclk);
  490. orIndex = data_decode_mpu(indata, FLASH_READ_LEN, tmp, &len_tmp, spiclk);
  491. errorNum++;
  492. if(errorNum > 20)
  493. {
  494. //升级失败
  495. ql_fclose(fd_updata_file);
  496. free(indata_tmp);
  497. *output_data_len = 0;
  498. return errorNum;
  499. }
  500. }
  501. frame_index++;
  502. readLen = ql_fread(pbuf, FLASH_SEND_DATA_LEN, 1, fd_updata_file);
  503. }
  504. memset(output, 0, FLASH_SEND_LEN);
  505. *output_data_len = sizeof(frame_pack_t);
  506. output[(*output_data_len)++] = 0X00;
  507. output[(*output_data_len)++] = frame_index & 0XFF;
  508. output[(*output_data_len)++] = (frame_index >> 8) & 0XFF;
  509. output[(*output_data_len)++] = crcFile & 0XFF;
  510. output[(*output_data_len)++] = (crcFile >> 8) & 0XFF;
  511. output[(*output_data_len)++] = ql_fsize(fd_updata_file) & 0XFF;
  512. output[(*output_data_len)++] = (ql_fsize(fd_updata_file) >> 8) & 0XFF;
  513. frame_tmp.data_lenth = (*output_data_len) + 2;
  514. memcpy(output, &frame_tmp, sizeof(frame_pack_t));
  515. crc16_tmp = crc16_modbus(output, (*output_data_len));
  516. output[(*output_data_len)++] = crc16_tmp & 0XFF;
  517. output[(*output_data_len)++] = (crc16_tmp >> 8) & 0XFF;
  518. spi_dma_write_hc(QL_CUR_SPI_PORT, output, FLASH_SEND_LEN, spiclk);
  519. QL_SPI_DEMO_LOG("end of frame_tmp.data_lenth:%d crc16_tmp:%d crcFile:%d", frame_tmp.data_lenth, crc16_tmp, crcFile);
  520. ql_spi_flash_data_printf(output, FLASH_READ_LEN);
  521. #undef DATA_SEND_LEN
  522. ql_fclose(fd_updata_file);
  523. free(indata_tmp);
  524. *output_data_len = 0;
  525. return 0;
  526. break;
  527. case 0X04:
  528. frame_tmp.cmd_type = 0X04;
  529. communication_control_t_info.can_send_data_type = 1;
  530. memcpy(output, &communication_control_t_info, sizeof(communication_control_t));
  531. *output_data_len += sizeof(communication_control_t);
  532. break;
  533. default:
  534. break;
  535. }
  536. break;
  537. default:
  538. break;
  539. }
  540. frame_tmp.data_lenth = 2 + *output_data_len;
  541. memcpy(output, &frame_tmp, sizeof(frame_pack_t));
  542. uint16_t crc16 = crc16_modbus(output, *output_data_len);
  543. output[(*output_data_len)++] = crc16 & 0XFF;
  544. output[(*output_data_len)++] = (crc16 >> 8) & 0XFF;
  545. return 0;
  546. }
  547. uint16_t data_decode_mpu(uint8_t *input_data, uint16_t input_data_len, uint8_t* output, uint16_t* output_data_len, ql_spi_clk_e spiclk)
  548. {
  549. uint16_t frame_start = 0; // 帧起始位
  550. uint16_t frame_len = 0;
  551. *output_data_len = 0;
  552. static frame_pack_t frame_tmp = {0};
  553. frame_tmp.frame_head = 0X5A;
  554. frame_tmp.destination_addr = MCU_ADDR;
  555. frame_tmp.source_addr = MPU_ADDR;
  556. //frame_pack_t* frame_read_tmp;
  557. frame_len = Full_Frame_Verifi(input_data, input_data_len, &frame_start);
  558. //QL_SPI_DEMO_LOG("cmd :%d %dxxxxxx",frame_len, frame_start);
  559. if(0 == frame_len)
  560. return 1;
  561. else
  562. {}
  563. *output_data_len += sizeof(frame_pack_t);
  564. //QL_SPI_DEMO_LOG("cmd :%d %dxxxxxx",input_data[frame_start + FRAME_CMD_INDEX], frame_start);
  565. uint8_t *pack_data = input_data + frame_start + sizeof(frame_pack_t);
  566. switch(input_data[frame_start + FRAME_CMD_INDEX])
  567. {
  568. case 0X50:
  569. frame_tmp.cmd = 0X50;
  570. switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
  571. {
  572. case 0X01:
  573. // // uint8_t temperatures_number;
  574. // int8_t temperatures_data[TEMP_NUMBER];
  575. QL_SPI_DEMO_LOG("cmd :0X01----");
  576. cmd_05_01_device_status_t* tmp_read1 = (cmd_05_01_device_status_t * )(input_data + frame_start + sizeof(frame_pack_t));
  577. QL_SPI_DEMO_LOG("work_status %d, backup_voltage:%d, backup_temperature:%d,high_driver_number:%d,\n\
  578. high_driver_status:%d, low_driver_number:%d low_driver_status:%d last_wake_up_source %d location_status:%d", tmp_read1->work_status, tmp_read1->backup_voltage,\
  579. tmp_read1->backup_temperature,tmp_read1->high_driver_number,tmp_read1->high_driver_status,\
  580. tmp_read1->low_driver_number,tmp_read1->low_driver_status, tmp_read1->last_wake_up_source,tmp_read1->location_status\
  581. );
  582. (void)tmp_read1;
  583. break;
  584. case 0X02:;
  585. QL_SPI_DEMO_LOG("cmd :0X02----");
  586. gps_info_t* tmp_read2 = (gps_info_t *)(input_data + frame_start + sizeof(frame_pack_t));
  587. QL_SPI_DEMO_LOG("gps locate_mark %d,satellite_num %d,", tmp_read2->locate_mark, tmp_read2->satellite_num);
  588. (void)tmp_read2;
  589. break;
  590. case 0X03:
  591. QL_SPI_DEMO_LOG("cmd :0X03----");
  592. cmd_05_03_communication_data_t* tmp_read = (cmd_05_03_communication_data_t *)(input_data + frame_start + sizeof(frame_pack_t));
  593. QL_SPI_DEMO_LOG("%d, %d,%d, %d,%d, %d,%d, %d,%d, %d,%d,",\
  594. tmp_read->x_data,tmp_read->y_data,tmp_read->z_data,tmp_read-> can0_data_status,tmp_read-> can0_fault_status,tmp_read->can0_data_lenth,\
  595. tmp_read-> can1_data_status,tmp_read-> can1_fault_status,tmp_read->can1_data_lenth,tmp_read-> rs485_data_status,tmp_read->rs485_data_lenth);
  596. (void)tmp_read;
  597. break;
  598. default:
  599. break;
  600. }
  601. break;
  602. case 0X60:
  603. //
  604. switch(input_data[frame_start + FRAME_CMD_TYPE_INDEX])
  605. {
  606. case 0X01:
  607. ///
  608. *output_data_len = 0;
  609. break;
  610. case 0X02:
  611. ///
  612. break;
  613. case 0X03:
  614. QL_SPI_DEMO_LOG("cmd60 03----flash\nframe_index :%d\n", (pack_data[0] + (pack_data[1] << 8)));
  615. return (pack_data[0] + (pack_data[1] << 8));
  616. break;
  617. case 0X04:
  618. //
  619. break;
  620. default:
  621. break;
  622. }
  623. *output_data_len = 0;
  624. return 0;
  625. break;
  626. default:
  627. break;
  628. }
  629. memcpy(output, &frame_tmp, sizeof(frame_pack_t)); //帧固定帧在此复制
  630. uint16_t crc16 = crc16_modbus(output, *output_data_len);
  631. output[(*output_data_len)++] = crc16 & 0XFF;
  632. output[(*output_data_len)++] = (crc16 << 8) & 0XFF;
  633. return 0;
  634. }
  635. unsigned short crc16_modbus(unsigned char *pdata, int len)
  636. {
  637. int j = 0;
  638. int i = 0;
  639. uint16_t reg_crc = 0xffff;
  640. while (i < len )
  641. {
  642. reg_crc ^= pdata[i];
  643. i++;
  644. for (j = 0; j < 8; j++)
  645. {
  646. if ((reg_crc & 0x01) == 1)
  647. {
  648. reg_crc = (uint16_t)((reg_crc >> 1) ^ 0xa001);
  649. }
  650. else
  651. {
  652. reg_crc = (uint16_t)( reg_crc >> 1);
  653. }
  654. }
  655. }
  656. return reg_crc;
  657. }
  658. #if 1
  659. uint16_t g_dnpcrc_table[256] =
  660. {
  661. 0x0000, 0x365E, 0x6CBC, 0x5AE2, 0xD978, 0xEF26, 0xB5C4, 0x839A,
  662. 0xFF89, 0xC9D7, 0x9335, 0xA56B, 0x26F1, 0x10AF, 0x4A4D, 0x7C13,
  663. 0xB26B, 0x8435, 0xDED7, 0xE889, 0x6B13, 0x5D4D, 0x07AF, 0x31F1,
  664. 0x4DE2, 0x7BBC, 0x215E, 0x1700, 0x949A, 0xA2C4, 0xF826, 0xCE78,
  665. 0x29AF, 0x1FF1, 0x4513, 0x734D, 0xF0D7, 0xC689, 0x9C6B, 0xAA35,
  666. 0xD626, 0xE078, 0xBA9A, 0x8CC4, 0x0F5E, 0x3900, 0x63E2, 0x55BC,
  667. 0x9BC4, 0xAD9A, 0xF778, 0xC126, 0x42BC, 0x74E2, 0x2E00, 0x185E,
  668. 0x644D, 0x5213, 0x08F1, 0x3EAF, 0xBD35, 0x8B6B, 0xD189, 0xE7D7,
  669. 0x535E, 0x6500, 0x3FE2, 0x09BC, 0x8A26, 0xBC78, 0xE69A, 0xD0C4,
  670. 0xACD7, 0x9A89, 0xC06B, 0xF635, 0x75AF, 0x43F1, 0x1913, 0x2F4D,
  671. 0xE135, 0xD76B, 0x8D89, 0xBBD7, 0x384D, 0x0E13, 0x54F1, 0x62AF,
  672. 0x1EBC, 0x28E2, 0x7200, 0x445E, 0xC7C4, 0xF19A, 0xAB78, 0x9D26,
  673. 0x7AF1, 0x4CAF, 0x164D, 0x2013, 0xA389, 0x95D7, 0xCF35, 0xF96B,
  674. 0x8578, 0xB326, 0xE9C4, 0xDF9A, 0x5C00, 0x6A5E, 0x30BC, 0x06E2,
  675. 0xC89A, 0xFEC4, 0xA426, 0x9278, 0x11E2, 0x27BC, 0x7D5E, 0x4B00,
  676. 0x3713, 0x014D, 0x5BAF, 0x6DF1, 0xEE6B, 0xD835, 0x82D7, 0xB489,
  677. 0xA6BC, 0x90E2, 0xCA00, 0xFC5E, 0x7FC4, 0x499A, 0x1378, 0x2526,
  678. 0x5935, 0x6F6B, 0x3589, 0x03D7, 0x804D, 0xB613, 0xECF1, 0xDAAF,
  679. 0x14D7, 0x2289, 0x786B, 0x4E35, 0xCDAF, 0xFBF1, 0xA113, 0x974D,
  680. 0xEB5E, 0xDD00, 0x87E2, 0xB1BC, 0x3226, 0x0478, 0x5E9A, 0x68C4,
  681. 0x8F13, 0xB94D, 0xE3AF, 0xD5F1, 0x566B, 0x6035, 0x3AD7, 0x0C89,
  682. 0x709A, 0x46C4, 0x1C26, 0x2A78, 0xA9E2, 0x9FBC, 0xC55E, 0xF300,
  683. 0x3D78, 0x0B26, 0x51C4, 0x679A, 0xE400, 0xD25E, 0x88BC, 0xBEE2,
  684. 0xC2F1, 0xF4AF, 0xAE4D, 0x9813, 0x1B89, 0x2DD7, 0x7735, 0x416B,
  685. 0xF5E2, 0xC3BC, 0x995E, 0xAF00, 0x2C9A, 0x1AC4, 0x4026, 0x7678,
  686. 0x0A6B, 0x3C35, 0x66D7, 0x5089, 0xD313, 0xE54D, 0xBFAF, 0x89F1,
  687. 0x4789, 0x71D7, 0x2B35, 0x1D6B, 0x9EF1, 0xA8AF, 0xF24D, 0xC413,
  688. 0xB800, 0x8E5E, 0xD4BC, 0xE2E2, 0x6178, 0x5726, 0x0DC4, 0x3B9A,
  689. 0xDC4D, 0xEA13, 0xB0F1, 0x86AF, 0x0535, 0x336B, 0x6989, 0x5FD7,
  690. 0x23C4, 0x159A, 0x4F78, 0x7926, 0xFABC, 0xCCE2, 0x9600, 0xA05E,
  691. 0x6E26, 0x5878, 0x029A, 0x34C4, 0xB75E, 0x8100, 0xDBE2, 0xEDBC,
  692. 0x91AF, 0xA7F1, 0xFD13, 0xCB4D, 0x48D7, 0x7E89, 0x246B, 0x1235,
  693. };
  694. #endif
  695. void creat_software_crc16(int fd, uint16_t *cur_crc)
  696. {
  697. #if 1
  698. uint16_t crc = 0u;
  699. uint32_t index = 0u;
  700. uint8 pbuf[256] = {0};
  701. int readLen = 0;
  702. readLen = ql_fread(pbuf, 256, 1, fd);
  703. while((readLen) > 0)
  704. {
  705. for (index = 0u; index < readLen; index++)
  706. {
  707. crc = ( crc >> 8 ) ^ g_dnpcrc_table[( crc ^ pbuf[index]) & 0x00ff] ;
  708. }
  709. readLen = ql_fread(pbuf, sizeof(pbuf), 1, fd);
  710. }
  711. *cur_crc = ((~crc) & 0xFFFFu);
  712. QL_SPI_DEMO_LOG("file len crc", *cur_crc);
  713. #else
  714. uint8 pbuf[256] = {0};
  715. int len = ql_fread(pbuf, 256, 1, fd);
  716. QL_SPI_DEMO_LOG("read len %d %d", len, pbuf[0]);
  717. for(int i = 0; i < len; i++)
  718. {
  719. QL_SPI_DEMO_LOG("%c ", pbuf[i]);
  720. }
  721. #endif
  722. }
  723. void spi_dma_write_hc(ql_spi_port_e spi_port, uint8_t *pbuf, uint32 len, ql_spi_clk_e spiclk)
  724. {
  725. unsigned int tx_free = 0;
  726. unsigned int framesize = 8;
  727. ql_spi_cs_low(QL_CUR_SPI_PORT);
  728. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_WRITE;
  729. //不允许进入慢时钟
  730. ql_spi_request_sys_clk(QL_CUR_SPI_PORT);
  731. ql_spi_write(spi_port, pbuf, len);
  732. ql_rtos_semaphore_wait(spi_demo_write, QL_WAIT_FOREVER);
  733. //tx_dma_done只是DMA完成了,但是SPI的FIFO还可能存在数据未发送,在进入慢时钟或clk频率较低时出现
  734. ql_spi_get_tx_fifo_free(QL_CUR_SPI_PORT, &tx_free);
  735. QL_SPI_DEMO_LOG("tx_free=%d",tx_free);
  736. ql_delay_us((framesize+2)*(QL_SPI_FIFO_SIZE - tx_free)*1000000/spiclk);
  737. //恢复允许进入慢时钟
  738. ql_spi_release_sys_clk(QL_CUR_SPI_PORT);
  739. ql_spi_cs_high(QL_CUR_SPI_PORT);
  740. }
  741. void spi_dma_read_hc(ql_spi_port_e spi_port, uint8_t *pbuf, uint32 len, ql_spi_clk_e spiclk)
  742. {
  743. unsigned int tx_free = 0;
  744. unsigned int framesize = 8;
  745. ql_spi_cs_low(QL_CUR_SPI_PORT);
  746. spi_demo_wait_write_read = QL_SPI_DEMO_WAIT_READ;
  747. //不允许进入慢时钟
  748. ql_spi_request_sys_clk(QL_CUR_SPI_PORT);
  749. ql_spi_read(spi_port, pbuf, len);
  750. ql_rtos_semaphore_wait(spi_demo_read, QL_WAIT_FOREVER);
  751. //tx_dma_done只是DMA完成了,但是SPI的FIFO还可能存在数据未发送,在进入慢时钟或clk频率较低时出现
  752. ql_spi_get_tx_fifo_free(QL_CUR_SPI_PORT, &tx_free);
  753. QL_SPI_DEMO_LOG("tx_free=%d",tx_free);
  754. ql_delay_us((framesize+2)*(QL_SPI_FIFO_SIZE - tx_free)*1000000/spiclk);
  755. //恢复允许进入慢时钟
  756. ql_spi_release_sys_clk(QL_CUR_SPI_PORT);
  757. ql_spi_cs_high(QL_CUR_SPI_PORT);
  758. }