core_service.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "user.h"
  22. #ifdef __BUILD_OS__
  23. #include "zbar.h"
  24. #include "symbol.h"
  25. #include "image.h"
  26. #include "tiny_jpeg.h"
  27. extern void SPI_TestInit(uint8_t SpiID, uint32_t Speed, uint32_t TestLen);
  28. extern void SPI_TestOnce(uint8_t SpiID, uint32_t TestLen);
  29. extern void DHT11_TestOnce(uint8_t Pin, CBFuncEx_t CB);
  30. extern void DHT11_TestResult(void);
  31. extern void SHT30_Init(CBFuncEx_t CB, void *pParam);
  32. extern void SHT30_GetResult(CBFuncEx_t CB, void *pParam);
  33. extern void GC032A_TestInit(void);
  34. extern void OV2640_TestInit(void);
  35. enum
  36. {
  37. SERVICE_LCD_DRAW = SERVICE_EVENT_ID_START + 1,
  38. SERVICE_CAMERA_DRAW,
  39. SERVICE_SDHC_WRITE,
  40. SERVICE_SPIFLASH_ERASE,
  41. SERVICE_SPIFLASH_WRITE,
  42. SERVICE_SPIFLASH_CLOSE,
  43. SERVICE_FILE_WRITE,
  44. SERVICE_DECODE_QR,
  45. SERVICE_SCAN_KEYBOARD,
  46. SERVICE_ENCODE_JPEG_START,
  47. SERVICE_ENCODE_JPEG_RUN,
  48. SERVICE_ENCODE_JPEG_END,
  49. SERVICE_RUN_USER_API,
  50. };
  51. typedef struct
  52. {
  53. tje_write_func *JPEGEncodeWriteFun;
  54. void *JPEGEncodeWriteParam;
  55. CoreUpgrade_HeadStruct *pFotaHead;
  56. SPIFlash_CtrlStruct *pSpiFlash;
  57. HANDLE LCDHandle;
  58. HANDLE ServiceHandle;
  59. HANDLE StorgeHandle;
  60. HANDLE UserHandle;
  61. uint64_t LCDDrawRequireByte;
  62. uint64_t LCDDrawDoneByte;
  63. uint32_t InitAllocMem;
  64. uint32_t LastAllocMem;
  65. uint32_t CRC32_Table[256];
  66. Buffer_Struct FotaDataBuf;
  67. uint32_t FotaPos;
  68. uint32_t FotaDoneLen;
  69. uint32_t FotaCRC32;
  70. uint8_t RFix;
  71. uint8_t GFix;
  72. uint8_t BFix;
  73. uint8_t FotaFindHead;
  74. uint8_t FotaReady;
  75. }Service_CtrlStruct;
  76. static Service_CtrlStruct prvService;
  77. static void prvCore_LCDCmd(LCD_DrawStruct *Draw, uint8_t Cmd)
  78. {
  79. GPIO_Output(Draw->DCPin, 0);
  80. if (Draw->DCDelay)
  81. {
  82. SysTickDelay(Draw->DCDelay * CORE_TICK_1US);
  83. }
  84. GPIO_Output(Draw->CSPin, 0);
  85. SPI_BlockTransfer(Draw->SpiID, &Cmd, NULL, 1);
  86. GPIO_Output(Draw->CSPin, 1);
  87. GPIO_Output(Draw->DCPin, 1);
  88. // SysTickDelay(300);
  89. }
  90. static void prvCore_LCDData(LCD_DrawStruct *Draw, uint8_t *Data, uint32_t Len)
  91. {
  92. GPIO_Output(Draw->CSPin, 0);
  93. SPI_BlockTransfer(Draw->SpiID, Data, NULL, Len);
  94. GPIO_Output(Draw->CSPin, 1);
  95. }
  96. static uint16_t RGB888toRGB565(uint8_t red, uint8_t green, uint8_t blue, uint8_t IsBe)
  97. {
  98. uint16_t B = (blue >> 3) & 0x001F;
  99. uint16_t G = ((green >> 2) << 5) & 0x07E0;
  100. uint16_t R = ((red >> 3) << 11) & 0xF800;
  101. uint16_t C = (R | G | B);
  102. if (IsBe)
  103. {
  104. C = BSP_Swap16(C);
  105. }
  106. return C;
  107. }
  108. static void RGB565toRGB888(uint16_t In, uint8_t *Out, uint8_t IsBe)
  109. {
  110. if (IsBe)
  111. {
  112. In = BSP_Swap16(In);
  113. }
  114. Out[2] = ((In & 0x001F) << 3) | prvService.BFix;
  115. Out[1] = ((In & 0x07E0) >> 3) | prvService.GFix;
  116. Out[0] = ((In & 0xF800) >> 8) | prvService.RFix;
  117. }
  118. static void prv_CoreJpegSave(void* context, void* data, int size)
  119. {
  120. }
  121. static void prvLCD_Task(void* params)
  122. {
  123. uint64_t StartUS;
  124. OS_EVENT Event;
  125. int32_t Result;
  126. LCD_DrawStruct *Draw;
  127. PV_Union uPV;
  128. uint16_t uColor[256];
  129. uint32_t i, j, Size;
  130. uint8_t CSPin;
  131. for(i = 0; i < 256; i++)
  132. {
  133. uColor[i] = RGB888toRGB565(i, i, i, 1);
  134. }
  135. while(1)
  136. {
  137. Result = Task_GetEvent(prvService.LCDHandle, CORE_EVENT_ID_ANY, &Event, NULL, 0);
  138. switch(Event.ID)
  139. {
  140. case SERVICE_LCD_DRAW:
  141. Draw = (LCD_DrawStruct *)Event.Param1;
  142. if (Draw->Speed > 30000000)
  143. {
  144. SPI_SetTxOnlyFlag(Draw->SpiID, 1);
  145. }
  146. SPI_SetNewConfig(Draw->SpiID, Draw->Speed, Draw->Mode);
  147. SPI_DMATxInit(Draw->SpiID, LCD_SPI_TX_DMA_STREAM, 0);
  148. SPI_DMARxInit(Draw->SpiID, LCD_SPI_RX_DMA_STREAM, 0);
  149. prvCore_LCDCmd(Draw, 0x2a);
  150. BytesPutBe16(uPV.u8, Draw->x1 + Draw->xoffset);
  151. BytesPutBe16(uPV.u8 + 2, Draw->x2 + Draw->xoffset);
  152. prvCore_LCDData(Draw, uPV.u8, 4);
  153. prvCore_LCDCmd(Draw, 0x2b);
  154. BytesPutBe16(uPV.u8, Draw->y1 + Draw->yoffset);
  155. BytesPutBe16(uPV.u8 + 2, Draw->y2 + Draw->yoffset);
  156. prvCore_LCDData(Draw, uPV.u8, 4);
  157. prvCore_LCDCmd(Draw, 0x2c);
  158. GPIO_Output(Draw->CSPin, 0);
  159. // StartUS = GetSysTickUS();
  160. // SPI_Transfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size, 2);
  161. SPI_BlockTransfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size);
  162. // {
  163. // DBG("%u, %u", Draw->Size, (uint32_t)(GetSysTickUS() - StartUS));
  164. // }
  165. prvService.LCDDrawDoneByte += Draw->Size;
  166. free(Draw->Data);
  167. CSPin = Draw->CSPin;
  168. free(Draw);
  169. GPIO_Output(CSPin, 1);
  170. SPI_SetTxOnlyFlag(Draw->SpiID, 0);
  171. break;
  172. case SERVICE_CAMERA_DRAW:
  173. Draw = (LCD_DrawStruct *)Event.Param1;
  174. SPI_SetTxOnlyFlag(Draw->SpiID, 1);
  175. SPI_SetNewConfig(Draw->SpiID, Draw->Speed, Draw->Mode);
  176. SPI_DMATxInit(Draw->SpiID, LCD_SPI_TX_DMA_STREAM, 0);
  177. SPI_DMARxInit(Draw->SpiID, LCD_SPI_RX_DMA_STREAM, 0);
  178. prvCore_LCDCmd(Draw, 0x2a);
  179. BytesPutBe16(uPV.u8, Draw->x1 + Draw->xoffset);
  180. BytesPutBe16(uPV.u8 + 2, Draw->x2 + Draw->xoffset);
  181. prvCore_LCDData(Draw, uPV.u8, 4);
  182. prvCore_LCDCmd(Draw, 0x2b);
  183. BytesPutBe16(uPV.u8, Draw->y1 + Draw->yoffset);
  184. BytesPutBe16(uPV.u8 + 2, Draw->y2 + Draw->yoffset);
  185. prvCore_LCDData(Draw, uPV.u8, 4);
  186. prvCore_LCDCmd(Draw, 0x2c);
  187. GPIO_Output(Draw->CSPin, 0);
  188. switch(Draw->ColorMode)
  189. {
  190. case COLOR_MODE_RGB_565:
  191. SPI_BlockTransfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size);
  192. break;
  193. case COLOR_MODE_GRAY:
  194. Size = Draw->Size/10;
  195. uPV.pu16 = malloc(Size * 2);
  196. for(i = 0; i < 10; i++)
  197. {
  198. for(j = 0; j < Size; j++)
  199. {
  200. uPV.pu16[j] = uColor[Draw->Data[i * Size + j]];
  201. }
  202. SPI_BlockTransfer(Draw->SpiID, uPV.pu8, uPV.pu8, Size * 2);
  203. }
  204. free(uPV.pu16);
  205. break;
  206. }
  207. free(Draw);
  208. GPIO_Output(Draw->CSPin, 1);
  209. SPI_SetTxOnlyFlag(Draw->SpiID, 0);
  210. break;
  211. }
  212. }
  213. }
  214. static void prvStorge_Task(void* params)
  215. {
  216. OS_EVENT Event;
  217. uint32_t *Param;
  218. SDHC_SPICtrlStruct *pSDHC;
  219. CommonFun_t CB;
  220. CBFuncEx_t CB2;
  221. HANDLE fd;
  222. while(1)
  223. {
  224. Task_GetEventByMS(prvService.StorgeHandle, CORE_EVENT_ID_ANY, &Event, NULL, 0);
  225. switch(Event.ID)
  226. {
  227. case SERVICE_SDHC_WRITE:
  228. pSDHC = (SDHC_SPICtrlStruct *)Event.Param1;
  229. if (pSDHC->WaitFree)
  230. {
  231. DBG("sdhc wait reboot");
  232. free(Event.Param2);
  233. free(Event.Param3);
  234. break;
  235. }
  236. Param = (uint32_t *)Event.Param3;
  237. SDHC_SpiWriteBlocks(pSDHC, Event.Param2, Param[0], Param[1]);
  238. free(Event.Param2);
  239. free(Event.Param3);
  240. break;
  241. case SERVICE_SPIFLASH_ERASE:
  242. if (prvService.pSpiFlash)
  243. {
  244. SPIFlash_Erase(prvService.pSpiFlash, Event.Param1, Event.Param2);
  245. }
  246. if (Event.Param3)
  247. {
  248. CB = (CommonFun_t )Event.Param3;
  249. CB();
  250. }
  251. break;
  252. case SERVICE_SPIFLASH_WRITE:
  253. if (prvService.pSpiFlash)
  254. {
  255. SPIFlash_Write(prvService.pSpiFlash, Event.Param1, Event.Param2, Event.Param3);
  256. prvService.FotaCRC32 = CRC32_Cal(prvService.CRC32_Table, Event.Param2, Event.Param3, prvService.FotaCRC32);
  257. prvService.FotaDoneLen += Event.Param3;
  258. }
  259. free(Event.Param2);
  260. break;
  261. case SERVICE_SPIFLASH_CLOSE:
  262. free(prvService.pSpiFlash);
  263. prvService.pSpiFlash = NULL;
  264. break;
  265. case SERVICE_FILE_WRITE:
  266. #ifdef __LUATOS__
  267. fd = luat_fs_fopen((char *)Event.Param1, "w");
  268. //DBG("%x,%s",fd, (char *)Event.Param1);
  269. if (fd)
  270. {
  271. luat_fs_fwrite(Event.Param2, Event.Param3, 1, fd);
  272. luat_fs_fclose(fd);
  273. }
  274. #endif
  275. prvService.FotaDoneLen += Event.Param3;
  276. free(Event.Param2);
  277. break;
  278. case SERVICE_RUN_USER_API:
  279. CB2 = (CBFuncEx_t)Event.Param1;
  280. CB2(Event.Param2, Event.Param3);
  281. break;
  282. }
  283. }
  284. }
  285. static void prvService_Task(void* params)
  286. {
  287. zbar_image_scanner_t *zbar_scanner;
  288. zbar_image_t *zbar_image;
  289. zbar_symbol_t *zbar_symbol;
  290. CBDataFun_t CBDataFun;
  291. PV_Union uPV;
  292. PV_Union uColor;
  293. HANDLE JPEGEncodeHandle = NULL;
  294. OS_EVENT Event;
  295. uint32_t i;
  296. CBFuncEx_t CB;
  297. Core_SetRGB565FixValue(0xff, 0xff, 0xff);
  298. // Audio_Test();
  299. while(1)
  300. {
  301. Task_GetEventByMS(prvService.ServiceHandle, CORE_EVENT_ID_ANY, &Event, NULL, 0);
  302. switch(Event.ID)
  303. {
  304. case SERVICE_SCAN_KEYBOARD:
  305. SoftKB_ScanOnce();
  306. break;
  307. case SERVICE_DECODE_QR:
  308. if (Event.Param3)
  309. {
  310. //此处代码可以更换成第三方解码
  311. CBDataFun = (CBDataFun_t)(Event.Param3);
  312. uPV.u32 = Event.Param2;
  313. zbar_scanner = zbar_image_scanner_create();
  314. zbar_image_scanner_set_config(zbar_scanner, 0, ZBAR_CFG_ENABLE, 1);
  315. zbar_image = zbar_image_create();
  316. zbar_image_set_format(zbar_image, *(int*)"Y800");
  317. zbar_image_set_size(zbar_image, uPV.u16[0], uPV.u16[1]);
  318. zbar_image_set_data(zbar_image, Event.Param1, uPV.u16[0] * uPV.u16[1], zbar_image_free_data);
  319. if (zbar_scan_image(zbar_scanner, zbar_image) > 0)
  320. {
  321. zbar_symbol = (zbar_symbol_t *)zbar_image_first_symbol(zbar_image);
  322. free(Event.Param1);
  323. //解码完成回调
  324. CBDataFun(zbar_symbol->data, zbar_symbol->datalen);
  325. }
  326. else
  327. {
  328. free(Event.Param1);
  329. //解码失败回调
  330. CBDataFun(NULL, 0);
  331. }
  332. zbar_image_destroy(zbar_image);
  333. zbar_image_scanner_destroy(zbar_scanner);
  334. }
  335. else
  336. {
  337. free(Event.Param1);
  338. }
  339. break;
  340. case SERVICE_ENCODE_JPEG_START:
  341. JPEGEncodeHandle = jpeg_encode_init(prvService.JPEGEncodeWriteFun, prvService.JPEGEncodeWriteParam, Event.Param2, Event.Param1 >> 16, Event.Param1 & 0x0000ffff, 3);
  342. break;
  343. case SERVICE_ENCODE_JPEG_RUN:
  344. if (JPEGEncodeHandle)
  345. {
  346. uColor.u32 = Event.Param1;
  347. switch(Event.Param3)
  348. {
  349. case COLOR_MODE_YCBCR_422_CBYCRY:
  350. uPV.pu8 = malloc((Event.Param2 >> 1) * 3);
  351. if (!uPV.pu8)
  352. {
  353. DBG("jpeg encode no momery");
  354. break;
  355. }
  356. Event.Param2 >>= 2;
  357. for(i = 0; i < Event.Param2; i++)
  358. {
  359. uPV.pu8[i * 6 + 0] = uColor.pu8[i * 4 + 1];
  360. uPV.pu8[i * 6 + 1] = uColor.pu8[i * 4 + 0];
  361. uPV.pu8[i * 6 + 2] = uColor.pu8[i * 4 + 2];
  362. uPV.pu8[i * 6 + 3] = uColor.pu8[i * 4 + 3];
  363. uPV.pu8[i * 6 + 4] = uColor.pu8[i * 4 + 0];
  364. uPV.pu8[i * 6 + 5] = uColor.pu8[i * 4 + 2];
  365. }
  366. jpeg_encode_run(JPEGEncodeHandle, uPV.pu8, 0);
  367. free(uPV.pu8);
  368. break;
  369. case COLOR_MODE_RGB_565:
  370. uPV.pu8 = malloc((Event.Param2 >> 1) * 3);
  371. if (!uPV.pu8)
  372. {
  373. DBG("jpeg encode no momery");
  374. break;
  375. }
  376. Event.Param2 >>= 1;
  377. for(i = 0; i < Event.Param2; i++)
  378. {
  379. RGB565toRGB888(uColor.pu16[i], uPV.pu8 + i * 3, 1);
  380. }
  381. jpeg_encode_run(JPEGEncodeHandle, uPV.pu8, 1);
  382. free(uPV.pu8);
  383. break;
  384. case COLOR_MODE_GRAY:
  385. uPV.pu8 = malloc(Event.Param2 * 3);
  386. if (!uPV.pu8)
  387. {
  388. DBG("jpeg encode no momery");
  389. break;
  390. }
  391. for(i = 0; i < Event.Param2; i++)
  392. {
  393. uPV.pu8[i * 3 + 0] = uColor.pu8[i];
  394. uPV.pu8[i * 3 + 1] = uColor.pu8[i];
  395. uPV.pu8[i * 3 + 2] = uColor.pu8[i];
  396. }
  397. jpeg_encode_run(JPEGEncodeHandle, uPV.pu8, 1);
  398. free(uPV.pu8);
  399. break;
  400. default:
  401. break;
  402. }
  403. }
  404. free(Event.Param1);
  405. break;
  406. case SERVICE_ENCODE_JPEG_END:
  407. if (JPEGEncodeHandle)
  408. {
  409. jpeg_encode_end(JPEGEncodeHandle);
  410. free(JPEGEncodeHandle);
  411. JPEGEncodeHandle = NULL;
  412. }
  413. if (Event.Param1)
  414. {
  415. CB = (CBFuncEx_t)Event.Param1;
  416. CB(NULL, Event.Param2);
  417. }
  418. break;
  419. case SERVICE_RUN_USER_API:
  420. CB = (CBFuncEx_t)Event.Param1;
  421. CB(Event.Param2, Event.Param3);
  422. break;
  423. }
  424. }
  425. }
  426. extern int luat_fs_init(void);
  427. static void prvLuatOS_Task(void* params)
  428. {
  429. // 文件系统初始化
  430. // luat_fs_init();
  431. // 载入LuatOS主入口
  432. luat_main();
  433. // 永不进入的代码, 避免编译警告.
  434. // for(;;)
  435. // {
  436. // vTaskDelayUntil( &xLastWakeTime, 2000 * portTICK_RATE_MS );
  437. // }
  438. }
  439. extern void luat_base_init(void);
  440. uint32_t Core_LCDDrawCacheLen(void)
  441. {
  442. if (prvService.LCDDrawRequireByte > prvService.LCDDrawDoneByte)
  443. {
  444. return (uint32_t)(prvService.LCDDrawRequireByte - prvService.LCDDrawDoneByte);
  445. }
  446. else
  447. {
  448. return 0;
  449. }
  450. }
  451. void Core_LCDDraw(LCD_DrawStruct *Draw)
  452. {
  453. prvService.LCDDrawRequireByte += Draw->Size;
  454. Task_SendEvent(prvService.LCDHandle, SERVICE_LCD_DRAW, Draw, 0, 0);
  455. }
  456. void Core_LCDDrawBlock(LCD_DrawStruct *Draw)
  457. {
  458. PV_Union uPV;
  459. uint64_t StartUS;
  460. // if (Draw->Speed > 30000000)
  461. // {
  462. // SPI_SetTxOnlyFlag(Draw->SpiID, 1);
  463. // }
  464. SPI_SetNewConfig(Draw->SpiID, Draw->Speed, Draw->Mode);
  465. // SPI_DMATxInit(Draw->SpiID, LCD_SPI_TX_DMA_STREAM, 0);
  466. // SPI_DMARxInit(Draw->SpiID, LCD_SPI_RX_DMA_STREAM, 0);
  467. prvCore_LCDCmd(Draw, 0x2a);
  468. BytesPutBe16(uPV.u8, Draw->x1 + Draw->xoffset);
  469. BytesPutBe16(uPV.u8 + 2, Draw->x2 + Draw->xoffset);
  470. prvCore_LCDData(Draw, uPV.u8, 4);
  471. prvCore_LCDCmd(Draw, 0x2b);
  472. BytesPutBe16(uPV.u8, Draw->y1 + Draw->yoffset);
  473. BytesPutBe16(uPV.u8 + 2, Draw->y2 + Draw->yoffset);
  474. prvCore_LCDData(Draw, uPV.u8, 4);
  475. prvCore_LCDCmd(Draw, 0x2c);
  476. GPIO_Output(Draw->CSPin, 0);
  477. // StartUS = GetSysTickUS();
  478. // SPI_Transfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size, 2);
  479. SPI_BlockTransfer(Draw->SpiID, Draw->Data, Draw->Data, Draw->Size);
  480. // DBG("%u, %u", Draw->Size, (uint32_t)(GetSysTickUS() - StartUS));
  481. // if (Draw->Speed > 30000000)
  482. // {
  483. // Task_DelayUS(1);
  484. // }
  485. GPIO_Output(Draw->CSPin, 1);
  486. SPI_SetTxOnlyFlag(Draw->SpiID, 0);
  487. }
  488. void Core_CameraDraw(LCD_DrawStruct *Draw)
  489. {
  490. Task_SendEvent(prvService.LCDHandle, SERVICE_CAMERA_DRAW, Draw, 0, 0);
  491. }
  492. void Core_WriteSDHC(void *pSDHC, void *pData)
  493. {
  494. uint32_t *Param = malloc(8);
  495. Param[0] =((SDHC_SPICtrlStruct *)pSDHC)->CurBlock;
  496. Param[1] = ((SDHC_SPICtrlStruct *)pSDHC)->EndBlock - ((SDHC_SPICtrlStruct *)pSDHC)->CurBlock;
  497. Task_SendEvent(prvService.StorgeHandle, SERVICE_SDHC_WRITE, pSDHC, pData, Param);
  498. }
  499. void Core_DecodeQR(uint8_t *ImageData, uint16_t ImageW, uint16_t ImageH, CBDataFun_t CB)
  500. {
  501. PV_Union uPV;
  502. uPV.u16[0] = ImageW;
  503. uPV.u16[1] = ImageH;
  504. Task_SendEvent(prvService.ServiceHandle, SERVICE_DECODE_QR, ImageData, uPV.u32, CB);
  505. }
  506. void Core_ScanKeyBoard(void)
  507. {
  508. Task_SendEvent(prvService.ServiceHandle, SERVICE_SCAN_KEYBOARD, 0, 0, 0);
  509. }
  510. void Core_SetRGB565FixValue(uint8_t R, uint8_t G, uint8_t B)
  511. {
  512. prvService.RFix = R & 0x07;
  513. prvService.GFix = G & 0x03;
  514. prvService.BFix = B & 0x07;
  515. }
  516. void Core_EncodeJPEGSetup(HANDLE Fun, void *pParam)
  517. {
  518. if (Fun)
  519. {
  520. prvService.JPEGEncodeWriteFun = Fun;
  521. }
  522. else
  523. {
  524. prvService.JPEGEncodeWriteFun = prv_CoreJpegSave;
  525. }
  526. prvService.JPEGEncodeWriteParam = pParam;
  527. }
  528. void Core_EncodeJPEGStart(uint32_t Width, uint32_t Height, uint8_t Quality)
  529. {
  530. Task_SendEvent(prvService.ServiceHandle, SERVICE_ENCODE_JPEG_START, (Width << 16 | Height), Quality, 0);
  531. }
  532. void Core_EncodeJPEGRun(uint8_t *Data, uint32_t Len, uint8_t ColorMode)
  533. {
  534. Task_SendEvent(prvService.ServiceHandle, SERVICE_ENCODE_JPEG_RUN, Data, Len, ColorMode);
  535. }
  536. void Core_EncodeJPEGEnd(CBFuncEx_t CB, void *pParam)
  537. {
  538. Task_SendEvent(prvService.ServiceHandle, SERVICE_ENCODE_JPEG_END, CB, pParam, 0);
  539. }
  540. void Core_PrintMemInfo(void)
  541. {
  542. uint32_t curalloc, totfree, maxfree;
  543. OS_MemInfo(&curalloc, &totfree, &maxfree);
  544. DBG("curalloc %uB, totfree %uB, maxfree %uB", curalloc, totfree, maxfree);
  545. }
  546. static uint8_t disassembly_ins_is_bl_blx(uint32_t addr) {
  547. uint16_t ins1 = *((uint16_t *)addr);
  548. uint16_t ins2 = *((uint16_t *)(addr + 2));
  549. #define BL_INS_MASK 0xF800
  550. #define BL_INS_HIGH 0xF800
  551. #define BL_INS_LOW 0xF000
  552. #define BLX_INX_MASK 0xFF00
  553. #define BLX_INX 0x4700
  554. if ((ins2 & BL_INS_MASK) == BL_INS_HIGH && (ins1 & BL_INS_MASK) == BL_INS_LOW) {
  555. return 1;
  556. } else if ((ins2 & BLX_INX_MASK) == BLX_INX) {
  557. return 1;
  558. } else {
  559. return 0;
  560. }
  561. }
  562. static void prvCore_PrintTaskStack(HANDLE TaskHandle)
  563. {
  564. uint32_t SP, StackAddress, Len, i, PC;
  565. uint32_t Buffer[16];
  566. if (!TaskHandle) return;
  567. char *Name = vTaskInfo(TaskHandle, &SP, &StackAddress, &Len);
  568. Len *= 4;
  569. DBG_Trace("%s call stack info:", Name);
  570. for(i = 0; i < 16, SP < StackAddress + Len; SP += 4)
  571. {
  572. PC = *((uint32_t *) SP) - 4;
  573. if ((PC > __FLASH_APP_START_ADDR__) && (PC < (__FLASH_BASE_ADDR__ + __CORE_FLASH_BLOCK_NUM__ * __FLASH_BLOCK_SIZE__)))
  574. {
  575. if (PC % 2 == 0) {
  576. continue;
  577. }
  578. PC = *((uint32_t *) SP) - 1;
  579. if (disassembly_ins_is_bl_blx(PC - 4))
  580. {
  581. DBG_Trace("%x", PC);
  582. i++;
  583. }
  584. }
  585. }
  586. }
  587. void Core_PrintServiceStack(void)
  588. {
  589. prvCore_PrintTaskStack(prvService.LCDHandle);
  590. prvCore_PrintTaskStack(prvService.UserHandle);
  591. prvCore_PrintTaskStack(prvService.ServiceHandle);
  592. prvCore_PrintTaskStack(prvService.StorgeHandle);
  593. }
  594. void Core_DebugMem(uint8_t HeapID, const char *FuncName, uint32_t Line)
  595. {
  596. int32_t curalloc, totfree, maxfree;
  597. OS_MemInfo(&curalloc, &totfree, &maxfree);
  598. if (!prvService.InitAllocMem)
  599. {
  600. prvService.InitAllocMem = curalloc;
  601. prvService.LastAllocMem = curalloc;
  602. DBG_Printf("base %d\r\n", prvService.InitAllocMem);
  603. }
  604. else
  605. {
  606. DBG_Printf("%s %u:total %d last %d\r\n", FuncName, Line, curalloc - prvService.InitAllocMem, curalloc - prvService.LastAllocMem);
  607. prvService.LastAllocMem = curalloc;
  608. }
  609. }
  610. static void Core_OTAReady(void)
  611. {
  612. prvService.FotaReady = 1;
  613. }
  614. int Core_OTAInit(CoreUpgrade_HeadStruct *Head, uint32_t size)
  615. {
  616. prvService.FotaReady = 0;
  617. PV_Union uPV;
  618. Flash_Erase(__FLASH_OTA_INFO_ADDR__, __FLASH_SECTOR_SIZE__);
  619. if (prvService.pFotaHead)
  620. {
  621. free(prvService.pFotaHead);
  622. }
  623. prvService.pFotaHead = Head;
  624. OS_ReInitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
  625. prvService.FotaPos = 0;
  626. uPV.u32 = prvService.pFotaHead->Param1;
  627. if (uPV.u8[1] == CORE_OTA_OUT_SPI_FLASH)
  628. {
  629. if (prvService.pSpiFlash)
  630. {
  631. free(prvService.pSpiFlash);
  632. }
  633. }
  634. prvService.FotaCRC32 = 0xffffffff;
  635. prvService.FotaPos = 0;
  636. prvService.FotaDoneLen = 0;
  637. prvService.FotaFindHead = 0;
  638. if (uPV.u8[1] == CORE_OTA_OUT_SPI_FLASH)
  639. {
  640. prvService.pSpiFlash = zalloc(sizeof(SPIFlash_CtrlStruct));
  641. prvService.pSpiFlash->SpiID = uPV.u8[2];
  642. uPV.u32 = prvService.pFotaHead->Param2;
  643. prvService.pSpiFlash->CSPin = uPV.u8[3];
  644. prvService.pSpiFlash->IsBlockMode = 1;
  645. SPIFlash_Init(prvService.pSpiFlash, NULL);
  646. if (!prvService.pSpiFlash->IsInit)
  647. {
  648. return -1;
  649. }
  650. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_ERASE, prvService.pFotaHead->DataStartAddress, size, Core_OTAReady);
  651. }
  652. else
  653. {
  654. prvService.FotaReady = 1;
  655. }
  656. return 0;
  657. }
  658. int Core_OTAWrite(uint8_t *Data, uint32_t Len)
  659. {
  660. if (!prvService.FotaFindHead)
  661. {
  662. if (Len < sizeof(CoreUpgrade_FileHeadStruct))
  663. {
  664. return -1;
  665. }
  666. CoreUpgrade_FileHeadStruct Head;
  667. memcpy(&Head, Data, sizeof(CoreUpgrade_FileHeadStruct));
  668. if (Head.MaigcNum != __APP_START_MAGIC__)
  669. {
  670. DBG("%x", Head.MaigcNum);
  671. return -1;
  672. }
  673. uint32_t crc32 = CRC32_Cal(prvService.CRC32_Table, &Head.MainVersion, sizeof(CoreUpgrade_FileHeadStruct) - 8, 0xffffffff);
  674. if (crc32 != Head.CRC32)
  675. {
  676. DBG("crc32 %x,%x", crc32, Head.CRC32);
  677. return -1;
  678. }
  679. //由于是整包升级,就不考虑版本的事情了
  680. prvService.FotaFindHead = 1;
  681. prvService.pFotaHead->DataLen = Head.DataLen;
  682. prvService.pFotaHead->DataCRC32 = Head.DataCRC32;
  683. prvService.pFotaHead->CRC32 = CRC32_Cal(prvService.CRC32_Table, &prvService.pFotaHead->Param1, sizeof(CoreUpgrade_HeadStruct) - 8, 0xffffffff);
  684. Data = Data + sizeof(CoreUpgrade_FileHeadStruct);
  685. Len -= sizeof(CoreUpgrade_FileHeadStruct);
  686. if (!Len) return 0;
  687. }
  688. uint32_t DummyLen;
  689. PV_Union uPV;
  690. uPV.u32 = prvService.pFotaHead->Param1;
  691. if (!prvService.pFotaHead )
  692. {
  693. return -1;
  694. }
  695. switch(uPV.u8[1])
  696. {
  697. case CORE_OTA_IN_FLASH:
  698. break;
  699. case CORE_OTA_OUT_SPI_FLASH:
  700. if (!prvService.pSpiFlash)
  701. {
  702. return -1;
  703. }
  704. break;
  705. case CORE_OTA_IN_FILE:
  706. break;
  707. }
  708. DummyLen = ((prvService.FotaDataBuf.MaxLen - prvService.FotaDataBuf.Pos) >= Len)?Len:(prvService.FotaDataBuf.MaxLen - prvService.FotaDataBuf.Pos);
  709. OS_BufferWrite(&prvService.FotaDataBuf, Data, DummyLen);
  710. if (prvService.FotaDataBuf.Pos == __FLASH_BLOCK_SIZE__)
  711. {
  712. switch(uPV.u8[1])
  713. {
  714. case CORE_OTA_IN_FLASH:
  715. prvService.FotaDataBuf.Pos = 0;
  716. prvService.FotaDoneLen += __FLASH_BLOCK_SIZE__;
  717. break;
  718. case CORE_OTA_OUT_SPI_FLASH:
  719. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_WRITE, prvService.pFotaHead->DataStartAddress + prvService.FotaPos, prvService.FotaDataBuf.Data, __FLASH_BLOCK_SIZE__);
  720. OS_InitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
  721. break;
  722. case CORE_OTA_IN_FILE:
  723. Task_SendEvent(prvService.StorgeHandle, SERVICE_FILE_WRITE, prvService.pFotaHead->FilePath, prvService.FotaDataBuf.Data, prvService.FotaDataBuf.Pos);
  724. OS_InitBuffer(&prvService.FotaDataBuf, __FLASH_BLOCK_SIZE__);
  725. break;
  726. }
  727. prvService.FotaPos += __FLASH_BLOCK_SIZE__;
  728. }
  729. else if ((prvService.FotaPos + prvService.FotaDataBuf.Pos) >= prvService.pFotaHead->DataLen)
  730. {
  731. // DBG("all data rx");
  732. switch(uPV.u8[1])
  733. {
  734. case CORE_OTA_IN_FLASH:
  735. prvService.FotaDoneLen += prvService.FotaDataBuf.Pos;
  736. OS_DeInitBuffer(&prvService.FotaDataBuf);
  737. break;
  738. case CORE_OTA_OUT_SPI_FLASH:
  739. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_WRITE, prvService.pFotaHead->DataStartAddress + prvService.FotaPos, prvService.FotaDataBuf.Data, prvService.FotaDataBuf.Pos);
  740. memset(&prvService.FotaDataBuf, 0, sizeof(prvService.FotaDataBuf));
  741. break;
  742. case CORE_OTA_IN_FILE:
  743. Task_SendEvent(prvService.StorgeHandle, SERVICE_FILE_WRITE, prvService.pFotaHead->FilePath, prvService.FotaDataBuf.Data, prvService.FotaDataBuf.Pos);
  744. memset(&prvService.FotaDataBuf, 0, sizeof(prvService.FotaDataBuf));
  745. break;
  746. }
  747. return 0;
  748. }
  749. if (DummyLen < Len)
  750. {
  751. OS_BufferWrite(&prvService.FotaDataBuf, Data + DummyLen, Len - DummyLen);
  752. }
  753. if (prvService.FotaDoneLen < prvService.FotaPos)
  754. {
  755. return (prvService.FotaPos - prvService.FotaDoneLen);
  756. }
  757. return 1;
  758. }
  759. uint8_t Core_OTACheckReadyStart(void)
  760. {
  761. return prvService.FotaReady;
  762. }
  763. int Core_OTACheckDone(void)
  764. {
  765. if (!prvService.pFotaHead )
  766. {
  767. return -1;
  768. }
  769. if (prvService.FotaDoneLen >= prvService.pFotaHead->DataLen)
  770. {
  771. return (prvService.FotaCRC32 == prvService.pFotaHead->DataCRC32)?0:-1;
  772. }
  773. return 1;
  774. }
  775. void Core_OTAEnd(uint8_t isOK)
  776. {
  777. PV_Union uPV;
  778. uPV.u32 = prvService.pFotaHead->Param1;
  779. if (isOK && prvService.pFotaHead)
  780. {
  781. Flash_Erase(__FLASH_OTA_INFO_ADDR__, __FLASH_SECTOR_SIZE__);
  782. Flash_Program(__FLASH_OTA_INFO_ADDR__, prvService.pFotaHead, sizeof(CoreUpgrade_HeadStruct));
  783. switch(uPV.u8[1])
  784. {
  785. case CORE_OTA_IN_FLASH:
  786. break;
  787. case CORE_OTA_OUT_SPI_FLASH:
  788. // Core_OTACheckSpiFlash();
  789. free(prvService.pSpiFlash);
  790. prvService.pSpiFlash = NULL;
  791. break;
  792. case CORE_OTA_IN_FILE:
  793. break;
  794. }
  795. }
  796. else
  797. {
  798. switch(uPV.u8[1])
  799. {
  800. case CORE_OTA_IN_FLASH:
  801. break;
  802. case CORE_OTA_OUT_SPI_FLASH:
  803. Task_SendEvent(prvService.StorgeHandle, SERVICE_SPIFLASH_CLOSE, 0, 0, 0);
  804. break;
  805. case CORE_OTA_IN_FILE:
  806. break;
  807. }
  808. }
  809. free(prvService.pFotaHead);
  810. prvService.pFotaHead = NULL;
  811. OS_DeInitBuffer(&prvService.FotaDataBuf);
  812. }
  813. void Core_ServiceRunUserAPIWithFile(CBFuncEx_t CB, void *pData, void *pParam)
  814. {
  815. Task_SendEvent(prvService.StorgeHandle, SERVICE_RUN_USER_API, CB, pData, pParam);
  816. }
  817. void Core_ServiceRunUserAPI(CBFuncEx_t CB, void *pData, void *pParam)
  818. {
  819. Task_SendEvent(prvService.ServiceHandle, SERVICE_RUN_USER_API, CB, pData, pParam);
  820. }
  821. void Core_LCDTaskInit(void)
  822. {
  823. prvService.LCDHandle = Task_Create(prvLCD_Task, NULL, 2 * 1024, HW_TASK_PRO, "lcd task");
  824. }
  825. void Core_ServiceInit(void)
  826. {
  827. CRC32_CreateTable(prvService.CRC32_Table, CRC32_GEN);
  828. prvService.ServiceHandle = Task_Create(prvService_Task, NULL, 4 * 1024, SERVICE_TASK_PRO, "service task");
  829. }
  830. void Core_UserTaskInit(void)
  831. {
  832. #ifdef __LUATOS__
  833. prvService.UserHandle = Task_Create(prvLuatOS_Task, NULL, 16*1024, LUATOS_TASK_PRO, "luatos task");
  834. luat_base_init();
  835. #endif
  836. }
  837. void Core_StorgeTaskInit(void)
  838. {
  839. prvService.StorgeHandle = Task_Create(prvStorge_Task, NULL, 2 * 1024, SERVICE_TASK_PRO, "storge task");
  840. }
  841. INIT_TASK_EXPORT(Core_LCDTaskInit, "0");
  842. INIT_TASK_EXPORT(Core_ServiceInit, "1");
  843. INIT_TASK_EXPORT(Core_StorgeTaskInit, "2");
  844. INIT_TASK_EXPORT(Core_UserTaskInit, "5");
  845. #endif